Why does h:selectOneRadio does not have a "name" attribute? - jsf

I want to do some crazy grouping with SelectOneRadio, so I decide to create my own custom component that allow me to specify the name attribute of the <input> tag (as you know, same name means the radio buttons are in the same group). The renderer is correct, so I have a <input> that used to render like this
<input name="myForm:test1" id="myForm:test1:0" value="0" type="radio">
now render like this
<input name="foo" id="myForm:test1:0" value="0" type="radio">
However, EL stop working when I submit a form (same for h:commandButton and p:commandButton). So if I have this
<xxx:selectOneRadio id="test1" value="#{myBean.selectedFood}">
then EL work, selectedFood print out the corrected value, but if I put in
<xxx:selectOneRadio id="test1" value="#{myBean.selectedFood}" groupId="foo">
which will make the name=foo in the <input> tag. Then EL binding stop working. selectedFood is null.
More interestingly, If I put in this
<xxx:selectOneRadio id="test1" value="#{myBean.selectedFood}" groupId="myForm:test1">
which myForm:test1 is the correct client Id, then EL binding work again, so it does not look like it is my code that make the binding stop working. Does JSF require the name attribute of the input tag to the client id?

The name becomes the HTTP request parameter name and this has to be used to collect submitted HTTP request parameter values. This defaults to the JSF component client ID and the collecting happens in the decode() method of the Renderer (or the UIComponent itself). You need to override/implement the decode() of the Renderer as well to change the way how you get request parameter values.

Related

<a jsf:rendered="#{...}"> is not interpreted as passthrough element

I don't understand why this piece of code is working:
<h:link value="Login" rendered="#{sessionBean.userInSessionBean == null}" />
and this piece of code is not working:
<a jsf:rendered="#{sessionBean.userInSessionBean == null}">Login</a>
A HTML element will only become a passthrough element if following conditions are met:
There's at least one jsf:xxx attribute from http://xmlns.jcp.org/jsf namespace.
There's at least one "identifying attribute" associated with a specific JSF component.
For the <a> element an identifying attribute is necessary so JSF can decide whether to interpret it as <h:commandLink>, <h:outputLink> or <h:link>. Without an identifying attribute, JSF wouldn't have any idea what component you actually meant to use, so any jsf:xxx attributes will be ignored. The jsf:rendered is not sufficient as identifying attribute because it appears on every single JSF component, so JSF would still have no idea which one you meant.
Given that you seem to intend to have a <h:link>, then use jsf:outcome as identifying attribute.
<a jsf:outcome="login" jsf:rendered="#{empty sessionBean.userInSessionBean}">Login</a>
A completely different alternative is to wrap plain HTML in an <ui:fragment rendered>. See also How to conditionally render plain HTML elements like <div>s?

JSF h:link rendered span [duplicate]

I'm getting this warning in my application
JSF1090: Navigation case not resolved for component j_idt51
What is the reason for this warning and how can I resolve it? The strange thing is that the component id j_idt51 is not in the rendered page. If I look to the HTML of the generated page there is no element with id j_idt51.
This warning will occur whenever you use an (implicit) navigation outcome in the outcome attribute of <h:link> or <h:button>, which does not represent a valid view ID.
E.g.
<h:link ... outcome="viewIdWhichDoesNotExist" />
<h:button ... outcome="viewIdWhichDoesNotExist" />
Additionally, the <h:link> will render a <span> element instead of an <a> element.
The solution is obvious: use a valid view ID, or make at least sure that the desired view is resolveable by ConfigurableNavigationHandler#getNavigationCase().
Note that some starters use for an unknown reason even a full URL like http://google.com as outcome value of <h:link>:
<h:link value="Go to Google" outcome="http://google.com" />
This abuse would then also yield exactly this warning. You should be using <h:outputLink> or just <a> instead.
As to the absence of a HTML element with the same ID as the JSF component, this may happen when you didn't explicitly specify the JSF component's id attribute. The JSF component ID does then not necessarily end up in the generated HTML output. Assigning those components a fixed ID should help better in nailing down the cause.

Update attribute in JSF custom component expect full element ID path where as direct PrimeFaces component runs with short element ID path

I am using <p:commandButton> tag with update attribute and passing current element ID in update attribute as currentForm: messages. something like: update="currentForm: messages". Where messages is the id of <div> element which I want to update after request call.
This is working fine.
Now I created a composite component with the same command button as we have in main template and replaces that PrimeFaces command button with created custom command button. (for now no any custom changes made in created command button just prime faces command button in this)
When I rendered the template it is complaining me about the ID given update attribute error given as:
javax.faces.FacesException: Cannot find component with expression "currentForm
and if I give full element ID path for this element it works again.
Although it is good if we give full element ID path to the element, but it surprise me why it is working when I am calling direct PrimeFaces command button ?
That's because composite components are like <h:form>, <h:dataTable>, etc also naming containers. Their effect on ajax client IDs is outlined in this related question: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".
This is done so because you otherwise run into "duplicate component ID" errors on composite component's implementation when reusing the composite component more than once in the same naming container parent. See also this related question: Should a composite component really require namingcontainer interface?
If you're absolutely positive that the composite component is the right solution for the concrete requirement and thus not a tagfile (a lot of starters namely overuse composite components due to their zero-configuration nature, while it should really best only be used if you intend to bind a single model property to a bunch of closely related components), then you may consider the following alternative ways to update the messages component:
Either dynamically pass the target client ID:
<my:compositeButton ... update=":#{messages.clientId}" />
...
<p:messages binding="#{messages}" ... />
(note: the code is as is; you don't need to bind it to a bean property or so!)
Or just let PrimeFaces auto-update the messages component on every ajax request:
<my:compositeButton ... />
...
<p:messages autoUpdate="true" ... />

commandlink in JSF not generating the intended HTML tag

I'm trying to call a managed bean from h:commandLink in JSF. But I don't see href attribute in the rendered HTML a tag.
Am I missing something?
There is a ManagedBean called AccountSetupController with a signUp method in it.
This is the tag I used in JSF:
<h:form prependId="false">
<h:commandLink action="#{accountSetupController.signUp()}"
value="#{msg['homepage.createaccount']}" styleClass="button large">
</h:commandLink>
</h:form>
This is the rendered tag. See there is nothing in href attribute.
<a href="#" onclick="mojarra.jsfcljs(document.getElementById('j_idt15'),
{'j_idt33':'j_idt33'},'');return false"
class="button large">CREATE MY ACCOUNT</a>
This is the form tag that is generated
<form id="j_idt15" name="j_idt15"
method="post" action="/myproject/faces/homepage/homepage.xhtml"
enctype="application/x-www-form-urlencoded"> .... </form>
As you can see, the form action is pointing to some place I don't need.
Am I missing something?
Command links in JSF are rendered that way. The form will be submitted by JSF via JavaScript's onclick method using JSF JS library, while the href will always stay #.
Moreover, you won't find the bound action / action listener method names in browser tools due to understandable reasons. Rather, JSF will find the id of a clicked link on the server and will trigger all of the component's action(listeners).
All in all, reading <h:commandLink> documentation unsurprisingly helps a lot (all emphasis mine):
General behavior: Both the encode and decode behavior require the ability to get the id/name for a hidden field, which may be rendered in markup or which may be programmatically added via client DOM manipulation, whose value is set by the JavaScript form submit (further referred to as hiddenFieldName.
Decode behavior: Obtain the "clientId" property of the component. Obtain the Map from the "requestParameterMap" property of the ExternalContext. Derive hiddenFieldName as above. Get the entry in the Map under the key that is the hiddenFieldName. If the there is no entry, or the entry is the empty String, or the entry is not equal to the value of the "clientId" property, return immediately. If there is an entry, and its value is equal to the value of the "clientId" property, create a new javax.faces.event.ActionEvent instance around the component and call queueActionEvent() on the component, passing the event.
Encode behavior: Render "#" as the value of the "href" attribute. Render the current value of the component as the link text if it is specified. Render JavaScript that is functionally equivalent to the following as the value of the "onclick" attribute: document.forms['CLIENT_ID']['hiddenFieldName'].value='CLIENT_ID'; ocument.forms['CLIENT_ID']['PARAM1_NAME'].value='PARAM1_VALUE'; document.forms['CLIENT_ID']['PARAM2_NAME'].value='PARAM2_VALUE'; return false; document.forms['CLIENT_ID'].submit()" where hiddenFieldName is as described above, CLIENT_ID is the clientId of the UICommand component, PARAM*_NAME and PARAM*_VALUE are the names and values, respectively, of any nested UIParameter children.

rendered attribute on inputText

I have a search form tied to a backing bean that contains 4 input text fields. The design i am working from indicates that the user should be able to see the search results, but they should not be editable. i decided to use the rendered attribute to show the inputs if the managed bean is empty, and to show an output text tag if it's not:
<t:inputText styleClass="inputText" id="name" rendered="#{not searchCriteria.fieldsEntered}"
value="#{searchCriteria.name}" autocomplete="off"></t:inputText>
<h:outputText value="#{searchCriteria.name}" rendered="#{searchCriteria.fieldsEntered}"></h:outputText>
The display part works correctly, but I am noticing that only the first field is stored in the managed bean when more than 1 search field is entered.
I removed a rendered attribute from an inputText, and sure enough that's causing my problems. I can infer what's going on here, but I don't understand why.
I believe in this situation I will just remove the outputText tags and change rendered to disabled. I am just curious why my initial plan is incorrect.
The rendered="false" will cause the input element not being rendered and thus its value will not be submitted to the server side. If you're using a request scoped bean, the initial value will not be set. You'd like to either put the bean in session scope or to add a h:inputHidden along the h:outputText which transfers the value to the subsequent request.
Since you're already using Tomahawk's t:inputText I'd suggest to rather use its displayValueOnly attribute instead of the rendered attribute and a complementary h:outputText.
In a nut:
<t:inputText displayValueOnly="#{searchCriteria.fieldsEntered}" ... />

Resources