Ajax Call get null value in backing bean in jsf - ajax

I have two SelectoneMenu and one inputText. within inputText I called one Ajax event(blur). But this ajax method does not get selected value from SelectoneMenu. But I called the same method using CommandButton it will get selected values and worked fine.
Here is My Code:
<h:form id=HarvestRateForm>
<table width="670px;">
<tr>
<td width="100px;"><p:outputLabel value="Crushing Season" for="crushingSeason"/></td>
<td width="80px;">
<p:selectOneMenu id="crushingSeason" style="width: 110px;" value="#{harvestRateBean.selectedSeason}">
<f:selectItem itemValue="#{null}" itemLabel="Select"/>
<f:selectItems value="#{harvestRateBean.seasons}"/>
</p:selectOneMenu><p:growl for="crushingSeason"/>
</td>
<td width="60px;" align="right"><p:outputLabel value="Plant" for="plant"/></td>
<td width="80px;"><p:selectOneMenu id="plant" style="width: 85px;" value="#{harvestRateBean.selectedPlant}">
<f:selectItem itemValue="#{null}" itemLabel="Select"/>
<f:selectItems value="#{harvestRateBean.plants}"/>
</p:selectOneMenu><p:growl for="plant"/></td>
<td width="60px;" align="right"><p:outputLabel value="Plot No" for="plotNo"/></td>
<td><p:inputText id="plotNo" value="#{harvestRateBean.sapPlotNo}" size="16">
<p:ajax event="blur" listener="#{harvestRateBean.loadPlotDetails}"
update="HarvestRateForm:plotNo HarvestRateForm:ryotCode"/>
</p:inputText>
<p:growl for="plotNo"/>
</td>
</tr>
<tr>
<td><p:outputLabel value="Ryot No" for="ryotCode"/></td>
<td><p:inputText value="#{harvestRateBean.ryotNo}" size="15" id="ryotCode" readonly="true" style="background: transparent;background-color: #cccccc"/></td>
My Bean Class:
public class HarvestRateBean implements Serializable {
private Map<String, String> seasons;
private Map<String, String> plants;
private String selectedPlant;
private String selectedSeason;
private String sapPlotNo;
private String ryotNo;
public HarvestRateBean() {
seasons = new HashMap<String, String>();
plants = new HashMap<String, String>();
}
public Map<String, String> getSeasons() {
List<Season> season_list = loadSeason();
for (Iterator<Season> it = season_list.iterator(); it.hasNext();) {
Season season1 = it.next();
seasons.put(season1.getSeason(), season1.getSeason());
}
return seasons;
}
public void setSeasons(Map<String, String> seasons) {
this.seasons = seasons;
}
public List<Season> loadSeason() {
Session session = HibernateUtil.getSessionFactory().openSession();
List<Season> seasonlist = null;
try {
seasonlist = session.createCriteria(Season.class).list();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
session.close();
HibernateUtil.getSessionFactory().close();
}
return seasonlist;
}
public Map<String, String> getPlants() {
List<Plant> plant_list = loadPlants();
for (Iterator<Plant> it = plant_list.iterator(); it.hasNext();) {
Plant plant = it.next();
plants.put(plant.getId().getPlant(), plant.getId().getPlant());
}
return plants;
}
public void setPlants(Map<String, String> plants) {
this.plants = plants;
}
public List<Plant> loadPlants() {
Session session = HibernateUtil.getSessionFactory().openSession();
List<Plant> plantlist = null;
try {
plantlist = session.createCriteria(Plant.class).list();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
session.close();
}
return plantlist;
}
public String getSelectedPlant() {
return selectedPlant;
}
public void setSelectedPlant(String selectedPlant) {
this.selectedPlant = selectedPlant;
}
public String getSelectedSeason() {
return selectedSeason;
}
public void setSelectedSeason(String selectedSeason) {
this.selectedSeason = selectedSeason;
}
public String getSapPlotNo() {
return sapPlotNo;
}
public void setSapPlotNo(String sapPlotNo) {
this.sapPlotNo = sapPlotNo;
}
public String getRyotNo() {
return ryotNo;
}
public void setRyotNo(String ryotNo) {
this.ryotNo = ryotNo;
}
public void loadPlotDetails {
Session session = HibernateUtil.getSessionFactory().openSession();
List<HarvesterRate> rateList = null;
FacesContext context = FacesContext.getCurrentInstance();
try {
if (getSelectedSeason() == null || getSelectedSeason().isEmpty()) {
context.addMessage(null, new FacesMessage("Season is required", ""));
} else if (getSelectedPlant() == null || getSelectedPlant().isEmpty()) {
context.addMessage(null, new FacesMessage("Plant is required", ""));
} else if (getSapPlotNo() == null || getSapPlotNo().isEmpty()) {
context.addMessage(null, new FacesMessage("Plot No is required", ""));
} else {
rateList = session.createCriteria(HarvesterRate.class).add(Restrictions.eq("id.season", getSelectedSeason())).add(Restrictions.eq("id.plant", getSelectedPlant())).add(Restrictions.eq("id.plotNo", getSapPlotNo())).list();
if (rateList.size() > 0) {
for (Iterator<HarvesterRate> it = rateList.iterator(); it.hasNext();) {
HarvesterRate harvesterRate = it.next();
setSapPlotNo(harvestRate.getPlotNo());
setRyotNo(harvestRate.getVendorCode());
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
getSelectedSeason() and getSelectedPlant() always return null in ajax Call but I Called same method using CommandButton it return Selected value and everything works fine.

The <p:ajax> will by default process only the parent ClientBehavior component, which is in your particular case the <p:inputText>. In other words, the actual value of <p:ajax process> is #this. If you actually want to process the entire form, then you should be using #form as in
<p:inputText ...>
<p:ajax process="#form" ... />
</p:inputText>
The process attribute of <p:commandButton> defaults to #form, that's why it works therewith.
Or, if you have more input components in the form and intend to process only the input and those two dropdowns, then you can specify the (relative) client IDs space separated:
<p:inputText ...>
<p:ajax process="crushingSeason plant #this" ... />
</p:inputText>

Implement ajaxEvent in bean class
Ajax event is not like normal method rather than it invokes the listeners as input, you can configure the Blur action on a text field as following
In JSF page
<p:inputText id="name" value="#{loginBean.name}">
<f:ajax event="blur" listener="#{loginBean.ajaxEvent}" />
</p:inputText>
Ensure that the above must be inside in <h:form>
In ManagedBean class
public void ajaxEvent(AjaxBehaviorEvent e)
{
//Do your stuffs
}
Know more about JSF start from here

Related

Primefaces Nested DataTable with InputText Not Updating Bean

I've a dataTable within a dataTable. The initial dataTable has a list of components that appear on the page. One of these components will be a list of strings which can have elements added or deleted. When I change a string in this list, I expect the value to show up in the bean and it is not.
Below I have an example of my problem. The page renders a text input field for the first component then three text input fields to represent the second component which is a list of three input fields.
I have valueChange listener on all the input fields. The listener, is in the InnerBean class, prints out the source and the value that changed.
For the standalone input field, the listener correctly prints out the changed value and shows that the bean has been updated with this value. For any of the input fields from the list, the listener prints out the previous value of the input field and the bean has not been updated. On the ajax update of the inner datatable, the changed value is replace with the original value.
Since the valueChange listener is called, it appears that Primefaces knows that the value has changed. The code just doesn't seem to record the changed value.
Any help is appreciated.
I'm using Primefaces 8.0 and JSF 2.2.20.
Here is the xhtml:
<p:panel id="testPanel" header="#{myController.outerBean.name}" toggleable="true" collapsed="false" >
<p:dataTable id="testTable" value="#{myController.outerBean.innerBeanList}" var="bean">
<p:column >
<!-- TEXT COMPONENT-->
<h:panelGroup rendered="#{bean.type eq 'text'}" >
<p:inputText id="textfield" value="#{bean.value}" style="width:100%;" >
<p:ajax event="valueChange" listener="#{bean.textListListener}" update="testTable" />
</p:inputText>
</h:panelGroup>
<!-- LIST COMPONENT -->
<h:panelGroup rendered="#{bean.type eq 'textlist'}" >
<p:dataTable id="testListTable" styleClass="datatableWithoutBorder" style="width:320px"
var="textAddition" value="#{bean.list}" rowIndexVar="rowIndex" >
<p:column >
<p:inputText id="textAdd" value="#{textAddition}" style="width: 100%;">
<p:ajax event="valueChange" listener="#{bean.textListListener}" update="testListTable"/>
</p:inputText>
</p:column>
</p:dataTable>
</h:panelGroup>
</p:column>
</p:dataTable>
<h:panelGrid columns="1" style="width:100%;">
<h:panelGroup style="float:right">
<p:commandButton id="submitBtn" value="Submit"
action="#{dummyController.submit}"
update="messages #this"
icon="fa fa-save"/>
</h:panelGroup>
</h:panelGrid>
</p:panel>
My controller code:
public class MyController {
private OuterBean outerBean;
public MyController() {
System.out.println("MyController instantiated");
setOuterBean(new OuterBean());
}
public void submit() {
for (InnerBean ab: outerBean.getInnerBeanList()) {
System.out.println(ab.getLabel() + ": " + ab.getValue() + ":" + ab.getList() );
}
}
public void clear() {
// TODO
}
// Getter/Setter methods
public OuterBean getOuterBean() {
return outerBean;
}
public void setOuterBean(OuterBean outerBean) {
this.outerBean = outerBean;
}
}
My OuterBean with the list of components:
public class OuterBean implements Serializable {
private String name;
private String value;
private List<InnerBean> innerBeanList;
public OuterBean() {
name = "Entry Panel #1";
value = "";
innerBeanList = new ArrayList<InnerBean>();
InnerBean ab1 = new InnerBean();
ab1.setLabel("First Component");
ab1.setType("text");
ab1.setValue("Input text");
innerBeanList.add(ab1);
InnerBean ab2 = new InnerBean();
ab2.setLabel("Second Component");
ab2.setType("textlist");
ArrayList<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
list.add("Item 3");
ab2.setList(list);
innerBeanList.add(ab2);
}
//
// Getter/Setters
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<InnerBean> getInnerBeanList() {
return innerBeanList;
}
public void setInnerBeanList(List<InnerBean> innerBeanList) {
this.innerBeanList = innerBeanList;
}
}
My InnerBean which represents a component to be render. One of which can be a list of strings:
public class InnerBean implements Serializable {
// Type of component
public static final String TEXT = "text";
public static final String TEXTLIST = "textlist";
private String label;
private String type; // If TEXT, use value; if TEXTLIST, use list.
private String value;
private List<String> list = new ArrayList<String>();
public InnerBean() {
}
public void textListListener(AjaxBehaviorEvent event) {
System.out.println("Listener called");
System.out.println(" Source: " + event.getSource().toString());
System.out.println(" Value: " + ((UIInput)event.getSource()).getValue());
System.out.println(" List: " + list.toString());
System.out.println(" Event: " + event.toString());
}
//
// Setters and getters
//
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}

How to display a record in a dataTable after saving in database?

In SQL Server, I have a schema (ade) with some tables, which two of them are:
I'm using Eclipselink ORM and Primefaces 6.2; I have a CRUD for both tables, which works fine.
In a ListDemandas.jsf, I have a datatable where the user can insert a new Demandas registry by clicking in a button. Then, a Dialog (located in the
CreateDemandas.jsf) is displayed to input data in some fields. After clicking on a save button, such Dialog is hidden and the datatable is updated, showing this new Demandas record; the same action occurs to the Anotacoes entity, using a ListAnotacoes.jsf and a CreateAnotacoes.jsf .
What I want is to insert Anotacoes registries through the ListDemandas.jsf page and, right after saving that new Anotacoes registry, it would be displayed in the Demandas datatable (which is in the ListDemandas.jsf page).
What I achieved so far to do it: I put a button in the ListDemandas.jsf to invoke the Dialog (located in CreateAnotacoes.jsf). After clicking on a save button in such Dialog, this (Anotacoes) Dialog is hidden and the data is correctly persisted in the database.
The problem is that this new Anotacoes record is not being displayed in the Demandas datatable, even updating as below:
<p:commandButton actionListener="#{anotacoesController.saveNew}" value="Save" update="display,:DemandasListForm:datalist,:DemandasListForm:DemandasDataTableContextMenu,:growl" oncomplete="handleSubmit(xhr,status,args,PF('AnotacaoCreateDialog'));" >
The ListDemandas.jsf:
<h:form id="DemandasListForm">
<p:panel id="PanelListForm" header="#{adeBundle.ListDemandasTitle}">
<p:commandButton id="createButton" value="Create Demanda" update=":DemandasCreateForm" oncomplete="PF('DemandasCreateDialog').show()" actionListener="#{demandasController.prepareCreate}" />
<p:commandButton id="createAnotacaoButton" value="Create Anotacao" update=":AnotacaoCreateForm, datalist" oncomplete="PF('AnotacaoCreateDialog').show()" />
<p:dataTable id="datalist"
value="#{demandasController.items}"
lazy="false"
rowKey="#{item.id}"
var="item"
selection="#{demandasController.selected}"
widgetVar="demandasTable">
<p:ajax event="rowSelect" update="#form:createAnotacaoButton, #form:createButton" listener="#{demandasController.resetParents}"/>
<p:ajax event="rowUnselect" update="#form:createAnotacaoButton, #form:createButton" listener="#{demandasController.resetParents}"/>
<p:ajax event="contextMenu" update="#form:createAnotacaoButton, #form:createButton" listener="#{demandasController.resetParents}"/>
<p:column id="idCod" >
<f:facet name="header">
<h:outputText value="id"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</p:column>
<!-- some columns ommited -->
<p:rowExpansion>
<p:panelGrid>
<p:column>
<p:row>
<p:accordionPanel value="Mais informacoes da Demanda" multiple="true">
<p:tab title="Anotacoes}" >
<p:dataList value="#{item.anotacoesCollection}" var="anotacoesCollectionItem" itemType="none" emptyMessage="-" >
<h:outputText value="#{anotacoesCollectionItem.anotacao.toString()}" />
</p:dataList>
</p:tab>
</p:accordionPanel>
</p:row>
</p:column>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
</p:panel>
<ui:include src="/WEB-INF/include/confirmation.xhtml"/>
</h:form>
The CreateAnotacao.jsf:
<p:dialog id="AnotacaoCreateDlg" widgetVar="AnotacaoCreateDialog" modal="true" appendTo="#(body)" header="Create Anotacoes" >
<h:form id="AnotacaoCreateForm" >
<h:panelGroup id="display" >
<p:panelGrid columns="2" columnClasses="column">
<p:outputLabel value="CreateAnotacoesLabel_anotacao" for="anotacao" />
<h:panelGroup>
<p:inputTextarea id="anotacao" value="#{anotacoesController.selected.anotacao}" title="CreateAnotacoesTitle_anotacao" />
</h:panelGroup>
<p:outputLabel value="CreateAnotacoesLabel_date" for="date" />
<h:panelGroup>
<p:calendar id="date" value="#{demandasController.currentDate}" title="CreateAnotacoesTitle_date" />
</h:panelGroup>
<!-- some other input fields ommited -->
</p:panelGrid>
</h:panelGroup>
<p:commandButton actionListener="#{anotacoesController.saveNew}" value="Save" update="display, :DemandasListForm:datalist, :growl" oncomplete="handleSubmit(xhr,status,args,PF('AnotacaoCreateDialog'));" >
<p:confirm header="Confirmation" message="Are you sure ?" />
</p:commandButton>
<p:commandButton value="Cancel" oncomplete="PF('AnotacaoCreateDialog').hide()" update="display" process="#this" immediate="true" resetValues="true"/>
</h:form>
</p:dialog>
Excerpts of the AbstractController.java class:
public abstract class AbstractController<T> implements Serializable {
private static final long serialVersionUID = 1L;
private Class<T> itemClass;
private T selected;
private Collection<T> items;
private List<T> filteredItems;
private enum PersistAction {
CREATE,
DELETE,
UPDATE
}
public AbstractController() {
}
public AbstractController(Class<T> itemClass) {
this.itemClass = itemClass;
}
public void setSelected(T selected) {
if (selected != null) {
if (this.selected == null || !this.selected.equals(selected)) {
this.selected = this.ejbFacade.findWithParents(selected);
this.setChildrenEmptyFlags();
}
} else {
this.selected = null;
}
}
protected void setEmbeddableKeys() {
}
protected void initializeEmbeddableKey() {
}
public Collection<T> getItems() {
if (itemClass.getSimpleName().equals("Demandas")) {
if (sessionPrefixo == 9600) {
items = this.ejbFacade.findAll();
} else {
items = this.ejbFacade.findAllVenceHojeByNomeUorPos(uorPosDiageJurisdiciona);
}
}
return items;
}
public void save(ActionEvent event) {
String msg = ResourceBundle.getBundle("/adeBundle").getString(itemClass.getSimpleName() + "Updated");
persist(PersistAction.UPDATE, msg);
if (!isValidationFailed()) {
// Update the existing entity inside the item list
List<T> itemList = refreshItem(this.selected, this.items);
// If the original list has changed (it is a new object)
if (this.items != itemList) {
this.setItems(itemList);
}
// Also refresh the filteredItems list in case the user has filtered the DataTable
if (filteredItems != null) {
refreshItem(this.selected, this.filteredItems);
}
}
}
public void saveNew(ActionEvent event) {
String msg = ResourceBundle.getBundle("/adeBundle").getString(itemClass.getSimpleName() + "Created");
persist(PersistAction.CREATE, msg);
if (!isValidationFailed()) {
items = null; // Invalidate list of items to trigger re-query.
lazyItems = null; // Invalidate list of lazy items to trigger re-query.
}
}
private void persist(PersistAction persistAction, String successMessage) {
if (selected != null) {
this.setEmbeddableKeys();
try {
if (persistAction != PersistAction.DELETE) {
this.ejbFacade.edit(selected);
} else {
this.ejbFacade.remove(selected);
}
this.setChildrenEmptyFlags();
JsfUtil.addSuccessMessage(successMessage);
} catch (EJBException ex) {
Throwable cause = JsfUtil.getRootCause(ex.getCause());
if (cause != null) {
if (cause instanceof ConstraintViolationException) {
ConstraintViolationException excp = (ConstraintViolationException) cause;
for (ConstraintViolation s : excp.getConstraintViolations()) {
JsfUtil.addErrorMessage(s.getMessage());
}
} else {
String msg = cause.getLocalizedMessage();
if (msg.length() > 0) {
JsfUtil.addErrorMessage(msg);
} else {
JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
}
}
}
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/adeBundle").getString("PersistenceErrorOccured"));
}
}
}
public T prepareCreate(ActionEvent event) {
T newItem;
try {
newItem = itemClass.newInstance();
this.selected = newItem;
initializeEmbeddableKey();
return newItem;
} catch (InstantiationException | IllegalAccessException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public boolean isValidationFailed() {
return JsfUtil.isValidationFailed();
}
public String getComponentMessages(String clientComponent, String defaultMessage) {
return JsfUtil.getComponentMessages(clientComponent, defaultMessage);
}
#PostConstruct
public void initParams() {
Object paramItems = FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(itemClass.getSimpleName() + "_items");
if (paramItems != null) {
setItems((Collection<T>) paramItems);
}
}
private List<T> refreshItem(T item, Collection<T> items) {
List<T> itemList;
if (this.items instanceof List) {
itemList = (List<T>) items;
} else {
itemList = new ArrayList<>(items);
}
int i = itemList.indexOf(item);
if (i >= 0) {
try {
itemList.set(i, item);
} catch (UnsupportedOperationException ex) {
return refreshItem(item, new ArrayList<>(items));
}
}
return itemList;
}
public AbstractFacade<T> getEjbFacade() {
return ejbFacade;
}
public void setEjbFacade(AbstractFacade<T> ejbFacade) {
this.ejbFacade = ejbFacade;
}
}
Excerpt of the AbstractFacade.java class:
[...]
public void edit(T entity) {
getEntityManager().merge(entity);
}
[...]
As mentioned in the comments, this is the reference for Demandas table:
Please, can someone help me to resolve it ?

Lazy DataTable rendering is very slow

Environment:
PrimeFaces 5.1
Mojarra 2.2.2
Spring 4.0.2
Problem:
I use a p:dataTable with lazy=true and I have implemented a LazyDataModel.
All works perfectly well (pagination, filtering, etc.), but it is very slow...
The load method is called, it performes the call to the DB and returns in 3sec max. But after that, it takes up to 20sec for the page to load (render?)...
For information, the page loads through ajax: a listener give informations to the LazyModel (setters), then change the page to insert (ui:insert, value stored in the controller), and finally update the form (update=":form").
After debugging it seems that I have no control on this...
Code:
<p:dataTable id="storeTable"
value="#{dashboard.stores}"
var="store"
lazy="true"
paginator="true" rows="30"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
paginatorPosition="bottom">
...
<!-- Columns -->
...
<c:forEach var="date" items="#{dashboard.days}">
<c:set var="day" value="#{store.getDay(date)}"/>
<p:column styleClass="store-day open-#{store.isAmOpen(date.date)} store-day-available-#{store.isAvailable(date.date)} #{store.storeKey} #{day.date.time} am"
width="30">
<h:outputText value=" " title="#{day.amComment}" />
<h:outputText styleClass="store" value="#{store.storeKey}" style="display: none" />
<h:outputText styleClass="date" value="#{day.date.time}" style="display: none" />
<h:outputText styleClass="am_pm" value="am" style="display: none" />
</p:column>
<p:column styleClass="store-day open-#{store.isPmOpen(date.date)} store-day-available-#{store.isAvailable(date.date)} #{store.storeKey} #{day.date.time} pm"
width="30">
<h:outputText value=" " title="#{day.pmComment}" />
<h:outputText styleClass="store" value="#{store.storeKey}" style="display: none" />
<h:outputText styleClass="date" value="#{day.date.time}" style="display: none" />
<h:outputText styleClass="am_pm" value="pm" style="display: none" />
</p:column>
</c:forEach>
</p:dataTable>
Relevant code of the controller:
#Controller("dashboard")
#Scope("session")
public class DashboardController implements Serializable {
private static final long serialVersionUID = 1971543164359627877L;
private LazyStoreWebModel stores;
// Some more attributes
#PostConstruct
public void postCtr() {
stores = new LazyStoreWebModel(restit);
update();
}
private void updateGroupList() {
groupList.clear();
groupList.addAll(groupDao.findByCountry(countryFilter));
}
public void updateStoreChainTypeList() {
storeChainTypeList.clear();
storeChainTypeList.addAll(storeTypeDao.findByCountry(countryFilter));
}
public void updateStoreZoneList() {
storeZoneList.clear();
storeZoneList.addAll(storeZoneDao.findByCountryAndChainType(
countryFilter, chainTypeFilter));
}
public void updateStoreRegionList() {
storeRegionList.clear();
if (storeZoneFilter != null) {
storeRegionList.addAll(storeRegionDao.findByCountryAndZone(
countryFilter, storeZoneFilter));
}
}
public void updateDays() {
days.clear();
days.addAll(calendar.generateListDateFromMonthAndYear(
yearFilter, monthFilter.getCode()));
stores.setYear(yearFilter);
stores.setMonth(monthFilter.getCode());
Collections.sort(days);
}
public void update() {
updateGroupList();
updateStoreChainTypeList();
updateStoreZoneList();
updateStoreRegionList();
updateDays();
stores.setCountry(countryFilter);
stores.setChainType(chainTypeFilter);
stores.setRegion(storeRegionFilter);
stores.setZone(storeZoneFilter);
}
public LazyDataModel<StoreWeb> getStores() {
return stores;
}
}
The LazyDataModel
public class LazyStoreWebModel extends LazyDataModel<StoreWeb> {
private static final long serialVersionUID = -4318420518897167924L;
private RestitService restit;
private Country country;
private StoreChainType chainType;
private StoreZone zone;
private StoreRegion region;
private Integer storeIntFlagFilter;
private Integer year;
private Integer month;
public LazyStoreWebModel(RestitService restit) {
this.restit = restit;
}
#Override
public StoreWeb getRowData(String key) {
try {
return restit.visualisationStoreById(key, year, month);
} catch (CalendarException e) {
e.printStackTrace();
} catch (NotExistStoreException e) {
e.printStackTrace();
}
StoreWeb sto = new StoreWeb();
sto.setStoreDesc("Should be null");
sto.setStoreKey("NULL:" + key);
return sto;
}
#Override
public Object getRowKey(StoreWeb sto) {
return sto.getStoreKey();
}
#Override
public List<StoreWeb> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> fieldFilters) {
List<StoreWeb> result = new ArrayList<StoreWeb>();
Map<String, Object> mainFilters = new HashMap<String, Object>();
mainFilters.put(RestitService.COUNTRY_KEY, country);
mainFilters.put(RestitService.CHAIN_TYPE_KEY, chainType);
mainFilters.put(RestitService.ZONE_KEY, zone);
mainFilters.put(RestitService.REGION_KEY, region);
mainFilters.put(RestitService.INT_FLAG_KEY, storeIntFlagFilter);
mainFilters.put(RestitService.YEAR_KEY, year);
mainFilters.put(RestitService.MONTH_KEY, month);
try {
result.addAll(restit.load(first, pageSize, sortField, sortOrder,
mainFilters, fieldFilters));
} catch (CalendarException e) {
e.printStackTrace();
} catch (NotExistStoreException e) {
e.printStackTrace();
}
setRowCount(restit.count(mainFilters, fieldFilters));
return result;
}
}
The restit attribute do the calls to the DB.
Any idea?
Thanks.
Edits:
Added relevant code of the controller
Added code of the LazyDataModel
Added code inside the HTML: Problem seems to come from the amount of columns (60+), more precisely from the quantity of attribute access done to build those.

JSF: Add AjaxBehaviour to dynamically generated HTMLInputText

I want to create UIComponents with an AjaxBehaviour dynamically and add it to a HTMLPanelGrid. The ajax method will be called but there was no value binding before and no rendering after that. Please help me! Thank you so much! Here is some code:
The Ajax function:
public void ajax(AjaxBehaviorEvent event) {
HtmlPanelGrid grid = (HtmlPanelGrid) event.getComponent().getParent();
HashMap<String, Object> params;
try {
ajaxSet(grid);
params = collect();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
SearchComponent search = (SearchComponent) ComponentRegistry.instance()
.getComponent(IComponentConstants.SEARCH);
this.score = Integer.toString(search.getSystemsCount(params));
}
The function for creating a HTMLInputText:
public HtmlInputText inputText(String id, String expression,
UIComponent parent, AjaxBehaviorListener listener) {
HtmlInputText text = new HtmlInputText();
text.setId(id);
if (!expression.isEmpty()) {
text.setValueExpression("value", createValueExpression(expression));
}
AjaxBehavior ajax = (AjaxBehavior) FacesContext.getCurrentInstance()
.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
ajax.setExecute(Arrays.asList(new String[] { "#form" }));
ajax.setRender(Arrays.asList(new String[] { "#all" }));
ajax.addAjaxBehaviorListener(listener);
text.addClientBehavior("valueChange", ajax);
add(text, parent);
return text;
}
The function for creating the fields depending on a list with the desired field informations and the listener:
public void createSearchFields(UIComponent parent) {
String beanname = Utilities.lookupManagedBeanName(this);
GUIHelper helper = GUIHelper.instance();
for (Searchfield searchfield : shown) {
helper.label(searchfield.id, searchfield.displayname, parent);
for (Field f : searchdto.getClass().getDeclaredFields()) {
GUISearchField gsf = f.getAnnotation(GUISearchField.class);
if (gsf == null)
continue;
if (gsf.id().equals(searchfield.id)) {
String expression = "#{" + beanname + ".searchdto."
+ f.getName() + "}";
helper.inputText(searchfield.id, expression, parent, this);
}
}
}
}
#Override
public void processAjaxBehavior(AjaxBehaviorEvent event)
throws AbortProcessingException {
ajax(event);
}
public abstract void ajax(AjaxBehaviorEvent event);
The xhtml part:
<h:form id="searchform" styleClass="ibm-column-form ibm-styled-form">
<h:panelGrid columns="2" binding="#{systemsearchable.searchfields}">
</h:panelGrid>
<h:commandButton value="Search" action="#{systemsearchable.search}">
<f:ajax execute="#form" render="results"></f:ajax>
</h:commandButton>
</h:form>
If you need more info please let me know :)

values in primefaces edit dialog not getting updated

I have table Providers.I am displaying the table contents in primefaces datatable and performing create,edit and delete operations on it using Jdbc and Tomcat 7.0.
In the edit dialog there are save and cancel buttons. When I click the cancel button and click on the edit button of another row the values of previous row are getting displayed.
I am getting the following warnings when I click on the cancel button:
com.sun.faces.application.view.FaceletPartialStateManagementStrategy saveDynamicActions
WARNING: Unable to save dynamic action with clientId 'editproviderform:btnCancelProviders' because the UIComponent cannot be found
Providers table structure:
ProviderId,
ProviderFirstName and
ProviderLastName
Providers.java
public class Providers implements Serializable {
private static final long serialVersionUID = 1L;
private Integer providerId;
private String providerFirstName;
private String providerLastName;
public Providers() {
}
public Providers(Integer providerId) {
this.providerId = providerId;
}
public Providers(Integer providerId, String providerFirstName, String providerLastName) {
this.providerId = providerId;
this.providerFirstName = providerFirstName;
this.providerLastName = providerLastName;
}
public Integer getProviderId()
{
return providerId;
}
public void setProviderId(Integer providerId)
{
this.providerId=providerId;
}
public String getProviderFirstName()
{
return providerFirstName;
}
public void setProviderFirstName(String providerFirstName)
{
this.providerFirstName=providerFirstName;
}
public String getProviderLastName()
{
return providerLastName;
}
public void setProviderLastName(String providerLastName)
{
this.providerLastName=providerLastName;
}
}
ProvidersBean.java
#ManagedBean(name = "providersBean")
#SessionScoped
public class ProvidersBean implements Serializable {
private Providers selectedProvider;
public Providers getSelectedProvider() {
return selectedProvider;
}
public void setSelectedProvider(Providers selectedProvider) {
this.selectedProvider = selectedProvider;
}
private Connection con;
#Resource(name = "jdbc/abc")
private DataSource ds;
public ProvidersBean() {
try {
Context ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ClinicalStudy");
} catch (NamingException e) {
e.printStackTrace();
}
}
public void updateProvider() {
try {
con = ds.getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE Providers SET
ProviderFirstName=?,ProviderLastName=? WHERE ProviderId=?");
ps.setString(1, selectedProvider.getProviderFirstName());
ps.setString(2, selectedProvider.getProviderLastName());
ps.setInt(3, selectedProvider.getProviderId());
ps.executeUpdate();
clearSelectedProvider();
ps.close();
con.close();
} catch (SQLException e) {
System.out.println("SQLException:" + e.getMessage());
}
}
#PostConstruct
public void init()
{
selectedProvider=new Providers();
}
public void clearSelectedProvider()
{
selectedProvider = null;
}
public void close(CloseEvent event)
{
event.getComponent().getChildren().clear();
clearSelectedProvider();
}
}
Edit dialog code
<p:dialog id="_EditProvider" header="Edit Provider" widgetVar="EditProvider" modal="true"
showEffect="fade" hideEffect="fade" resizable="false" position="center"
appendToBody="true">
<p:ajax event="close" listener="#{providersBean.close}"
update=":editproviderform" global="false"/>
<h:form id="editproviderform">
<p:panelGrid columns="2" rendered="#{not empty providersBean.selectedProvider}">
<h:outputLabel for="EdtProviderFirstName" value="ProviderFirstName*:"/>
<p:inputText id="EdtProviderFirstName" value="#{providersBean.selectedProvider.providerFirstName}"
required="true" requiredMessage="FirstName must be entered" maxlength="30"
validatorMessage="FirstName must be an alphanumeric value">
<f:validateRegex pattern="[a-zA-Z0-9\s]+"/>
</p:inputText>
<h:outputLabel for="EdtProviderLastName" value="ProviderLastName*:"/>
<p:inputText id="EdtProviderLastName" value="#{providersBean.selectedProvider.providerLastName}"
required="true" requiredMessage="LastName must be entered" maxlength="30"
validatorMessage="LastName must be an alphanumeric value">
<f:validateRegex pattern="[a-zA-Z0-9\s]+"/>
</p:inputText>
<p:commandButton id="btnUpdateProvider" value="Save" actionListener="#{providersBean.updateProvider()}"
update=":providersform:providersdt :providersmessages:messages" oncomplete="handleEditProviders(xhr,status,args)"/>
<p:commandButton id="btnCancelProviders" value="Cancel" actionListener="#{providersBean.clearSelectedProvider()}"
oncomplete="EditProvider.hide()"/>
</p:panelGrid>
</h:form>
</p:dialog>
Below is the code for the edit button in datatable:
<p:column style="text-align: center;">
<p:commandButton id="btneditproviders" value="Edit" update=":editproviderform" oncomplete="EditProvider.show()" title="Edit">
<f:setPropertyActionListener value="#{item[0]}" target="#{providersController.selectedProvider}"/>
</p:commandButton>
</p:column>

Resources