Primefaces selectBooleanCheckbox with binding - jsf-2

i am trying to make composite component(multiply use on each view) which allows me to show some inputs by checkbox value. One input is depended on checkbox value. I dont want to bind it to bean cause this value is not saved to database or so. I though that i ll save it in view scope holder.
I ve added in face config holder for bindings
<managed-bean>
<description>Holder of all component bindings.</description>
<managed-bean-name>components</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
composite component:
<p:selectBooleanCheckbox binding="#{components[cc.attrs.bindingId]}">
<p:ajax update="panel"/>
</p:selectBooleanCheckbox>
<h:panelGroup id="panel">
<p:inputText rendered="#{components[cc.attrs.bindingId].value}" value="#{cc.attrs.beanPropertyOnTrue}">
<p:inputText rendered="#{not components[cc.attrs.bindingId].value}" value="#{cc.attrs.beanPropertyOnFalse}">
</h:panelGroup>
It works fine, I can use this component multiply on one view, but the problem is when i am using commandButton to send form to server, checkboxes are changing to unchecked....
<p:commandButton value="show decision dialog"
actionListener="#{testBean.action}"
update="#form"
oncomplete="if (args && !args.validationFailed){ dialog.show() }"/>

Related

Primefaces dialog client validation not displaying

I have a Primefaces 5.0 modal dialog on a composite control. The dialog has a few field marked as required. When the button on the dialog is clicked I expected the client validation to fire and it seems it does as the backing bean is not called, but the messages are not displaying:
<p:dialog id="dialogCorporateShareHolder" header="Shareholder (Company)"
widgetVar="dlgCorporateShareHolder" modal="true">
<p:panelGrid columns="3" id="corporateShareHolderDetails">
<h:outputLabel for="companyName" value="Company name"/>
<p:inputText id="companyName" required="true"
value="#{cc.attrs.corporateShareHolder.companyName}"
label="Company name"/>
<p:message for="companyName"/>
<f:facet name="footer">
<p:commandButton id="submitCorporate" value="Submit"
update="corporateShareholders"
actionListener="#{cc.attrs.controller.addCorporateShareHolder}"/>
</f:facet>
</p:panelGrid>
</p:dialog>
The dialog displays, the validation gets called (I'm pretty sure), but no message is displayed.
You only need to update the p:message or a parent too, for example with
update="corporateShareholders corporateShareholderDetails"
Btw. I believe best practises are to
have the dialog(s) last in xhtml, outside of other forms
have a form inside the dialog itself

Primefaces commandButton inside dialog not firing backing bean's method

I've just started learning JSF and PrimeFaces, and as soon as I solve a problem (with your help), another one arises. I have a datatable showing some data about my application's users; in the last column, a commandButton invokes a dialog allowing the corresponding data to be edited. The dialog actually interacts with the backing bean, since the fields are correctly precompiled with the existing data, but the "Submit changes" commandButton doesn't fire the proper editUser() method!
I've searched everywhere for a solution to my problem, but none of the threads on the PrimeFaces forums nor any question here on Stack Overflow helped me: I tried all combinations of action, actionListener, inner <h:form>, outer <h:form>, even the dreaded nested <h:form>, but the underlying method is still not called.
Thank you all, people!
EDIT: I included some more xhtml. Just to be clear: in the datatable I'm implementing both single and multiple selection mechanisms. The single selection is performed by the editButton in the last column and triggers the editDialog that's giving me pain, while multiple selection is enabled by the checkboxes in the first column and is targeted by a commandButton at the bottom of the table that deletes all selected users; of course they store the selections in different fields in the backing bean (selectedUser and selectedUsers[], respectively).
xhtml file
<h:form id="tableForm">
<p:dataTable id="userList" var="user" value="#{userListBean.userList}"
selection="#{userListBean.selectedUsers}" rowKey="#{user.username}">
<!-- this is a checkbox column I use for multiple selection -->
<p:column selectionMode="multiple" style="width:2%"/>
<!-- other datatable columns -->
<!-- this is the button column that triggers the dialog -->
<p:column style="width:4%">
<p:commandButton id="editButton" update=":tableForm:editUserData"
oncomplete="PF('editDialog').show()" title="Edit" icon="ui-icon-pencil">
<f:setPropertyActionListener target="#{userListBean.selectedUser}"
value="#{user}" />
</p:commandButton>
</p:column>
</p:datatable>
<p:dialog id="editDlg" widgetVar="editDialog" header="Edit User"
showEffect="fade" hideEffect="fade" modal="true" dynamic="true">
<h:panelGrid columns="6" id="editUserData">
<p:outputLabel for="editUsername">Username:</p:outputLabel>
<p:inputText disabled="true" id="editUsername" value="#{userListBean.selectedUser.username}" />
<p:message for="editUsername" />
<!-- and other fields like that -->
</h:panelGrid>
<p:commandButton id="submitChanges" action="#{userListBean.editUser()}"
value="Submit changes" oncomplete="PF('editDialog').hide();" />
</p:dialog>
</h:form>
Backing bean
#ManagedBean(name="userListBean")
#ViewScoped
public class UserListBean {
private UserDTO selectedUser;
public UserListBean() {
}
//some methods...
public String editUser() {
System.out.println("------------------ EDIT TRIGGERED! -------------------");
System.out.println(selectedUser.getUsername());
//this stuff never gets printed, so the method is never called!
}
//getters and setters
}
Actually, the only thing didn't come to my mind turned out to be the one that worked.
I sorted out my issue by using THREE forms (as I mentioned in my question, I had already tried out all possible combinations of one and two forms, even nested ones), like this:
<h:form id="tableForm">
<!-- here lies the p:dataTable -->
</h:form>
<p:dialog>
<h:form id="dialogForm">
<!-- here lies the h:panelGrid with the editable fields -->
</h:form>
<h:form id="buttonForm">
<!-- and HERE goes the commandButton, alone -->
</h:form>
</p:dialog>
It looks like everyone solves this problem in ways that don't work for others :) .

how to reset form inputs after they are submitted in jsf

so i have this code(not in details)
<p:tabView id="tabviewId">
<p:tab>
<h:form id="mainHeadOfAccountsId_form">
// some input fields with validation
// using viewscoped
<p:commandButton value="Add" process="mainHeadOfAccountsId_form" update="mainHeadOfAccountsId_form :#{p:component('allMainHeadOfAccountsId_table')} :#{p:component('successfullySavedUpdatedId_growl')}" action="#{budgetHeadOfAccountsAction.addMainHeadOfAccountsOnAjax}" />
/// also using <p:datatable id= "allMainHeadOfAccountsId_table" >
</h:form
</p:tab>
<p:tab>
<h:form>
</h:form
</p:tab>
</p:tabView>
<p:growl id="successfullySavedUpdatedId_growl" for="successfullySavedUpdatedFor_growl" value="error" showDetail="false" />
my Question is that when i submit form mainHeadOfAccountsId_form successfully i need to update(reset) all fields which are in mainHeadOfAccountsId_form
but remember that i am also using <h:selectOneMenu> so i want to reset(option[0] selected) not empty, how can i do that ? currently its updating allMainHeadOfAccountsId_table and successfullySavedUpdatedId_growl except mainHeadOfAccountsId_form
i have tired tabviewId:mainHeadOfAccountsId_form but getting exception component not found,
as i am thinking this is just because of #viewScoped and i should reset value of those inputs in my action class (.java), m i right ?
see what primefaces offer for reset input or after submitting the form by the action in the bean reset the values by new or null and recreate the list held by
<h:selectOneMenu>

ignoreValidationFailed doesn´t work inside ui:repeat

I´m using o:ignoreValidationFailed, but it doesn´t work inside the ui:repeat. When I do the same outside, it works! I tried with mojarra ans MyFaces... I´m using primefaces. If there is another way to skip the validations only for one button...
<o:form id="rateplanEditByPeriod" prependId="false">
<p><p:messages id="mensagensDlg"/></p>
<p:tabView id="tabs">
<p:tab title="Cancelamento" id="tabCanc">
<h:panelGrid id="cancelationsTable" columns="2" cellpadding="10px" columnClasses="alignTop,alignTop">
<ui:repeat id="repeat" var="rest" value="#{rateplanByPeriodManaged.rateplanByPeriod.restriction.restTypeCancelation.restTypeCanConfs}" >
<h:panelGrid columns="8">
<p:inputText id="penaltyValue_#{loop.index}" value="#{rest.penalityValue}" style="width:28px" label="Valor" title="Valor" disabled="#{rest.noCancel}" required="true"/>
<p:commandLink id="add_#{loop.index}" actionListener="#{rateplanByPeriodManaged.addCancConf}" update=":rateplanEditByPeriod:tabs:cancelationsTable" partialSubmit="true" process=":rateplanEditByPeriod:tabs:cancelationsTable" value="+">
<o:ignoreValidationFailed />
</p:commandLink>
<p:commandLink actionListener="#{rateplanByPeriodManaged.removeCancConf(rest)}" value="-" update=":rateplanEditByPeriod:tabs:cancelationsTable" partialSubmit="true" process=":rateplanEditByPeriod:tabs:cancelationsTable">
<o:ignoreValidationFailed />
</p:commandLink>
</h:panelGrid>
</ui:repeat>
</h:panelGrid>
</p:tab>
</p:tabView>
<p:commandLink styleClass="button" onclick="dlgEdit.hide()" immediate="true" update=":msgsPanel">#{msgs['inventory.editByPeriod.cancel']}</p:commandLink>
<p:commandLink styleClass="button" actionListener="#{rateplanByPeriodManaged.editByPeriod(loginManaged.hotelSelected)}" oncomplete="if (!args.validationFailed) {dlgEdit.hide(); updateAllSearches(); updateAllNotifications();}" update="mensagensDlg, tabs" >#{msgs['inventory.editByPeriod.confirm']}</p:commandLink>
</o:form>
I have faced the same issue but with p:datatable
I solved it with
1- add a condition to the required field to know if the ajax come from submit button or not
as #Camilla said.
required="#{!empty param['trans_desc_form:savetransid']}"/>
trans_desc_form is the entire form id and savetransid is the submit button save id
2- I removed #NotNull from my JPA entity which force the validation
#JoinColumn(name = "ITEMNO", referencedColumnName = "ITEMNO")
#ManyToOne(optional = false, fetch = FetchType.LAZY)
//#NotNull
private Item item;
I have created a question for this issue
ignoreValidationFailed doesn´t work inside p:dataTable
I don´t know if it´s the best aproach but it worked for me...
<h: inputText id="text1" value="" required="#{!empty param['formName:btnSave']}" />
This is not the right way to have a "Cancel" button.
Just put process="#this" in the <p:commandLink>, or if you don't need to do any business logic, make it a normal <h:link> which reloads the page (and thus implicitly recreates the request/view scoped bean).
As to <o:ignoreValidationFailed> the failure in <ui:repeat> on its own, please create an issue.

Create new data objects with a popup panel fails

Here I am again with a JSF problem, this time it is more about richfaces (4.2.1 final, JSF 2). I have an eytended DataTable and want to add new items. There ist the List of Journey-objects, every attribute have getter and setter. The table is created well (there are already some items in the list). And now I click the "add new item" button:
<a4j:commandButton ajax="true" value="Neue Fahrt hinzufügen"
actionListener="'{editorBean.prepareCreateJourney}" render="createJourneyPopupForm"
oncomplete="#{rich:component('createJourneyPopup')}.show()" />
The editorBean is SessionScoped, the method is properply called and create a new object of Journey called currentJourney. A popup comes up and should allow me to insert some input:
<rich:popupPanel id="createJourneyPopup" modal="true">
<h:panelGrid id="createJourneyPopupForm" columns="3">
<h:outputLabel for="currentId" value="ID" />
<h:inputText id="currentId"
value="#{editorBean.currentJourney.journeyNumber}" />
<rich:message for="currentId" />
[...and more...]
</h:panelGrid>
<a4j:commandButton value="Save"
execute="currentId currentTrainType operator">
<f:ajax event="click" listener="#{editorBean.doCreateJourney}"
render=":vmsEditorForm:resultTable" />
<rich:componentControl target="createJourneyPopup" operation="hide" />
</a4j:commandButton>
<a4j:commandButton value="Abbrechen"
onclick="#{rich:component('createJourneyPopup')}.hide();" />
</rich:popupPanel>
When i clicked the button, the method doCreateJourney is called, but the currentJourney is empty. It is the default Journey object after creating it. No setter was called, do a hint on the inputfields.
I checked the names twice, there are getters and setters for alle needed objects. I tried to change the scope, but no effect. Objects are the same, in the prepare method i created Journey(id=151) and in the save method it is still Journey(id=151).
What is going on here? I can't be this difficult to make some dialogs to create and edit data objects. Thank you for listening and for your help!
You need to wrap both your inputs and your commandButtons in a form in order to correctly submit the data.
<rich:popupPanel id="createJourneyPopup" modal="true">
<h:form>
... the content of your popupPanel
</h:form>
</rich:popupPanel>
Regards,

Resources