Primefaces Calendar <f:ajax> and <p:ajax> issue - ajax

I am currently facing issue using with primefaces Calendar control
My requirement is to invoke a java method on change of the Calendar control value either from the input box or using the button and also pass a set of parameters(Java object and the field id) to the java method.
below is the code that I have implemented and it is not working
<p:calendar showOn="button" id="effectiveDt" navigator="true" pattern="MM/dd/yyyy"
styleClass="overrideable" value="#{coverage.startDate}">
<f:ajax event="change" render="hiddenStartDt" onevent="myEvent" listener="#{certInquiry.ovrrrideListener}"/>
<f:attribute name="covg" value="#{coverage}" />
<f:attribute name="field" value="StartDate" />
</p:calendar>
here myEvent is a java script method which will be called after the ajax is completed where i am checking the ajax status is success and performing some action.
method signature of the java method is.
*public void overrideListener(AjaxBehaviorEvent e) *
I tried with all kinds of methos signatures like
public overrideListener(ValueChangeEvent e)
public overrideListener(ActionEvent e)
public ovrrrideListener(DateSelectEvent event)
nothing was working for me
I have tried using also even this was not working
I also tried using valueChangeListener if the method gets called but it was not invoking the method
this is working for and fields using the
<h:selectBooleanCheckbox class="overrideable"
value="#{coverage.clIndicator}">
<f:ajax event="change" render="hidgenLiabClaimsMdInd" onevent="myEvent" listener="#{certInquiry.overrideListener}"/>
<f:attribute name="covg" value="#{coverage}" />
<f:attribute name="field" value="ClIndicator" />
</h:selectBooleanCheckbox>
<h:inputText id="genLiabEachOccAmt" value="#{coverage.eachOccAmt}"
class="amt_field overrideable">
<f:ajax event="change" render="hidgenLiabEachOccAmt" onevent="myEvent" listener="#{certInquiry.overrideListener}"/>
<f:attribute name="covg" value="#{coverage}" />
<f:attribute name="field" value="EachOccAmt" />
</h:inputText>
Please help me in solving this issue for the Calendar component.

Make the ajax event="dateSelect" and you should get the date value in your BB when you use ovrrrideListener(DateSelectEvent event).

Related

How to submit manual entered date in primefaces calendar?

I've got a form with two primefaces calendar input elements and a datatable on it. The calendar items are used to filter the result displayed in the table as from to values. Therefore I use an p:ajax ‘dateSelect’ event which is working fine when doing the manipulation with the mouse over the popup. But when I change the date manually in the input field with the keybord no change event is fired. When I use a second p:ajax event for blur or change I'm not able to get the new value.
<p:calendar id="startDate"
value="#{filterStart}"
required="true"
showOn="button"
maxdate="#{filterEnd}"
>
<p:ajax event="dateSelect"
listener="#{listController.onFilterStartChanged}"
update="filterTbl, endDate" />
<p:ajax event="change"
listener="#{listController.onFilterStartBlured}"
update="filterTbl, endDate"
process="#this"
partialSubmit="true" immediate="true" />
</p:calendar>
the method onFilterStartChanged gets called when selection is made over the pupup it's possible to read the new value:
public void onFilterStartChanged(final SelectEvent event) {...}
but the Keyboard changes are not fired when moving Focus to another component
public void onFilterStartBlured(final AjaxBehaviorEvent event) {
Date newDate = (Date)((Calendar)event.getSource()).getValue();
...
}
how can I get the new date?
I have same need with p:calendar in Primefaces 5.3 and it's work for me whit this code. I don't use event parameter
<p:calendar id="startDate"
value="#{filterStart}"
required="true"
showOn="button"
maxdate="#{filterEnd}">
<p:ajax event="dateSelect"
listener="#{listController.onFilterStartChanged()}"
update="filterTbl, endDate" />
<p:ajax event="change"
listener="#{listController.onFilterStartChanged()}"
update="filterTbl, endDate" />
</p:calendar>
no parameter in the method, value is in filterStart
public void onFilterStartChanged() {...}

How to conditionally run jsf Validator on blur event with p:ajax?

In my xhtml page I have inputText field with two Validators attached to it. Also there is ajax event "blur" attached for triggering validation when switching focus from a field. Here is the code:
<t:selectOneMenu id="locateRecordBy" value="#{personBean.locateRecordBy}">
<f:selectItems value="#{personBean.locateRecordByItems}"/>
</t:selectOneMenu>
<t:inputText id="personName"
value="#{personBean.name}"
required="true"
requiredMessage="Name is required.">
<p:ajax event="blur" partialSubmit="true" process="#this" update="nameerror" global="false" />
<f:validator disabled="#{param['PersonForm:locateRecordBy'] == 'FEMALE'}" validatorId="com.myapp.validators.MalePersonValidator"/>
<f:validator disabled="#{param['PersonForm:locateRecordBy'] == 'MALE'}" validatorId="com.myapp.validators.FemalePersonValidator"/>
</t:inputText>
So I'd like to validate personName against appropriate Validator depending of selecting item after focus is not anymore on the personName field. Any suggestions please, what should I change or add?
p.s. On form submit validation work very well.
Actually I found what was missing in my code. I added locateRecordBy componnent to be processed with ajax so instead of having this:
<p:ajax event="blur" partialSubmit="true" process="#this" update="nameerror" global="false" />
I have this:
<p:ajax event="blur" partialSubmit="true" process="#this, locateRecordBy" update="nameerror" global="false" />
Basically I forgot instruct JSF to process locateRecordBy and that's why locateRecordBy parameter was never present in the ajax request which caused both validators to be became disabled and validation of personName field to be skipped.

Dynamic disable validator when click checkbox

I got one number validator and one checkbox in my jsf. When a checkbox is selected then the number validator will check validation. When checkbox is unselected, the validation will skip it.
Please see my code
<h:outputText value="#{trancheResources.label_enable}:" />
<p:selectBooleanCheckbox id="enableCheckBox" itemLabel="#{trancheResources.label_yes}" value="#{trancheBean.enableCheck}" disabled="#{trancheBean.readonly}">
</p:selectBooleanCheckbox>
<p:outputLabel for="acceptableMinVal" value="#{trancheResources.label_acceptableMinVal}:" />
<pe:inputNumber id="acceptableMinVal" value="#{trancheBean.trancheValidation.podMin}" disabled="#{trancheBean.readonly}" maxValue="999"
required="#{trancheBean.requiredIfEnableCheck}" requiredMessage="#{trancheResources.label_acceptableMinVal} is required.">
<f:validateDoubleRange disabled="#{trancheBean.cValidation}" minimum="1.00" />
</pe:inputNumber>
<p:outputLabel for="acceptableMaxVal" value="#{trancheResources.label_acceptableMaxVal}:" />
<pe:inputNumber id="acceptableMaxVal" value="#{trancheBean.trancheValidation.podMax}" disabled="#{trancheBean.readonly}" maxValue="999"
required="#{trancheBean.requiredIfEnableCheck}" requiredMessage="#{trancheResources.label_acceptableMaxVal} is required.">
<p:ajax event="keyup" listener="#{trancheBean.acceptableMaxValOnkeyup}" ></p:ajax>
</pe:inputNumber>
<p:outputLabel for="exceptionMinVal" value="#{trancheResources.label_exceptionMinVal}:" />
<pe:inputNumber id="exceptionMinVal" value="#{trancheBean.trancheValidation.podExceptionMin}" disabled="#{trancheBean.readonly}" maxValue="999"/>
<p:outputLabel for="exceptionMaxVal" value="#{trancheResources.label_exceptionMaxVal}:" />
<pe:inputNumber id="exceptionMaxVal" value="#{trancheBean.trancheValidation.podExceptionMax}" disabled="#{trancheBean.readonly}" maxValue="999"/>
Please guide me to a solution. I have no idea on how to solve this.
I'll provide you with this sample answer and you can use it to apply it to yours. This approach is based on Pankaj Kathiriya's comment since that seems to be what you want to do.
In the sample code below, you have two <h:inputText> (substitute this component with yours <pe:inputNumber>). Their rendered attribute value will change every time you check/uncheck the <p:selectBooleanCheckBox>. When rendered evaluates to true, the <h:inputText> with validation will appear, the one without validation disappears (and vice versa).
The <selectBooleanCheckBox> will fire a ValueChangeEvent every time you check/uncheck it. You also need to make sure to set immediate to true so that it can be processed first (one phase before). Then call renderResponse in your listener to skip the remaining life cycles. Validation will kick in for the <h:inputText> with validation if you don't and you will see a validation error message when the switch occurs. Finally, for the <h:selectBooleanCheckBox>, you want to submit the form when the selection/deselection occurs. This can be done with javascript by setting its onchange attribute to submit() (e.g. onchange = "submit()"). Try to run the code so this could all make sense.
Again, keep in mind this is just a sample to help guide you to your solution.
public class SampleBean {
private boolean renderValidatedForm;
private String firstInput;
private String secondInput;
//Constructor ommitted
//Setters and getters ommitted
public void toggleRender(ValueChangeEvent e) {
boolean valueCheck = (Boolean) e.getNewValue();
renderValidatedForm = valueCheck;
FacesContext.getCurrentInstance().renderResponse();
}
}
The xhtml
<h:form>
<h:panelGrid>
<h:panelGroup>
<h:outputLabel for="enableCheckBox" value="Check to view form with validation"/>
<p:selectBooleanCheckbox id="enableCheckBox" value="#{sampleBean.renderValidatedForm}"
onchange="submit()"
valueChangeListener="#{sampleBean.toggleRender}"
immediate="true"/>
</h:panelGroup>
<h:panelGroup>
<h:outputLabel for="withValidation" value="Form with validation"
rendered="#{sampleBean.renderValidatedForm}"/>
<h:inputText id="withValidation" value="#{sampleBean.firstInput}"
required="true" rendered="#{sampleBean.renderValidatedForm}"/>
<h:message for="withValidation"/>
</h:panelGroup>
<h:panelGroup>
<h:outputLabel for="noValidation" value="Form without validation"
rendered="#{!sampleBean.renderValidatedForm}"/>
<h:inputText id="noValidation" value="#{sampleBean.secondInput}"
rendered="#{!sampleBean.renderValidatedForm}"/>
</h:panelGroup>
</h:panelGrid>
<h:commandButton value="Submit"/>
</h:form>

JSF2: cannot get data from a HtmlSelectOneMenu in java code

I am working with MyFaces/Primefaces and I have a problem to get information using ajax.
My page contains a list of panel, inside each panel, the user can select value in a dropdown list, and click on a checkbox which will update its panel (Ajax), I hope I am clear.
This is my code:
<p:panel>
...
<h:selectOneMenu id="beanSet" value="#{myBean.selectedSet}">
<f:selectItem itemLabel=" " noSelectionOption="true" />
<f:selectItems value="#{langSet}" />
</h:selectOneMenu>
<h:selectBooleanCheckbox
id="chkbxBeanSet"
value="#{myBean.selectedSetChkbx}" >
<p:ajax
event="click" render="#parent"
listener="#{action.updateSet}"
execute="#form"
immediate="true"
/>
</h:selectBooleanCheckbox>
...
<p:panel>
And here my java code:
public void updateSet(AjaxBehaviorEvent e) {
UIComponent source = (UIComponent)e.getSource();
System.out.println("Value:"+((HtmlSelectBooleanCheckbox)source).getValue());
UIComponent parent = source.getParent();
List<UIComponent> children = parent.getChildren();
HtmlSelectOneMenu lvSet = (HtmlSelectOneMenu)parent.findComponent("beanSet");
Object value = lvSet.getValue();
System.out.println("value: " + value);
I get the beanSet component, but I can't get its value. As I understand, the getValue calls the getSelectedSet from myBean which is not set (it is in request scope).
I don't understant how I can get the selected value in the dropdown list using ajax.
Another way is to post all the form, but in that case, I have to determine which checkbox was clicked by the user...
If someone can explain me where I am wrong?
The culprit is immediate="true" on the ajax action. This will skip all input components which do not have this attribute set during the processing. You should finetune the to-be-processed components in the process attribute of <p:ajax>. Yes, another culprit is that you used execute instead of process. The <p:ajax> uses process where <f:ajax> uses execute. Also, the way how you accessed the dropdown value is unnecessarily overcomplicated. Just access the selectedSet property directly. JSF will set it in the same bean anyway.
So, this should do
<h:selectOneMenu id="beanSet" value="#{myBean.selectedSet}">
<f:selectItem itemLabel=" " noSelectionOption="true" />
<f:selectItems value="#{langSet}" />
</h:selectOneMenu>
<h:selectBooleanCheckbox id="chkbxBeanSet" value="#{myBean.selectedSetChkbx}">
<p:ajax process="#this beanSet" listener="#{action.updateSet}" update="#parent" />
</h:selectBooleanCheckbox>
with
public void updateSet() {
System.out.println(selectedSet);
}
Note that I omitted event="click" from <p:ajax>. It's already the default for checkboxes.
place this (listener is optional) , the <f:ajax event="change" is what you need the most
<f:ajax event="change" render="IdsOfComponentToRender" listener="#{myBean.someMethod}" />
inside your <h:selectOneMenu id="beanSet" value="#{myBean.selectedSet}">
this is the signature of the listener
public void someMethod(AjaxBehaviorEvent ev) {...
b.t.w what is that updateLvSet method , and where you call it , and you should not access you data that way...

<f:ajax> does not render at all

This is my Facelet:
<h:inputText id="input" value="#{managedBean.runner.postnr}" maxlength="4" size="4">
<f:ajax execute="#this" onevent="blur" render="output" />
</h:inputText>
<h:outputText id="output" value="#{managedBean.placeFromPostNR}"/>
I'm trying to autoupdate outputText with a value from managedBean.placeFromPostNRwhen the user exit's the inputText. But this does not work at all.
Here's my managedBean.placeFromPostNR code:
public String getPlaceFromPostNR(){
return db.getPlaceFromPostNR(runner.getPostnr());
}
This method is never invoked, have some printlines as test.
I've even tried with setting <h:outputText id="output" value="#{managedBean.runner.postnr}"/> and setting onevent="keyup" to check if my methods which gives the error. But this doesn't work either.
The onevent attribute is invalid. It should be event.
<f:ajax execute="#this" event="blur" render="output" />

Resources