Dynamic navigation with parameter passing in JSF - jsf

I want to pass the "title" parameter in the following listing dynamicaly to another jsf Facelet, depending on the selection of the selectOneMenu. My first approach looks like this:
<h:form id="form">
<p:selectOneMenu value="#{exerciseEditorBean.selectedExerciseType}" >
<f:selectItem itemLabel="Multiple Choice Exercise" itemValue="MultipleChoiceExercise" />
<f:selectItem itemLabel="Vocabulary Test" itemValue="VocabularyTest" />
</p:selectOneMenu>
<h:outputText value="Enter Title of your Exercise: " />
<h:inputText id="title" value="#{exerciseEditorBean.exerciseTitle}" />
<h:commandButton value="Next" action="#{exerciseEditorBean.openEditor()}" />
</h:form>
The ExerciseEditorBean is ViewScoped.
The openEditor() function then decides by the selectedExerciseType attribute which Facelet to show next and returns something like "multipleChoiceEditor.xhtml".
How can I now pass the titel attribute to this Facelet?

I now use the f:ViewParam in the target servelet, which works well except, that "multipleChoiceEditor.xhtml?includeViewParams=true" does not work, but this is another issue. Thanks for the discussion!

Related

Why is only the getter invoked on the inputText value expression?

<h:form>
First Name: <h:inputText value="#{studentFormBean.fname}" /> <br/><br/>
Last Name: <h:inputText value="#{studentFormBean.lname}" /> <br/><br/>
Country :
<h:selectOneMenu value="#{studentBean.country}">
<f:selectItem itemValue="Brazil" itemLabel="Brazil" />
<f:selectItem itemValue="US" itemLabel="US" />
<f:selectItem itemValue="UK" itemLabel="UK" />
<f:selectItem itemValue="Myanmar" itemLabel="Myanmar" />
</h:selectOneMenu>
<h:commandButton value="Submit" action="FormResponse"/>
</h:form>
At this code, "#{studentFormBean.fname}" should point to setFname() in StudentFormBean.java but it point to getFname(). Why is this happened and how can I solve it?
#{studentFormBean.fname} will use both the getter and setter if used in an editable value holder like h:inputText. It will get the current value when the input is rendered. It will set the submitted when the for is submitted (and validation and conversion have passed).
See also:
Debugging JSF Life Cycle - what exactly happens in each phase

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.

how do I pass outputtext to other form

as simple as this. But the outputtext is not passed to another function or form. inputtext of course works but looks ugly.
What should I subsititute outputtext with?
<h:form>
<h:outputtext value="xx" />
<h:commandButton action="#{serviceTest.function() }" value="test"
</h:commandButton>
</h:form>
Real world example
<p:column id="average" sortBy="#{resultClub.stringAverage}">
<f:facet name="header">Snitt</f:facet>
<h:outputText id="testing" value="#{resultClub.stringAverage}" />
<h:inputHidden id="hiddenAvg" value="#{resultClub.stringAverage}" />
</p:column>
javax.faces.component.UpdateModelException: javax.el.PropertyNotFoundException: /hcp/showAverages.xhtml #96,74 value="#{resultClub.stringAverage}": Property 'stringAverage' not writable on type com.jk.hcp.ResultClub
javax.faces.component.UIInput.updateModel(UIInput.java:867)
javax.faces.component.UIInput.processUpdates(UIInput.java:749)
org.primefaces.component.api.UIData.process(UIData.java:328)
After you described the problem to me, I figure it out for you...
You can do this by using javascript
Outputtext:
<h:outputText id="text1" value="xx" />
Button:
<h:commandButton value="click me"
action="#{serviceTest.function()}" value="test"
onclick="submitFieldValue()" >
</h:commandButton>
XHTML:
This will set the myfield instance variable in your controller. It basically will generate a java script function at compile time which will be able to call the controller.
<a4j:jsFunction name="setTheValue">
<a4j:actionparam name="param" assignTo="#{serviceTest.myfield}"/>
</a4j:jsFunction>
JavaScript:
This will call setTheValue with the outputtext value
function submitFieldValue(){
var x = document.getElementById("text1").value;
setTheValue(x);
}
If you want to have the "xx" value submitted after clicking on the commandButton, you can either use hidden field for it
<h:inputHidden value="some text" />
or you can use
<h:inputText readonly="true" />
which will render the text in an input text that user cannot change (it may look like the outputText), but its value will be submitted after clicking the button.
What I understand is that you want to view some data in the outputtext after the button is pressed, right?
Please if I got it wrong, tell me to delete the answer!
Is this case you need to make the button renders the outputfield upon clicked:
Outputtext:
<h:outputText id="text1" value="#{serviceTest.text1Value}" />
Button:
<a4j:commandButton value="click me"
action="#{serviceTest.function() }" value="test"
render="text1" >
</a4j:commandButton>
As you can see I used a4j:commandButton which will enable me to render any element on the page by id upon click.

Validator is called but error message is not displayed

when i click on the command button. validate method is getting called but the error message is not getting displayed..
here is my code..
<h:form id="form">
<h:body>
<p:panel style="width:500px">
<h:outputLabel for="year" value="Select Year: *" style="font-weight:bold" />
<p:selectOneMenu id="year" value="#{leaveBean.year}">
<f:selectItem itemLabel="Select One" itemValue="null" />
<f:selectItems value="#{leaveBean.yearDTO}" var="currentUser" itemValue="#{currentUser.name}" itemLabel="#{currentUser.name}" />
<f:validator validatorId="LeaveCardValidator" />
</p:selectOneMenu>
</p:panel>
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="updateList,updateDetails" id="button"/>
<h:message for="year" style="color:red"/>
You seem to expect that JSF auto-updates the <h:message> on every ajax request. This is untrue. Perhaps you're confusing with PrimeFaces <p:messages> or <p:growl> which have each an autoUpdate attribute which enables you to tell them to auto-update themselves on every ajax request.
You really need to make sure that the <h:message> is covered by the ajax update. Just give it an ID
<h:message id="yearMessage" ... />
and include it in the client ID collection of the ajax update
<p:commandButton ... update="updateList updateDetails yearMessage" />
An alternative would be to replace <h:message> by <p:messages autoUpdate="true">.
Not sure where are the updateList and updateDetails are located but in the example give above you should use update="#form" instead or in addtion like this:
update="updateList updateDetails #form"
so that the form will be rendered again...
just use one of these :
update the whole form in order to update the content of
<h:message />
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="#form" id="button"/>
or give the <h:message /> an id and id this id to the <p:commandButton/>
<h:message id="msg" for="year" style="color:red"/>
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="updateList,updateDetails,msg" id="button"/>

How to set JSF input field value before submit

I a have a JSF page with PrimeFaces with some input fields. Before a submit is done, I would like to use the value of a field as input for a method which does some calculations and updates another field with the result but without submitting the form.
This is the field that will be used as input for my method:
<h:outputLabel for="hiredate" value="#{msgs['addUser.hireDate']}" />
<p:calendar id="hiredate" value="#{userWizardMB.user.hireDate}" required="true" immediate="true"/>
<p:message for="hiredate" />
The calculation is done by clicking a <p:commandButton>:
<p:commandButton value="Calculate days" icon="ui-icon-circle-check" action="#{userWizardMB.calculateVacationDays}" update="vacationDays" process="#this" immediate="true"/>
And this is the method called:
public void calculateVacationDays() {
user.setVacationDays((int) vacationDaysCalculator
.calculateWithHireDate(user.getHireDate()));
}
When debugging, though, I see that this field is NULL even if I set value in the form.
How can I force the setting of this field - user.hireDate because I really need this value for my calculation?
Thank you
Edit: I removed all of the other fields in the form and the immediate attribute:
<h:form id="addUserForm">
<p:wizard widgetVar="wizard" flowListener="#{userWizardMB.onFlowProcess}">
<!-- TAB FOR PERSONAL DATA -->
<p:tab id="personal" title="#{msgs['addUser.personalTab']}">
<p:panel header="#{msgs['addUser.personalInformation']}">
<p:message for="vacationDays" showDetail="true" autoUpdate="true" closable="true"/>
<h:panelGrid columns="3" columnClasses="label, value" styleClass="grid">
<h:outputLabel for="hiredate" value="#{msgs['addUser.hireDate']}" />
<p:calendar id="hiredate" value="#{userWizardMB.user.hireDate}" required="true" />
<p:message for="hiredate" />
<h:outputLabel for="vacationDays" value="#{msgs['addUser.vacationDays']}"/>
<p:inputText id="vacationDays" value="#{userWizardMB.user.vacationDays}"/>
<p:commandButton value="Calculate days" icon="ui-icon-circle-check" action="#{userWizardMB.calculateVacationDays}" process="#this hiredate" update="vacationDays"/>
</h:panelGrid>
</p:panel>
</p:tab>
</p:wizard>
</h:form>
And the backing bean method is still not called.
Remove immediate="true" from the input and the command component. Do not use immediate unless you really understand what it should be used for. Further you also need to include the input component which you'd like to process in the update attribute of the command component. Note that this should represent the client ID, not the property name as mentioned in one of your comments.
<p:calendar id="hiredate" value="#{userWizardMB.user.hireDate}" required="true" />
...
<p:commandButton value="Calculate days" icon="ui-icon-circle-check"
action="#{userWizardMB.calculateVacationDays}"
process="#this hiredate" update="vacationDays" />
See also:
Why was "immediate" attribute added to the EditableValueHolders?
Use process="#form" (or process="[the id of the calendar component]" in the commandButton
process="#this" means that only the part of the model related to the commandButton (usually none) gets updated.
Old question, but did you add partialSubmit="true" in the commandButton tag? At least in PrimeFaces 3.5, false is the default value of this attribute (see the PrimeFaces PDF documentation).

Resources