I'm doing a dynamic view according to a dropdown selection:
there's the code:
<h:selectOneMenu value="#{controller.type}" >
<p:ajax listener="#{controller.switchPanels}" update="panels" />
<f:selectItem itemValue="1" itemLabel="option 1" />
<f:selectItem itemValue="2" itemLabel="option 2" />
</h:selectOneMenu>
<h:panelGroup layout="block" id="panels">
<h:panelGroup layout="block" rendered="#{controller.type == '1'}" >
<h:inputText value="#{controller.value}" >
<f:validateRegex pattern="^[0-9a-zA-Z ]*$" />
</h:inputText>
</h:panelGroup>
<h:panelGroup layout="block" rendered="#{controller.type == '2'}" >
Panel 2
</h:panelGroup>
</h:panelGroup>
<h:commandLink action="#{controller.go}">Go</h:commandLink>
The controller:
#ViewScoped
#ManagedBean
public class Controller {
String type = "1";
String value;
// getters and setters
public void switchPanels(AjaxBehaviorEvent event) {
this.value = "";
}
public void go(){
}
...
}
Try this scenario:
- write special characters in the value field
- press Go (causes the validation message to popup)
- try changing the selection and reselect the same panel again
The result is that the field is not cleared even though I clear it in the switchPanels method
Please any explanation would be helpful
Thank you
Related
I have a problem using f:ajax with t:selectOneRadio in layout="spread"
Without layout="spread", this is working :
<t:selectOneRadio id="test" value="#{bean.type}" >
<f:selectItem itemLabel="yes" itemValue="1"/>
<f:selectItem itemLabel="no" itemValue="0"/>
<f:ajax render="label" />
</t:selectOneRadio>
<h:panelGroup id="label" layout="block">
<h:outputText value="OK" rendered="#{bean.type == 1}"/>
<h:outputText value="KO" rendered="#{bean.type == 0}"/>
</h:panelGroup>
When i click on a radio, the text is modified, my type attribute is set in my bean as expected.
My bean is :
#ManagedBean
#ViewScoped
public class Bean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
But With layout="spread", my bean is not set, the setter is not call, but the render works (to test it, inscpect the html, write foo in the div with id="label" and after clicking a radio the text is clear because of the render.
My code with layout="spread" :
<t:selectOneRadio id="test" value="#{bean.type}" layout="spread">
<f:selectItem itemLabel="yes" itemValue="1"/>
<f:selectItem itemLabel="no" itemValue="0"/>
<f:ajax render="label" />
</t:selectOneRadio>
<div><t:radio id="radio1" for="test" index="0"/></div>
<div><t:radio id="radio2" for="test" index="1"/></div>
<h:panelGroup id="label" layout="block">
<h:outputText value="OK" rendered="#{bean.type == 1}"/>
<h:outputText value="KO" rendered="#{bean.type == 0}"/>
</h:panelGroup>
I have tomahawk2.1 in version 1.1.14 and JSF myfaces 2.2.8
To be more specific, I want to use disable calendar component when selectOneMenu component change its value!
<h:form>
<h:panelGrid columns="2" id="Panel" >
<p:calendar id="deadLineDate" value="# {projectsControllerCreate.selected.deadLineDate}" disabled="#{listenerFromSelectOneMenu}" >
</p:calendar>
<p:selectOneMenu id="listUrgent" value="#{projectsControllerCreate.selected.listUrgent}">
<p:ajax update="deadLineDate" event="change" listener="#{bean.listenerFromSelectOneMenu}">
<f:selectItem itemLabel="1" itemValue="1" />
<f:selectItem itemLabel="2" itemValue="2" />
</p:selectOneMenu>
</h:panelGrid>
</h:form>
My listenerFromSelectOneMenu looks like this.
public boolean listenerFromSelectOneMenu() {
Date d = deadLine;
String urg = current.getListUrgent();
String hackUrg = "";
hackUrg = (urg==null) ? "":urg;
return !hackUrg.isEmpty();
}
But whole page is refreshing every time!
I'm using JSF 2 along with primefaces, i have a selectOneButton which have 2 values, EN/FR, i want to be notified each time the language is changed, and then change the locale of the page, i have set valueChangeListener and an ajax event,
but everytime the change listener is fired, the new value is always null!
here is the xhtml code:
<h:form id="f">
<p:selectOneButton id="lang" value="#{currentUser.language}" valueChangeListener="#{currentUser.languageChanged}" >
<f:selectItem itemLabel="English" itemValue="en" />
<f:selectItem itemLabel="Françcais" itemValue="fr" />
<f:ajax event="change"/>
</p:selectOneButton>
</h:form>
the languageChanged method for testing:
public void languageChanged(ValueChangeEvent event) {
System.out.println("new val: " + event.getNewValue());
System.out.println("old val: " + event.getOldValue());
}
i even tried to attach to the ajax a listener:
<f:ajax event="change" listener="#{currentUser.languageChanged}"/>
and the method:
public void languageChanged(AjaxBehaviorEvent event) {
SelectOneButton button = (SelectOneButton)event.getComponent();
System.out.println(button.getValue()) ;
}
Is this the wrong way to retrieve the new selected value from a p:selectOneButton with ajax?
UPDATE:
So i know what is causing this problem
actually my selectOneButton is inside a menuItem which is inside a splitButton, when i take the selectOneButton out side the splitButton it works fine!
why is the fact that the selectOneButton is inside the menuItem preventing it from send it to the server?
here the code:
<h:panelGroup style="float: right;" >
<h:form id="f">
<p:splitButton value="#{currentUser.fullName}" icon="ui-icon-person" styleClass="toTheRight" style="min-width: 200px;" >
<p:menuitem value="Matricule: #{currentUser.matricule}" />
<p:menuitem value="#{msgs.role}: #{currentUser.role}" />
<p:separator />
<p:menuitem>
<p:selectOneButton id="lang" value="#{currentUser.language}" valueChangeListener="#{currentUser.languageChanged}" >
<f:selectItem itemLabel="English" itemValue="en" />
<f:selectItem itemLabel="Françcais" itemValue="fr" />
<f:ajax event="change"/>
</p:selectOneButton>
</p:menuitem>
<p:separator />
<p:menuitem value="#{msgs.settings}" icon="ui-icon-wrench" />
<p:menuitem value="#{msgs.logout}" icon="ui-icon-arrowthickstop-1-w" url="/j_spring_security_logout"/>
</p:splitButton>
</h:form>
</h:panelGroup>
I have a similiar snap-code and that should work, here is what i have:
<p:outputLabel for="scriptMigrate" value="Migrate" style="font-weight:bold" />
<p:selectOneButton id="scriptMigrate" value="#{scriptConfiguration.scriptMigrate}" required="true">
<f:selectItem itemLabel="Yes" itemValue="1" />
<f:selectItem itemLabel="No" itemValue="0" />
<p:ajax update="fsstobe" event="change" listener="#{scriptConfiguration.updateForm()}" />
</p:selectOneButton>
The update componetent is just for me to know what to render or not in the rest of the page, but here is the method:
public void updateForm() {
System.out.println("entered with value: " + scriptMigrate);
if (scriptMigrate.equals("1")) {
renderScriptAsIs = true;
}
if (scriptMigrate.equals("0") || scriptMigrate.equals("")) {
renderScriptAsIs = false;
}
}
So i assume when you change the value you just want to call the method languageChanged(), so maybe my example helps, i have no arguments, try without them first to see if it helps.
Could you try
<p:ajax listener="#{currentUser.languageChanged}"/>
and remove the valueChangeListener from the selectOneButton.
In languageChanged(AjaxBehaviorEvent event) just read the new value from the language-property.
<p:selectOneButton value="#{languageBean.languageName}">
<p:ajax listener="#{languageBean.changeLanguage()}" partialSubmit="true"/>
<f:selectItem itemLabel="DE" itemValue="#{CONST.LANGUAGE_DE}"/>
<f:selectItem itemLabel="EN" itemValue="#{CONST.LANGUAGE_EN}" />
</p:selectOneButton>
and in the method from bean:
public void changeLanguage() {
System.out.println(languageName);
}
I have a datatable and two checkboxes. The content of the datatable is rendered considering which of the checkboxes are selected. I have the following functional code which renders the datable content when pressing the submit button:
<h:form>
<h:selectManyCheckbox value="#{myBean.selections}">
<f:selectItem itemValue="expired" itemLabel="Expired" />
<f:selectItem itemValue="active" itemLabel="Active" />
</h:selectManyCheckbox>
<h:commandButton id="submit" value="Select"
action="#{myBean.getList}" />
</h:form>
<h:form>
<h:dataTable ... />
</h:form>
However, I want to replace the submit button with an ajax call using the f:ajax tag. I tried something like:
<h:selectManyCheckbox value="#{myBean.selections}">
<f:selectItem itemValue="expired" itemLabel="Expired" />
<f:selectItem itemValue="active" itemLabel="Active" />
<f:ajax event="click" render="#form" listener="#{myBean.getList}" />
</h:selectManyCheckbox>
<h:form>
<h:dataTable .... />
</h:form>
But the content is not rendered. What am I doing wrong?
Bean:
public String[] selections = { "expired", "active" };
public String[] getSelections() {
return selections;
}
public void setSelections(String[] selections) {
this.selections = selections;
}
public void getList() {
for (String option : selections) {
// add expired
if (option.equals("expired"))
showExpired();
// add active
else if (option.equals("active"))
showActive();
}
//return Arrays.toString(selections);
}
What I'd like to do is simple to explain :
bean
#ManagedBean
#ViewScoped
public class Articles {
private String selectedMenu;
#PostConstruct
public void init() {
if(selectedMenu==null || selectedMenu.trim().isEmpty()) {
this.selectedMenu="0";
}
}
public String getSelectedMenu() { return selectedMenu; }
public void setSelectedMenu(String selectedMenu) { this.selectedMenu = selectedMenu; }
}
page
<h:selectOneListbox onchange="..?? ajax call that render on loadMenu and pass the value of the focused listbox to Articles Bean" id="category" size="0" >
<f:selectItem itemLabel="first" itemValue="0" />
<f:selectItem itemLabel="second" itemValue="1" />
<f:selectItem itemLabel="third" itemValue="2" />
</h:selectOneListbox>
<h:panelGroup layout="block" id="loadMenu">
<h:panelGroup rendered="#{articles.selectedMenu=='0'}">
MENU 0
</h:panelGroup>
<h:panelGroup rendered="#{articles.selectedMenu=='1'}">
MENU 1
</h:panelGroup>
<h:panelGroup rendered="#{articles.selectedMenu=='2'}">
MENU 2
</h:panelGroup>
</h:panelGroup>
When I change the value of the listbox, the menu should change dinamically (by calling some function on the server). I think that the code above expresses what I'm looking for.
I must know how call it using the onchange option. Is it possible?
Cheers
UPDATE
<h:panelGroup layout="block">
<h:selectOneListbox styleClass="article_combo" size="0" id="selectedMenu" >
<f:selectItem itemLabel="first" itemValue="0" />
<f:selectItem itemLabel="second" itemValue="1" />
<f:selectItem itemLabel="third" itemValue="2" />
<f:ajax event="change" execute="#this" render="loadMenu" />
</h:selectOneListbox>
</h:panelGroup>
<h:panelGroup layout="block" id="loadMenu">
<h:panelGroup rendered="#{articles.selectedMenu=='0'}">
MENU 0
</h:panelGroup>
<h:panelGroup rendered="#{articles.selectedMenu=='1'}">
MENU 1
</h:panelGroup>
<h:panelGroup rendered="#{articles.selectedMenu=='2'}">
MENU 2
</h:panelGroup>
</h:panelGroup>
You can use the ajax support built in to JSF 2 to achieve this. To do this nest an f:ajax tag in your h:selectOneListbox tag. The f:ajax tag should look like:
<f:ajax render="loadMenu" execute="#this" />
This should process the changed value in your list box, and re-render the panelGroup.
for further details, see:
http://mkblog.exadel.com/2010/04/learning-jsf-2-ajax-in-jsf-using-fajax-tag/