Update p:inputText style while typing - jsf

How do I update the style of a p:inputText while the user is typing without interrupting their typing?
<p:inputText id="radiusValue" value="#{bean.radius}"
styleClass="#{bean.radiusStyle}">
<p:ajax event="keyup" update="radiusValue" />
</p:inputText>
This is for validation. It updates fine and gets the correct style but when the p:inputText updates, it sets the cursor back to the beginning... interrupting the user's entry. There has to be a less invasive way to update the style?

Could you do that validation on client?
I have not tried, but you can use onkeyup attribute to execute a Javascript function that adds a style class depending on what do you need.
function applyStyle() {
var element = document.getElementById("myInputText");
element.classList.add("mystyle");
}

Related

p:inputText blur event doesn't work the first time

I have the code below with java, JSF, and PrimeFaces, but when I start for the first time the program, the event Blur doesn't work, just after the first time, it worked. Could you know why this works like that?
The main problem here is, the event blur should work the first time.
<p:column headerText="Col1">
<p:inputText style="width:100px;" id="valorUnitario"
disabled="#{OrcamentoNovoBean.desabilitar}"
value="#{item.valor}" converter="BigDecimalConverter"
onkeypress="javascript:return currencyFormat(this,'.',',',event,2);"
onkeydown="javascript:return pressTabSaldo(event, #{indiceVar});"
maxlength="12">
<p:ajax
listener="#{OrcamentoNovoBean.verificaCalculoPecasMaoDeObraSaldo()}"
event="blur"
update=":form1:dataTablePecas:valorTotalSaldo,:form1:totalSaldo,:form1:totalEstoque,:form1:btnEnviar" />
</p:inputText>
</p:column>
Don't use the blur event. There is no need to check or update things if the value has not changed. It is just a waste of resources. It's better to just use the default change event. As it is the default, you can simply remove the event attribute from p:ajax.
I also noticed you are using an onkeypress listener to format the value as a currency. If you would use p:inputNumber, you'll get currency formatting out of the box.
Just to update this. I resolved including onblur="function" I dont know why this works like that, but at the first time Java pickup the event blur inside the inputtext, at second time AJAX works

Trigger valueChange event after a visible character is added or removed in InputText

I am in need for a valueChange event, that triggers every time a visible character is added or removed.
I've got 2 inputText-fields, one of which is read only and a commandButton.
<div>
<p:inputText>
<p:ajax id="encodedString" event="valueChange"/>
</p:inputText>
<p:commandButton action="#{bean.foo}" update="output"/>
<p:inputText id="output" readonly="true">
</p:inputText>
</div>
Now, the users enters some encoded string in the first field and presses the button, which then decodes the string and presents it in human readable form in the read-only input field. Now, whenever the user manipulates the original string, the output should be reset since it does not represent the original encoded string anymore.
Sadly, the valueChange event only triggers when the input field loses focus. I have tried the keypress event, but it also triggers when buttons like the arrow keys are pressed.
JavaScript is viable for me, but should be omitted if possible.
What is the best way to trigger the valueChange event (or a similar event) whenever the actual input changes? I.e. when a visible character is added or removed.
You essentially need the HTML DOM input event. This relatively new event is unfortunately not supported in <p:ajax> of <p:inputText> because the oninput attribute is not supported in <p:inputText> (yet?).
However, you can make use of JSF 2.2's passthrough attributes feature to force JSF to render an oninput attribute anyway where you in turn explicitly trigger the default onchange() function.
<... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
<p:inputText value="#{bean.value}" a:oninput="onchange()">
<p:ajax listener="#{bean.listener}" />
</p:inputText>
True, that involves JavaScript but it's really only a small bit.
Note that I removed event="valueChange" from <p:ajax> because that's the default one already.
value changed event not supported for inputText you have to use
keyup or blur
<p:inputText>
<p:ajax id="encodedString" event="keyup"/>
</p:inputText>

How to change order in which the components are processed

I have a selectOneMenu and an editor. What I want is to submit the value of the editor before the value of the selectOneMenu. The code looks like this
<p:selectOneMenu value="#{myBB.selectedItem}">
<f:selectItems value="#{myBB.selectItems}"/>
<p:ajax event="change" process="itemText #this" update=":mainForm"/>
</p:selectOneMenu>
<p:editor id="itemText" value="#{myBB.selectedItem.text}"/>
It looks like the order of elements in process="itemText #this" doesn't matter, because when I change it, the values are submitted in unchanged order.
The problem is, that the selectedItem of the editor is changed by the selection before the value from the editor is submitted.
Am I right, that the order doesn't matter and it is submitted based on the order in the DOM tree? (When I change order of the input fields it's working as I would like to)
What is the best way to work around this?
You shouldn't rely on things like layout or processing order in your code. If the problem is that itemText value is reset when selectedItem is changed, then bind the text to separate String text bean variable, and update selectedItem.text in some other code, maybe <p:ajax listener="#{...}".

PrimeFaces autocomplete: itemSelect versus change events

I need to trigger an ajax update upon change to a text box, which is a <p:autoComplete> component. I have observed that if the user opts to type the text manually, the event is a change, whereas if the user clicks one of the suggestions for the autocomplete, the event is itemSelect. So I added two <p:ajax> children to the input, each calling the same method and having the same update list, but one having event="change" and the other event="itemSelect".
However, I now discover something odd. For example, while in normal server mode I opened my page and typed "12". The autocomplete offered "1233" and "1234" as suggestions. I clicked "1233" and seemingly nothing happened. I clicked again and everything else filled in.
Repeat this in the debugger with a breakpoint on the event handler, and I can see that after the first click, the value is "12" and on the second click, it becomes "1233".
By switching commenting out the two different <p:ajax> I can see the different consequences. Without the "change" one, the handler is never called if the user selects an autocomplete suggestion, and without the "itemSelect" one, the handler is never called if the user types manually. But with both of them, there are two calls, and I'm sure there will be complaints about the double-click.
Some pseudo-code for those that like, first the xhtml:
<p:autoComplete id="itemId" value="#{myBacker.myBean.itemNumber}"
required="true" completeMethod="#{myBacker.idAutoComplete}">
<p:ajax event="itemSelect" update="beanDetails"
listener="#{myBacker.idChangeEventListener()}" />
<p:ajax event="change" update="beanDetails"
listener="#{myBacker.idChangeEventListener()}" />
</p:autoComplete>
<h:panelGroup id="beanDetails">
<h:panelGroup rendered="#{not empty myBacker.myBean.institutionName}">
<h:outputText value="#{myBacker.myBean.institutionName}" />
<!-- Continues with address, phone, etc.. -->
</h:panelGroup>
</h:panelGroup>
Then the Java backing bean code:
public void idChangeEventListener() {
myBean = myDAO.getDetails(myBean);
// another couple of init-type method calls
}
Give the parent tag a widgetVar attribute, then add this little attribute to the <p:ajax event="change" ...> child tag:
onstart="if(widgetVarName.panel.is(':visible')) return false;"
When the question was written, we were on PrimeFaces version 3.5, if I recall correctly. Since then, we need to update the solution to:
onstart="if(PF('widgetVarName').panel.is(':visible')) return false;"
with thanks to mwalter for pointing out the change.

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

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?

Resources