JSF h:selectManyCheckbox valueChangeEventListener not fired when user unchecks all - jsf

My problem is that when the user unchecks everything (leaving 0 checkboxes checked) JSF does not fire the valueChangeListener.
I appreciate any help, thanks.
JSPX:
<h:selectManyCheckbox
value="#{EME01.selectedMaterials}"
valueChangeListener="#{EME01.materialsValueChangeListener}"
onchange="submit();">
<f:selectItems value="#{EME01.materials}" />
</h:selectManyCheckbox>
Backing bean (EME01):
public void materialsValueChangeListener(ValueChangeEvent e) {
System.out.println("hello");
}

For checkboxes (and radio buttons) you're rather interested in click event than the change event.
onclick="submit()"
Unrelated to the concrete problem, consider using Ajax for this as it's pretty bad user experience to submit the entire form and have a flash of content on every change/click of the checkbox. If you're already on JSF2 for example, use <f:ajax> instead.

Related

onchange="submit()" reloads my PrimeFaces Mobile page

I am having a problem with my JSF project, where I am using PrimeFaces Mobile. This page has several pm:views
I have a list of radio buttons, which looks like this:
<p:selectOneRadio value="#{bean.currentElement}" converter="omnifaces.SelectItemsConverter"
onchange="submit()"
valueChangeListener="#{bean.elementChanged}">
<f:selectItems value="#{bean.currentItem.elements}" var="element"
itemLabel="#{element.elementName}" itemValue="#{element}" />
</p:selectOneRadio>
My valueChangeListener looks like this:
public void elementChanged(ValueChangeEvent e) {
currentElement = (Element) e.getNewValue();
System.out.println(getCurrentElement().getElementName());
}
The problem is, whenever I click on a radio button element, my page completely reloads to the start view, which has to do with the onchange="submit()". I have also tried f:ajax elements, but this doesn't seems to be working with my radio buttons, because I can't click them when I use this.
Is there a possiblty to just submit my current form or pm:view (without the f:ajax)?
PS: I have also tried exactly this on a single PrimeFaces Mobile page, which completely worked, since the application just consisted of one page.
When using PrimeFaces components, you should be using <p:ajax> instead of <f:ajax>. Just get rid of the onchange="submit()". This indeed invokes a synchronous (non-ajax) form submit which totally explains the page reload. You also need to replace valueChangeListener by <p:ajax listener>. The valueChangeListener is the wrong tool for the job whereby you're merely interested in invoking a JSF action method when the newly selected value is being set.
All in all, the rewrite should look like this:
<p:selectOneRadio value="#{bean.currentElement}" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{bean.currentItem.elements}" var="element"
itemLabel="#{element.elementName}" itemValue="#{element}" />
<p:ajax listener="#{bean.elementChanged}" />
</p:selectOneRadio>
Don't forget to remove the ValueChangeEvent argument from the elementChanged() method. In order to access the selected value, just access the currentElement property directly.
See also:
When to use valueChangeListener or f:ajax listener?

Cancel button jsf not resetting entity

I'm trying to implement a cancel button to clear the fields from my entity.
Though, when I'm setting the entity to null my fields still keep their value.
Code:
The EntityBB's cancel method (note that the debugger can reach the cancel method):
public void cancelAddStandardLetter() {
setEntity(null);
standardLetterInit();
}
this method really sets all the values from the entity back to null and the standardLetterInit method sets some default values that are needed (tried the same method without the standardLetterInit -> same result).
The xhtml page (other inputfields are left out):
<o:form includeRequestParams="true" id="addStandardLetterForm">
<h:inputTextvalue="#{entityBB.entity.fileName}" styleClass="rInput"/>
<h:commandButton value="Cancel" immediate="true"
styleClass="floatRight"
action="#{entityBB.cancelAddStandardLetter()}" />
</o:form>
After pressing the "cancel" button, the values being typed in the "fileName" field are still there. How can that be?
Make sure that the bean is view scoped and use a plain GET button.
<h:button value="Cancel" />
This basically refreshes the page. It'll recreate the view scoped bean instance. No need to submit the whole form. If the input values still appear, then it's either the browser cache or autocomplete/autofill which you in turn can control with respectively a servlet filter and autocomplete="off".

java ee - JSF 2.0 ViewScoped Bean after redirect to new window NPE

I use tip from this post https://stackoverflow.com/a/13838907 to open new tab, however when I go back to old one I get nullPointerException and my ViewScoped bean data are lost.
<h:form target="_blank">
<p:commandButton value="open new tab" action="#{otherBean.newTab}" ajax="false" />
</h:form>
<h:form>
<p:commandButton value="this wll cause NPE" action="#{pageBean.action}"/>
</h:form>
Click first button, go back to previous tab, click second button. PageBean is created once again and all data are lost. Both beans are ViewScoped.
Indeed, the view scoped bean in the initial tab/window get killed by returning a String navigation case outcome. You would like to return null or void to keep it alive. Based on the newTab() code as shown in your other question, you need to replace the navigation case by a Faces#redirect() call (assuming that it's indeed OmniFaces which you're using there for Faces#setFlashAttribute()). You only need to set Flash#setRedirect() to true beforehand to instruct the flash scope that a redirect will occur.
public void newTab() throws IOException {
Faces.setFlashAttribute("foo", bar);
Faces.getFlash().setRedirect(true);
Faces.redirect("otherView.xhtml");
}
ViewScope beans only live as long as you post back to same view.
If you post back to other views in your action data will be lost since the ViewScope bean will be recreated.

<p:commandButton> not working when disable="true" initially

This is my ManagedBean:
#Named(value = "mrBean")
#RequestScoped
public class MrBean {
public void laugh() {
System.out.println("HAHAHA");
}
public void prepareToLaugh() {
System.out.println("Drink water.");
}
}
And this is the working version of my commandButton:
<p:commandButton actionListener="#{mrBean.laugh}" widgetVar="laughtButton"
value="Laugh" oncomplete="laughButton.disable();" />
When I clicked the above button, I saw HAHAHA and the button is disabled. However, when I set the laughButton's disable attribute to true, the button does not work anymore:
<p:commandButton actionListener="#{mrBean.laugh}" widgetVar="laughtButton"
value="Laugh" disabled="true" oncomplete="laughButton.disable();" />
<p:commandButton actionListener="#{mrBean.prepareToLaugh}"
value="Prepare to laugh" oncomplete="laughButton.enable();" />
When I click the 2nd button, I saw Drink water and the 1st button is enabled. However, when I click on the 1st button, nothing happens.
I'd be very grateful if someone could give me an advice on how I should tackle this problem. I'm using PrimeFaces 3.0 RC2.
Like as with rendered attribute, JSF re-evaluates the disabled attribute in the server side during processing of the form submit as part of safeguard against tampered requests and like. You're however enabling/disabling it by JS without notifying the server side of the changes.
You need to ensure that the value of the disabled attribute evaluates false during the request whenever you intend the button to be enabled during processing of the form submit. For example, bind it to a boolean property of a view scoped bean which is set by the other button.
<h:commandButton disabled="#{bean.laughDisabled}" />
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated

ValueChangeListener method not called on my h:selectOneRadio

I am little confused about my radio button list in JSF and how it reacts to stuff and I didn't find much help online. Below is the declaration of my radio button list and the method which should be called in case the value of the radio changes:
<h:selectOneRadio value="#{AddExpense.selectedTypeExp}" layout="pageDirection"
valueChangeListener="#{AddExpense.changed}">
<f:selectItems value="#{AddExpense.typeExpList}"/>
<a:support event="onclick" action="#{AddExpense.typeExpChanged}" immediate="true"/>
</h:selectOneRadio>
When I choose a different value, only the typeExpChanged is called, but the AddExpense.changed method is not called. I think I'm confusing something here, not sure how the changeListener should react... Below is my very simple test method which should be called:
public void changed(ValueChangeEvent event){
System.out.println("In changed event method: "+event.getNewValue());
}
Should I change something in the <a:support> ?
The reason I have both event and valueChangeListener is because I wanted to test what reacts to my changing the selection. I just need a method to be called with a parameter which tells me the selected value, so I can load something else.
Thanks in advance!
The valueChangeListener is not a client side event listener. It's a server side event listener. It does not generate any line of HTML/JS/Ajax code and it is triggered by JSF itself when you submit the form to the server and the submitted value is different from the initial model value.
Just keep using Ajax4jsf <a4j:support>, it's perfectly fine for your particular functional requirement.

Resources