Jsf calling bean method from input text when pressing enter - jsf

JSF 2.0, Mojarra 2.0.1, PrimeFaces 3.4.1
Here is a p:inputText component which is expected to call a backing bean method when the enter key is pressed.
<p:inputText id="commentInput" rendered="#{status.haveComment}"
value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { onchange(); return false; }">
<f:ajax event="change" listener="#{statusBean.test}" />
</p:inputText>
While backing bean has the method of:
public void test(AjaxBehaviorEvent event) {
System.out.println("Pressed enter!");
}
It's calling method when enter key is pressed but it has more than this; unexpected behaviour case:
--Click input text
----Type some letters
------Click somewhere else in the page
--------CONSOLE: Pressed enter!
I think ajax event=change detects a change somehow and calls the method. How to convert this p:inputText component into a proper comment taker component like Facebook or others has?

This is the way how onchange event works in HTML. It is happening when text in input element is changed, but is fired when component loses focus (in your case that is the moment when you click somewhere else in the page).
You can define p:remoteCommand for test method and just write:
<p:remoteCommand name="test" actionListener="#{statusBean.test}"/>
<p:inputText id="commentInput" rendered="#{status.haveComment}"
value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { test(); return false; }"/>
and in backing bean:
public void test() {
System.out.println("Pressed enter!");
}

With newer PrimeFaces versions (5+ at least) you can use p:defaultCommand instead of scripting. Though you can't use p:remoteCommand then, because p:defaultCommand needs something clickable.
<p:inputText id="input" />
<p:defaultCommand target="submit" />
<!--you can show the button to allow the user to click too, or hide it with display: none-->
<p:commandButton id="submit" style="display: none;" process="input" />
By default p:defaultCommand applies to the whole form. You could limit it with the scope attribute.

Related

jsf inputText not refreshing when i reset the bean's property

My screen looks like this
The problem is that, when I press the Reset Button, the Code input field does not clear, as it was supposed to.
The jsf is the following:
<h:form id="form1">
<h:inputText id="code" value="#{MyBean.data.code}" />
<a4j:commandButton immediate="true"
action="#{MyBean.clear}" render="form1" update="#form">
</a4j:commandButton>
<h:outputText value="#{session.lastAccessedTime}">
<f:convertDateTime pattern="HH:mm:ss.SSS" type="date" />
</h:outputText>
</h:form>
The bean code is the following:
public class MyBean {
DataInnerClass data = new DataInnerClass();
//getter and setter for data
public class DataInnerClass {
private String code;
//getter and setter for code
public DataInnerClass() {
super();
}
}
public void clear() {
data = new DataInnerClass();
Logger.getLogger( MyBean.class.getName() ).log(Level.SEVERE, "data.code="+data.code);
//logs data.code=null
}
}
When I press the Reset button, the log shows that the value of the field code has become null (its no longer 'ZZ'); i also know that the screen refreshes successfully, because i have displayed the current time, which updates after every click. So the backing bean property changes, the screen refreshes, and still the input field keeps the same value. Do you have any idea why this is happening?
I found useful BalusC's answer on: How can I populate a text field using PrimeFaces AJAX after validation errors occur?
I understand from there that, in the case of some validation error, the input field will keep the value entered by the user, and will be out of sync with the backing bean. I must emphasize that in my case, there were no validation errors, but still, adding an <f:ajax resetValues> to the commandButton worked for me.
A concrete example of the resetValues attribute is on https://jsflive.wordpress.com/2013/06/20/jsf-22-reset-values/
Finally, my button tag looks like this:
<a4j:commandButton immediate="true"
action="#{MyBean.clear}" render="form1" update="#form">
<f:ajax render="code" resetValues="true" />
</a4j:commandButton>

How to pass the selected values from selectcheckBoxMenu to my bean?

I'm using JSF 2.2.8 and primefaces 6.0, and i have a selectCheckBoxMenu i want to retrieve the selected values in my bean.
The selectCheckboxMenu is filled from the database but when i select the attributes and I save nothing happens it does not call the save function
Here is my selectCheckBoxMenu
<p:outputLabel for="ressource" value="Ressource"/>
<h:panelGroup >
<p:selectCheckboxMenu id="ressource" label="Ressource" value="#{affectationBean.selectedRessource}" multiple="true">
<f:selectItems value="#{affectationBean.ressources}" var="r" itemLabel="#{r.nom}" itemValue="r.idt_ressource" />
</p:selectCheckboxMenu>
</h:panelGroup>
<p:commandButton icon="ui-icon-save" actionListener="#{affectationBean.save}" value="Save" update="#affectation" ajax="false" style="display:inline-block;margin-top:5px"/>
Here is the the declaration of the selectedRessource and the actionListener save
private Long [] selectedRessource;
// Getters setters and Construct
public void save(){
for(int i=0 ;i<selectedRessource.length;i++){
system.out.println("id ===> " + selectedRessource[i]);
}
My suggestion would be:
First make sure everything is inside the h:form tag.
don't need to multiple = true as this tag does not take this attribute
i tested with below modification and got the selected multiple value in my bean. The only difference is i am using same value for itemLabel and itemValue but in your case it is object. i am using primefaces 6 also and dont even need to change actionListner to action. It is working as it is.sample xhtml
sample ResourceBean.java
<p:outputLabel for="ressource" value="Ressource"/>
<h:panelGroup >
<p:selectCheckboxMenu id="ressource" label="Ressource" value="#{resourceBean.selectedRessource}">
<f:selectItems value="#{resourceBean.ressources}" var="r" itemLabel="#{r}" itemValue="#{r}" />
</p:selectCheckboxMenu>
</h:panelGroup>
<p:commandButton icon="ui-icon-save" actionListener="#{resourceBean.save}" value="Save" ajax="false" style="display:inline-block;margin-top:5px"/>
The problem is in your p:commandButton, you have 3 options
change your method:
public void save(ActionEvent actionEvent){...}
change your action listener value:
actionListener="#{affectationBean.save()}"
or change your button to use action
action="#{affectationBean.save}"
DISCLAIMER: This is a workaround. It is not intended to be a permanent solution but will allow you to use selectCheckboxMenu and keep working.
There is an issue with this component that prevents it from passing values to the backing bean upon submit.
For some reason the array that should contain the selected values gets cleared out upon submit. Therefore I made an extra array that I did not declare in the tag, and updated in on every change event. Then on submit the values were still there. See below:
BackingBean.java
private String[] sCodes;
private String[] sCodes2; //extra array, not in form.xhtml
public void updateCodes()
{
sCodes2 = sCodes; //keeps the values in the other array
}
public void doSend() throws IOException
{
log.trace("selected codes: {} selected codes2 length: {}", sCodes.length, sCodes2.length);
}
form.xhtml
<p:selectCheckboxMenu id="codeCtl" value="#{bean.SCodes}" label="Codes" filter="true" filterMatchMode="startsWith" panelStyle="width:250px">
<f:selectItems value="#{bean.menuCodes}" />
<p:ajax event="change" listener="#{bean.updateCodes()}" />
</p:selectCheckboxMenu>
<p:commandButton value="submit" actionListener="#{bean.doSend}" id="ctlSubmit" update="appform"/>

submit button does not submit but only triggers InputText's onChange event

I am automatically selecting a value for radio button when the user types something in an input text using ajax.
The problem is: when the user types something in the input text and directly submits the form by clicking Get, the form does not submit but only the ajax is called because of the change event and the radio is updated.
A second click on the Get button, submits the form.
I also do not want to use keyup since it migth disturb the user while typing.
I use primefaces 5.1
here is my code:
<h:form id="myForm">
<p:selectOneRadio
value="#{myBean.include}" id="IncludeRadio">
<f:selectItem itemValue="Include" itemLabel="Include" />
<f:selectItem itemValue="Exclude" itemLabel="Exclude" />
<p:ajax process="#this" update="#form" />
</p:selectOneRadio>
<p:radioButton id="IncludeRadio0" for="IncludeRadio" itemIndex="0"/>
<p:radioButton id="IncludeRadio1" for="IncludeRadio" itemIndex="1"/>
<p:inputText
value="#{myBean.fieldValue}"
id="FieldValueInputText">
<p:ajax process="#this" update="#form" />
</p:inputText>
<p:commandButton id="GetButton"
action="#{myBean.execute}"
value="Get">
</p:commandButton>
</h:form>
and the bean:
#ManagedBean
#SessionScoped
public class MyBean {
public void setFieldValue(final String fieldValue) {
if (fieldValue != null && !fieldValue.trim().isEmpty()) {
if (!"Include".equals(getInclude())
&& !"Exclude".equals(getInclude())) {
setInclude("include");
}
} else {
setInclude("");
}
}
public void setInclude(String include) {
this.include = include;
}
public String getInclude() {
return this.include;
}
public void execute() {
// do something
}
}
submit button does not submit but only triggers InputText's onChange event
That happened because the blur event of the input field ajax-updates the submit button around the moment you click it. This way the JavaScript/Ajax logic associated with submit button is not guaranteed to work anymore, because the source element is removed from the DOM.
Make sure that you don't cover the submit button in the ajax update.
Instead of updating the entire form,
<p:ajax ... update="#form" />
update only the pieces which really need to be updated, which are only the inputs in your specific case:
<p:ajax ... update="IncludeRadio FieldValueInputText" />
Or if you'd rather like to not keep track of all those IDs when you have many inputs, grab PFS:
<p:ajax ... update="#(#myForm :input)" />

Log the number of submit button clicks though the form is invalid

I am trying to log the number of the button clicks.
1. Should log the number of clicks though the form is invalid. The field value1 in the form is integer. So, It shall also consider conversion errors.
2. Action to be done at backing bean
I have tried with listener on ajax.
<h:form id="form">
<h:inputText id="in" name="in" value="#{listenBean.value1}" autocomplete="off">
</h:inputText>
<h:commandButton value="Click Me" action="#{listenBean.save}">
<f:ajax execute="#form" render="#form message eventcount" />
</h:commandButton>
<h:message for="in"/>
Button Clicks: <h:outputText id="eventcount" value="#{listenBean.eventCount}"/>
</h:form>
Bean
public void eventCount(AjaxBehaviorEvent event) {
//increment the counter
}
public void save() {
//save
}
Issues:
The listener method is not called when the conversion errors on input field binded to integer at bean. I enter the value as "some text". During thsi time listener is not called.
Version: Mojaraa 2.2.8
Is this the correct way of doing. Am I doing any mistake.
Can some one help me.
The <h:outputText value> doesn't represent a method expression which should reference a bean (listener) method. It represents a value expression which should reference a bean property which will then be outputted as (escaped) text to the response.
Your best bet is to hook on preRenderView event of the component and check if the current request represents a postback request.
<h:form id="form">
<h:commandButton ...>
<f:ajax execute="#form" render="#form" />
</h:commandButton>
Button Clicks:
<h:outputText id="eventcount" value="#{listenBean.eventCount}">
<f:event type="preRenderView" listener="#{listenBean.incrementEventCount}" />
</h:outputText>
</h:form>
private int eventCount;
public void incrementEventCount(ComponentSystemEvent event) {
if (FacesContext.getCurrentInstance().isPostback()) {
eventCount++;
}
}
public int getEventCount() {
return eventCount;
}
Note that render="#form" covers the entire form already, so there's no need of specifying individual components inside the very same form. In case you've another ajax action inside the same form for which you'd like to not count the event, then make sure that render="..." is specific enough that it doesn't cover the eventcount component.

<p:inputText> value not updated in model on change

I have a form that lets me edit a list of beans (one at a time), using buttons I can switch between the beans.
Keeping it simple :
public class MyBean {
private String text;
}
public class MyController {
private List<MyBean> availableBeans = new ArrayList<MyBean>(); // has five MyBeans with random text
private MyBean selectedBean; // initialized with first element of list
private int index = 0;
public void nextBean() { index++; }
public void previousBean() { index--; }
private void refreshBean() { selectedBean = availableBeans.get(index); }
}
For the html part I have something like
<h:form id="someForm">
<!-- stuff -->
<p:inputText value="#{myController.selectedBean.text}" />
<p:inplace editor="true" label="#{myController.selectedBean.text}" >
<p:inputText value="#{myController.selectedBean.text}" />
</p:inplace>
<!-- more stuff-->
</h:form>
If I change the text inside the inplace tag, the variable in myBean will be updated just fine, but If I only use inputText the bean will still have the old value, even if I change it on the webpage. Why is that?
Its because the p:inplace editor="true" implicitly submits the value to the server while <p:inputText does not do it implicitly,
You can solve it in several ways
1) add submit button like <p:commandButton to submit the value from p:inputText
2) use p:ajax event="keyup" or event="change",inside p:inputText
also take a look at the showcase p:ajax enables ajax features on supported components.
p.s , remove the value attribute from the p:inplace (there is no such attribute in p:inplace)
Lets give your components ids:
<h:form id="someForm">
<p:inputText id="first" value="#{myController.selectedBean.text}" />
<p:inplace id="second" editor="true" value="#{myController.selectedBean.text}">
<p:inputText id="third" value="#{myController.selectedBean.text}" />
</p:inplace>
</h:form>
According to the Primefaces Documentation 3.5 the component p:inplace has no attribute called value.
Do you submit the form someForm when changing the value of first? Otherwise the updated values from first won't be passed to MyController and MyBean. p:inplace submits the values automatically whereby you have to do it yourself it you use the standard p:inputText.

Resources