I need to trigger action on the p:selectCheckboxMenu when user finishes his selection(s) (on close). the datatable need to be updated with new selected columns(done).
I couldn't find the event name of the ajax behavior that suits this principal role of a Menu.the default ajax behavior of the p:selectCheckboxMenu updates the datatable on every selection which is annoying for me and the user, i need only the p:selectCheckboxMenu to trigger action when it is closed.
Here is my code :
<p:selectCheckboxMenu id="colser"
scrollHeight="100"
filterMatchMode="contains"
filter="true"
label="Colonnes"
value="#{datatableBean.selectedstateOptions}">
<f:selectItems value="#{datatableBean.columner}"
var="list"
itemLabel="#{list.listname}"
itemValue="#{list.headername}"/>
<p:ajax event="close_event_name_here"
update=":form1:tabexam"
listener="#{datatableBean.updateCols()}"/>
</p:selectCheckboxMenu>
You can try onhide attribute of the p:selectCheckboxMenu.
<p:selectCheckboxMenu id="colser"
scrollHeight="100"
filterMatchMode="contains"
filter="true"
label="Colonnes"
value="#{datatableBean.selectedstateOptions}"
onHide="executeOnOnhide();>
<f:selectItems value="#{datatableBean.columner}"
var="list"
itemLabel="#{list.listname}"
itemValue="#{list.headername}"/>
</p:selectCheckboxMenu>
<p:remoteCommand name="executeOnOnhide"
update=":form1:tabexam" process="#this form:colser"
action="#{datatableBean.updateCols()}"/>
The link for the documentation guide for primefaces for your reference
http://primefaces.org/documentation.html
Hope this helps
Related
I am validating a user entered account number using two validators, one for basic standard format, and the other that validates the account number against values stored in a database. The database of valid account numbers may not always be up to date so I want to allow the user to override and submit their entered account number but only after the database validation has failed. I always want to validate its standard format 8 characters with no spaces.
<h:form id="formId">
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel value="Account : " for="acct" />
</p:column>
<p:column>
<p:selectOneMenu id="acct" value="#{bean.acct.acctNum}" effect="fold" editable="true" validator="acctLengthAndSpaceValidator" required="true" requiredMessage="Required">
<f:selectItems value="#{bean.mySavedAccounts}" var="acct"
itemLabel="#{acct.acctNumber} itemValue="#{acct.acctNumber}" />
<o:validator validatorId="accountDatabaseValidator" disabled="#{bean.skipDbValidation}" />
</p:selectOneMenu>
</p:column>
<p:column>
<p:messages for="acct" showDetail="true" skipDetailIfEqualsSummary="true" />
</p:column>
</p:row>
</p:panelGrid>
<br />
<p:selectBooleanCheckbox rendered="#{facesContext.validationFailed}" value="#{bean.skipDbValidation}" itemLabel="I know this account is really valid, please skip validation and let me submit!">
<p:ajax update="#this" listener="#{bean.testListener()}" />
</p:selectBooleanCheckbox>
<p:commandButton value="Submit" action="#{bean.submit()}" update="formId"/>
</h:form>
The checkbox does appear after the form is initially submitted and has any validation failure (I will figure out how to isolate to just the failed accountDatabaseValidator). But then when I select the checkbox, and submit again, both validators are still fired. I added the ajax listener to debug, and it isn't firing and the boolean value skipDbValidation is still false.
Perhaps my approach is not correct in achieving my concrete goal of validating against the database but then giving the user the option of skipping the db validation after initial failure.
EDIT
if i remove rendered="#{facesContext.validationFailed}" from the checkbox and have it visible all the time, the boolean skipDbValidation will get set to true if the checkbox is checked and then on subsequent submit, the skipDbValidation is ignored as expected. But I do not want the checkbox allowing the user to bypass visible at first. Only after validation fails.
The technical explanation that this doesn't work is that the rendered attribute is re-evaluated during processing the form submit. At this point the faces context is not validationFailed anymore (it was only validationFailed during the previous request) and thus the component is not rendered anymore and then the component's submitted value won't be applied. This matches #6 of commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated.
Your work around by rendering it client-side rather than server-side is acceptable. But I gather that you wanted to show it only when the specific validator has been invoked. There are at least 2 ways to achieve this:
Check UIInput#isValid() of the input component of interest. You can achieve that by binding the component to the view (not to the bean!) via component's binding attribute so you can reference it elsewhere in the same view.
<p:selectOneMenu binding="#{acct}" ...>
...
</p:selectOneMenu>
...
<p:selectBooleanCheckbox styleClass="#{acct.valid ? 'ui-helper-hidden' : ''}" ...>
...
</p:selectBooleanCheckbox>
Note that I took the opportunity to reuse the PrimeFaces-provided style class.
Or, make the validator a view scoped bean and reference it via <o:validator binding> instead.
#Named
#ViewScoped
public class AccountDatabaseValidator implements Validator, Serializable {
private boolean validationFailed;
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
// ...
validationFailed = !isValid(value);
if (validationFailed) {
throw new ValidatorException(createError("Invalid value"));
}
}
public boolean isValidationFailed() {
return validationFailed;
}
}
<p:selectOneMenu ...>
<o:validator binding="#{accountDatabaseValidator}" ... />
</p:selectOneMenu>
...
<p:selectBooleanCheckbox rendered="#{accountDatabaseValidator.validationFailed}" ...>
...
</p:selectBooleanCheckbox>
My work around to get the checkbox to programmatically display and so the checkbox would function was to hide and display using CSS instead of the render attribute.
style="#{facesContext.validationFailed ? 'Display: inline' : 'Display: none;'}"
<p:selectBooleanCheckbox style="#{facesContext.validationFailed ? 'Display: inline' : 'Display: none;'}" value="#{bean.skipDbValidation}" itemLabel="I know this account is really valid, please skip validation and let me submit!">
<p:ajax update="#this" />
</p:selectBooleanCheckbox>
But I still can't figure out how to display the checkbox for a specific validation failure.
I will post another question for that
EDIT
Here is how I ended up displaying the checkbox only after the Invalid Account validation failure.
<p:selectBooleanCheckbox style="#{facesContext.messageList.stream()
.anyMatch(v -> v.summary == 'Invalid Account') or
bean.skipDbValidation ? 'Display: inline' : 'Display: none;'}"
value="#{bean.skipDbValidation}" itemLabel="I know this account is really valid, please skip validation and let me submit!">
<p:ajax update="#this" />
</p:selectBooleanCheckbox>
I am having a problem, I am firing a ajax event in a selectOneMenu like this: the first one does not fire any event
<p:selectOneMenu id="IdSelectOne" value="#{MB.myentity.myValue}" converter="myConverter1">
.....
</p:selectOneMenu>
<p:selectOneMenu id="IdSelectTwo" converter="myConverter2">
<p:ajax event="change" process="#this" partialSubmit="true"
listener="#{MB.ChangeOption}" update="creatPanel" >
</p:ajax>
</p:selectOneMenu>
The problem is that when the ajax event updates the panel, the first SelectOneMenu sets tu null, i can't use #form because it validates all fields and never do what I need which is show a field based on the selection of the second SelectOneMenu, is there a way to avoid this problem to happend?
This is my backing bean:
public void ChangeOption(AjaxBehaviorEvent event){
.....
}
I solved it by updating just the element I needed and not the complete panel, Thanks
hava an inputText and a gmap
<h:inputText class="text" value="#{restaurant.address}" />
<p:gmap id="gmap" center="21.027845,105.852268" zoom="12" type="ROADMAP"
style="width:360px;height:388px"
model="#{restaurant.emptyModel}"
onPointClick="handlePointClick(event);"
widgetVar="map">
First, address="", when i click on gmap, address="xxx" not null.So how can i show its value in inputText tag after clicking on gmap. Thank you!
You can just add an ajax event to the map
<p:gmap id="gmap" center="21.027845,105.852268" zoom="12"
type="ROADMAP" style="width:360px;height:388px"
model="#{restaurant.emptyModel}"
onPointClick="handlePointClick(event);" widgetVar="map">
<p:ajax event="pointSelect" update="theInputText"/>
</p:gmap>
Where theInputText is going to be the id of the <p:inputText/> to be updated
i ve this code in my application
i want to submit h:selectBooleanCheckbox value to server,
h:selectBooleanCheckbox inside p:tabView and outside p:dataTable
i want to submit h:selectBooleanCheckbox value from
p:ajax process="scenarioTabViewId:isApprovedBooleanId_checkBox"
scenarioTabViewId:isApprovedBooleanId_checkBox this is checkbox id created by firefox v23.0
and scenarioTabViewId:budgetAnalysisDataTableId this is datatable id
can any one explan,how can i do this?
this is actual code in .xhtml
<ui:composition template="/template/mastertemplate.xhtml">
<ui:define name="content">
<h:form styleClass="form" prependId="false">
<p:panel id="analysisTheBudgetPenel" header="Analysis The Budget">
<p:tabView id="scenarioTabViewId" style="width:850px">
<p:tab title="Scenario One" id="scen">
<h:selectBooleanCheckbox id="isApprovedBooleanId_checkBox" value="#{budgetAnalysisAction.budgetScenarioHescoProposalBean.abc}" />
<p:scrollPanel style="width:800px; height:auto;">
<p:dataTable id="budgetAnalysisDataTableId" rowIndexVar="index" editable="true" resizableColumns="true" value="#{budgetAnalysisAction.budgetScenarioHescoProposalBean.budgetScenarioHescoProposalListBean}" var="budgetScenarioHescoProposalList">
<p:ajax event="rowEdit" process="#{scenarioTabViewId:isApprovedBooleanId_checkBox}" listener="#{budgetAnalysisAction.testAjax}" />
// some columns
// closing tags of above
thanks in advance
First of all, remove <h:form prependId="false">. It's incompatible with ajax. Don't forget to give the form a fixed ID now.
<h:form id="formId" styleClass="form">
Secondly, the process attribute is in your case wrong, you were using an EL expression with the component's cliend ID as a variable in the EL scope. This isn't making any sense. Just make it a normal string.
The rules of referencing the proper client ID can be found in the following answer: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar". Applying that, it should look something like this (note the : prefix):
process=":formId:scenarioTabViewId:isApprovedBooleanId_checkBox"
An alternative would be to bind the physical checkbox component to the view like so:
<p:selectBooleanCheckbox binding="#{checkbox}" ... />
And then reference its client ID with help of UIComponent#getClientId() like so (also here, note the : prefix):
process=":#{checkbox.clientId}"
I am using an editable primefaces selectOneMenu to display some values. If the user selects an item from the List a textarea should be updated. However, if the user types something in the selectOneMenu, the textarea should not be updated.
I thought I could work this with ajax event out. However, I don't know which event I can use here. I only know the valueChange event. Are there any other events, like onSelect or onKeyUp?
Here is my code:
<p:selectOneMenu id="betreff" style="width: 470px !important;"
editable="true" value="#{post.aktNachricht.subject}">
<p:ajax event="valueChange" update="msgtext"
listener="#{post.subjectSelectionChanged}" />
<f:selectItems value="#{post.subjectList}" />
</p:selectOneMenu>
<p:inputTextarea style="width:550px;" rows="15" id="msgtext"
value="#{post.aktNachricht.text}" />
The PrimeFaces ajax events sometimes are very poorly documented, so in most cases you must go to the source code and check yourself.
p:selectOneMenu supports change event:
<p:selectOneMenu ..>
<p:ajax event="change" update="msgtext"
listener="#{post.subjectSelectionChanged}" />
<!--...-->
</p:selectOneMenu>
which triggers listener with AjaxBehaviorEvent as argument in signature:
public void subjectSelectionChanged(final AjaxBehaviorEvent event) {...}
I'd rather use more convenient itemSelect event. With this event you can use org.primefaces.event.SelectEvent objects in your listener.
<p:selectOneMenu ...>
<p:ajax event="itemSelect"
update="messages"
listener="#{beanMB.onItemSelectedListener}"/>
</p:selectOneMenu>
With such listener:
public void onItemSelectedListener(SelectEvent event){
MyItem selectedItem = (MyItem) event.getObject();
//do something with selected value
}
Be carefull that the page does not contain any empty component which has "required" attribute as "true" before your selectOneMenu component running.
If you use a component such as
<p:inputText label="Nm:" id="id_name" value="#{ myHelper.name}" required="true"/>
then,
<p:selectOneMenu .....></p:selectOneMenu>
and forget to fill the required component, ajax listener of selectoneMenu cannot be executed.
You could check whether the value of your selectOneMenu component belongs to the list of subjects.
Namely:
public void subjectSelectionChanged() {
// Cancel if subject is manually written
if (!subjectList.contains(aktNachricht.subject)) { return; }
// Write your code here in case the user selected (or wrote) an item of the list
// ....
}
Supposedly subjectList is a collection type, like ArrayList. Of course here your code will run in case the user writes an item of your selectOneMenu list.