Possible to execute `valueChangeListener` for `p:inputText` without hitting `enter` key? - jsf

I'd like to execute valueChangeListener for p:inputText when user changes text and inputText looses focus (onchange). Is this possible? For now it only executed after I press return.

The valueChangeListener method requires a form submit to be invoked. This is a server side event, not a client side event or so. Just changing and blurring the input does by default not submit the form at all. Bring in a <p:ajax> to do the magic.
<p:inputText value="#{bean.inputValue}" valueChangeListener="#{bean.inputChanged}">
<p:ajax />
</p:inputText>
However, although you didn't tell anything about the concrete functional requirement for which you thought that this is the right solution, I just wanted to mention that the valueChangeListener is more than often the wrong tool for the job you had in mind. Use <p:ajax listener> instead.
<p:inputText value="#{bean.inputValue}">
<p:ajax listener="#{bean.inputChanged}" />
</p:inputText>
Note that this would then make it possible to pass method arguments by EL 2.2, which would immediately then answer the possible underlying functional requirement of your other — actually pretty poor — question.
<p:inputText value="#{bean.inputValue}">
<p:ajax listener="#{bean.inputChanged('arg1', 'arg2')}" />
</p:inputText>
Also note that this might not be the solution at all if you're actually interested on the entered value; you could just access the inputValue property directly.
See also:
When to use valueChangeListener or f:ajax listener?

Related

Prevent ajax call via JS validation

In some cases, I need to do some simple client side validation, and depending on that, fire an ajax call or not.
However, it appears that in IE, even when returning false in onchange, or in onstart on the p:ajax, the ajax event is still getting fired anyway.
So, my component currently looks like this:
<p:inputText id="pc" value="#{bean.pc}" valueChangeListener="#{bean.doStuff}" styleClass="if-nospace-upper" onchange="return isOK()">
<p:ajax immediate="true" onstart="PF('busyPopup').show();" oncomplete="PF('busyPopup').hide();" />
</p:inputText>
When invalid, my isOK() function returns false, but the ajax call is still being made, whereas I don't want it to.
Is there any possibility to do this at all?
One alternative is
<p:remoteCommand>
<p:inputText id="pc" value="#{bean.pc}"
valueChangeListener="#{bean.doStuff}" styleClass="if-nospace-upper"
onchange="return isOK()">
</p:inputText>
<p:remoteCommand name="rc">
<p:ajax onstart="PF('busyPopup').show();" oncomplete="PF('busyPopup').hide();" />
</p:remoteCommand>
and from javascript :
funtion isOK(){
//If Condtion matches
rc();
}
and please take out immediate="true" noticed you are using for <p:ajax> although it is not giving you any problem here but it's not good to force jsf to skip some life cycle steps unless and untill you have requirement

How to submit additional data to managed bean while p:autocomplete' s completeMethod is triggered for suggestions?

The title says it all.
--
I'm using primefaces's autocomplete. Whenever a query to server is triggered for fetching suggestions, I need to submit some data from an input field.
How do I do it ?
Just add a keyup ajax event to the other input, in order to send it when user changes its value. Later on, you'll have it already available for completion:
<p:inputText value="#{autoCompleteBean.value}">
<p:ajax event="keyup" />
</p:inputText>
<p:autoComplete value="#{val2}"
completeMethod="#{autoCompleteBean.completeItem}" />

<p:commandButton CONDITIONAL onclick event

i have a jsf-form with an input field and a save-button as seen in the code below. What i want to achieve is, when the save-button clicked, the input should be validated with the regex-pattern. If the validation failed, no save-confirmation-dialog should be shown. Otherwise a save-confirmation-dialog shown, and let the user to choose if to save or not.
In the code below, the dialog has always been shown, despite the conditional onclick="if(#{conditionOK}). I want no confirmation-dialog got shown, when conditionOK returns false!!! After many tries, i think the facescontext.isValidateFailed() will not be re-evalutated.
Please help :(
All what i want, is only to check, if the regex-Validator returns true. For this case, the confirmation-dialog should be shown.
My approach could be wrong. Many thank if you guys have also other solutions.
<h:form id="save_all_form">
<p:inputTextarea rows="1" style="width:100%;resize:none"
value="#{cusBean.saveAll}" autoResize="false"
validatorMessage="Wrong format">
<f:validateRegex pattern="#{msgs.pattern}" />
</p:inputTextarea>
<ui:param name="conditionOK"
value="#{facesContext.postback and !facesContext.validationFailed}" />
<p:commandButton value="#{msgs.button_overwrite_all}"
onclick="if(#{conditionOK}){confirmation.show()}"/>
</h:form>
I do not think that the JSF-validation is the way to go for you. It is intended to prevent the change of model data in the case, that the validation fails.
And if you would like to make a check in JavaScript you have to update the section in HTML. JavaScript does not reevaluate the Expression, so the value when the view was rendered the first time will be used everytime.
Try the following in the xhtml:
<h:form id="save_all_form">
<p:inputTextarea id="input" rows="1" style="width:100%;resize:none"
value="#{cusBean.saveAll}" autoResize="false">
<p:ajax global="false" update="input submit" partialSubmit="true"/>
</p:inputTextarea>
<p:commandButton id="submit" value="#{msgs.button_overwrite_all}"
onclick="if(#{cusBean.validate(msgs.pattern)}){confirmation.show()}"/>
</h:form>
And add this method in CusBean:
public boolean validate(String pattern) {
return getSaveAll().matches(pattern);
}
The result will be, that there is not JSF validation which takes place and the value of the textArea is submitted everytime you change it. Plus the commandButton-section is updated so the condition will be updated.
Like the other answer explained onclick event is too early to check the validation status of a JSF request(using !facesContext.validationFailed) because the request has not been submitted yet; Validation has not been run so the validation status will always be false (well, sort of) during onclick.
So what you'll want to do is carry out an ajax validation of the field (like shown in the earlier answer) and then use the primefaces args variable to check the status of the request:
<p:commandButton value="#{msgs.button_overwrite_all}" id="createReport" onclick="if(!args.validationFailed){confirmation.show();}"/>

f:setPropertyActionListener doesn't set the value however action is triggered

I need to set a boolean field whenever p:fieldset is toggled. I tried out following code but the field is never set by f:setPropertyActionListener although p:ajax listener is invoked on toggle. I tried out following code.
<p:fieldset legend="(Optional) Link.." toggleable="true">
<p:ajax event="toggle" listener="..">
<f:setPropertyActionListener target="#{viewScope.rendrUsrProjctsList}" value="#{true}"/>
</p:ajax>
</p:fieldset>
However when I tried modifying the code as below then field is successfully set:
<p:fieldset legend="(Optional) Link.." toggleable="true">
<p:ajax event="toggle" listener="#{view.viewMap.put('rendrUsrProjctsList', true)}" />
<p:ajax event="toggle" listener=".."/>
</p:ajax>
</p:fieldset>
I want to ask:
Why 1st way doesn't work ?
Is it bad attaching multiple p:ajax to
single parent as done in 2nd way ?
The <f:setPropertyActionListener> works as being an ActionListener implementation only on components implementing ActionSource interface, such as UICommand, i.e. <h:commandXxx>, <p:commandXxx>, etc. The <p:ajax> does not implement this interface and therefore the <f:setPropertyActionListener> is basically completely ignored.
As to your workaround, you could do so although I'd rather just use a concrete view scoped bean or wrap it in a composite with a backing component.

Update form from value change of Primefaces spinner

I am trying to update my form on the basis of changes of the spinner
<p:spinner id="spin1" min="1" max="#{editPhoto.max}" size="1"
value="#{editPhoto.page}" validator="#{editPhoto.validator()}"
valueChangeListener="#{editPhoto.refreshForm()}" />
<p:commandButton value="Insert" action="#{editPhoto.insertImage()}" />
<p:commandButton value="Delete" action="#{editPhoto.deleteImage()}" />
I've put break points in the value, setPage as well as in the validator and valueChangeListener and it hits them only when I press the commandButton. I've tried immediate="true", but that adds nothing. What I really want is to know when the value has been changed, but without having to hit the commandButton.
In a previous question BalusC suggested the use of
<f:event type="preRenderView" listener="#{nextpageBacking.onPreRenderView}" />
I suspect that I need something similar here, but what sort of event should I be looking for? Maybe not, so what do I need to do to get changes in the spinner without having to press on the commandButton? Thanks, Ilan
My bean is view-scoped. Perhaps the answer is to use another request scoped-bean and have the request scoped-bean operate on the view-scoped bean? I will try this if this looks like the correct direction.
You should use f:ajax or p:ajax.
The valueChangeListener will only fire when the whole form or the spinner is submitted.
<p:spinner id="spin1" min="1" max="#{editPhoto.max}" size="1"
value="#{editPhoto.page}" validator="#{editPhoto.validator()}">
<p:ajax listener="#{editPhoto.refreshForm()}"
update="#form" process="#this" />
</p:spinner>
The valueChangeListener attribute of the spinner is not the best place to fire your method. You should better put it in the listener attribute of p:ajax. The valueChangeListener should be used if you are interested in the old and the new value.

Resources