How to trigger ajax and update another dropdown when user select dropdown - ajax

I am implementing a dropdown change event and on change event, another dropdown should update the value based on selected dropdown value.
I tried with my actual code and don't work. later I tried Primeface sample dropdown ajax example which also did not work.
Primeface Version: 7.0 (tried 6.1 also)
Java : 1.8
dropdown.xhtml
<h:form>
<p:growl id="msgs" showDetail="true" />
<p:panel header="Select a Location" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px">
<p:ajax listener="#{dropdownView.onCountryChange}" update="city" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:selectOneMenu id="city" value="#{dropdownView.city}" style="width:150px">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.cities}" />
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs" action="#{dropdownView.displayLocation}" icon="pi pi-check" />
</p:panel>
</h:form>```
dropdownView.java
#ManagedBean
#ViewScoped
public class DropdownView implements Serializable {
private Map<String,Map<String,String>> data = new HashMap<String, Map<String,String>>();
private String country;
private String city;
private Map<String,String> countries;
private Map<String,String> cities;
#PostConstruct
public void init() {
countries = new HashMap<String, String>();
countries.put("USA", "USA");
countries.put("Germany", "Germany");
countries.put("Brazil", "Brazil");
Map<String,String> map = new HashMap<String, String>();
map.put("New York", "New York");
map.put("San Francisco", "San Francisco");
map.put("Denver", "Denver");
data.put("USA", map);
map = new HashMap<String, String>();
map.put("Berlin", "Berlin");
map.put("Munich", "Munich");
map.put("Frankfurt", "Frankfurt");
data.put("Germany", map);
map = new HashMap<String, String>();
map.put("Sao Paulo", "Sao Paulo");
map.put("Rio de Janerio", "Rio de Janerio");
map.put("Salvador", "Salvador");
data.put("Brazil", map);
}
public Map<String, Map<String, String>> getData() {
return data;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Map<String, String> getCountries() {
return countries;
}
public Map<String, String> getCities() {
return cities;
}
public void onCountryChange() {
if(country !=null && !country.equals(""))
cities = data.get(country);
else
cities = new HashMap<String, String>();
}
public void displayLocation() {
FacesMessage msg;
if(city != null && country != null)
msg = new FacesMessage("Selected", city + " of " + country);
else
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", "City is not selected.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}```
Expected is on selecting any country, city should load into city dropdown.

Related

Primefaces datatable duplicates data on deletion

im using hibernate 4, spring 4, lucene 3, primefaces 5, java 7.
I got a data table, which data is populated on the baking bean, the idea with the table is that it shows me some uncategorized words, and lets me categorizate them.
an example of the initial table looks normal for example
1 2 3 4 5
here is my page
<html xmlns="http://www.w3.org/1999/xhtml"
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">
<h:head>
</h:head>
<h:form id="form">
<p:growl id="msgs" showDetail="true" life="2000" />
<p:dataTable id="words" var="word"
value="#{wordCatalogatorController.unknownWords}" editable="true"
style="margin-bottom:20px">
<f:facet name="header">Row Editing</f:facet>
<p:ajax event="rowEdit"
listener="#{wordCatalogatorController.onRowEdit}" update=":form:msgs" />
<p:ajax event="rowEditCancel"
listener="#{wordCatalogatorController.onRowCancel}" update=":form:msgs" />
<p:column headerText="Palabra">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{word.word}" />
</f:facet>
<f:facet name="input">
<h:outputText value="#{word.word}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Tipo Palabra">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{word.wordType}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{word.wordType}" style="width:100%"
converter="#{wordTypeConverter}">
<f:selectItems value="#{wordCatalogatorController.wordTypes}"
var="man" itemLabel="#{man.wordType}" itemValue="#{man}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
</html>
the bean for this is:
#Controller
#Transactional
public class WordCatalogatorController {
private List<Word> unknownWords = new ArrayList<Word>();
private List<WordType> wordTypes = new ArrayList<WordType>();
public WordCatalogatorController(){
//inicializamos palabras desconocidas y tipos de palabras!
for(int i = 0 ; i < 6 ; i++){
unknownWords.add(new Word("" + i));
}
for(int i = 0 ; i < 4 ; i++){
wordTypes.add(new WordType("" + i));
}
}
public void onRowEdit(RowEditEvent event) {
Word currentWord = (Word) event.getObject();
unknownWords.remove(currentWord);
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edit Cancelled",
((Word) event.getObject()).getWord());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if (newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
then after editing and saving the first row (1) the datatables updates with 1 2 2 3 4 5
Any ideas will be really apreciated!
here comes the code for pojo clases
#Entity
#Table(name="Word")
#Indexed
#AnalyzerDef(name = "searchtokenanalyzer",tokenizer = #TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
#TokenFilterDef(factory = StandardFilterFactory.class),
#TokenFilterDef(factory = LowerCaseFilterFactory.class),
#TokenFilterDef(factory = StopFilterFactory.class,params = {
#Parameter(name = "ignoreCase", value = "true") }) })
#Analyzer(definition = "searchtokenanalyzer")
public class Word {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long wordId;
#Column(name="word")
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#Analyzer(definition="searchtokenanalyzer")
private String word;
#ManyToMany(mappedBy="words")
private Collection<Danger> dangers = new ArrayList<Danger>();
#ManyToMany(mappedBy="words")
private Collection<Risk> risks = new ArrayList<Risk>();
#ManyToMany(mappedBy="words")
private Collection<Control> controls = new ArrayList<Control>();
#ManyToOne
#JoinColumn(name = "wordTypeId")
private WordType wordType;
public Word(String word, WordType wordType) {
super();
this.word = word;
this.wordType = wordType;
}
public Word(String word) {
super();
this.word = word;
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Word){
return ((Word)obj).getWord().equalsIgnoreCase(this.getWord());
}else{
return false;
}
}
public Word() {
super();
}
public long getWordId() {
return wordId;
}
public void setWordId(long wordId) {
this.wordId = wordId;
}
#Entity
#Table(name = "WordType")
#Indexed
public class WordType {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long wordTypeId;
#Column(name = "wordType")
#Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
#Analyzer(definition = "searchtokenanalyzer")
private String wordType;
#Column(name = "description")
private String description;
#OneToMany(mappedBy = "wordType")
private Set<Word> words;
#Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if (!(obj instanceof WordType)) {
return false;
} else {
WordType extenalWT = (WordType) obj;
if (this.wordType.equalsIgnoreCase(extenalWT.getWordType())
&& this.wordTypeId == extenalWT.getWordTypeId()) {
return true;
} else {
return false;
}
}
}
public WordType() {
}
public WordType(String wordType) {
this.wordType = wordType;
}
public long getWordTypeId() {
return wordTypeId;
}
public void setWordTypeId(long wordTypeId) {
this.wordTypeId = wordTypeId;
}
public String getWordType() {
return wordType;
}
public void setWordType(String wordType) {
this.wordType = wordType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Word> getWords() {
return words;
}
public void setWords(Set<Word> words) {
this.words = words;
}
#Override
public String toString() {
return wordType;
}
}
For anyone else having this issue:
It seems to be an issue between the rowEditor and the table sorting. Having the correct update target on the ajax tag isn't an issue as the row is technically removed but the display gets messed up. You can get around this with just a touch of nastiness. You can force a filter during oncomplete for the ajax tag. This will get rid of the ghost duplicate record.
<p:ajax event="rowEdit"
listener="#{beanName.onRowEdit}"
update=":growl :messages :formName:tableId"
oncomplete="PF('tableWidgetVar').filter();" />
Finally the best solution was to implement the select event for the data table, and in the event have a dialog to pick the option, then refresh the table, this is the final xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
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">
<h:head>
</h:head>
<h:body>
<h:form id="myForm">
<p:growl id="msgs" showDetail="true" life="2000" />
<p:panel header="Sale Item" style="width: 400px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel value="Texto" for="acSimple" />
<p:autoComplete id="acSimple"
value="#{wordCatalogatorController.texto}"
completeMethod="#{wordCatalogatorController.completeText}"
binding="#{wordCatalogatorController.autoCompleteText}" />
<p:commandButton value="Guardar actividad" id="save"
update=":myForm:msgs words"
binding="#{wordCatalogatorController.saveButton}"
actionListener="#{wordCatalogatorController.saveActivity}"
styleClass="ui-priority-primary" process="#this" />
</h:panelGrid>
<p:dataTable id="words" widgetVar="words" var="word"
value="#{wordCatalogatorController.unknownWords}" editable="true"
style="margin-bottom:20px" rowKey="#{word.word}"
selection="#{wordCatalogatorController.selectedWord}"
selectionMode="single" editMode="row">
<p:ajax event="rowSelect"
listener="#{wordCatalogatorController.changeClient}"
oncomplete="PF('activityDialog').show()"
update=":myForm:activityDialog" />
<f:facet name="header">Edicion de palabras</f:facet>
<p:column headerText="Palabra">
<h:outputText value="#{word.word}" />
</p:column>
<p:column headerText="Edicion">
<h:outputText value="Presione para catalogar la palabra" />
</p:column>
</p:dataTable>
</p:panel>
<p:dialog id="activityDialog" width="500px" height="600px"
header="Palabra a catalogar: #{wordCatalogatorController.selectedWord.word}"
widgetVar="activityDialog" modal="true" closable="false">
<h:panelGrid columns="2" cellpadding="5">
<p:selectOneMenu id="wordTypes"
value="#{wordCatalogatorController.selectedWordType}"
style="width: 150px;" converter="#{wordTypeConverter}">
<p:ajax
listener="#{wordCatalogatorController.wordTypeChangeListener}"
update=":myForm:words" />
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{wordCatalogatorController.wordTypes}" />
</p:selectOneMenu>
</h:panelGrid>
</p:dialog>
</h:form>
</h:body>
</html>

update dataTable depending on the value chosen in selectOneMenu

I'm using a selectOneMenu and i want to update datatable depending on what i choose on the combobox, i have two tables on the database:
Fournisseur
idFournisseur
raisonSociale
telephone..
and
Devis
idDevis
idFournisseur
devis.xhtml
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<p:outputLabel for="console" value="Basic:" />
<p:selectOneMenu id="console" value="#{fournisseurBean.raisonSociale}">
<f:selectItems value="#{fournisseurBean.listeFournisseurs}" var="fournisseur" itemValue="#{fournisseur}" itemLabel="#{fournisseur.raisonSociale}" />
<p:ajax event="change" update="display" listener="#{fournisseurBean.getFournisseurByRaison()}" />
</p:selectOneMenu>
<p:dataTable id="display" var="listeDevis" value="#{devisBean.listeDevis}" editable="true" style="margin-bottom:10px">
<f:facet name="header">
Liste des devis
</f:facet>
<p:ajax event="rowEdit" listener="#{dtEditView.onRowEdit}" update=":form:msgs" />
<p:ajax event="rowEditCancel" listener="#{dtEditView.onRowCancel}" update=":form:msgs" />
<p:column headerText="Id devis">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{listeDevis.idDevis}" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput" value="#{listeDevis.idDevis}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Date devis">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{listeDevis.dateDevis}" /></f:facet>
<f:facet name="input"><p:inputText value="#{listeDevis.dateDevis}" style="width:100%" label="Year"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px" headerText="Modification">
<p:rowEditor />
</p:column>
</p:dataTable>
</h:form>
FournisseurBean.xhtml
package controller;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.event.ValueChangeEvent;
import model.services.FournisseurMetier;
import net.vo.Fournisseur;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component
#Scope("view")
public class FournisseurBean {
#Autowired
private FournisseurMetier fournisseurMetier;
private List<Fournisseur> listeFournisseurs;
private List<String> listeRaisons;
private int idFournisseur;
private String raisonSociale;
private String rib;
private String adresse;
private Long telephone;
#PostConstruct
public void init() {
listeFournisseurs = fournisseurMetier.getAllFournisseurs();
listeRaisons = fournisseurMetier.getAllRaisonsSociales();
}
public List<Fournisseur> getListeFournisseurs() {
return listeFournisseurs;
}
public void insert()
{
Fournisseur fournisseur = new Fournisseur();
fournisseur.setIdFournisseur(getIdFournisseur());
fournisseur.setRaisonSociale(getRaisonSociale());
fournisseur.setRib(getRib());
fournisseur.setAdresse(getAdresse());
fournisseur.setTelephone(getTelephone());
fournisseurMetier.insert(fournisseur);
}
public void update()
{
Fournisseur fournisseuur = fournisseurMetier.getFournisseur(this.idFournisseur);
fournisseuur.setRaisonSociale(getRaisonSociale());
fournisseuur.setRib(getRib());
fournisseuur.setAdresse(getAdresse());
fournisseuur.setTelephone(getTelephone());
fournisseurMetier.update(fournisseuur);
}
public FournisseurMetier getFournisseurMetier() {
return fournisseurMetier;
}
public void setFournisseurMetier(FournisseurMetier fournisseurMetier) {
this.fournisseurMetier = fournisseurMetier;
}
public void setListeFournisseurs(List<Fournisseur> listeFournisseurs) {
this.listeFournisseurs = listeFournisseurs;
}
public int getIdFournisseur() {
return idFournisseur;
}
public void setIdFournisseur(int idFournisseur) {
this.idFournisseur = idFournisseur;
}
public String getRaisonSociale() {
return raisonSociale;
}
public void setRaisonSociale(String raisonSociale) {
this.raisonSociale = raisonSociale;
}
public String getRib() {
return rib;
}
public void setRib(String rib) {
this.rib = rib;
}
public Long getTelephone() {
return telephone;
}
public void setTelephone(Long telephone) {
this.telephone = telephone;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
#Override
public String toString() {
return "FournisseurBean{" + "raisonSociale=" + raisonSociale + '}';
}
public void getFournisseurByRaison()
{
System.out.println(raisonSociale);
}
}
This method getFournisseurByRaison() shows me a reference to object Fournisseur not the attribute raisonSociale.
You can sue p:ajax as you mentioned in comments.
OR
Since you are using Primefaces you can also Update any component from ManagedBean itself using org.primefaces.context.RequestContext object.
For example:
Facelet:
<h:form id="form1">
<p:dataTable id="myTab">
...
</p:dataTable>
</h:form>
ManagedBean:
RequestContext reqCtx = Requestcontext.getCurrentInstance();
req.Ctx.update("form1:myTab");
this method getFournisseurByRaison() shows me a reference to object Fournisseur not the attribure raisonSociale
This is because you're setting the object as the value:
<!-- itemValue="#{fournisseur}" <= here is the object set as value -->
<f:selectItems value="#{fournisseurBean.listeFournisseurs}"
var="fournisseur"
itemValue="#{fournisseur}"
itemLabel="#{fournisseur.raisonSociale}" />
You should use an identifier or another field to be able to seek the selected fournisseur from the values of the list. This may be a starting approach:
<!-- itemValue="#{fournisseur.id}" <= or another unique identifier field -->
<f:selectItems value="#{fournisseurBean.listeFournisseurs}"
var="fournisseur"
itemValue="#{fournisseur.id}"
itemLabel="#{fournisseur.raisonSociale}" />
Then, in your bean:
public void getFournisseurByRaison() {
System.out.println(raisonSociale); //will print the user selected id or unique identifier
//access to devisBean and update the data in `devisBean.listeDevis` in there
}

Ajax update breaks Primefaces datatable functionality

In my application I have a PF layout with a Tree node on west part, and a content part on center where I want to load different pages dynamically with ajax technology.
To get it, this content part contains an ui:include tag with EL expression. When the user clicks a tree node button, a page is rendered correctly on the center (and that works pretty well!). But some functionality of datatable such as sorting is broken or lost.
Moreover, if a refresh completely the page from the web browser all works OK.
I have simplified my project in order to give you a clean example.
The index.xhtml:
<p:layout fullPage="true">
<p:layoutUnit position="north" size="100" header="Top">
</p:layoutUnit>
<p:layoutUnit position="west" size="100" resizable="true">
<h:form>
<p:tree id="menuTree"
value="#{menuController.root}"
var="node"
selection="#{menuController.selectedNode}"
selectionMode="single">
<p:ajax event="select" update=":content" listener="#{menuController.setPage(node)}" />
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="east" size="50"/>
<p:layoutUnit position="south" size="60"/>
<p:layoutUnit position="center" id="centerlayout">
<h:panelGroup id="content">
<c:if test="${not empty menuController.page}">
<ui:include src="#{menuController.page}.xhtml" />
</c:if>
</h:panelGroup>
</p:layoutUnit>
</p:layout>
</h:body>
I would like to remark that I've tried to change the ui:include with EL and use the conditional render of a container h:panelGroup and an static ui:include, but the problem persist.
The backing bean of Tree menu:
#Named
#SessionScoped
public class MenuController implements Serializable {
private TreeNode root;
private TreeNode selectedNode;
private String pageName;
public MenuController() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node00 = new DefaultTreeNode("/list", node0);
TreeNode node01 = new DefaultTreeNode("/list2", node0);
}
public TreeNode getRoot() {
return root;
}
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public void setPage(String page){
this.pageName = page;
}
public String getPage(){
return this.pageName;
}
The page that contains data table list.xhtml (note that list2.xhtml is equal, changing some text to 'watch' the content update):
<ui:composition>
<h:form id="ItemListForm">
<p:panel header="Title">
<p:dataTable id="datalist" value="#{itemController.items}" var="item"
selectionMode="single" selection="#{itemController.selected}"
rowKey="#{item.itemid}"
paginator="true"
rows="10"
rowsPerPageTemplate="10,20,30" >
<p:column sortBy="#{item.itemid}" filterBy="#{item.itemid}">
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText value="#{item.itemid}"/>
</p:column>
<p:column sortBy="#{item.productid}" filterBy="#{item.productid}">
<f:facet name="header">
<h:outputText value="ProductId"/>
</f:facet>
<h:outputText value="#{item.productid}"/>
</p:column>
<p:column sortBy="#{item.name}" filterBy="#{item.name}">
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column sortBy="#{item.description}" filterBy="#{item.description}">
<f:facet name="header">
<h:outputText value="Description"/>
</f:facet>
<h:outputText value="#{item.description}"/>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
The ItemController bean:
#Named
#SessionScoped
public class ItemController implements Serializable {
private Item selected;
private List<Item> items;
public ItemController() {
this.items = new ArrayList<>();
this.items.add(new Item("1", "1", "Product 1", "testing sorting"));
this.items.add(new Item("3", "3", "Product 3", "testing sorting"));
this.items.add(new Item("2", "2", "Product 2", "testing sorting"));
this.items.add(new Item("4", "4", "Product 4", "testing sorting"));
this.items.add(new Item("5", "5", "Product 5", "testing sorting"));
this.items.add(new Item("6", "6", "Product 6", "testing sorting"));
}
public Item getSelected() {
return selected;
}
public void setSelected(Item selected) {
this.selected = selected;
}
public List<Item> getItems() {
return items;
}
The class Item, very simple:
public class Item implements Serializable {
private String itemid;
private String productid;
private String name;
private String description;
public Item() {
}
public Item(String itemid) {
this.itemid = itemid;
}
public Item(String itemid, String productid, String name, String description) {
this.itemid = itemid;
this.productid = productid;
this.name = name;
this.description = description;
}
public String getItemid() {
return itemid;
}
public void setItemid(String itemid) {
this.itemid = itemid;
}
public String getProductid() {
return productid;
}
public void setProductid(String productid) {
this.productid = productid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
Finally, I'm working with:
Java EE 7
PrimeFaces 3.5 Community
JSF 2.2
Glassfish 4
NetBeans 7.3.1
Safari browser
the problem is taht Primefaces 3.5 doesnt go well with glassfish 4 switch to primefaces 4.0-SNAPSHOT and I guess it might work
I'm sorry, I speak english not well, but this happens because PF include to the page only javascript that needed for succesfully rendering of components that are present on the page. If you include component to the page dinamically by using for example ui:include, page will not contain js for rendering of this component

JSF ajax validation don't validate items with required true

I have a datatable, a column with h:commandlink for edit (ajax request), the detail show in jquery dialog, everything ok, in the edit form i have h:commandlink (ajax request) for save, if i make changes eg, drop a value in input required, and push submit, jsf don't validate this input, and don't show the message "this input is required"
<div id="container">
<button id="create-user" >Create new user</button>
<h:dataTable value="#{gasweb.lsProveedor}" var="tabpro" id="example" class="display dataTable" >
<h:column>
<f:facet name="id">
<h:outputLabel value="Id"/>
</f:facet>
<h:outputText value="#{tabpro.proveedor_id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel value="Cedula"/>
</f:facet>
<h:outputText value="#{tabpro.cedula_ruc}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel value="NombreComercial"/>
</f:facet>
<h:commandLink value="#{tabpro.nombre_comercial}" actionListener="#{gasweb.doEditProveedor2}" class="labrir" >
<f:param name="pproveedor_id" value="#{tabpro.proveedor_id}" />
<f:ajax execute="#this" render=":forma:editgrid" >
</f:ajax>
</h:commandLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputLabel value="Razon Social"/>
</f:facet>
<h:outputText value="#{tabpro.razon_social}"/>
</h:column>
</h:dataTable>
</div>
<div id="divformap" title="Proveedor">
<h:inputHidden value="#{gasweb.newRecord}" id="txtnewrecord" />
<h:inputHidden value="#{gasweb.ruc_proveedor_ori}" id="txtcedulaori" />
<h:panelGrid columns="2" id="editgrid" >
<h:outputLabel value="Id :" />
<h:outputText id="txtid" value="#{gasweb.proveedor.proveedor_id}" />
<h:outputLabel value="Ruc :" />
<h:inputText id="txtcedula" value="#{gasweb.proveedor.cedula_ruc}" size="20" class="text ui-widget-content ui-corner-all" />
<h:outputLabel value="Nombr Comercial :" />
<h:inputText id="txtnombre" value="#{gasweb.proveedor.nombre_comercial}" required="true" size="80" class="text ui-widget-content ui-corner-all"/>
<h:outputLabel value="Razón Social :" />
<h:inputText id="txtrazon" value="#{gasweb.proveedor.razon_social}" size="80" class="text ui-widget-content ui-corner-all"/>
<h:outputLabel value="Dirección :" />
<h:inputText id="txtdireccion" value="#{gasweb.proveedor.direccion}" size="80" class="text ui-widget-content ui-corner-all"/>
<h:outputLabel value="Telefono :" />
<h:inputText id="txttelefono" value="#{gasweb.proveedor.telefono}" size="20" class="text ui-widget-content ui-corner-all"/>
<h:outputLabel value="Estado :" />
<h:outputText id="txtestado" value="#{gasweb.proveedor.estado}" />
<h:commandButton id="aceptar" value="Aceptar" actionListener="#{gasweb.doGrabaProveedor}" >
<f:param name="pproveedor_id2" value="#{gasweb.proveedor.proveedor_id}" />
<f:ajax render="bProveedor" execute="#form" onevent="resetFocus" />
</h:commandButton>
<h:outputText id="bProveedor" value="#{gasweb.bProveedorExiste}" />
</h:panelGrid>
</div>
My managed bean
public class GasperWebMB implements Serializable{
private List<Contribuyente> lsContribuyente;
private List<Proveedor> lsProveedor;
private Contribuyente contribuyente;
private Proveedor proveedor;
private Declara serdec;
private FacesContext fc = FacesContext.getCurrentInstance();
private Boolean newRecord;
private String ruc_proveedor_ori;
private String bProveedorExiste;
//#ManagedProperty("#param.pproveedor_id")
//private Integer pproveedor_id;
//private HttpServletRequest request;
public GasperWebMB(){
serdec = new Declara();
contribuyente = new Contribuyente();
proveedor = new Proveedor();
lsContribuyente = serdec.getAllContribuyente();
lsProveedor = serdec.getAllProveedor();
newRecord = true;
log("creado");
//request.getHeader(ruc_proveedor_ori);
}
public String getbProveedorExiste() {
return bProveedorExiste;
}
public void setbProveedorExiste(String bProveedorExiste) {
this.bProveedorExiste = bProveedorExiste;
}
public String getRuc_proveedor_ori() {
log(ruc_proveedor_ori);
return ruc_proveedor_ori;
}
public void setRuc_proveedor_ori(String ruc_proveedor_ori) {
log(ruc_proveedor_ori);
this.ruc_proveedor_ori = ruc_proveedor_ori;
}
public Boolean getNewRecord() {
log(newRecord);
return newRecord;
}
public void setNewRecord(Boolean newRecord) {
log(newRecord);
this.newRecord = newRecord;
}
public List<Proveedor> getLsProveedor() {
log(lsProveedor);
return lsProveedor;
}
public void setLsProveedor(List<Proveedor> lsProveedor) {
log(lsProveedor);
this.lsProveedor = lsProveedor;
}
public Proveedor getProveedor() {
log(proveedor);
return proveedor;
}
public void setProveedor(Proveedor proveedor) {
log(proveedor);
this.proveedor = proveedor;
}
public List<Contribuyente> getLsContribuyente() {
return lsContribuyente;
}
public void setLsContribuyente(List<Contribuyente> lsContribuyente) {
this.lsContribuyente = lsContribuyente;
}
public Contribuyente getContribuyente() {
return contribuyente;
}
public void setContribuyente(Contribuyente contribuyente) {
this.contribuyente = contribuyente;
}
public String doEditContribuyente(){
Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
contribuyente = serdec.getContribuyenteById(Integer.parseInt(par));
newRecord = false;
ruc_proveedor_ori = proveedor.getCedula_ruc();
return "FContribuyente";
}
public String doGrabaContribuyente(){
System.out.println("grabar " + contribuyente.getCedula_ruc()+ " id " + contribuyente.getContribuyente_id());
serdec.updContribuyente(contribuyente);
return "lisContribuyente";
}
public String doEditProveedor(){
System.out.println("Entra");
Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
String par = params.get("pproveedor_id");
System.out.println("pro" + par);
proveedor = serdec.getProveedorById(Integer.parseInt(par));
newRecord = false;
System.out.println("va a salir");
return "editprov";
}
public void doGrabaProveedor(ActionEvent event){
System.out.println("gra"+proveedor.getNombre_comercial()+" new "+ newRecord);
Proveedor xpro = serdec.getProveedorByRuc(proveedor.getCedula_ruc());
if (xpro != null && !proveedor.getCedula_ruc().equals(ruc_proveedor_ori)){
System.out.println("Ya existe");
bProveedorExiste = xpro.getNombre_comercial();
//FacesContext.getCurrentInstance().validationFailed();
FacesMessage fmes = new FacesMessage("El Ruc "+proveedor.getCedula_ruc()+" ya se encuentra registrado para otro proveedor");
fc.addMessage(null, fmes);
//fc.addMessage("Proveedor ya existe", fmes);
//return "sucess";
return;
}
if (newRecord){
proveedor.setEstado("A");
//serdec.insProveedor(proveedor);
}
else {
//serdec.updProveedor(proveedor);
}
System.out.println("Si graba");
//return "sucess";
}
public void doEditProveedor2(ActionEvent event){
/*Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
String par = params.get("pproveedor_id");
proveedor = serdec.getProveedorById(Integer.parseInt(par));
newRecord = false;
return "FProveedor";*/
String pproveedor_id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("pproveedor_id");
proveedor = serdec.getProveedorById(Integer.parseInt(pproveedor_id));
newRecord = false;
System.out.println("si edit2 param "+ pproveedor_id + " new "+ newRecord);
System.out.println("si edit2 proveedor "+ proveedor.getNombre_comercial() + " new "+ newRecord);
}
private void log(Object object) {
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
System.out.println("Bean " + methodName + ": " + object);
}
}
In this code, dropped the jquery dialog and show detail in div
you must either put <h:messages /> or <h:message /> at html page.
h:messages – Output all messages in current page.
h:message – Output a single message for a specific component.
1- in your case, try put <h:messages /> at the top page or inside the edit form.
2- or u can to put <h:message /> for each required input such as
<h:message for="txtnombre" style="color:red" /> after/before the input.

Problems sorting a richfaces datatable

I'm trying to get my richfaces datatable to have sortable headers. I've basically followed the code here: http://richfaces-showcase.appspot.com/richfaces/component-sample.jsf?demo=dataTable&sample=tableSorting&skin=blueSky
My headers have links, and when I click them, you can see in the firebug console that a post request is happening. After it's done processing, nothing happens to the table.
Also, I have some jquery code that highlights a row when your mouse is hovered over it. Once you click one of the headers, the row highlighting doesn't happen anymore.
Here is my code.
<h:form>
<rich:dataTable value="#{protocolDetail.details.protocolEvents}" var="detail" id="table" rows="20" rowClasses="odd, even" styleClass="stable">
<rich:column sortBy="#{detail.date}">
<f:facet name="header">
<a4j:commandLink value="Date" render="table" action="#{protocolDetail.sortByDate}" />
</f:facet>
<f:facet name="footer">
<a4j:commandLink value="Date" render="table" action="#{protocolDetail.sortByDate}" />
</f:facet>
<h:outputText value="#{detail.date}" />
</rich:column>
<rich:column sortBy="#{detail.description}">
<f:facet name="header">
<a4j:commandLink value="Description" render="table" action="#{protocolDetail.sortByDescription}" />
</f:facet>
<f:facet name="footer">
<a4j:commandLink value="Description" render="table" action="#{protocolDetail.sortByDescription}" />
</f:facet>
<h:outputText value="#{detail.description}" />
</rich:column>
<rich:column sortBy="#{detail.comment}">
<f:facet name="header">
<a4j:commandLink value="Comment" render="table" action="#{protocolDetail.sortByComments}" />
</f:facet>
<f:facet name="footer">
<a4j:commandLink value="Comment" render="table" action="#{protocolDetail.sortByComments}" />
</f:facet>
<h:outputText value="#{detail.comment}" />
</rich:column>
</rich:dataTable>
</h:form>
<rich:jQuery selector=".stable tr" event="mouseover" query="jQuery(this).addClass('active')" />
<rich:jQuery selector=".stable tr" event="mouseout" query="jQuery(this).removeClass('active')" />
bean:
#ManagedBean(name = "protocolDetail")
#SessionScoped
public class ProtocolDetailBacker extends BaseObject {
private String protocol = "";
private int studyNumber;
// private ArrayList<ProtocolDetailBean> details;
private ProtocolDetailBean details = new ProtocolDetailBean();
ProtocolDAO dao = new ProtocolDAO();
private SortOrder dateOrder = SortOrder.UNSORTED;
private SortOrder descriptionOrder = SortOrder.UNSORTED;
private SortOrder commentsOrder = SortOrder.UNSORTED;
public ProtocolDetailBacker() {
FacesContext context = FacesContext.getCurrentInstance();
String[] values = context.getExternalContext().getRequestParameterValuesMap().get("protocol");
setProtocol(values[0]);
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public ProtocolDetailBean getDetails() {
try {
studyNumber = dao.getStudyNumber(getProtocol());
details.setProtocolNumber(getProtocol());
details.setStudyChair(dao.getStudyChair(studyNumber));
details.setShortDesc(dao.getShortDescription(studyNumber));
details.setLongDesc(dao.getLongDescription(studyNumber));
details.setPdc(dao.getPDC(studyNumber));
details.setProtocolEvents(dao.getProtocolEventDetails(getProtocol()));
System.out.println("");
} catch (SQLException e) {
e.printStackTrace();
}
return details;
}
public void setDetails(ProtocolDetailBean details) {
this.details = details;
}
public int getStudyNumber() {
return studyNumber;
}
public void setStudyNumber(int studyNumber) {
this.studyNumber = studyNumber;
}
public SortOrder getDateOrder() {
return dateOrder;
}
public void setDateOrder(SortOrder dateOrder) {
this.dateOrder = dateOrder;
}
public SortOrder getDescriptionOrder() {
return descriptionOrder;
}
public void setDescriptionOrder(SortOrder descriptionOrder) {
this.descriptionOrder = descriptionOrder;
}
public SortOrder getCommentsOrder() {
return commentsOrder;
}
public void setCommentsOrder(SortOrder commentsOrder) {
this.commentsOrder = commentsOrder;
}
public void sortByDate() {
descriptionOrder = SortOrder.UNSORTED;
commentsOrder = SortOrder.UNSORTED;
System.out.println("dateOrder = "+dateOrder);
if(dateOrder.equals(SortOrder.ASCENDING)) {
setDateOrder(SortOrder.DESCENDING);
System.out.println("dateOrder now = "+dateOrder);
} else if(dateOrder.equals(SortOrder.DESCENDING)) {
setDateOrder(SortOrder.ASCENDING);
System.out.println("dateOrder now = "+dateOrder);
} else {
setDateOrder(SortOrder.ASCENDING);
System.out.println("else dateOrder now = "+dateOrder);
}
}
public void sortByDescription() {
dateOrder = SortOrder.UNSORTED;
commentsOrder = SortOrder.UNSORTED;
System.out.println("dateOrder = "+dateOrder);
if(descriptionOrder.equals(SortOrder.ASCENDING)) {
setDescriptionOrder(SortOrder.DESCENDING);
System.out.println("dateOrder now = "+dateOrder);
} else if(descriptionOrder.equals(SortOrder.DESCENDING)) {
setDescriptionOrder(SortOrder.ASCENDING);
System.out.println("dateOrder now = "+dateOrder);
} else {
setDescriptionOrder(SortOrder.ASCENDING);
System.out.println("else dateOrder now = "+dateOrder);
}
}
public void sortByComments() {
descriptionOrder = SortOrder.UNSORTED;
commentsOrder = SortOrder.UNSORTED;
System.out.println("dateOrder = "+dateOrder);
if(commentsOrder.equals(SortOrder.ASCENDING)) {
setCommentsOrder(SortOrder.DESCENDING);
System.out.println("dateOrder now = "+dateOrder);
} else if(commentsOrder.equals(SortOrder.DESCENDING)) {
setCommentsOrder(SortOrder.ASCENDING);
System.out.println("dateOrder now = "+dateOrder);
} else {
setCommentsOrder(SortOrder.ASCENDING);
System.out.println("else dateOrder now = "+dateOrder);
}
}
}
Sorting your table recreates the rows. Therefor the onmouseover and onmouseout events are no more bound to your rows after sorting.
Luckily jQuery can handle this by creating a live handler. Live-Handlers will also trigger to rows, that are added after the execution of the jQuery-call.
The following works for me:
<rich:jQuery selector=".stable tr" query="live('mouseover mouseout', function(event) {
if ( event.type == 'mouseover' ) {
jQuery(this).addClass('active-row');
} else {
jQuery(this).removeClass('active-row');
}});"/>
I too had the same problem was working with the sample code given in richfaces demo , still same issue
I added f:ajax to the a:commandlink now the sort is getting properly updated
<a4j:commandLink execute="#this" value="Vendor"
render="carstable" action="#{carsSortingBean.sort}">
<f:param name="sortProperty" value="vendor" />
<f:ajax render="carstable" />
</a4j:commandLink>
In case anyone is still looking for this answer, If you're using RichFaces 4.0 and JSF 2, try setting JSF's partial state saving to true in your web.xml as seen below:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>true</param-value>
</context-param>

Resources