I have a listing page that goes to an add page. The add page has a name textbox whose value is bound to a session scoped bean.
The listing page has an add button that goes via an action method to the add page. This action method clears the object that the name textbox is bound to.
I also have a cancel button on the add page, which is bound to an action method that again clears the value that the name textbox is bound to.
If nothing is set to immediate, this all works fine.
However, if I set the cancel button to immediate, if I enter values in the name field, and then click cancel, the action method is fired and clears the object in the backing bean and goes to the listing page. If I then click add, the action method clears the object again (ignore if it's best method or not) and then goes to the add page. I would now expect the add page's name textbox to be empty, but it's not?! Surely, since the add button is not immediate, the values should be re-bound and empty?
Below is the relevant XHTML for the add button on the listing page
<h:commandButton id="addButton"
value="Add"
action="#{myBean.gotoAdd}"/>
Below is the relevant XHTML for the input box on the add page (myBean is session scoped), followed by that of the cancel button on the add page.:
<h:inputText id="newName"
value="#{myBean.newObject.name}"
binding="#{myBean.newNameInput}"
styleClass="name" />
<h:commandButton id="cancelButton"
value="Cancel" immediate="true"
action="#{myBean.cancelAdd}"
onclick="return confirm('You sure?');"/>
I almost never use the binding property of tags, except for when I need to identify which item of a list has had an action fired on it, so I am not particularly well-informed about its uses. But I know that without using binding your code would most likely work as you expected, so my expectation is that whatever javax.faces.component.UIxxx object you are binding to isn't getting reset correctly.
I'm having very similar problems right now.
Besides removing the binding and/or immediate attribute, try calling setSubmittedValue() on component with binding from action called upon click on 'add' button.
Alas, even if it helps you, you would still have to do it in any action that can lead to displaying same component after cancel.
That's why I'm still trying to figure out some better solution...
If you use immediate="true" then the value will be kept, this is how the parameter works. You should take a look at the following links:
http://wiki.apache.org/myfaces/How_The_Immediate_Attribute_Works
http://wiki.apache.org/myfaces/ClearInputComponents
Ok, here's an example that I did from scratch. I have two cancel buttons, one that is immediate, and one that isn't. Example of steps to reproduce:
Go to james-list page and click Add
The add page displays with empty fields. Enter values for all fields and click Add.
The listing page displays and is updated to include the new person. Click Add.
The add page displays with empty fields. Enter values for all fields and Click Cancel (Immediate)
The listing page displays and is unchanged. Click Add.
The add page displays however the fields are not empty as I would expect. Click Cancel.
The listing page displays and is unchanged. Click Add.
The add page displays and NOW the fields are not empty.
James.java:
package com.jamiebarrow;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
#ManagedBean
#SessionScoped
public class James {
private UIComponent idComponent;
private UIComponent firstNameComponent;
private UIComponent lastNameComponent;
public UIComponent getIdComponent() {
return idComponent;
}
public void setIdComponent(UIComponent idComponent) {
this.idComponent = idComponent;
}
public UIComponent getFirstNameComponent() {
return firstNameComponent;
}
public void setFirstNameComponent(UIComponent firstNameComponent) {
this.firstNameComponent = firstNameComponent;
}
public UIComponent getLastNameComponent() {
return lastNameComponent;
}
public void setLastNameComponent(UIComponent lastNameComponent) {
this.lastNameComponent = lastNameComponent;
}
private List<Person> personResults;
private Person person;
public James() {
personResults = new ArrayList();
personResults.add(new PersonBuilder(1, "Bob", "Uncle").build());
personResults.add(new PersonBuilder(2, "Jack", "Black").build());
}
public List<Person> getPersonResults() {
return personResults;
}
public void setPersonResults(List<Person> personResults) {
this.personResults = personResults;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
private void clearPerson() {
person = new PersonBuilder().build();
}
public String gotoList() {
return "james-list";
}
public String gotoAdd() {
clearPerson();
return "james-add";
}
public String cancelAdd() {
clearPerson();
return gotoList();
}
public String addPerson() {
personResults.add(person);
return gotoList();
}
}
james-list.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>list page</title>
</h:head>
<body>
<div class="container">
<div class="content">
<h:messages showSummary="true" showDetail="false" errorClass="error" infoClass="info"
warnClass="warn"/>
<h:form>
<h:dataTable value="#{james.personResults}" var="person">
<h:column>
<f:facet name="header">Id</f:facet>
<h:outputText value="#{person.id}"/>
</h:column>
<h:column>
<f:facet name="header">Name</f:facet>
<h:outputText value="#{person.firstName}"/>
</h:column>
<h:column>
<f:facet name="header">Surname</f:facet>
<h:outputText value="#{person.lastName}"/>
</h:column>
</h:dataTable>
<h:panelGroup layout="block">
<h:commandButton value="Add" action="#{james.gotoAdd}"/>
</h:panelGroup>
</h:form>
</div>
</div>
<ui:debug hotkey="L" rendered="true"/>
</body>
</html>
james-add.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>add page</title>
</h:head>
<body>
<div class="container">
<div class="content">
<h:messages showSummary="true" showDetail="false" errorClass="error" infoClass="info"
warnClass="warn"/>
<h:form>
<fieldset>
<legend>Add Person</legend>
<h:panelGrid columns="2">
<h:outputLabel for="PersonId" value="Id:"/>
<h:inputText id="PersonId" value="#{james.person.id}" binding="#{james.idComponent}"/>
<h:outputLabel for="PersonFirstName" value="First Name:"/>
<h:inputText id="PersonFirstName" value="#{james.person.firstName}" binding="#{james.firstNameComponent}"/>
<h:outputLabel for="PersonLastName" value="Last Name:"/>
<h:inputText id="PersonLastName" value="#{james.person.lastName}" binding="#{james.lastNameComponent}"/>
</h:panelGrid>
<h:panelGroup layout="block">
<h:commandButton value="Add" action="#{james.addPerson}"/>
<h:commandButton value="Cancel (immediate)" action="#{james.cancelAdd}" immediate="true"/>
<h:commandButton value="Cancel" action="#{james.cancelAdd}"/>
</h:panelGroup>
</fieldset>
</h:form>
</div>
</div>
<ui:debug hotkey="L" rendered="true"/>
</body>
</html>
Related
I am having trouble to update the view from the bean in the back using PrimeFaces's RequestContext. In the example below I have a button and 2 panels. When pressing the button, I want to update one panel, but not the other one.
It does not work though and I can't find the error! requestContext.update("panela"); is fired, but doesn't do its job!
Help greatly appreciated!
The XHTML file:
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head/>
<h:body>
<h:form>
<p:panelGrid columns="1">
<p:commandButton value="Save" actionListener="#{runtimeUpdatesBean.save}" />
<p:panel id="panela">
<h:outputText value="#{runtimeUpdatesBean.texta}"/>
</p:panel>
<p:panel id="panelb">
<h:outputText value="#{runtimeUpdatesBean.textb}"/>
</p:panel>
</p:panelGrid>
</h:form>
</h:body>
</html>
The bean:
package com.glasses.primework;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.context.RequestContext;
#ManagedBean
#SessionScoped
public class RuntimeUpdatesBean {
private String texta;
private String textb;
private boolean outcome;
public String getTexta() {
texta += "a";
System.out.println("RuntimeUpdatesBean.getTexta() = " + texta);
return texta;
}
public String getTextb() {
textb += "b";
System.out.println("RuntimeUpdatesBean.getTextb() = " + textb);
return textb;
}
public void save() {
RequestContext requestContext = RequestContext.getCurrentInstance();
if(outcome) {
System.out.println("RuntimeUpdatesBean.save() = update panela");
requestContext.update("panela");
outcome = false;
} else {
System.out.println("RuntimeUpdatesBean.save() = update panelb");
requestContext.update("panelb");
outcome = true;
}
}
}
Well the problem is the ID of the component that you are referring.
In JSF when you place a component inside h:form (or Some Primefaces components like TabView), that component's Id will be generated based on the h:form id too.
Here is the Example:
<h:form id="panelaForm">
<p:panel id="panela">
....
</p:panel>
</h:form>
In the above case your p:panel's id will be generated as panelaForm:panela.
In your case since you haven't provided any ID for h:form a dynamic id will be attached like for example j_xyz:panela(you can see it using you browser's Inspect Element).
So If you wan to access p:panel with Id panela inside the same h:form then no need to attach the form Id.
But If you want to access the p:panel outside h:form then you need to attach the h:form id to access it.
Solution to you problem is: use an custom ID to your h:form (which is a best practice by the way..) and access the p:panel by attaching that form ID.
<h:form id="panelaForm">
<p:panel id="panela">
....
</p:panel>
</h:form>
And in Managed bean use:
RequestContext.getCurrentInstance().update("panelaForm:panela");
I'm the new guy here (Java EE) however below solution works for me:
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head/>
<h:body>
<h:form id="form">
<p:panelGrid columns="1">
<p:commandButton value="Save" actionListener="#{runtimeUpdatesBean.save}" update=":form" />
<p:panel id="panela">
<h:outputText value="#{runtimeUpdatesBean.texta}"/>
</p:panel>
<p:panel id="panelb">
<h:outputText value="#{runtimeUpdatesBean.textb}"/>
</p:panel>
</p:panelGrid>
</h:form>
</h:body>
i have a requirement like i need to show/hide datatable upon button click . I tried implementing it , but its not working . below is the code .
please let me know if we can do with ajax . It is possible only if i set ajax to false .
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>hello world</title>
</h:head>
<h:body>
<h:form>
<p:outputPanel id="panel" rendered="#{bye1.showtable}">
<p:dataTable value="#{bye1.carmodel}" var="cartypes">
<p:column headerText="Model">
<h:outputText value="#{cartypes.carname}">
</h:outputText>
</p:column>
<p:column headerText="Location">
<h:outputText value="#{cartypes.location}"></h:outputText>
</p:column>
<p:column headerText="Price">
<h:outputText value="#{cartypes.rate}"></h:outputText>
</p:column>
</p:dataTable>
</p:outputPanel>
<p:commandButton value="show" action="#{bye1.enabletable}" update="panel">
</p:commandButton>
</h:form>
</h:body>
</html>
package lifecycle;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
public class bye {
private String output;
private Boolean showtable;
private List<cars> carmodel;
public List<cars> getCarmodel() {
System.out.println("cars populated...........");
return carmodel;
}
#PostConstruct
public void bye1() {
System.out.println("constructor called");
carmodel = new ArrayList<cars>();
output = "hai";
carmodel.add(new cars("ford","chennai","4 laks"));
carmodel.add(new cars("AUDI","chennai","44 laks"));
}
public String getOutput() {
return output;
}
public Boolean getShowtable() {
return showtable;
}
public String enabletable() {
showtable = true;
return "";
}
}
Any help ?
Thanks in Advance
Use an actionListener on your commandbutton instead of action.
"A return value of an empty string or the same view ID will also return to the same page, but recreate the view scope and thus destroy any currently active view scoped beans and, if applicable, recreate them:"
Differences between action and actionListener
Also consider the use of Boolean vs boolean.
It also seems like your class is missing the #ManagedBean and scope annotations?
I think the update="panel" is not working properly, and the panel component is not getting updated. When you disable ajax, the whole page gets update, and maybe this is why the update works only with ajax="false".
Can you try this and tell me if it works now ? :
<p:commandButton value="show" actionListener="#{bye1.enabletable}" ajax="true" update=":#{p:component('panel')}">
</p:commandButton>
i found this solution .
i did a change like this
<p:outputPanel id="panel" >
<p:dataTable value="#{bye1.carmodel}" var="cartypes"
rendered="#{bye1.showtable}">
..............
</p:dataatble>
</p:outputPanel>
set the rendered attribute to the datatable rather to the outputpanel .
I have a DataTable (Primefaces 3.5, JSF 2.0) which is populated from a database. In the first column of this table, checkboxes are displayed (multiple row selection).
After selecting row(s), when a button (<p:commandButton>) is pressed, the selected rows are expected to be deleted from the database.
Before deleting row(s), a confirm message regarding the deletion of the selected row(s) is displayed in <p:confirmDialog> with two buttons Yes and No something like the following.
Test.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition template="template/Template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:define name="title">Test</ui:define>
<ui:define name="content">
<h:form id="form">
<p:dataTable id="dataTable" var="row" value="#{testManagedBean.list}"
selection="#{testManagedBean.selectedValues}"
rowKey="#{row.id}"
rowIndexVar="rowIndex">
<p:column selectionMode="multiple" style="width:5%; text-align: center;">
<f:facet name="footer">
----------------> <p:commandButton actionListener="#{testManagedBean.deleteMultipleActionListener}" oncomplete="confirmDeleteMultiple.show()" update=":form:confirmDialogDeleteMultiple" process=":form:dataTable" icon="ui-icon ui-icon-close"/>
</f:facet>
</p:column>
<p:column headerText="Index">
<h:outputText value="#{rowIndex+1}"/>
</p:column>
<p:column id="id" headerText="Id">
<h:outputText value="#{row.id}"/>
</p:column>
<p:column id="countryName" headerText="Description">
<h:outputText value="#{row.description}"/>
</p:column>
</p:dataTable>
---------------><p:confirmDialog id="confirmDialogDeleteMultiple" widgetVar="confirmDeleteMultiple" appendToBody="true" message="Delete row(s)?" showEffect="true" hideEffect="true" header="Deletion of row." severity="alert" closeOnEscape="true" closable="true">
<p:commandButton id="confirmDeleteMultiple" value="Yes" oncomplete="confirmDeleteMultiple.hide()" actionListener="#{testManagedBean.deleteMultiple}" process="#this dataTable" update="dataTable"/>
<p:commandButton id="declineDeleteMultiple" value="No" onclick="confirmDeleteMultiple.hide()" type="button" />
</p:confirmDialog>
</h:form>
</ui:define>
</ui:composition>
The managed bean:
#ManagedBean
#ViewScoped
public final class TestManagedBean implements Serializable
{
#EJB(mappedName="ejb/JNDI")
private TestService testService;
private List<Test> list;
private List<Test>selectedValues;
public TestManagedBean(){}
#PostConstruct
public void init()
{
list=testService.getList();
}
public List<Test> getList() {
return list;
}
public List<Test> getSelectedValues() {
return selectedValues;
}
public void setSelectedValues(List<Test> selectedValues) {
this.selectedValues = selectedValues;
}
public void deleteMultipleActionListener(ActionEvent actionEvent)
{
//Just show a warning message, when the delete button is pressed.
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//Displays the list.
}
public void deleteMultiple(ActionEvent actionEvent)
{
System.out.println("multiple");
for(Test test:selectedValues)
{
System.out.println(test.getId()+" : "+test.getDescription());
}//The list is not null and empty.
}
}
When the button (indicated by an arrow in XHTML) is pressed, the deleteMultipleActionListener() method in the managed bean is invoked where it simply displays the list which is populated by the selected rows and the confirm dialog as shown in XHTML appears afterwards. (This is just to show a warning message before deletion. The loop in this method is just for the demonstration).
When the Yes button on the confirm dialog is pressed, the deleteMultiple() method is invoked which is responsible for actual deletion of rows (actionListioner in <p:commandButton> inside <p:confirmDialog>) and the deletion of rows should be performed but here the list of the selected rows retrieved here is empty (not null).
The resulting list inside the deleteMultiple() method is empty because of <f:view> on the template page. The template page is shown below.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
--------->
<f:view locale="#{localeBean.locale}" encoding="UTF-8" contentType="text/html">
<f:loadBundle basename="messages.ResourceBundle" var="messages"/>
<h:head><title><ui:insert name="title">Default Title</ui:insert></title></h:head>
<h:body>
<p:layout fullPage="true">
<p:layoutUnit position="north" size="135" collapsed="false" resizable="false" closable="false" collapsible="false" gutter="6">
<h:form>
<h:selectOneMenu id="languages" value="#{localeBean.language}" onchange="submit();" style="position: absolute; right: 0; top: 50px;">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="hi" itemLabel="Hindi" />
</h:selectOneMenu>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="west" id="leftPanel" size="225" header="Menu Item" resizable="false" closable="false" collapsible="true" gutter="6">
</p:layoutUnit>
<p:layoutUnit position="center" size="2500" maxSize="2500">
<ui:insert name="content">Put default content here, if any.</ui:insert>
</p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>
When I remove this template from the above Test.xhtml page and use this <f:view> tag on the Test.xhtml page itself, everything works fine and the list of the selected rows inside the deleteMultiple() method is obtained correctly.
So, what is going wrong? Why does the list become empty when the Yes button is pressed, if the template page is enclosed by <f:view>? Is it wrong? How to accomplish this? (<f:view> is used for the localization of the application as it can be imagined).
Your problem is solved when you replace the process="#this datatable" in your confirmDeleteMultiple by process="#this", which makes the button component only be processed. In fact you don't need Ajax to process your datatable when you send the deletion confirmation, because values for deletion are already stored in the bean since previous step (that's the main benefit of the view scope).
Making your datatable to be processed in your Ajax request invokes again the setSelectedValues setter, so the original value is getting overriden by the new (empty) selection.
I have one primeface page certHollderList.xhtml:
In this page i have one expire Link. And on click one action is fired and after processing the action, i want to open one dialog box in same page.
code 1:Expire Link::
<h:commandLink id="expire" value="#{label.expire}" action="expire" immediate="true" oncomplete="dlg3.show()"
update="dialogPanel">
code 2 :: In the same page i added one outputpanel having a dialog box.
<h:form>
<p:outputPanel id="dialogPanel" rendered="# {certHolderSearchHandler.openDialog eq 'Success'}">
<p:dialog header="Expire Holder Information" widgetVar="dlg3"
showEffect="bounce" hideEffect="explode" appendToBody="true">
<p:outputPanel id="dialogPanel1"
rendered="#{certHolderSearchHandler.openDialog eq 'Success'}">
<h:panelGrid columns="2">
<h:outputText value="Do you want to continue?" />
<p:spacer width="30" height="10" />
<h:outputText />
<p:spacer width="30" height="10" />
</h:panelGrid>
<div align="left"><p:commandButton immediate="true"
value="Yes" action="continue" /> <p:spacer width="25" height="5" />
<p:commandButton value="No" action="cancel" /></div>
</p:outputPanel>
</p:dialog>
</p:outputPanel>
</h:form>
And when i clicked the expire link,it doesn't open the dialog page.
Please advise me....:(
Try using the Primefaces model to actually update it:
//JSF
<h:form id="someForm">
<p:commandLink
id = "expire"
value="#{label.expire}"
actionListener="#{myBean.doSomething}"
oncomplete="dialog.show()"
update="dialogForm:dialogPanel"
/>
...
<h:form id="dialogForm">
<p:dialog id="dialog"..... />
</h:form>
//MyBean...
public void doSomething(ActionEvent evt)
{
//Logic
}
What you're missing is that you're not using the Primefaces ajax engine. There's some good tutorials at primefaces.org and the forums are very helpful. The other thing you should know is an action is probably not the best way to handle showing the dialog. There's nothing you can do with an ActionListener and it will give you a very fine level of control on the page. You can then use the action when you actually need to throw something up for navigation.
Here is a tested working example of the above (Primefaces 2.2.1)
//Bean
#ViewScoped
#ManagedBean(name = "demoBean")
public class DemoBean
{
private String hello = "Hello World";
private String notSet = "not set";
public void doAction(ActionEvent evt)
{
notSet = hello;
}
/**
* #return the hello
*/
public String getHello()
{
return hello;
}
/**
* #return the notSet
*/
public String getNotSet()
{
return notSet;
}
/**
* #param hello
* the hello to set
*/
public void setHello(String hello)
{
this.hello = hello;
}
/**
* #param notSet
* the notSet to set
*/
public void setNotSet(String notSet)
{
this.notSet = notSet;
}
}
JSF Demo file as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
</h:head>
<h:body class="center" style="zIndex:-3">
<h:form id="commands">
<p:inputText value="#{demoBean.hello}" />
<p:commandButton
value="Open Dialog"
actionListener="#{demoBean.doAction}"
update="dialog"
oncomplete="dialogWidget.show()"
/>
</h:form>
<p:dialog widgetVar="dialogWidget">
<h:form id="dialog">
<p:panel>
<h3>Dialog</h3>
<p>
<h:outputText value="Copied: #{demoBean.notSet}"/>
</p>
</p:panel>
</h:form>
</p:dialog>
</h:body>
The thing to watch out for in Primefaces is that it is not using the built in AJAX implementation (it is compatible, but there can be "double" updates so things don't render properly). As such, when you use the widgetVar you're directly calling a show method from Javascript, you'll notice this code does the update and then calls the method.
<p:commandLink id="expire" value="#{label.expire}" onclick="dlg3.show()">
<f:param name="certHoldertId" value="#{certHolder.accountOwner.itemIdInfo.insurerId}" />
<f:param name="accNumberId" value="#{certHolder.accountNumberId}"/>
</p:commandLink>
#Daniel..Its working fine with button and also able to call the popup on click of this link.But we are able to pass the values with this link. When we try to retrieve the value of certHoldertId varible with FaceContext,its give the null value.I think it return the false value.
How can we send these value with this link?
I'm using a PrimeFaces DataTable to display records (randomly generated in a sandbox application). I am using the check box selection version. The basic DataTable works perfectly, including the Delete and Cancel buttons (which functionality only really is available from the confirmation dialog). I am trying to add functionality to the DataTable so that when a check box is selected, other controls on the page are enabled or disabled based on the selection.
In other words, if no rows are selected (no check boxes are checked) certain buttons and/or menu items are disabled or not rendered. Selecting one or more rows by clicking the check box should enable or render the controls. I have tried using the built in JavaScript event handlers, but I cannot make this work.
Right now my page displays a DataTable 5 columns: a check box selection column, First Name, Last Name, Age. I made something like this work in another sandbox of mine using simple boolean check boxes and updating a boolean with the onclick event. Unfortunately, there doesn't seem to be anything similar in this DataTable - or if there is I don't know how to implement it.
My index page:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="./newTemplate.xhtml">
<ui:define name="content">
<h:form>
<p:dataTable rowSelectListener="#{tableBean.onRowSelect}" var="data" value="#{tableBean.data}" paginator="true" rows="10"
selection="#{tableBean.selectedNames}">
<f:facet name="header">
Customer List
</f:facet>
<p:column selectionMode="multiple" />
<p:column headerText="Cust ID">
<h:outputText value="#{data.id}" />
</p:column>
<p:column headerText="First Name">
<h:outputText value="#{data.firstName}" />
</p:column>
<p:column headerText="Last Name">
<h:outputText value="#{data.lastName}" />
</p:column>
<p:column headerText="Age">
<h:outputText value="#{data.age}" />
</p:column>
<f:facet name="footer">
<p:commandButton update="deleteList" value="Delete" oncomplete="deleteDlg.show()" />
</f:facet>
</p:dataTable>
<p:dialog header="Delete Selected Records" modal="true" widgetVar="deleteDlg"
>
<h:outputText value="You are about to permanently delete records." /><br /><br />
<h:outputText value="Are you sure you want to continue?" /><br /><br/>
<h:commandButton value="CANCEL" action="#{tableBean.cancelDelete()}" /> <h:commandButton value="Delete" action="#{tableBean.deleteNames()}" />
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
Code from my backing bean which may be relevant:
public void deleteNames()
{
for(Data person : selectedNames)
{
data.remove(person);
}
}
public void cancelDelete()
{
for(Data name : selectedNames)
selectedNames = null;
}
public void onRowSelect(SelectEvent event)
{
if(selectedNames == null || selectedNames.length < 1)
setDisable(true);
else
setDisable(false);
}
public boolean isDisable() {
if(selectedNames == null || selectedNames.length < 1)
disable = true;
else
disable = false;
return disable;
}
public void setDisable(boolean disable) {
this.disable = disable;
}
There is a workaround indeed, at least work for me.
extract the datatable.js from primefacess
modify the datatable.js selectRowWithRadio,selectRowWithRadio functions as below
PrimeFaces.widget.DataTable.prototype.selectRowWithCheckbox = function(element) {
...
...
//save state
this.writeSelections();
// added to add instant row selection
this.fireRowSelectEvent(rowId);
// end
}
Append the javascript below to end of your datatable component
<p:datatable widgetVar="wv1" id='mydatatable' ....>
...
<p:datatable/>
<script type="text/javascript">
if(!wv1_main.cfg.onRowSelectUpdate){
wv1.cfg.onRowSelectUpdate="";
}else{
wv1.cfg.onRowSelectUpdate+=" ";
}
wv1.cfg.onRowSelectUpdate+="UPDATE_IDS";
</script>
Replace 'UPDATE_IDS' with your panel ids seperated by space such as "panel1 panel2";
Replace 'wv1' with the value of data table widgetVar property
import the modified js in your jsf page where you want to use instant ajax checkbox/radia selection.
<h:header/>
...
<script type="text/javascript" src="#{CONTEXT_PATH}/resources/js/datatable.js"/>
<h:header/>
you may highligh selected rows with some more modification
Was just searching for solution to the same problem and since JSF 2 / Primefaces are evolving quite fast these days, found more up-to-date solution for Primefaces of version 3.0 or higher.
As per following answer in PrimeFaces forum thread:
http://forum.primefaces.org/viewtopic.php?f=3&t=1373&sid=bbfcd6a343edf586f927cd7ecd7d01b9&start=10#p48388
one can add client-side javascript handler to <p:datatable> component by doing following steps:
1.Add primefaces-extension JAR to your webapp's classpath (this library is also available in central Maven repo under the same name). I tried version 0.6.3 which was the latest at the time of writing, and it worked for me
2.Add pe namespace to corresponding xhtml file:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:pe="http://primefaces.org/ui/extensions">
...
</html>
3.Add <pe:javascript> as a child element to your <p:datatable> component (can be actually added to any component which implements ClientBehaviorHolder interface) like the following:
<html>
...
<p:dataTable rowSelectListener="#{tableBean.onRowSelect}" var="data" value="#{tableBean.data}" paginator="true" rows="10" selection="#{tableBean.selectedNames}">
<pe:javascript event="rowSelect" execute="onRowSelectedHandler();"/>
...
</p:dataTable>
...
</html>
And that should be it, hope this helps...
You can catch ajax events that are fired when the row is selected.
In your case,
<p:dataTable rowSelectListener="#{tableBean.onRowSelect}"
var="data" value="#{tableBean.data}" paginator="true" rows="10"
selection="#{tableBean.selectedNames}">
<p:ajax event="rowSelectCheckbox" listener="#{tableBean.handleEvent}"
update="buttonThatNeedsToBeRendered"/>
<p:column selectionMode="multiple" />
...
</p:dataTable>
Other useful events that are fired depending on the selection mode of the dataTable are:
rowSelect and rowUnselect
rowSelectCheckbox and rowUnselectCheckbox
rowSelectRadio
toggleSelect