Validation of a b:modal form is not working - jsf

I am trying to validate a modal form ( JSF/Bootsfaces ) and prevent it from being saved if the inputtext is not correct. For some reason I ignore it is not working, here is the JSF code:
<b:modal id="creation"
title="#{msgs['page.manageFlights.addingNew']}"
styleClass="formValidationModalClass"
closeOnEscape="false"
backdrop="false"
closable="false">
<b:form id="createModal">
<b:selectOneMenu
value="#{flightBean.currentFlight.journey}"
label="#{msgs['page.manageFlights.findAllJourneys']}"
required="true"
requiredMessage="Please select a journey"
large-screen="full-width">
<f:selectItems value="#{journeyBean.findAllJourneys()}" var="journey" itemValue="#{journey}" itemLabel="#{journey.departureLocation} -> #{journey.arrivalLocation}" />
</b:selectOneMenu>
<b:dateTimePicker
value="#{flightBean.currentFlight.departureDate}"
label="#{msgs['page.manageFlights.departureDate']}"
required="true"
requiredMessage="Please enter a date and time"
large-screen="full-width">
</b:dateTimePicker>
<b:dateTimePicker
value="#{flightBean.currentFlight.arrivalDate}"
label="#{msgs['page.manageFlights.arrivalDate']}"
required="true"
requiredMessage="Please enter a date and time"
large-screen="full-width">
</b:dateTimePicker>
<b:inputText value="#{flightBean.currentFlight.numberOfBusinessClassSeats}"
label="#{msgs['page.manageFlights.numberOfBusinessClassSeats']}"
required="true"
requiredMessage="The number of seats must be positive"
large-screen="full-width">
<f:validateLongRange minimum = "1" maximum = "2000" />
</b:inputText>
<b:inputText
value="#{flightBean.currentFlight.numberOfEconomyClassSeats}"
label="#{msgs['page.manageFlights.numberOfEconomyClassSeats']}"
required="true"
requiredMessage="Please enter a number"
validatorMessage="The number of seats must be positive"
large-screen="full-width">
</b:inputText>
<br/>
<b:row>
<b:column>
<b:commandButton
largeScreen="half"
value="#{msgs['cancel.button']}"
dismiss="modal"
action="#{flightBean.resetCurrentFlight()}"
oncomplete="$('#creation').modal('hide')"
/>
<b:commandButton
largeScreen="half"
dismiss="modal"
update="#(#dataTable)"
value="#{msgs['save.button']}" look="success"
action="#{flightBean.addFlight(flightBean.currentFlight)}"
oncomplete="if(!validationFailed) { $('#creation').modal('hide')};">
</b:commandButton>
</b:column>
</b:row>
<b:fetchBeanInfos/>
<b:messages/>
</b:form>
</b:modal>
I am trying to check if the number of business class seats is positive.
As you can see I added fetchbeaninfos, validateLongRange and oncomplete.

<b:fetchBeanInfos> and validationFailed only work after an AJAX request. You need to send the input to the server, have it validated there, and only when the response is sent back to the client, validationFailed is updated.
My suggestion is to use simple JavaScript to show the error message and to disable the button.
However, if you prefer to use server-side validation, here's what to do:
Add an empty validateInput() method to your bean. It doesn't need any implementation; it just has to be there so it can be called by an JSF AJAX call.
Add an id to <b:fetchBeanInfos>.
Add an AJAX change listener to each input field. Depending on the type of the input field, you may need a different listener (onblur, onchange, etc.), but the general idea is like so:
<b:inputText
onblur="ajax:flightBean.validateInput()"
update="**:fetchBeansId"
value="..."
label="..."
required="true"
requiredMessage="..."
validatorMessage="...">
</b:inputText>
<b:fetchBeanInfos id="fetchBeansId"/>
The **:idbit helps you if your JSF page has multiple "namespaces", such as forms, modals, data tables, and tabs. These namespaces add a prefix to the id, and **:id allows you to find the id no matter what the prefix is.

Related

Validation on checkbox and input field in jsf [duplicate]

I have a form which contains a dropdown and two input fields.
<h:selectOneMenu />
<h:inputText />
<h:inputText />
I would like to make the required attribute of the input fields conditional depending on the selected value of the dropdown. If the user chooses the first item of the dropdown, then the input fields must be required. If the user chooses the second item, then those would not be required.
How can I achieve this?
Just bind the dropdown to the view and directly check its value in the required attribute.
<h:selectOneMenu binding="#{menu}" value="#{bean.item}">
<f:selectItem itemValue="first" itemLabel="First item" />
<f:selectItem itemValue="second" itemLabel="Second item" />
</h:selectOneMenu>
<h:inputText value="#{bean.input1}" required="#{menu.value eq 'first'}" />
<h:inputText value="#{bean.input2}" required="#{menu.value eq 'first'}" />
Note that the binding example is as-is. Do absolutely not set it to a bean property here. See also How does the 'binding' attribute work in JSF? When and how should it be used?
Also note that the ordering of the components is significant. If the menu is located below the inputs in the tree, use #{menu.submittedValue eq 'first'} instead. Or if you want to be independent from that, use #{param[menu.clientId] eq 'first'} instead.
Assuming you are using JSF 2.0: Let your SelectOneListBox execute with ajax and re-render the input fields on change of the list box:
A quick sketch:
<h:selectOneMenu value="#{myBean.myMenuValue}">
<f:ajax render="input1"/>
..
</h:selectOneMenu>
<h:inputText id="input1" value="#{myBean.myInputValue}"
required="#{myBean.myMenuValue == 'firstEntry'}" />

How to pass knowledge of what button was pressed to a p:dialog

I'm trying to help users fill in entity Id numbers on a submittal form. I can't use a pulldown because there are 1000's.
In a PF dialog, I'm able to copy a selected value to the main form but I'm hardcoding the actionaListener into the commandLink to tell the popup dialog which h:textInput box on the main form to copy the value to and to render. If I have three h:inputText boxes I would then need to duplicate three p:dialogs.
For example in my p:dialog I would have a column in the datatable as such:
<h:commandLink value="Select This Item" onclick="PF('dlg').hide()">
<f:ajax render=":myForm:text_field_1" event="click"
listener="#{bean.popDownId1(item.id)}" />
</h:commandLink>
How can I pass those variables myForm:text_field_1 (the form name and field) to the p:dialog so that it becomes a more generic popup dialog? Also is there a way to not have to code a listener method for each field (popDownId1, popDownId2, etc...)As a bonus I'd also like to externalize the dialog and include it in every xhtml page instead of cutting and pasting as I'm doing now.
Here is more actual code:
form.xhtml
<h:form id="myForm">
<h:panelGrid columns="3">
<p:outputLabel value="Manager Employee Number: " />
<h:panelGroup>
<p:inputText id="managerId"
title="Type Employee Id or click the ? to search for their Id"
value="#{bean.department.manager}" >
<f:validator validatorId="com.company.app.EmployeeIdValidator" />
</p:inputText>
<p:commandButton title="Click here if you don't know their Employee Number"
id="managerId" value="Lookup Id"
onclick="PF('dlgManager').show();" type="button" >
</p:commandButton>
other fields and submit button
</h:form>
<p:dialog id="popup" modal="false" widgetVar="dlgManager" dynamic="true" >
<f:facet name="header">
<h:outputText value="Employee Number Finder" />
</f:facet>
<p>Search using any keyword.</p>
<h:form>
Keyword: <p:inputText id="search" value="#{employeeSearch.searchString}" />
<p:commandButton value="Search"
action="#{employeeSearch.searchByKeyword}">
<f:ajax execute="#form" render="output" />
</p:commandButton> (Enter keywords separated by spaces)
<p:dataTable id="output" var="employee" value="#{employeeSearch.employees}">
<p:column headerText="Action">
<h:commandLink value="Select" onclick="PF('dlgManager').hide()">
<f:ajax render=":myForm:managerId" event="click"
listener="#{bean.popDownManagerId(employee.id)}" />
</h:commandLink>
</p:column>
other columns(employee name, phone number, etc...)
</p:dialog>
you can see that I'd need to copy the dialog and tweak it a bit for every field on my form where I want to do an employee number lookup.
onclick="PF('dlgManager').show();">
onclick="PF('dlgSupervisor').show();">
onclick="PF('dlgFloorChief').show();">
EDIT
When applying BalusC's answer, if I add a second lookup Id button, the popup dialog to select an employee id has a command link which is tied to only the ManagerId field
action="#{bean.popDownManagerId(employee.id)}"
Also, when the second lookup id button is pressed the previous search results are still listed so the select command link would be referencing the wrong field to update
popup dialog

How to make one field from two required at least with JSF/Primefaces

I'm using primefaces with jsf and i want to make one of two fields required at least. that means that the error message will be displayed if this two fields are empties togheter:
this is a sample of my code:
<h:outputLabel for="srcNumber" value="Originator MSISDN (EXAMPLE 32495959595)" />
<p:inputText id="srcNumber" value="#{cdrMmscRecBean.srcNumber}" label="srcNumber" />
<h:outputLabel for="destNumber" value="Destination MSISDN (EXAMPLE 32495959595)" />
<p:inputText id="destNumber" value="#{cdrMmscRecBean.destNumber} label="destNumber" />
thanks :)
You can implement it this way:
<p:inputText id="srcNumber" value="#{cdrMmscRecBean.srcNumber}" label="srcNumber"
required="#{empty cdrMmscRecBean.destNumber}" requiredMessage="SRC Number Required">
<p:ajax event="change" update="destNumber" />
</p:inputText>
<p:inputText id="destNumber" value="#{cdrMmscRecBean.destNumber}" label="destNumber"
required="#{empty cdrMmscRecBean.srcNumber}" requiredMessage="DEST Number Required">
<p:ajax event="change" update="srcNumber" />
</p:inputText>
For more reference on how to parametrize your validation message:
Parametrized Messages in JSF with Facelets Taglib Functions
If you want to show the validation error use <p:message for="srcNumber" />
and same for test number, get rid of your outputLabels, this will show the validations warnings.
You neeed to add the required="true" flag to your inputTexts as well.
This is primefaces
EDIT
Purpose of the h:outputLabel and its "for" attribute this here shows the outputLabel for using non primefaces to show validatoin messages if this is all your problem was then u just need to add the required="true" validation flag indicators on your input texts

Richfaces and JSF/AJAX Lifecycles

I´ve managed to get the code to do what I intended, but I do not understand a particular aspect of why this works. I´m running Seam 2.2.2 with Richfaces 3.3.3.
Here is the code from the xhtml page:
...
<h:form id="radiobuttontestform">
<fieldset>
<h:panelGrid columns="3">
<h:selectOneRadio layout="pageDirection" id="myRadio" value="#{actionBean.myRadioButton}">
<f:selectItem itemLabel="First" itemValue="0" />
<f:selectItem itemLabel="Second" itemValue="1" />
<a4j:support event="onclick" ajaxSingle="true" process="myDropdown" reRender="myDropdown,myCount,test" />
</h:selectOneRadio>
<h:panelGrid columns="1" border="0">
<h:selectOneListbox size="1" id="myDropdown" value="#{actionBean.rowCountPredefined}" disabled="#{actionBean.myRadioButton != '0'}">
<f:selectItem itemLabel="10" itemValue="10" />
<f:selectItem itemLabel="20" itemValue="20" />
<f:selectItem itemLabel="30" itemValue="30" />
</h:selectOneListbox>
<h:inputText id="myCount" maxlength="5" value="#{actionBean.rowCountSpecified}" disabled="#{actionBean.myRadioButton != '1'}" required="true">
<f:validateLongRange minimum="1" maximum="1000" />
<rich:ajaxValidator event="onkeyup" for="myCount" />
</h:inputText>
<rich:message id="errorMessage" for="myCount" ajaxRendered="true" showDetail="false" showSummary="true">
<f:facet name="errorMarker">ERROR:</f:facet>
</rich:message>
</h:panelGrid>
</h:panelGrid>
</fieldset>
<h:outputLabel id="test" value="RadioValue: #{actionBean.myRadioButton}" />
<a4j:commandButton id="show" value="Show Values in Log" action="#{actionBean.showValues}" />
<a4j:commandButton id="done" value="Save and end conversation" action="#{actionBean.apply}" />
</h:form>
...
The backing bean is just a simple POJO with getters and setters for the three properties here. (myRadioButton, rowCountPredefined, rowCountSpecified)
This is what I get: (the correct result)
radio button example http://katzekat.de/Bilder/radio2.png
radio button example http://katzekat.de/Bilder/radio.png
Here is my thinking:
Setting ajaxSingle to true means that only the radio button will be processed on the server. The dropdown next to it doesn´t need validation - it will always contain a correct value. I´ve added the process="myDropdown" in order to persist the value into the backing bean, otherwise when I switch the radio button to position 2 the dropdown reverts to its original value. (I realise this is only cosmetic!) I´ve checked this with a debugger and it does indeed set the property in the backing bean and everything is working as expected.
Once the radio button is switched into position 2 a value can be entered in the textbox and will be validated. This works perfectly, and when I switch the radio button back to position 1, the validation error is cleared if this field is in an error state. Presumably because the error message is only present in the request scope.
Firing up the debugger again when the radio button is in position 2 and entering a valid value in the text field reveals no update on the backing bean when switching back to position 1. I also expected this as I´m telling only the radio and the dropdown to process on the server. This is the bit I don´t understand though - the value in the textfield is persisted on postback. (See 2nd link above) Where is this value for this textfield saved if not in the backing bean ?
Submitted form values are stored in component on Apply Request Values phase.
For example in your case javax.faces.component.html.HtmlInputText#decode method of the textfield calls javax.faces.component.UIInput#setSubmittedValue. The submitted values are not set to the bean (as you expected) as the component is not included to execute part. Then inputText's renderer re-displays (writes to the response) the submitted values.
It works pretty the same when validation fails. Submitted values are stored on Apply Request Values phase, and then because of failed validation the submitted values are not set to beans (Update Model Values phase is skipped), then the submitted values are re-displayed.

p:selectOneMenu, custom content and editable=true

I have the following usage of the p:selectOneMenu:
<p:selectOneMenu id="selectField"
value="#{someBean.someField}"
converter="#{selectItemConverter}" var="x" editable="true">
<f:selectItems
value="#{selectItemsBean.getSelectItems(tab, field)}" var="si"
itemLabel="#{si.label}" itemValue="#{si}" />
<p:column>
<h:outputText value="#{si.label}" />
</p:column>
<p:column>
<h:graphicImage library="images" name="noway_16x16.png"
title="#{si.disabledReason}" rendered="#{si.disabled}" />
</p:column>
<p:ajax event="change" update="#form" partialSubmit="true" process="selectField" />
</p:selectOneMenu>
As you can see, I use custom content in combination with editable=true. When I submit the form, the Converter gets the label of a selected item as the value, not the actual value. In the HTML page, the values are correct, e.g. <option value="C">C-style mounting</option>. With editable=false, the correct value (e.g. C is sent to the converter, with editable=true the converter retrieves C-style mounting.
What I want is that the user can either select one of the pre-defined items in the list and the server submits that value of the item OR the user enters something and that is submitted as value. But the current behavior is a bit strange - or am I just wanting too much?

Resources