Nested ajax with nested rendered attribute in JSF - jsf

<h:form action="" prependId="false">
<h:selectOneRadio value="#{managedBean.color}" id="color">
<f:selectItem itemValue="red" itemLabel="Color1 - Red" />
<f:selectItem itemValue="green" itemLabel="Color1 - Green" />
<f:ajax event="click" render="group1" listener="#{managedBean.renderSubQuestions}"/>
</h:selectOneRadio>
<h:panelGroup id="group1">
<h:outputLabel value=" Color Description " rendered="#{managedBean.colorRender}"></h:outputLabel>
<h:inputText rendered="#{managedBean.colorRender}"></h:inputText>
<h:selectOneRadio id="number" value="#{managedBean.integer}" rendered="#{managedBean.colorRender}" >
<f:selectItem itemValue="1" itemLabel="Number1 - 1" />
<f:selectItem itemValue="2" itemLabel="Number1 - 2" />
<f:selectItem itemValue="3" itemLabel="Number1 - 3" />
<f:ajax event="click" render="group2 " listener="#{managedBean.renderSubQuestions}"/>
</h:selectOneRadio>
</h:panelGroup>
<h:panelGroup id="group2">
<h:outputLabel value="Number Description " rendered="#{managedBean.integerRender}"></h:outputLabel>
<h:inputText rendered="#{managedBean.integerRender}"></h:inputText>
</h:panelGroup>
</h:form>
In my scenario I used nested JSF AJAX with nested rendered attribute. If I select a color based on the selection, it rendered some radio button (addition elements) with AJAX. It is working fine, but additional elements with AJAX behavior is not working for me. If I remove rendered attribute in number radio button, it is working fine. I dont know where I did mistake.

It is most likely what your ManagedBean is not in ViewScoped or SessionScoped. When you post back to the bean, you are loosing rendered states. I suggest to change for the ViewScoped one.
Not related :
You should remove the action attribute from the h:form since JSF override it.

Related

jsf 1.2 update form without submit value

I have a form with JSF 1.2 & RichFaces 3.3.4.
Currently I'm able to use AJAX for update value. When I update the form (by clicking element value1) I properly update element value2, but the value1, that updates the form, is submitted.
I would like to update the element value2 of the form without submitting the element value1.
It is possible?
<h:form id="formId">
<h:selectOneMenu id="value1" value="#{searchCriteria.value1}">
<f:selectItem itemLabel="---" itemValue="#{null}" />
<f:selectItem itemLabel="a" itemValue="a" />
<f:selectItem itemLabel="b" itemValue="b" />
<a4j:support event="onchange" action="#{searchCriteria.changeAction}"
reRender="value2" />
</h:selectOneMenu>
<h:selectOneMenu id="value2" value="#{searchCriteria.value2}">
<f:selectItems value="#{searchCriteria.valueList}" />
</h:selectOneMenu>
<a4j:commandButton action="#{searchCriteria.search}" value="Search"
reRender="formId" />
</h:form>

Conditionally render depend on p:selectOneMenu value

I'm trying to build a custom component from existing Primefaces components and I need some help here. I have a selectOneMenu and I want it to render or not (and disable or enable) other components according to which option is selected in the menu. The hard thing here is that I can't do it using a Managed Bean (I have a few reasons for that), I need a pure xhtml code.
I tried some <c:choose> and <ui:parameter> stuff to create booleans but for some reason that I can't see it's not working. Could you guys take a look at my code and see if you have any ideas? It may be something simple that I can't figure or something I don't know yet.
<h:body>
<h:form id="abc">
<ui:repeat var="pd" value="#{produtoMB.produtos}">
<h:panelGroup id="linha">
<c:choose>
<c:when test="#{pd.marca == X1}">
<c:set var="render" value="#{true}" />
</c:when>
<c:otherwise>
<c:set var="render" value="#{false}" />
</c:otherwise>
</c:choose>
<p:selectOneMenu value="#{pd.marca}">
<f:selectItem itemLabel="Select One" itemValue="" noSelectionOption="true"/>
<f:selectItem itemLabel="Xbox One" itemValue="X1" />
<f:selectItem itemLabel="PlayStation 4" itemValue="PS4" />
<f:selectItem itemLabel="Wii U" itemValue="WU" />
<p:ajax update="linha" />
</p:selectOneMenu>
<p:inputText value="#{pd.aparelho}" disabled="#{render}"/>
<h:outputText value="Microsoft" rendered="#{render}"/>
<p:commandButton value="X" />
</h:panelGroup>
<br />
</ui:repeat>
<br />
<p:commandButton actionListener="#{produtoMB.botaoMais}" value="+" update="abc"/>
<p:commandButton actionListener="#{produtoMB.botaoMenos}" value="-" update="abc"/>
</h:form>
There are a couple of issues here.
First,
<ui:repeat ...>
<c:choose>
...
</c:choose>
</ui:repeat>
JSTL tags run during view build time. It's executed only once before all JSF component runs. So, on contrary to what you'd intuitively expect from the XML code flow, it isn't executed when the <ui:repeat> component runs and iterates. See also JSTL in JSF2 Facelets... makes sense?
Second,
<c:when test="#{pd.marca == X1}">
...
<f:selectItem ... itemValue="X1" />
The itemValue="X1" represents a String. The EL expression #{X1} basically looks for a variable named X1 in respectively the facelet, request, view, session, and application scopes until the first non-null value is found. In order to represent a String value in EL, you need to quote it with singlequotes like so #{'X1'}. So, you should have used #{pd.marca == 'X1'} instead. Nonetheless, this still won't work for the reason mentioned in the first point. See also Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work.
You can however use <c:set> to create an alias in the EL scope, as long as you don't set its scope attribute. See also Defining and reusing an EL variable in JSF page.
After removing JSTL <c:choose> and fixing the EL expression #{X1} to represent a real String literal #{'X1'}, here's how it should look like:
<ui:repeat var="pd" value="#{produtoMB.produtos}">
<p:selectOneMenu value="#{pd.marca}">
<f:selectItem itemLabel="Select One" itemValue="#{null}" />
<f:selectItem itemLabel="Xbox One" itemValue="X1" />
<f:selectItem itemLabel="PlayStation 4" itemValue="PS4" />
<f:selectItem itemLabel="Wii U" itemValue="WU" />
<p:ajax update="linha" />
</p:selectOneMenu>
<h:panelGroup id="linha">
<c:set var="marcaIsX1" value="#{pd.marca eq 'X1'}" />
<p:inputText value="#{pd.aparelho}" disabled="#{marcaIsX1}" />
<h:outputText value="Microsoft" rendered="#{marcaIsX1}" />
</h:panelGroup>
<p:commandButton value="X" />
</ui:repeat>
Note that I also removed the unused noSelectionOption="true" and moved the <h:panelGroup id="linha"> to wrap only the components which really need to be updated.

Conditionally render other component when radiobutton is changed

I am trying to display a menu if a radiobutton is selected. I'm using the rendered attribute for this purpose.
Model:
private int type; // +getter+setter
View:
<h:selectOneRadio value="#{bean.type}">
<f:selectItem itemLabel="A" itemValue="1"/>
<f:selectItem itemLabel="B" itemValue="2"/>
</h:selectOneRadio>
<h:form id="formMention" rendered="#{bean.type == 1}">
<h:selectOneMenu ...>
<f:selectItems ... />
</h:selectOneMenu>
</h:form>
Nothing shows when I check A. How can I achieve this?
Normally, you'd grab ajax for this, but as you're apparently on dead JSF 1.x, which lacks ajax fanciness, you're resorted to "plain" HTML/JS as long as you don't want to introduce an ajax capable component library. One of the ways is just submitting the form outright on click of the radio button.
<h:form>
<h:selectOneRadio value="#{bean.type}" onclick="this.form.submit()">
<f:selectItem itemLabel="A" itemValue="1"/>
<f:selectItem itemLabel="B" itemValue="2"/>
</h:selectOneRadio>
</h:form>
<h:form id="formMention">
<h:selectOneMenu ... rendered="#{bean.type == 1}">
<f:selectItems ... />
</h:selectOneMenu>
</h:form>

show a panel in primefaces depending on a dropdownlist

I have a drop down list with several values and I want to show a panel only if a value has been selected
Here is the code simplified
<p:selectOneMenu id="" value="#{myBean.myElement}" >
<f:selectItem itemLabel="Choose an element itemValue="" />
<f:selectItems value="#{myBean.myElementList}" />
<p:ajax update="myPanel" listener="#{myBean.handleChange}"/>
</p:selectOneMenu>
<p:panel id="myPanel" header="My Header" style="margin-bottom:10px;" rendered="#{myBean.myElement != null}">
But this does not seem to work (it works only if I refresh manually the page).
How could you fix this ?
Since myPanel is not rendered, the component won't be in the component tree, so it cannot be updated later in the view. Use another UIContainer to wrap it like <h:panelGroup> and update this container:
<p:selectOneMenu id="" value="#{myBean.myElement}" >
<f:selectItem itemLabel="Choose an element itemValue="" />
<f:selectItems value="#{myBean.myElementList}" />
<!-- here update to foo instead of myPanel -->
<p:ajax update="foo" listener="#{myBean.handleChange}"/>
</p:selectOneMenu>
<h:panelGroup id="foo">
<p:panel id="myPanel" header="My Header" style="margin-bottom:10px;"
rendered="#{myBean.myElement != null}">
</h:panelGroup>

Change Attribute Display Type from Managed Bean in JSF

In my scenario i need to change attribute display type from managed bean using ajax
<h:inputText id="text1" value="#{managedBean.value}" />
<h:selectOneRadio value="#{managedBean.option}">
<f:selectItem itemValue="Yes" itemLabel="Yes" />
<f:selectItem itemValue="No" itemLabel="No" />
<f:ajax listener="#{managedBean.changeAttrDisplayType}" event="click" render="text1"/>
</h:selectOneRadio>
If i click yes in the radio button,then attribute(id=text1) will render as textbox and if i click No then attribute (id=text1) will be render as label.
Is it possible ?Please Guide me ...
Yes! this is possible! put your h:inputText and h:outputLabel in a h:panelGroup and in the ajax event rerender the h:panelGroup. Put the condition of which one you want to render in the respective rendered attribute like bellow:
<h:panelGroup id="changingPanel">
<h:outputLabel id="id1"
rendered="#{managedBean.option == 'Yes'}"
value="This is label"/>
<h:inputText id="id2" value="#{managedBean.input}"
rendered="#{managedBean.option == 'No'}" />
</h:panelGroup>
<h:selectOneRadio value="#{managedBean.option}">
<f:selectItem itemValue="Yes" itemLabel="Yes" />
<f:selectItem itemValue="No" itemLabel="No" />
<f:ajax event="click" render="changingPanel"/>
</h:selectOneRadio>
Assumed that, you want to display outputLabel when "Yes" is selected and inputText when "No" is selected.

Resources