Im getting my primefaces scaffold ready for my developers and I have a problem. When I do a form submit with validation via AJAX, it displays the message right, but the return deletes all but the first field in the form. Its almost like something screwy in the return ajax call is causing everything after the first text field to fail to render. If I do a standard form submit button, it works just fine, but just with the ajax submit (which of course is the one i want to use) it acts weird. Any ideas?
My index.xhtml page. Just look for header="New Person", pasted it right out of the showcase
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:core="http://highmark.com/dtmcore"
xmlns:inq="http://highmark.com/dtminq"
template="templates/default.xhtml">
<ui:define name="navDisplay">
<ui:include src="navBar/mainNavBar.xhtml" />
</ui:define>
<ui:define name="content">
<script type="text/javascript">
$(document).ready(
function() {
jvers = $.fn.jquery;
$("#testJQueryLoaded").text(
"jQuery Loaded Correctly version " + jvers);
});
</script>
<div class="row clearfix">
<div class="col-md-12 column">
<div class="row clearfix">
<div class="col-md-12">
<div class="jumbotron">
<h2>Inquiry App System</h2>
<p>This page right now is used primarily for testing controls
and layout</p>
<p></p>
<span id="testJQueryLoaded"></span> <br />
<h3>Your application can run on:</h3>
<h:graphicImage library="gfx" name="dualbrand_as7eap.png" />
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12">
<div class="well">
<h:form id="form">
<p:panel id="panel" header="New Person" style="margin-bottom:10px;">
<p:messages id="messages" />
<h:panelGrid columns="3">
<h:outputLabel for="firstname" value="Firstname: *" />
<p:inputText id="firstname"
value="#{pprBean.firstname}" required="true" label="Firstname">
<f:validateLength minimum="2" />
</p:inputText>
<p:message for="firstname" />
<h:outputLabel for="surname" value="Surname: *" />
<p:inputText id="surname"
value="#{pprBean.surname}" required="true" label="Surname"/>
<p:message for="surname" />
</h:panelGrid>
</p:panel>
<p:commandButton value="Ajax Submit" update="panel,display" id="ajax"
actionListener="#{pprBean.savePerson}" styleClass="ui-priority-primary"/>
<p:commandButton value="Non-Ajax Submit" actionListener="#{pprBean.savePerson}"
ajax="false" />
<p:commandButton value="With Icon" actionListener="#{pprBean.savePerson}" id="withIcon"
update="panel,display" icon="ui-icon-disk" />
<p:commandButton actionListener="#{pprBean.savePerson}" update="panel,display" id="iconOnly"
icon="ui-icon-disk" title="Icon Only"/>
<p:commandButton value="Disabled" disabled="true" id="disabled" />
<p:panel id="display" header="Information" style="margin-top:10px;">
<h:panelGrid columns="2">
<h:outputText value="Firstname: " />
<h:outputText value="#{pprBean.firstname}" />
<h:outputText value="Surname: " />
<h:outputText value="#{pprBean.surname}" />
</h:panelGrid>
</p:panel>
</h:form>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-6">
<ui:include src="modules/buttonExample.xhtml" />
</div>
<div class="col-md-6">
<p:outputPanel id="displayHotkey">
<p:outputLabel value="Hotkey Result" />
<br />
<h:outputText value="#{hotkeyController.keyText}"
rendered="#{not empty hotkeyController.keyText}" />
</p:outputPanel>
</div>
</div>
<div class="row clearfix">
<div class="col-md-6">
<ui:include src="modules/datePickerExample.xhtml" />
</div>
<div class="col-md-6"></div>
</div>
<div class="row clearfix">
<div class="col-md-12">
<div class="well">
<h2>Members</h2>
<br />
<h:panelGroup rendered="#{empty members}">
<em>No registered members.</em>
</h:panelGroup>
<p:dataTable id="dataTable" var="_member" value="#{members}"
rendered="#{not empty members}"
styleClass="table table-striped table-bordered">
<p:column>
<f:facet name="header">Id</f:facet>
#{_member.id}
</p:column>
<p:column>
<f:facet name="header">Name</f:facet>
#{_member.name}
</p:column>
<p:column>
<f:facet name="header">Email</f:facet>
#{_member.email}
</p:column>
<p:column>
<f:facet name="header">Phone #</f:facet>
#{_member.phoneNumber}
</p:column>
<p:column>
<f:facet name="header">REST URL</f:facet>
/rest/members/#{_member.id}
</p:column>
<f:facet name="footer">
REST URL for all members: /rest/members
</f:facet>
</p:dataTable>
</div>
</div>
</div>
</div>
</div>
</ui:define>
<ui:define name="hotkeyMenu">
<ui:include src="hotkeyBar/hotkeyExample.xhtml" />
</ui:define>
</ui:composition>
And my template file (so far, work in progress)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.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.org/ui">
<h:head>
<title>#{app.applicationName}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>#{app.applicationName}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta name="author" content="" />
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
</style>
<h:outputStylesheet name="css/bootstrap.min.css" />
<h:outputStylesheet name="css/inquiry.css" />
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:outputScript library="js" name="respond.min.js" />
<h:outputScript library="js" name="bootstrap.min.js" />
<!-- <h:outputScript library="js" name="bootstrap-dropdown.js"/> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</h:head>
<h:body>
<div class="container">
<div class="row">
<div class="col-md-12 column">
<ui:insert name="navDisplay">[Navigation Display inserted here]</ui:insert>
</div>
<div class="row show-grid">
<div class="col-md-11 column">
<div class="row">
<div class="col-md-12 column">
<ui:insert name="content">[Template content will be inserted here]</ui:insert>
</div>
</div>
</div>
<div class="col-md-1 column">
<ui:insert name="hotkeyMenu">[The Hotkey vertical bar goes here.]</ui:insert>
</div>
</div>
<div class="row">
<div class="col-md-12 column">
<p>United Concordia Rocks!</p>
</div>
</div>
</div>
</div>
<!--/.fluid-container-->
</h:body>
</html>
my backing bean
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.context.RequestContext;
#ManagedBean(name = "pprBean")
#SessionScoped
public class PPRBean implements Serializable {
private String firstname;
private String surname;
private String city;
private String suburb;
private Map<String, String> cities = new HashMap<String, String>();
private Map<String, Map<String, String>> suburbsData = new HashMap<String, Map<String, String>>();
private Map<String, String> suburbs = new HashMap<String, String>();
private Map<String, String> rooms = new HashMap<String, String>();
private Map<String, Map<String, String>> itemsData = new HashMap<String, Map<String, String>>();
private Map<String, String> items = new HashMap<String, String>();
private String room;
private String item;
private String[] selectedCities;
public PPRBean() {
cities.put("Istanbul", "Istanbul");
cities.put("Ankara", "Ankara");
cities.put("Izmir", "Izmir");
Map<String, String> suburbsIstanbul = new HashMap<String, String>();
suburbsIstanbul.put("Kadikoy", "Kadikoy");
suburbsIstanbul.put("Levent", "Levent");
suburbsIstanbul.put("Cengelkoy", "Cengelkoy");
Map<String, String> suburbsAnkara = new HashMap<String, String>();
suburbsAnkara.put("Kecioren", "Kecioren");
suburbsAnkara.put("Cankaya", "Cankaya");
suburbsAnkara.put("Yenimahalle", "Yenimahalle");
Map<String, String> suburbsIzmir = new HashMap<String, String>();
suburbsIzmir.put("Cesme", "Cesme");
suburbsIzmir.put("Gumuldur", "Gumuldur");
suburbsIzmir.put("Foca", "Foca");
suburbsData.put("Istanbul", suburbsIstanbul);
suburbsData.put("Ankara", suburbsAnkara);
suburbsData.put("Izmir", suburbsIzmir);
rooms.put("Living Room", "Living Room");
rooms.put("Kitchen", "Kitchen");
rooms.put("Bedroom", "Bedroom");
Map<String, String> livingRoomItems = new HashMap<String, String>();
livingRoomItems.put("Sofa", "Sofa");
livingRoomItems.put("Armchair", "Armchair");
livingRoomItems.put("Coffee Table", "Coffee Table");
Map<String, String> kitchenItems = new HashMap<String, String>();
kitchenItems.put("Refrigirator", "Refrigirator");
kitchenItems.put("Dishwasher", "Dishwasher");
kitchenItems.put("Oven", "Oven");
Map<String, String> bedroomItems = new HashMap<String, String>();
bedroomItems.put("Bed", "Bed");
bedroomItems.put("Wardrobe", "Wardrobe");
bedroomItems.put("Drawer Chest", "Drawer Chest");
itemsData.put("Living Room", livingRoomItems);
itemsData.put("Kitchen", kitchenItems);
itemsData.put("Bedroom", bedroomItems);
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void savePerson(ActionEvent actionEvent) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("You've registered"));
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getSuburb() {
return suburb;
}
public void setSuburb(String suburb) {
this.suburb = suburb;
}
public Map<String, String> getCities() {
return cities;
}
public void setCities(Map<String, String> cities) {
this.cities = cities;
}
public Map<String, Map<String, String>> getSuburbsData() {
return suburbsData;
}
public void setSuburbsData(Map<String, Map<String, String>> suburbsData) {
this.suburbsData = suburbsData;
}
public Map<String, String> getSuburbs() {
return suburbs;
}
public void setSuburbs(Map<String, String> suburbs) {
this.suburbs = suburbs;
}
public void handleCityChange() {
if (city != null && !city.equals(""))
suburbs = suburbsData.get(city);
else
suburbs = new HashMap<String, String>();
}
public void handleRoomChange(ActionEvent actionEvent) {
if (room != null && !room.equals(""))
items = itemsData.get(room);
else
items = new HashMap<String, String>();
}
private boolean checked;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String[] getSelectedCities() {
return selectedCities;
}
public void setSelectedCities(String[] selectedCities) {
this.selectedCities = selectedCities;
}
public String getSelectedCitiesAsString() {
if (selectedCities == null)
return "";
StringBuffer buffer = new StringBuffer();
for (String city : selectedCities) {
buffer.append("(");
buffer.append(city);
buffer.append(")");
}
return buffer.toString();
}
public Map<String, String> getRooms() {
return rooms;
}
public void setRooms(Map<String, String> rooms) {
this.rooms = rooms;
}
public Map<String, Map<String, String>> getItemsData() {
return itemsData;
}
public void setItemsData(Map<String, Map<String, String>> itemsData) {
this.itemsData = itemsData;
}
public Map<String, String> getItems() {
return items;
}
public void setItems(Map<String, String> items) {
this.items = items;
}
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public void displayLocation() {
FacesMessage msg = new FacesMessage("Selected", "City:" + city + ", Suburb: " + suburb);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void reset() {
RequestContext.getCurrentInstance().reset("form:panel");
}
public void resetFail() {
this.firstname = null;
this.surname = null;
FacesMessage msg = new FacesMessage("Model reset, but it won't work.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
This is the screen as when you first come to it
If you click the ajax button, this is what returns. The normal submit works just fine
And here's what the JSF is returning in the ajax call. You can see, all the fields are included in the response, but its only displaying the first one
<?xml version="1.0" encoding="utf-8"?><partial-response><changes><update id="form:panel"><![CDATA[<div id="form:panel" class="ui-panel ui-widget ui-widget-content ui-corner-all" style="margin-bottom:10px;" data-widget="widget_form_panel"><div id="form:panel_header" class="ui-panel-titlebar ui-widget-header ui-helper-clearfix ui-corner-all"><span class="ui-panel-title">New Person</span></div><div id="form:panel_content" class="ui-panel-content ui-widget-content"><div id="form:messages" class="ui-messages ui-widget" aria-live="polite"><div class="ui-messages-error ui-corner-all"><span class="ui-messages-error-icon"></span><ul><li><span class="ui-messages-error-summary">Firstname: Validation Error: Value is required.</span></li><li><span class="ui-messages-error-summary">Surname: Validation Error: Value is required.</span></li></ul></div></div><table><tbody>
<tr><td><label for="form:firstname">Firstname: *</label></td><td><input id="form:firstname" name="form:firstname" type="text" value="" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all ui-state-error" /><script id="form:firstname_s" type="text/javascript">//<![CDATA[
PrimeFaces.cw('InputText','widget_form_firstname',{id:'form:firstname'});
//]]><![CDATA[]]]]><![CDATA[></script></td><td><div id="form:j_id679843775_7ac2197c" aria-live="polite" class="ui-message ui-message-error ui-widget ui-corner-all"><span class="ui-message-error-icon"></span><span class="ui-message-error-detail">Firstname: Validation Error: Value is required.</span></div></td></tr>
<tr><td><label for="form:surname">Surname: *</label></td><td><input id="form:surname" name="form:surname" type="text" value="" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all ui-state-error" /><script id="form:surname_s" type="text/javascript">//<![CDATA[
PrimeFaces.cw('InputText','widget_form_surname',{id:'form:surname'});
//]]><![CDATA[]]]]><![CDATA[></script></td><td><div id="form:j_id679843775_7ac21953" aria-live="polite" class="ui-message ui-message-error ui-widget ui-corner-all"><span class="ui-message-error-icon"></span><span class="ui-message-error-detail">Surname: Validation Error: Value is required.</span></div></td></tr>
</tbody>
</table></div></div><script id="form:panel_s" type="text/javascript">//<![CDATA[
PrimeFaces.cw('Panel','widget_form_panel',{id:'form:panel'});
//]]><![CDATA[]]]]><![CDATA[></script>]]></update><update id="form:display"><![CDATA[<div id="form:display" class="ui-panel ui-widget ui-widget-content ui-corner-all" style="margin-top:10px;" data-widget="widget_form_display"><div id="form:display_header" class="ui-panel-titlebar ui-widget-header ui-helper-clearfix ui-corner-all"><span class="ui-panel-title">Information</span></div><div id="form:display_content" class="ui-panel-content ui-widget-content"><table><tbody>
<tr><td>Firstname: </td><td></td></tr>
<tr><td>Surname: </td><td></td></tr>
</tbody>
</table></div></div><script id="form:display_s" type="text/javascript">//<![CDATA[
PrimeFaces.cw('Panel','widget_form_display',{id:'form:display'});
//]]><![CDATA[]]]]><![CDATA[></script>]]></update><update id="javax.faces.ViewState"><![CDATA[zSrt/a8fGazYeKThaR1kLCIZ9H+Byig1+R3m5/RMMwuGDQUZXOPr/aj4D7YpgH6NUcb5jAudj1QUNy6WMLUaVXYQrGkvy6fxpzBhHuvzVejCEMDhFVUj8d7NHCI=]]></update><extension ln="primefaces" type="args">{"validationFailed":true}</extension></changes></partial-response>
EDIT
I found it. Turns out its a bug in PrimeFaces with Websphere.
http://forum.primefaces.org/viewtopic.php?f=3&t=34650
Try
<p:commandButton value="Ajax Submit" update="panel,display" id="ajax"
actionListener="#{pprBean.savePerson}" styleClass="ui-priority-primary"
process="panel,display,#this"/>
And tell me more details about Back Bean to replicate :)
Related
I'm currently trying to implement a dynamic survey page containing pages, sections and questions defined by the user (part of a larger application).
The user may defined different question types, which will render a different component (radio, textarea, textfield, selectionlist, ...).
This app is currently deployed in Wildfly 16 / Java 8 / JSF 2.3 / Servlet 4.
Since the user may define a specific set of values and associated images for the radio button, I need to customize the radio button output. So my option was to use the new group attribute available in selectoneradio.
Using this new attribute is causing erratic behaviour when used inside a multi-level ui:repeat.
The following example was simplified and created in order to illustrate the problem.
Class
package test;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named("test")
#ViewScoped
public class Test implements Serializable
{
private static final long serialVersionUID = 1L;
private static Map<String, Map<String, String>> questionMap = new TreeMap<>();
private static Map<String, String> fixedValuesMap = new TreeMap<>();
private Map<String, String> answerMap = new TreeMap<>();
private List<String> sections = Arrays.asList("Section_1", "Section_2", "Section_3", "Section_4");
static
{
fixedValuesMap.put("1", "Value 1");
fixedValuesMap.put("2", "Value 2");
fixedValuesMap.put("3", "Value 3");
fixedValuesMap.put("4", "Value 4");
fixedValuesMap.put("5", "Value 5");
Map<String, String> sec1questions = new TreeMap<>();
sec1questions.put("1", "Question 1");
sec1questions.put("2", "Question 2");
sec1questions.put("3", "Question 3");
questionMap.put("Section_1", sec1questions);
Map<String, String> sec2questions = new TreeMap<>();
sec2questions.put("4", "Question 4");
questionMap.put("Section_2", sec2questions);
Map<String, String> sec3questions = new TreeMap<>();
sec3questions.put("5", "Question 5");
questionMap.put("Section_3", sec3questions);
Map<String, String> sec4questions = new TreeMap<>();
sec4questions.put("6", "Question 6");
questionMap.put("Section_4", sec4questions);
}
public Test()
{
}
#PostConstruct
private void init()
{
answerMap.put("1", null);
answerMap.put("2", null);
answerMap.put("3", null);
answerMap.put("4", null);
answerMap.put("5", null);
answerMap.put("6", null);
}
public String getQuestionType(String index)
{
switch(index)
{
case "1":
return "RADIO_BUTTON";
case "2":
return "RADIO_BUTTON";
case "3":
return "RADIO_BUTTON";
case "4":
return "TEXT_AREA";
case "5":
return "RADIO_BUTTON";
case "6":
return "FREE_TEXT";
default:
return "FREE_TEXT";
}
}
public Map<String, String> getQuestions(String section)
{
return questionMap.get(section);
}
public Map<String, String> getAnswerMap()
{
return answerMap;
}
public Map<String, String> getFixedValues()
{
return fixedValuesMap;
}
public List<String> getSections()
{
return sections;
}
public void changeRadio(String questionKey, String questionValue)
{
answerMap.put(questionKey, questionValue);
}
public String submit()
{
for(Map.Entry<String, String> entry : answerMap.entrySet())
System.out.println("ENTRY: " + entry.getKey() + " - " + entry.getValue());
return null;
}
}
XHTML
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
<h:head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<meta name="description" content="My Test"/>
<link rel="stylesheet" href="#{request.contextPath}/resources/bootstrap/css/bootstrap.min.css" />
<title>My Test</title>
</h:head>
<h:body>
<div class="container-fluid">
<div class="row">
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">UI Repeat Test</h1>
</div>
<h:form role="form" prependId="false">
<div class="row mx-2">
<ui:repeat var="sec" value="#{test.sections}">
<div class="col-12">
<ui:repeat var="question" value="#{test.getQuestions(sec)}">
<div>
<div class="col-12">
<div class="form-group">
<label for="answer">#{question.key} - #{question.value}</label>
<div class="col-12">
<h:panelGroup rendered="#{test.getQuestionType(question.key) eq 'FREE_TEXT'}" layout="block">
<h:inputText value="#{test.answerMap[question.key]}" styleClass="form-control"/>
</h:panelGroup>
<h:panelGroup rendered="#{test.getQuestionType(question.key) eq 'TEXT_AREA'}" layout="block">
<h:inputTextarea value="#{test.answerMap[question.key]}" styleClass="form-control" rows="2" />
</h:panelGroup>
<h:panelGroup rendered="#{test.getQuestionType(question.key) eq 'RADIO_BUTTON'}" layout="block">
<table class="radio-label checkbox">
<tbody>
<tr>
<ui:repeat var="item" value="#{test.fixedValues.entrySet()}">
<td class="text-center grid-margin">
<h:selectOneRadio group="#{question.key}" value="#{test.answerMap[question.key]}" layout="lineDirection" styleClass="checkbox" >
<f:selectItem itemValue="#{item.key}" itemLabel="#{item.value}" />
</h:selectOneRadio>
</td>
</ui:repeat>
</tr>
</tbody>
</table>
</h:panelGroup>
</div>
</div>
</div>
</div>
</ui:repeat>
</div>
</ui:repeat>
</div>
<div class="row mx-2 my-2">
<div class="col-12">
<h:commandButton value="Test Me" type="submit" action="#{test.submit}" styleClass="btn btn-primary" />
</div>
</div>
</h:form>
</main>
</div>
</div>
<script src="#{request.contextPath}/resources/jquery/jquery.slim.min.js"></script>
<script src="#{request.contextPath}/resources/bootstrap/js/bootstrap.bundle.min.js"></script>
</h:body>
</html>
When the form is submitted only the last radio button and text field values are stored.
If I replace the selectItems ui:repeat
<table class="radio-label checkbox">
<tbody>
<tr>
<ui:repeat var="item" value="#{test.fixedValues.entrySet()}">
<td class="text-center grid-margin">
<h:selectOneRadio group="#{question.key}" value="#{test.answerMap[question.key]}" layout="lineDirection" styleClass="checkbox" >
<f:selectItem itemValue="#{item.key}" itemLabel="#{item.value}" />
</h:selectOneRadio>
</td>
</ui:repeat>
</tr>
</tbody>
</table>
with
<h:selectOneRadio value="#{test.answerMap[question.key]}" layout="lineDirection" >
<f:selectItems value="#{test.fixedValues.entrySet()}" var="item" itemLabel="#{item.key}" itemValue="#{item.value}" />
</h:selectOneRadio>
everything works fine.
I really need to use the first option, so I can add some images to the radio button values.
Am I missing something?
It seemes like you have found an issue. I tried to simplify the example as follows:
My managed Bean:
package my.pkg;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named
#RequestScoped
public class MyBean {
private List<String> items;
private List<Number> numbers;
private Map<String, Object> mapVal;
#PostConstruct
public void init() {
mapVal = new LinkedHashMap<>();
items = new ArrayList<>();
numbers = new ArrayList<>();
for (int i = 0; i < 3; i++) {
items.add("group_" + i);
numbers.add(i);
}
}
// getters/setters ...
}
Example form:
<!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:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
<h:head />
<h:body>
<h:form id="frm1">
<ui:repeat var="grp" value="#{myBean.items}">
<ui:repeat var="num" value="#{myBean.numbers}" varStatus="stat">
<h:selectOneRadio id="radioButton" value="#{myBean.mapVal[grp]}"
group="myGroup_#{grp}">
<f:selectItem itemValue="#{num}" itemLabel="#{grp}: #{num}" />
</h:selectOneRadio>
<br />
</ui:repeat>
<hr />
</ui:repeat>
<h:commandButton value="submit" />
<h:outputText value="myBean.mapVal: #{myBean.mapVal}" />
</h:form>
</h:body>
</html>
User interface an example input:
After submission I'd expect output to be:
myBean.mapVal: {group_0=0, group_1=1, group_2=2}
But it is:
myBean.mapVal: {group_2=2}
The radio buttons from group 0 and 1 lose their selection.
For some inputs I get the expected results:
myBean.mapVal: {group_0=0, group_1=0, group_2=0}
myBean.mapVal: {group_0=1, group_1=1, group_2=1}
myBean.mapVal: {group_0=2, group_1=2, group_2=2}
... using Mojarra 2.3.9.
For MyFaces 2.3.4 I get the expected result for the selection in above screenshot:
{group_0=0, group_1=1, group_2=2}
but it fails for other selections:
1)
expected: {group_0=0, group_1=0, group_2=0}
but is: {group_2=0}
2)
expected: {group_0=0, group_1=0, group_2=2}
but is: {group_1=0, group_2=2}
3)
expected: {group_0=1, group_1=1, group_2=0}
but is: {group_1=1, group_2=0}
In my opinion we should reportan issue for Mojarra and ( if not already present) for MyFaces.
Workaround
If I replace
<ui:repeat var="grp" value="#{myBean.items}">
by
<c:forEach var="grp" items="#{myBean.items}">
I get the expected results for Mojarra and MyFaces.
Like #Selaron suggested, I created an issue under eclipse-ee4j/mojarra
Thank you for the help!
I want to print a simple report with data exporter, but what I got print is the structure not the data, same issue with any format (xsl,csv,pdf). The number of rows I got and the name columns is correct, except data in table.
The browser throws this warning:
Resource interpreted as Document but transferred with MIME type text/csv: "http://localhost:8081/prueba2/faces/views/usrManagement.xhtml".
here is my code:
<p:dataTable id="userTable"
value="#{userManagementBean.lazyModel}"
var="user" emptyMessage="No se encontraron registros"
tableStyle="table-layout:auto;" reflow="true"
paginator="true" rows="5" lazy="true"
paginatorTemplate="{RowsPerPageDropdown}{FirstPageLink}
{PreviousPageLink}{PageLinks}
{NextPageLink}{LastPageLink}">
<f:facet name="header">
Usuarios
</f:facet>
<p:column exportable="false">
<f:facet name="header">Acciones</f:facet>
<p:commandLink class="btn-floating
waves-effect waves-light blue"
action="#{userManagementBean.chosenUsr(user)}"
onsuccess="$('#CRUDModal').modal('open');"
update="modalForm"><i class="fa fa-edit"></i>
</p:commandLink>
</p:column>
<p:column>
<f:facet name="header">Clave de usuario</f:facet>
#{user.aliasVarc}
</p:column>
<p:column>
<f:facet name="header">Número de empleado</f:facet>
#{user.codEmployeeInt}
</p:column>
<p:column>
<f:facet name="header">Nombre</f:facet>
#{user.nameVarc}
</p:column>
<p:column>
<f:facet name="header">A paterno</f:facet>
#{user.lastNameVarc}
</p:column>
<p:column>
<f:facet name="header">Activo</f:facet>
<h:selectBooleanCheckbox value="#{user.isActiveBit}" />
<label></label>
</p:column>
</p:dataTable>
</div>
</div>
<div class="row"></div>
</div>
</div>
</div>
<div class="row" style="margin-bottom: -1px;">
<div class="fixed-action-btn ">
<a class="btn-floating btn-large amber accent-3">
<i class="fa fa-ellipsis-h"></i>
</a>
<ul>
<li><a class="btn-floating blue lighten-3"><i class="fa fa-file-text-o">
</i></a></li>
<li><a class="btn-floating red darken-1"><i class="fa fa-file-pdf-o"></i>
</a></li>
<li>
<h:commandLink class="btn-floating green darken-3">
<p:dataExporter type="pdf" target="userTable" fileName="reporte"
pageOnly="false" />
<i class="fa fa-file-excel-o">
</i></h:commandLink>
</li>
<li><p:commandLink class="btn-floating blue waves-effect waves-light"
action="#{userManagementBean.newUser()}"
onsuccess="$('#CRUDModal').modal('open');"
update="modalForm">
<i class="fa fa-plus"></i>
</p:commandLink></li>
</ul>
</div>
</div>
here is the managed bean:
#ManagedBean
#ViewScoped
public class UserManagementBean implements Serializable{
static final long serialVersionUID = 1L;
private String userName;
private List<Usrs> liUsrs;
private Usrs selectedUsr;
private boolean deleteBtnRendered;
private LazyDataModel<Usrs> lazyModel;
private HashMap<String,Object> params;
private int paginator;
#PostConstruct
public void initMethod() {
selectedUsr = new Usrs();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public List<Usrs> getLiUsrs() {
return liUsrs;
}
public void setLiUsrs(List<Usrs> liUsrs) {
this.liUsrs = liUsrs;
}
public Usrs getSelectedUsr() {
return selectedUsr;
}
public void setSelectedUsr(Usrs selectedUsr) {
this.selectedUsr = selectedUsr;
System.out.println("alias"+selectedUsr.getAliasVarc());
}
public boolean isDeleteBtnRendered() {
return deleteBtnRendered;
}
public void setDeleteBtnRendered(boolean deleteBtnRendered) {
this.deleteBtnRendered = deleteBtnRendered;
}
public LazyDataModel<Usrs> getLazyModel() {
return lazyModel;
}
public int getPaginator() {
return paginator;
}
public void setPaginator(int paginator) {
this.paginator = paginator;
}
public void chosenUsr(Usrs selected){
selectedUsr = selected;
deleteBtnRendered = true;
}
public void callSearchProcess(){
params = new HashMap<>();
params.put("aliasVarc", userName);
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().
getViewRoot().
findComponent("searchForm:userTable");
dataTable.reset();
lazyModel = new LazyUserList(params);
}
public void callInUpProcess(){
new UserManagementController(this).mergeUser();
selectedUsr = new Usrs();
}
public void callDeleteProcess(){
new UserManagementController(this).deleteUser();
selectedUsr = new Usrs();
}
public void newUser(){
selectedUsr = new Usrs();
deleteBtnRendered = false;
}
}
and this is the result
result in pdf format
[csv format][2]
The PF dataexporter only knows how to export simple 'data' things. It is not an html exporter. So that <label> does not work is 'by design'. Regarding the other EL, you need to use them like this:
<h:outputText value=" #{user.lastNameVarc}" />
Then it will work for sure
This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 6 years ago.
I am using the Primefaces Ultima template on a project. I am stuck with an issue trying to fire an action listener on a page.
I am using the ultima template.xhtml as the template for my application.
template.xhtml
<!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:facet name="first">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="theme-color" content="#{guestPreferences.themeColors[guestPreferences.theme]}" />
</f:facet>
<title><ui:insert name="title"/></title>
<h:outputScript name="js/nanoscroller.js" library="ultima-layout" />
<h:outputScript name="js/layout.js" library="ultima-layout" />
<h:outputScript name="js/ripple.js" library="ultima-layout" />
<h:outputScript name="js/swipe.js" library="ultima-layout" />
<h:outputStylesheet library="css" name="pfcrud.css"/>
<h:outputScript library="scripts" name="pfcrud.js"/>
<ui:insert name="head"/>
</h:head>
<h:body styleClass="main-body #{guestPreferences.compact ? 'layout-compact' : null}">
<p:growl id="growl" life="3000"/>
<div class="layout-wrapper #{guestPreferences.menuLayout} #{guestPreferences.orientationRTL ? 'layout-rtl' : null}">
<ui:include src="./topbar.xhtml" />
<ui:include src="./menu.xhtml" />
<div class="layout-main">
<ui:insert name="content"/>
<ui:include src="./footer.xhtml" />
</div>
</div>
<p:ajaxStatus style="width:32px;height:32px;position:fixed;right:7px;bottom:7px">
<f:facet name="start">
<i class="fa fa-circle-o-notch fa-spin ajax-loader" aria-hidden="true"></i>
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<h:outputStylesheet name="css/nanoscroller.css" library="ultima-layout" />
<h:outputStylesheet name="css/animate.css" library="ultima-layout" />
<h:outputStylesheet name="css/ripple.css" library="ultima-layout" />
<h:outputStylesheet name="css/my_layout.css" library="ultima-layout" />
</h:body>
The page I am having issue has the code below.
profile.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 xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
template="/WEB-INF/template.xhtml">
<ui:define name="title">
Profile
</ui:define>
<ui:define name="content">
<div class="ui-g ui-fluid">
<div class="ui-g-12 ui-lg-6">
<!-- Left Side -->
<h:form id="personalForm">
<div class="card card-w-title">
<h1>Personal Info</h1>
<h:panelGroup id="personalInfo" rendered="#{loginController.currentUser != null}">
<p:panelGrid columns="2" layout="grid" styleClass="ui-panelgrid-blank form-group">
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="accessCode" value="#{loginController.tempUser.accessCode}" title="#{messages.CreateUserTitle_firstName}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_firstName}" maxlength="50" disabled="true"/>
<label>Access Code</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="firstName" value="#{loginController.tempUser.firstName}" title="#{messages.CreateUserTitle_firstName}" maxlength="50"/>
<label for="firstName">First Name</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="lastName" value="#{loginController.tempUser.lastName}" title="#{messages.CreateUserTitle_lastName}" maxlength="50"/>
<label for="lastName">Last Name</label>
</h:panelGroup>
<p:selectOneMenu id="country" value="#{loginController.tempUser.country}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_country}" converter="countryConverter" style="width: 100%">
<f:selectItem itemLabel="#{messages.CreateUserLabel_country}"/>
<f:selectItems value="#{countryController.items}"
var="countryItem"
itemValue="#{countryItem}"
itemLabel="#{countryItem.id.toString()}"
/>
</p:selectOneMenu>
<p:selectOneMenu id="nationality" value="#{loginController.tempUser.nationality}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_nationality}" converter="countryConverter" style="width: 100%">
<f:selectItem itemLabel="#{messages.CreateUserLabel_nationality}"/>
<f:selectItems value="#{countryController.items}"
var="nationalityItem"
itemValue="#{nationalityItem}"
itemLabel="#{nationalityItem.id.toString()}"
/>
</p:selectOneMenu>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="city" value="#{loginController.tempUser.city}" title="#{messages.CreateUserTitle_city}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_city}" size="50" maxlength="50" style="width: 100%"/>
<label for="city">City</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="email" value="#{loginController.tempUser.email}" title="#{messages.CreateUserTitle_email}" required="true" requiredMessage="#{messages.CreateUserRequiredMessage_email}" size="50" maxlength="50"/>
<label for="email">Email</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="telephone1" value="#{loginController.tempUser.telephone1}" title="#{messages.CreateUserTitle_telephone1}"
required="true" requiredMessage="#{messages.CreateUserRequiredMessage_telephone1}" size="20" maxlength="20" style="width: 100%"/>
<label for="telephone1">Telephone 1</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="telephone2" value="#{loginController.tempUser.telephone2}" title="#{messages.CreateUserTitle_telephone2}"
size="20" maxlength="20" style="width: 100%"/>
<label for="telephone2">Telephone 2</label>
</h:panelGroup>
</p:panelGrid>
<p:commandButton actionListener="#{loginController.updateProfile(event)}" value="Update" update="personalForm:personalInfo, :growl" icon="fa fa-paper-plane-o" >
<p:confirm header="#{messages.ConfirmationHeader}" message="#{messages.ConfirmCreateMessage}"/>
</p:commandButton>
</h:panelGroup>
</div>
</h:form>
</div>
<div class="ui-g-12 ui-lg-6">
<!-- Right Side -->
<h:form id="passwordForm">
<div class="card card-w-title">
<h1>Change Password</h1>
<h:panelGroup id="passwordInfo" rendered="#{loginController.currentUser != null}">
<p:panelGrid columns="2" layout="grid" styleClass="ui-panelgrid-blank form-group">
<h:panelGroup styleClass="md-inputfield">
<p:password id="password" required="true" requiredMessage="Please fill out the new password"
value="#{loginController.password}" match="confirmPassword"/>
<label for="password">New Password</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:password id="confirmPassword" value="#{loginController.password}" required="true"
requiredMessage="Please repeate the new password"/>
<label for="confirmPassword">Confirm New Password</label>
</h:panelGroup>
</p:panelGrid>
<p:commandButton actionListener="#{loginController.updatePassword(event)}" value="Update" update="passwordForm:passwordInfo, :growl" icon="fa fa-paper-plane-o" >
<p:confirm header="#{messages.ConfirmationHeader}" message="#{messages.ConfirmCreateMessage}"/>
</p:commandButton>
</h:panelGroup>
</div>
</h:form>
</div>
</div>
</ui:define>
</ui:composition>
And the session beans having the action listeners has the code below:
LoginController.java
#ManagedBean(name = "loginController")
#SessionScoped
public class LoginController implements Serializable {
private static final long serialVersionUID = 1L;
private User currentUser = new User();
private User tempUser = new User();
private User oldUserValue = new User();
private String accessCode;
private String password;
private String telephone;
private String email;
private String userName;
#Inject
RoleFacade roleFacade;
private enum UsersActions {
SIGN_UP,
CHANGE_PWD,
UPDATE
}
#Inject
private UserFacade userFacade;
public String getAccessCode() {
return accessCode;
}
public void setAccessCode(String accessCode) {
this.accessCode = accessCode;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User getCurrentUser() {
return currentUser;
}
public void setCurrentUser(User currentUser) {
FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().put("currentUser", currentUser);
this.currentUser = currentUser;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User getOldUserValue() {
return oldUserValue;
}
public void setOldUserValue(User oldUserValue) {
this.oldUserValue = oldUserValue;
}
public User getTempUser() {
return tempUser;
}
public void setTempUser(User tempUser) {
this.tempUser = tempUser;
}
public String authenticate() throws NoSuchAlgorithmException {
User user = userFacade.findByAccessCode(accessCode);
if (user != null && user.getPassword().equals(MyStringUtil.toSHA256(password))) {
this.setCurrentUser(user);
StringBuilder strBuilder = new StringBuilder();
String firstName = getNonNullValue(this.getCurrentUser().getFirstName());
String lastName = getNonNullValue(this.getCurrentUser().getLastName());
strBuilder.append(firstName);
strBuilder.append((lastName.isEmpty() ? "" : " " + lastName));
this.setUserName(strBuilder.toString());
return "/dashboard";
}
return "#";
}
public String signOut() {
this.setCurrentUser(null);
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.invalidateSession();
return "/login";
}
private String getNonNullValue(String value) {
return (value == null || value.isEmpty() ? "" : value);
}
public void forgotPassword(ActionEvent event) {
if (accessCode != null && email != null && telephone != null) {
User user = userFacade.findByEmailAndTelephone(accessCode, email, telephone);
if (user != null) {
try {
String clearPwd = MyStringUtil.generatePwd();
User user2 = (User) (new PersistenceCloner(user)).generateCopyToPersist();
user.setPassword(MyStringUtil.toSHA256(clearPwd));
// outgoing message information
String mailTo = user.getEmail();
String subject = "My Way Investracker Password updated";
// message contains HTML markups
String message = "<i>Hello Investor!</i><br><br>";
message += "<p><b>You new password is:</b><br>";
message += "<i></i> <b><h2><font color=red>" + clearPwd + "</font></h2></b>";
message += "<i>Please kindly change it upon next login.</i><br><br></p>";
message += "<font color=red>My Way Sarl</font>";
System.out.println("User 1 = " + user);
System.out.println("User 2 = " + user2);
try {
this.persist(user, user2, UsersActions.CHANGE_PWD,
"A mail has been sent to you with the new password.");
MailUtil.sendHtmlEmail(mailTo, subject, message);
} catch (Exception ex) {
JsfUtil.addErrorMessage("Sorry there was an error handling this, please try again!");
Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchAlgorithmException ex) {
JsfUtil.addErrorMessage("Sorry there was an error handling this, please try again!");
Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
JsfUtil.addErrorMessage("Sorry the email and telephone number doesn't match!");
}
}
}
public void signUp(ActionEvent event) throws NoSuchAlgorithmException {
String access = MyStringUtil.generateAccessCode();
Role role = new Role();
role.setId("NONE");
role.setName("NONE");
this.tempUser.setIdRole(role);
this.tempUser.setAccessCode(access);
this.tempUser.setPassword(MyStringUtil.toSHA256(this.tempUser.getPassword()));
this.tempUser.setActivityStatus(false);
persist(this.tempUser, this.tempUser, LoginController.UsersActions.SIGN_UP, "You have successfully registered, check your email for your access code.");
}
public void updateProfile(ActionEvent event) {
System.out.println("UPDATE PROFILE LAUNCHED.");
System.out.println("UPDATE PROFILE COMPLETED.");
}
public void updatePassword(ActionEvent event) {
System.out.println("UPDATE PASSWORD LAUNCHED");
System.out.println("UPDATE PASSWORD COMPLETED.");
}
private void persist(User newValue, User oldValue, LoginController.UsersActions actionName, String successMessage) {
System.out.println("PERSISTENCE METHOD ALREADY RAN.");
}
}
So far I have made some research on this issue and have come across as similar issue with an answer proposed by #BalusC, but I am unable to find the issue. Please I would need your help!
You are using p:confirm in combination with p:commandButton, but you didn't define a global p:confirmDialog.
You have two options:
Remove the p:confirm child from the p:commandButton.
Add a global p:confirmDialog to your page (see example of p:confirmDialog in PrimeFaces-Showcase). The actionListener will then be invoked on pressing the Yes-button inside the confirmation dialog.
I have checked as much as i can ,but i could not find where the problem is , i have seen few stack overflow Questions related to mine but mostly they all seems missing # .
and i have seen somewhere that old version of mojora lib may cause this exceptions.i checked Names i am using in hibernate beans they all looks good but am not able to locate the problem .....
My Html 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: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.org/ui"
xmlns:t="http://myfaces.apache.org/tomahawk">
<h:body>
<ui:composition template="/WEB-INF/templates/layout.xhtml">
<ui:param name="category" value="Admin" />
<ui:param name="item" value="Create User" />
<ui:param name="user" value="#{createUserAccountBean}" />
<ui:define name="content">
<h:form id="productsForm">
<div class="headerbg">
<div id="innerheaderbg">
<div id="iconarea">
<img src="#{request.contextPath}/images/headerimages/productlist.png" />
</div>
<div id="headertextarea">
<p class="headingtext">Order</p>
<p id="breadCrumbtext">Order <img src="#{request.contextPath}/images/error-bullet.gif" />
Product Category List
</p>
</div>
<div id="otherarea"></div>
</div>
</div>
<p:growl />
<div class="widget widget-table action-table">
<div class="widget-header"> <i class="icon-th-list"></i>
<h3>Product List</h3>
<p:spacer width="10px" height="30px"/>
<h:outputLabel value="Product Category" style="color:#0A8FFF;font-weight:bold;margin-bottom:50px;"/>
<p:selectOneMenu value="#{productBean.productCategoryId}" id="pFilter" >
<f:selectItem itemLabel="--All--" itemValue="all" noSelectionOption="false"/>
<f:selectItems value="#{productCategoryBean.categoriesList}" var="category"
itemLabel="#{category.productCategoryName}"
itemValue="#{category.productCategoryId}" />
<p:ajax update=":productsForm:productsTable" event="change" listener="#{productBean.filterProducts}" />
</p:selectOneMenu>
</div> <!-- /widget-header -->
<div class="widget-content">
<p:dataTable id="productsTable" value="#{productBean.products}" var="products" rowIndexVar="rowIndex"
paginator="true" rows="10" paginatorPosition="bottom"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" widgetVar="dt_products">
<p:column headerText="S.No">#{rowIndex+1}</p:column>
<p:column headerText="Product Name">#{products.name}</p:column>
<p:column headerText="Product Code">#{products.code}</p:column>
<p:column headerText="Price">#{products.price}</p:column>
</p:dataTable>
</div> <!-- /widget-content -->
</div>
</h:form>
<br></br>
</ui:define>
</ui:composition>
</h:body>
</html>
and here is my bean, ProductCategoryBean.java:
#Named(value = "productCategoryBean")
#Scope("session")
public class ProductCategoryBean
{
private java.util.List<ProductCategory> categoriesList;
public java.util.List<ProductCategory> getCategoriesList()
{
categoriesList.removeAll(Collections.singleton(null));
return categoriesList;
}
public void setCategoriesList(java.util.List<ProductCategory> categoriesList)
{
this.categoriesList = categoriesList;
}
}
Am Initializing categories list while Login in at LoginBean.java
#Named(value = "loginBean")
#Scope("session")
public class LoginBean {
#Inject
private UserService userService;
#Inject
private StocktrackService stocktrackService;
#Inject
private MenuController menuController;
#Inject
private CheckOut checkOut;
#Inject
private ProductCategoryBean categoryBean;
#Inject
private ProductsBean productsBean;
private String userName;
private String password;
private String statusMessage;
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getStatusMessage() {
return statusMessage;
}
public void setStatusMessage(String statusMessage) {
this.statusMessage = statusMessage;
}
public String login() throws EncryptionException, ServiceException
{
StringEncrypter se = new StringEncrypter("DES");
String encpassword = se.encrypt(getPassword());
UserAccount userAccount = userService.validateLogin(userName,
encpassword);
if (userAccount == null) {
statusMessage = "The username or password is incorrect.";
return "login.xhtml";
}
session.setAttribute("UserAccount", userAccount);
statusMessage = "";
menuController.setTopmenu(menuLoader(userAccount));
checkOut.setUserId(userAccount.getUserId());
checkOut.setUsername(userAccount.getUserName());
checkOut.setUserAccount(userAccount);
//setting category list of ProductCategoryBean
categoryBean.setCategoriesList(stocktrackService.getProductCategory());
//setting product list of ProductListBean
productsBean.setProducts(stocktrackService.getProduct());
return "/pages/leave/home.xhtml?faces-redirect=true";
}
}
Am getting the following Error:
> Feb 09, 2015 1:04:54 PM
> com.sun.faces.application.view.FaceletViewHandlingStrategy
> handleRenderException SEVERE: Error Rendering
> View[/pages/order/products.xhtml] javax.faces.FacesException:
> javax.el.PropertyNotFoundException: /pages/order/products.xhtml #52,59
> itemLabel="#{category.productCategoryName}": Property
> 'productCategoryName' not found on type java.lang.String at
> javax.faces.component.UIComponentBase$AttributesMap.get(UIComponentBase.java:2364)
> at
> org.primefaces.renderkit.InputRenderer.createSelectItem(InputRenderer.java:102)
> at
> org.primefaces.renderkit.InputRenderer.getSelectItems(InputRenderer.java:86)
> at
> org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeMarkup(SelectOneMenuRenderer.java:71)
> at
> org.primefaces.component.selectonemenu.SelectOneMenuRenderer.encodeEnd(SelectOneMenuRenderer.java:65)
> at
> javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
> at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786)
> at javax.faces.render.Renderer.encodeChildren(Renderer.java:168) at
> javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
> at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
> at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
> at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
> at
> com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:419)
> at
> com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
> at
> com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
> at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
The Problem is that you are already using the parameter-name category and that it refers to a String
<ui:param name="category" value="Admin" />
And then you are reusing the parameter-name in f:selectItems,
<f:selectItems value="#{productCategoryBean.categoriesList}" var="category"
itemLabel="#{category.productCategoryName}"
itemValue="#{category.productCategoryId}" />
but as it is already defined as an ui:param you are getting the given Exception. To resolve this, just use another name for the var in f:selectItems:
<f:selectItems value="#{productCategoryBean.categoriesList}" var="productCategory"
itemLabel="#{productCategory.productCategoryName}"
itemValue="#{productCategory.productCategoryId}" />
I have issue to update other rows in the same datatable when one row updated using primeface datatable in-cell edit ajax rowEdit.
But failed to update other row with ajax call. The ajax response only return the same row data which was updated.
The codes are as following:
<h:form id="testForm">
<p:dataTable id="testDT" var="d" rowIndexVar="rowIndex"
value="#{testBean.lists}" editable="true">
<p:column>
<f:facet name="header">No</f:facet>
<h:outputText value="#{rowIndex}" />
</p:column>
<p:column headerText="Value">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{d.value}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{d.value}" size="5" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Edit" style="width:50px">
<p:outputPanel rendered="#{d.editable}">
<p:rowEditor>
</p:rowEditor>
</p:outputPanel>
</p:column>
<p:ajax event="rowEdit" update=":testForm:testDT"
listener="#{testBean.onRowUpdate}" />
</p:dataTable>
</h:form>
My TestBean:
package web.bean.test;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.RowEditEvent;
#ManagedBean(name="testBean")
#ViewScoped
public class TestBean {
private List<TestData> lists = new ArrayList<>();
#PostConstruct
protected void init() {
TestData d = new TestData("Row1Data", 1d, true);
lists.add(d);
d = new TestData("Row1Data", 11.11d, false);
lists.add(d);
}
public void onRowUpdate(RowEditEvent event) {
Object o = event.getObject();
if (o != null) {
TestData d = (TestData)o;
TestData d1 = lists.get(1);
d1.setValue(d1.getValue() + d.getValue());
}
}
public List<TestData> getLists() {
return lists;
}
public void setLists(List<TestData> lists) {
this.lists = lists;
}
}
package web.bean.test;
public class TestData {
private String name;
private double value;
private boolean editable;
public TestData(String name, double value, boolean editable) {
super();
this.name = name;
this.value = value;
this.editable = editable;
}
public TestData() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public boolean isEditable() {
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
}
The ajax response body:
<!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"><head><link type="text/css" rel="stylesheet" href="/Octopus-G/javax.faces.resource/theme.css.xhtml?ln=primefaces-bluesky" /><link type="text/css" rel="stylesheet" href="/Octopus-G/javax.faces.resource/primefaces.css.xhtml?ln=primefaces&v=3.2" /><script type="text/javascript" src="/Octopus-G/javax.faces.resource/jquery/jquery.js.xhtml?ln=primefaces&v=3.2"></script><script type="text/javascript" src="/Octopus-G/javax.faces.resource/primefaces.js.xhtml?ln=primefaces&v=3.2"></script></head><body>
<form id="testForm" name="testForm" method="post" action="/Octopus-G/test.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="testForm" value="testForm" />
<div id="testForm:testDT" class="ui-datatable ui-widget"><table role="grid"><thead><tr role="row"><th id="testForm:testDT:j_idt5" class="ui-state-default" role="columnheader"><div class="ui-dt-c"><span>No</span></div></th><th id="testForm:testDT:j_idt8" class="ui-state-default" role="columnheader"><div class="ui-dt-c"><span>Value</span></div></th><th id="testForm:testDT:j_idt12" class="ui-state-default" role="columnheader" style="width:50px"><div class="ui-dt-c"><span>Edit</span></div></th></tr></thead><tfoot></tfoot><tbody id="testForm:testDT_data" class="ui-datatable-data ui-widget-content"><tr data-ri="0" class="ui-widget-content ui-datatable-even" role="row"><td role="gridcell"><div class="ui-dt-c">0</div></td><td role="gridcell" class="ui-editable-column"><div class="ui-dt-c"><span id="testForm:testDT:0:j_idt9" class="ui-cell-editor"><span class="ui-cell-editor-output">1.0</span><span class="ui-cell-editor-input"><input id="testForm:testDT:0:j_idt11" name="testForm:testDT:0:j_idt11" type="text" value="1.0" size="5" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" /><script id="testForm:testDT:0:j_idt11_s" type="text/javascript">PrimeFaces.cw('InputText','widget_testForm_testDT_0_j_idt11',{id:'testForm:testDT:0:j_idt11'});</script></span></span></div></td><td role="gridcell" style="width:50px"><div class="ui-dt-c"><span id="testForm:testDT:0:j_idt13"><span id="testForm:testDT:0:j_idt14" class="ui-row-editor"><span class="ui-icon ui-icon-pencil"></span><span class="ui-icon ui-icon-check" style="display:none"></span><span class="ui-icon ui-icon-close" style="display:none"></span></span></span></div></td></tr><tr data-ri="1" class="ui-widget-content ui-datatable-odd" role="row"><td role="gridcell"><div class="ui-dt-c">1</div></td><td role="gridcell" class="ui-editable-column"><div class="ui-dt-c"><span id="testForm:testDT:1:j_idt9" class="ui-cell-editor"><span class="ui-cell-editor-output">11.11</span><span class="ui-cell-editor-input"><input id="testForm:testDT:1:j_idt11" name="testForm:testDT:1:j_idt11" type="text" value="11.11" size="5" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" /><script id="testForm:testDT:1:j_idt11_s" type="text/javascript">PrimeFaces.cw('InputText','widget_testForm_testDT_1_j_idt11',{id:'testForm:testDT:1:j_idt11'});</script></span></span></div></td><td role="gridcell" style="width:50px"><div class="ui-dt-c"></div></td></tr></tbody></table></div><script id="testForm:testDT_s" type="text/javascript">$(function() {PrimeFaces.cw('DataTable','widget_testForm_testDT',{id:'testForm:testDT',editable:true,behaviors:{rowEdit:function(event) {PrimeFaces.ab({source:'testForm:testDT',process:'testForm:testDT',update:'testForm:testDT',event:'rowEdit'}, arguments[1]);}}});});</script><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-8223787210091934199:-360328890338571623" autocomplete="off" />
</form></body>
</html>
Place the ajax event dispatcher in side the rowEditor and use the #all reference.
<p:rowEditor>
<p:ajaxStatus update="#all" listener="#{testBean.onRowUpdate}"/>
</p:rowEditor>