JSF CommandButton Show/Hide Issue - jsf-2

Im using a primefaces FieldSet component and have a button field specified inside the field set. I have a requirement, Where, when I click on the command button, a h:selectonemenu & an inputtext should be displayed and On further click, the h:selectOnemenu &inputtext should be hidden. Below is the code that I have written to show & hide. The show part works fine. But when I try to click on the button to hide, it does not work.
xhtml code
<h:panelGrid id="grid1" columns="3">
<p:fieldset id="GlobalAdjustment" legend="GlobalAdjustment" style="font-size:12px !important;width:30%" >
<h:commandButton id="globalAdjustID" image="#{review.imageUrl}" actionListener="#{review.showUpdateList}" />
</p:fieldset>
<h:selectOneMenu id="SelectID" value="#{review.reviewList}" rendered="#{demandReview.selectoneRenderer}">
<f:selectItems id="FilterSelectListID" value="#{review.reviewListIDs}" style="font-size:12px !important"></f:selectItems>
</h:selectOneMenu>
<h:inputText id="fieldUpdateID" required="false" rendered="#{review.inputTextRenderer}"></h:inputText>
</h:panelGrid>
ManagedBean ActionListener method
public void showUpdateList(ActionEvent event)
{
System.out.println("entering the Action Method:");
Map<String, Object> idMap = new HashMap<String, Object>() ;
idMap = event.getComponent().getAttributes();
String url = (String) idMap.get("image");
System.out.println("The url is :"+url);
if(url.equals("/images/add_data_button.png")){
//upbean.setImageUrl("/images/remove_data_button.png") ;
imageUrl ="/images/remove_data_button.png" ;
selectoneRenderer = true;
inputTextRenderer = true;
}else
{
imageUrl ="/images/add_data_button.png" ;
selectoneRenderer = false;
inputTextRenderer = false;
}
}
When I click the command button inside the fieldset for the first time, it works fine and displays the selectoneMenu & the textbox. Once further clicks, the ActionListener is not getting invoked. Please help me resolve the issue.
Thanks

You can try another approach. Use p:commandButton with an update attribute like this:
<h:panelGrid id="grid1" columns="3">
<p:fieldset id="GlobalAdjustment" legend="GlobalAdjustment" style="font-size:12px !important;width:30%" >
<p:commandButton id="globalAdjustID" image="#{review.imageUrl}" actionListener="#{review.showUpdateList}" update="grid1"/>
</p:fieldset>
<h:selectOneMenu id="SelectID" value="#{review.reviewList}" rendered="#{demandReview.selectoneRenderer}">
<f:selectItems id="FilterSelectListID" value="#{review.reviewListIDs}" style="font-size:12px !important"></f:selectItems>
</h:selectOneMenu>
<h:inputText id="fieldUpdateID" required="false" rendered="#{review.inputTextRenderer}"></h:inputText>
</h:panelGrid>
This way you'll use partial processing and the conditional renderization of the panel's inner components will be done through AJAX.
Also, it could be a good idea to check your server's console to see if there are any messages in the queue that were not displayed.

Does the requirement specify using the server side? For something like this, I would have thought a simple Javascript script would have been better suited.
For example, use the jQuery library to do something like:
<h:commandButton id="xyz" onclick="$('#elementId').toggle();"/>

Related

Getting selected value of a SelectOneMenu

I'm testing the component "SelectOneMenu" on a jsf page. I'm populating this component dinamically though my ManageBean (that will get all Animals from database).
I would like to know if is possible to see the user selected item of that "SelectOneMenu" (combobox), I'm trying with value="#{animalsManage.animalSelect}" but it is only called on the beginning of the page. Also, I'm using an inputText to see the value of the selected intem of the "SelectOneMenu".
What I'm doing wrong?
JSF:
<body>
<ui:component>
<h:form>
<h:outputText value="Select one Mets File" />
<h:selectOneMenu id="combo" value="#{animalsManage.animalSelected}">
<f:selectItem itemLabel="Select..." noSelectionOption="true"/>
<f:selectItems value="#{animalsManage.allAnimals}" />
</h:selectOneMenu>
<h:inputText id="textbox" value="#{animalsManage.animalSelected }" />
</h:form>
</ui:component>
</body>
ManageBean:
#ManagedBean
#ViewScoped
public class AnimalsManage implements Serializable {
#EJB
private AnimalsFacadeREST animalsFacadeREST;
private String animalSelected;
private List< SelectItem> selectAnimals;
public List<SelectItem> getAllAnimals() {
List<Animals> al = animalsFacadeREST.findAll();
selectAnimals = new ArrayList< SelectItem>();
int i = 0;
for (Animals animal: al) {
selectAnimals.add(new SelectItem(i, animal.getName()));
i++;
}
return selectAnimals;
}
public String getAnimalSelected() {
return animalSelected;
}
public void setAnimalSelected(String animalSelected) {
this.animalSelected = animalSelected;
}
}
There are many solutions to the presented problem. I present here two basic ideas.
Server-side solution. Simply attach <f:ajax> tag inside your <h:selectOneMenu> to update selected values and rerender user's choice, like in
<h:selectOneMenu id="combo" value="#{animalsManage.animalSelected}">
<f:selectItem itemLabel="Select..." noSelectionOption="true"/>
<f:selectItems value="#{animalsManage.allAnimals}" />
<f:ajax execute="combo" render="textbox" />
</h:selectOneMenu>
<h:inputText id="textbox" value="#{animalsManage.animalSelected }" />
If you like, you may also do some custom logic with selected element in ajax listener by specifying listener="#{animalsManage.performCustomAjaxLogic}" of <f:ajax> tag.
Client-side solution. Simply update element with id="textbox" on basic change event. So, if you use jQuery the solution will be
$('#combo').change(function() {
$('#textbox').val($('#combo').val());
});
Thought the client-side solution will bind only text value of your input component.

Primefaces Datatable filter values are lost after the datatable is refreshed

I am using JSF 2.0 and Primefaces 3.2. I have a main form with a datatable and a button on each row that brings up a dialog with another data table. The dialog has its own form. When the datatable row is selected in the dialog, i process the selection and then refresh the datatable in the main form. After the refresh all my filters on the main datatable are lost. Is there a way to remember the filter values?
My JSF page
<h:panelGroup id="mainTable">
<h:form id="mainForm" prependId="false">
<p:dataTable id="cl_grid1" var="item" widgetVar="mainGrid"
value="# {controller.items}">
<p:column headerText="Colum1" filterMatchMode="contains" filterBy="#{item.myObj.code}" sortBy="#{item.myObj.code}">
<h:outputText value="#{item.myObj.code}" style="float:left" />
<p:commandButton id="selectBtn" icon="select"
oncomplete="selectDialog.show()" actionListener="#{controller.setMainItem}">
<f:param name="selectedMainItem" value="#{item.id}"/>
</p:commandButton>
</p:column>
</p:dataTable
</h:form>
</h:panelGroup>
<p:dialog id="cl_selectDialog" header="Select AAAA" dynamic="true" modal="true" widgetVar="selectDialog"
height="500" width="900" showEffect="explode" hideEffect="explode">
<h:form id="selectForm" prependId="true">
<p:dataTable id="cl_selectGrid" var="selectorItem" widgetVar="selectGrid"
value="# {controller.selectorItems}" selection="#{controller.selectedItem}"
rowKey="#{selectorItem.id}" selectionMode="single">
<p:commandButton actionListener="#{controller.processSelection}" value="Ok" icon="ui-icon ui-icon-search"
oncomplete="selectDialog.hide()" update=":mainTable" process="#form"/>
<p:commandButton value="Cancel" icon="ui-icon ui-icon-search" onclick="selectDialog.hide()" type="button"/>
</h:form>
</p:dialog>
My Controller
In my controller all i am doing is hydrating my datatable again.
#Component
#Scope("view")
public class Controller extends BaseController implements Serializable {
private List<Item> items;
public Controller() {
items = new ArrayList<Item>();
}
#PostConstruct
public void init() {
loadItems();
}
protected void loadItems() {
items = //Load items from Database
}
public void processSelection(ActionEvent event) {
//Add the selected Item and then reload items
loadItems();
}
}
If it is an AJAX Request, you can add on your trigger component a 'oncomplete' method which has :
<p: ... update='myDatatableId' oncomplete='myDatatableWidget.filter();' />
By this way you will re-triggering current filters on the datatable or you can also clear all filters by using
... oncomplete='myDatatableWidget.clearFilters();' ...
We also came up with a slightly more elegant solution than the one posted by kolossus which is as simple as extending the PF Datatable for persistent filter values.
http://www.stickysession.com/?p=258
Since you must to refresh the table from within its form (so it will preserve the filter state) another solution could be to place a hidden button in the main table form and use it as a 'proxy' by clicking it from your dialog, that way the filter will be preserved, like this
change your button from
<p:commandButton actionListener="#{controller.processSelection}" value="Ok" icon="ui-icon ui-icon-search"
oncomplete="selectDialog.hide()" update=":mainTable" process="#form"/>
into this (just a simple button that clicks the hidden one)
<p:commandButton onclick="$('#my-proxy-button-id').click(); return false;" value="Ok" icon="ui-icon ui-icon-search"/>
and add a new button inside the main table form
<p:commandButton style="display:none;" id="my-proxy-button-id" actionListener="#{controller.processSelection}"
oncomplete="selectDialog.hide()" update="mainTable" process=":selectForm"/>
using this technique you wont be needed to call for filtering manually and no additional "blinking" will appear on screen

h:selectManyListBox valueChangeListener is not calling

I am using Netbeans 6.9.1. I am using code in which i am simply using selectManyListBox and i want that when user selects all the values then my valueChangeListener is call. Here what i am doing
<h:selectManyListbox id="countryListBox" size="5" value="#{news.saarcCountries}"
onselect="form.submit();" valueChangeListener="#{news.changeAppearOnCountryPage}">
<f:selectItems value="#{news.saarcCountriesMap}"/>
<f:ajax render="countryPageExpiryCalender" />
</h:selectManyListbox>
<p:calendar id="countryPageExpiryCalender" value="#{news.countryPageExpiryDate}"
navigator="true" style="z-index: 1;" locale="en" mode="popup"
pattern="dd/MM/yyyy" showOn="button" readOnlyInputText="true"
disabled="#{!news.appearOnCountryPage}" />
I also tried this, instead of onselect i used onchnage like
onchange="submit()"
Here is my valueChangeListener
#ManagedBean(name = "news")
#ViewScoped
public class News {
private Map<String, String> saarcCountriesMap = new LinkedHashMap<String, String>();
private Set<String> saarcCountries = new TreeSet<String>();
...
public void changeAppearOnCountryPage(ValueChangeEvent vcEvent){
Iterator iter = saarcCountries.iterator();
while(iter.hasNext()) {
String name = (String)iter.next();
System.out.println(name);
}
} //end of changeAppearOnCountryPage
} //end of class News
I want that when user select all the values from the selectmanyListBox, then my valueChangeListener is call, and i check if i have the values in saarcCountries variable, then i set appearOncountryPage = true, so my calender is render. But my valueChangeListener is not calling. What i am doing wrong?
If i choose onselect, then i want to ask one thing this event will trigger whenever i select the value, of after i have selected all the values. I want that when user select all the values then my ValueChangeListener is call and the values that user selected will be in my saarcCountries variable. So i can check the values that user selected.
I think onchange() is not appropriate in my case. Please help. I am stuck because of it:(
Thanks
try it like this:
<h:selectManyListbox id="countryListBox" size="5" value="#{news.saarcCountries}">
<f:selectItems value="#{news.saarcCountriesMap}"/>
<f:ajax event="change" listener="#{news.changeAppearOnCountryPage}" render="countryPageExpiryCalender"/>
</h:selectManyListbox>
You don't need the form.submit(); since you can use the ajax...

Can not use hidden commandButton with #RequestScoped backing-bean

I have following sample code.
Initially, only commandButton Two is visible. When I click this button, commandButton One is also visible. But when I click One, the backing-bean method click1 does not get fired.
Following is my code:
xhtml
<h:form id="form1">
<h:inputHidden id="show" value="#{bean.show1}" />
<h:commandButton id="button1" value="One" action="#{bean.click1}"
rendered="#{bean.show1}" />
</h:form>
<h:form id="form2">
<h:inputHidden id="show" value="#{bean.show1}" />
<h:commandButton id="button2" value="Two" action="#{bean.click2}" />
</h:form>
backing-bean
#RequestScoped
#Named("bean")
public class JsfTrial implements Serializable {
private static final long serialVersionUID = 2784462583813130092L;
private boolean show1; // + getter, setter
public String click1() {
System.out.println("Click1()");
return null;
}
public String click2() {
System.out.println("Click2()");
setShow1(true);
return null;
}
}
I found a very informative answer by BalusC.
h:commandLink / h:commandButton is not being invoked
If I understand it correctly, my problem is due to point 5 of this answer.
Does that also mean we can not use hidden commandButton with #RequestScoped backing-bean?
You can use the request scope, you should only pass the condition as a request parameter to the subsequent requests by <f:param> instead of by a JSF hidden input field <h:inputHidden>. The value of the hidden input field is only set in the model during Update Model Values phase, while the condition of the rendered attribute is already evaluated during Apply Request Values phase which is earlier.
So, use <f:param> instead of <h:inputHidden>:
<h:form id="form1">
<h:commandButton id="button1" value="One" action="#{bean.click1}"
rendered="#{bean.show1}">
<f:param name="show1" value="#{bean.show1}" />
</h:commandButton>
</h:form>
<h:form id="form2">
<h:commandButton id="button2" value="Two" action="#{bean.click2}">
<f:param name="show1" value="#{bean.show1}" />
</h:commandButton>
</h:form>
This way you can extract them as request parameter in bean's (post)constructor.
public JsfTrial() {
String show1 = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("show1");
this.show1 = (show1 != null) && Boolean.valueOf(show1);
}
Ugly, but CDI doesn't offer a builtin annotation which substituties JSF's #ManagedProperty("#{param.show1}"). You could however homegrow such an annotation.

JSF 2 check / uncheck list of h:selectBooleanCheckbox

I have a loop with a bunch of h:selectBooleanCheckboxs inside a ui:repeat and I want to be able to check / uncheck all of them with one click. Following this this is how I try to do it:
<h:selectBooleanCheckbox value="#{bean.selectAll}" valueChangeListener="#{bean.selectAllCustomers}">
<f:ajax execute="#form" render="entireLoop"/>
</h:selectBooleanCheckbox>
The loop:
<h:panelGroup id="entireLoop">
<ui:repeat var="customer" varStatus="status" value="#{bean.customers}">
<tr>
<td>
<h:selectBooleanCheckbox value="#{bean.customersMap[customer]}"/>
</td>
<td><h:commandLink value="#{customer.userID}" action="#{navBean.gotoEditCustomer(customer)}"/></td>
<td>#{bean.getContact(user)}</td>
<td>#{customer.companyName}</td>
<td>#{customer.email}</td>
<td>#{customer.phone}</td>
</tr>
</ui:repeat>
</h:panelGroup>
The code in the bean:
public void selectAllCustomers() {
Iterator<User> keys = customersMap.keySet().iterator();
while(keys.hasNext()) {
User user = keys.next();
customersMap.put(user, selectAll);
}
}
When I click to check the "select all" checkbox, I have two problems:
Nothing happens. Only when I click on somewhere else in the page the method is called. How can I get it to go directly?
The entire loop disappears from the page. Why? (I tried to get the ajax to render only the selectBooleanCheckbox by giving it an id, or a name, but I'm getting an error saying this is not a naming component.)
Instead of using valueChangeListener, your method will work if you use the listener attribute of the <f:ajax> tag. It would be something like this:
<h:selectBooleanCheckbox value="#{bean.selectAll}">
<f:ajax listener="#{bean.selectAllCustomers}" render="entireLoop"/>
</h:selectBooleanCheckbox>
Besides, you don't need to submit the whole form with execute="#form". You only need to submit selectAll property and re-render the entireLoop.
If you really want to use valueChangeListener, you must note that your method will be triggered before the new value is applied in the selectAll property. As a result, your entireLoop will not be updated until the next request. To use valueChangeListener, your listener method should look like this:
public void selectAllCustomers(ValueChangeEvent e) {
boolean newSelectAll = (Boolean) e.getNewValue();
Iterator<Users> keys = customersMap.keySet().iterator();
while(keys.hasNext()) {
Users user = keys.next();
customersMap.put(user, newSelectAll);
}
}

Resources