Consultation List cast an object in Primefaces? - jsf

I have a datatable with primefaces, loaded about three records, it happens that I have in a column one inputText, it happens that the button is outside the datable record, and click the button I want to record, capture me inputText values​​, and to update records each dataTable.
<p:dataTable id="dataTable" var="confParamGen" value="#{regRolMB.paramLdap}"
rowIndexVar="rowIndex">
<p:column>
<f:facet name="header" >
<h:outputText value="N°" />
</f:facet>
<h:outputText value="#{rowIndex+1}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Number Long" />
</f:facet>
<h:outputText value="#{confParamGen.numberCort}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Value Role" />
</f:facet>
<p:inputText value="#{confParamGen.valuesRole}" style="width: 200px;" />
</p:column>
</p:dataTable>
<p:commandButton value="Save" rendered="#{regRolMB.showButtonUpdate}"
actionListener="#{regRolMB.actualizarRol}" styleClass="positionButton">
<f:attribute name="confParamGen" value="#{confParamGen}" />
</p:commandButton>
In the controller I have it so, but it falls to cast the Arraylist.
public void updateRol(ActionEvent event) {
List<DateGeneral> rolConPar = new ArrayList<DateGeneral>();
rolConPar = ((ArrayList<DateGeneral>) event.getComponent().getAttributes().get("confParamGen"));
for(DateGeneral dato: rolConPar){
System.out.println("===> "+dato.getValuesRole());
}
}
I get this error, although the problem is not the modified data capture of inputText, only captures the data loaded from DataTable
java.lang.ClassCastException: com.bbva.sca.adm.bean.DatoGeneral cannot be cast to java.util.ArrayList

The ClassCastException is being thrown because you've actually set an instance of DatoGeneral as attribute here:
<f:attribute name="confParamGen" value="#{confParamGen}" />
This is clearly not a List<DatoGeneral> (or List<DateGeneral> or whatever typo you made during careless oversimplifying/translating of the code; just use English all the time in code). Technically, you can solve it by passing the list itself instead:
<f:attribute name="confParamGen" value="#{regRolMB.paramLdap}" />
After all, this approach isn't making any sense. Your sole purpose seems to be just collecting the submitted values. In that case, you seem to be completely new to JSF and not yet fully understand why you're using JSF and what it is all capable of. JSF has already updated the model values with the submitted values. You just have to access the very same list behind <p:dataTable value> directly.
public void actualizarRol(ActionEvent event) {
for(DateGeneral dato: paramLdap){
System.out.println("===> "+dato.getValuesRole());
}
}
This way you can just get rid of the whole <f:attribute>.

My datatable load it like this:
public ArrayList<DatoGeneral> getParamLdap() {
try{
if(codSistema != null){
confParamGen = new ArrayList<DatoGeneral>();
confParamGen = datoGeneralService.obtenerParamGen(sistema.getConfLdap().getCdCodigo());
}
}catch(Exception e){
e.printStackTrace();
}
return (ArrayList<DatoGeneral>) confParamGen;
}

Related

Way to store variable in JSF / issue with c:set and ui:param

I tried c:set and ui:param, but in the end I think I did something wrong.
Here is the crucial XHTML part:
<h:form id="formTable">
<p:dataTable editable="true" value="#{types.dataList}" var="datalist" style="width:90%; margin-bottom:20px"
rows="10" paginator="true" rowsPerPageTemplate="10,25" resizableColumns="true" liveResize="true" tableStyle="width:auto">
<!-- save the old value for the edit action-->
<c:set var="oldValue" value="#{datalist.getType()}"/>
<!-- column for testing purpose-->
<p:column>
<h:outputText value="#{oldValue}" />
</p:column>
<p:column headerText="Type" sortBy="#{datalist.type}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{datalist.type}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{datalist.type}" binding="#{inputUpdateType}" required="true" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Date" sortBy="#{datalist.lastModifyDate}">
<h:outputText value="#{datalist.lastModifyDate}"/>
</p:column>
<p:column headerText="Edit">
<p:rowEditor rendered="#{!datalist.dependenciesFound}"/>
<h:graphicImage value="../images/attention.png" rendered="#{datalist.dependenciesFound}" />
</p:column>
<p:column headerText="Delete">
<p:commandLink action="#{types.delete(datalist.type)}" rendered="#{!datalist.dependenciesFound}" update=":formTable">
<p:graphicImage url="../images/delete.png" />
<p:confirm header="Confirmation" message="Are you sure?" icon="ui-icon-alert" />
</p:commandLink>
<h:outputText value="Not editable because of dependency" rendered="#{datalist.dependenciesFound}"/>
</p:column>
<!-- We edit/update the value here. This is where the old value is needed-->
<p:ajax event="rowEdit" listener="#{types.update(oldValue, inputUpdateType.value)}"/>
</p:dataTable>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:form>
I hope this is somewhat understandable.
For my project I use Primefaces 6.1. To edit a row in this table I need to save the old value and use that value in the ajax call at the bottom. I need this, because the application or rather the DB table behind this demands it (id is this value).
The edited value is stored in the variable inputUpdateType.
My problem:
When I enter a new value and hit edit, the old value is the same as the edited value, when the application enters the update method. I made a log entry in my update method to verify what values are passed. Same with c:set and ui:param.
What am I doing wrong? How can I make this work?
EDIT:
Here is how I try to get the old value stored in my bean:
<p:ajax event="rowEdit" listener="#{types.update(types.dataListOld.toArray()[rowIndex].getType(), inputUpdateType.value)}"/>
So, it seems with ajax the values will be updated before executing the method. Therefore the old value is not available on server side anymore. Unfortunately storing the variable in JSF is also not possible because c:set will be processed before the JSF tags and will thus not hold any values (without a scope it will act as an alias and in the end also been updated before the method gets executed).
To make this whole thing work I used cell edit mode instead of the default row edit mode. With this I'm able to get the old and new value:
public void onCellEdit(CellEditEvent event){
//We will call this method on edits made to a cell
//Values are stored in a Arraylist. Number of entries depend on how many components there are in the edited cell/facet
//Here we have two because in "input" there are two components defined (although both are rendered at the same time).
#SuppressWarnings("unchecked")
ArrayList<String> oldValue = ((ArrayList<String>)(event.getOldValue()));
#SuppressWarnings("unchecked")
ArrayList<String> newValue = ((ArrayList<String>)(event.getNewValue()));
//In the end both entries have the same value, so we just take the first.
if(newValue != null && !newValue.equals(oldValue)) {
update(oldValue.get(0), newValue.get(0));
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue.get(0) + ", New:" + newValue.get(0));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
Here is why I have two entries in my values list (two components in "input"):
<f:facet name="input">
<h:inputText value="#{datalist.type}" binding="#{inputUpdateType}" required="true" rendered="#{!datalist.dependenciesFound}"/>
<h:outputText value="#{datalist.type}" rendered="#{datalist.dependenciesFound}"/>
</f:facet>
</p:cellEditor>

PrimeFaces Datatable - What is f:facet actually doing?

Looking through some PrimeFaces code in an app I noticed the following line:
<f:facet name="header">#{trainSearch.trainCount} Trains</f:facet>
It looks like it is overriding the header, which makes sense, but can someone explain this to me in a little more detail?
What is actually happening with this line of code?
Complete code listed below:
<p:dataTable id = "results" value = "#{trainSearch.trains}" var = "train" rendered="#{not empty trainSearch.trains}" styleClass = "train-search-table horizontal-border">
<f:facet name="header">#{trainSearch.trainCount} Trains</f:facet>
<p:column headerText = "Train ID">
<p:panelGrid columns="1" styleClass = "train-id-grid" layout = "grid">
<h:outputText styleClass = "train-id-label" value="#{train.trainI}"/>
<h:outputText value="#{train.originCityState} > #{train.destinationCityState}" />
</p:panelGrid>
</p:column>
<p:column headerText="Scheduled Departure">
<h:outputText value="#{train.formattedScheduledDepartureText}" />
</p:column>
<p:column headerText="Scheduled Arrival">
<h:outputText value="#{train.formattedScheduledArrivalText}" />
</p:column>
<p:column headerText="Loco Count">
<h:outputText value="#{train.locoCount}" />
</p:column>
<p:column headerText="Car Count">
<h:outputText value="#{train.carCount}" />
</p:column>
</p:dataTable>
Facets in JSF are used to customize the rendering of a component, without touching its code, like the header facet in datatable, where you can put custom code in datatable header, without touching actual PrimeFaces datatable code.
The DataTableRenderer (class that writes html code of datatable) gets the xhtml code you put inside a facet and renders it inside a div.
You can see this in the method encodeFacetof DataTableRenderer:
protected void encodeFacet(FacesContext context, DataTable table, UIComponent facet, String styleClass) throws IOException {
if(facet == null)
return;
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", null);
writer.writeAttribute("class", styleClass, null);
facet.encodeAll(context);
writer.endElement("div");
}
The line facet.encodeAll(context); renders the code you put inside facet as html, in RENDER_RESPONSE jsf phase.

when i select multiple checkbox in p:datatable selected list is empty

I have followed this link in using the selection of mutiple values in p:datatable
http://www.primefaces.org/showcase/ui/datatableRowSelectionRadioCheckbox.jsf
Now when i select mutiple values from it and click on the button in my form it should call a method in the bean which is working fine.But the selected values list is empty. I read the posts here and oucld not figure out the solution.I also tried different ways but did not work out.
JSF Code:
<p:dataTable value="#{deviceController.devicesModel}" var="deviceList" widgetVar="deviceTable" selection="#{deviceController.selectedDevices}>
<p:column sortBy="#{deviceList.manufacturerSerialNum}" filterBy="#{deviceList.manufacturerSerialNum}">
<f:facet name="header">
<h:outputText value="Manufacturer Serial No"/>
</f:facet>
<h:outputText value="#{deviceList.manufacturerSerialNum}" />
</p:column>
<p:column selectionMode="multiple">
<f:facet name="header">
<h:outputText value="#{bundle.ListLaptopTitle_inService}"/>
</f:facet>
</p:column>
</p:dataTable>
<p:commandButton action="#{deviceController.update(deviceController.selectedDevices)}" value="Submit Request" style="margin-top: 20px"/>
Code in Bean:
public String update(List updateDevice) {
try {
for(Device d:updateDevice)
{
getFacade().edit(d);
}
//message which indiactes device update is successful
return "/example.html";
} catch (Exception e) {
//handling exception
return null;
}
}
So from the page I am passing the value of deviceController.selectedDevices which is empty when checked.
Thanks

render column in jsf datatable first time only

as per my requirement I have to show a delete button end of row in datattable but restriction is to show only for first row, not in each row.
how to restrict it
belwo is my datatable
<h:dataTable id="datatable" value="#{relationBean.languageDTOList}" var="lang">
<h:column>
<f:facet name="header"> Relation Type Name</f:facet>
<h:outputText value="#{relationBean.relationName}" />
</h:column>
<h:column>
<f:facet name="header"> Value</f:facet>
<h:inputText />
</h:column>
<h:column>
<f:facet name="header">language</f:facet>
<h:outputText value="#{lang.languageName}" />
</h:column>
<h:column>
<f:facet name="header"> Delete</f:facet>
<p:commandLink rendered="" action="#{relationBean.deleteDataTable}" immediate="true" update="#form" process="#this">
<h:graphicImage value="../images/delete.png" />
<f:setPropertyActionListener target="#{relationBean.deleteId}" value="#{var}" />
</p:commandLink>
</h:column>
Bean.java its showing contents of bean
public List<LanguageDTO> getLanguageDTOList() {
System.out.println("RelationBean:getLanguageDTOList:Enter");
CountryList = new ArrayList<Country>();
try {
CountryList.add(countryService.getCountryByCode(city));
List<LanguageDTO> tempLangDTOlst=new ArrayList<LanguageDTO>();
for (Country lang : CountryList) {
LanguageDTO languageDTO = new LanguageDTO();
for (CountryLanguage CLang : lang.getCountryLanguage()) {
languageDTO = new LanguageDTO();
languageDTO.setLanguageName(CLang.getLanguage().getLanguageName());
languageDTO.setLanguageCode(CLang.getLanguage().getLanguageCode());
System.out.println(CLang.getLanguage().getLanguageName());
tempLangDTOlst.add(languageDTO);
}
}
setLanguageDTOList(tempLangDTOlst);
System.out.println("languageDTOList :"+languageDTOList);
} catch (Exception e) {
e.printStackTrace();
}
//BeanUtils.copyProperties(tempLangDTO,languageDTOList);
System.out.println("--------------------Start -------------");
for (LanguageDTO iterable_element : languageDTOList) {
System.out.println(iterable_element.getLanguageName());
}
System.out.println("-------------------- End -------------");
System.out.println("RelationBean:getLanguageDTOList:Exit");
return languageDTOList;
}
Bind the <h:dataTable> to the view via binding, which will reference an UIData component instance and in the rendered attribute just check if UIData#getRowIndex() equals to 0.
<h:dataTable binding="#{table}" ...>
<h:column>
<p:commandLink ... rendered="#{table.rowIndex eq 0}">
(note: do not bind it to a bean like #{bean.table}! the code is complete as-is)
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
JSF component binding without bean property
You can test if the current element is the same as the first element of your list:
<p:commandLink rendered="#{lang eq relationBean.languageDTOList.get(0)}"> ...
This would works only if languageDTOList is a List.
If you were using p:dataTable instead of the standard JSF DataTable, you could use the rowIndexVar variable to test if your are at the first iteration.

p:commandLink actionListener is processed for each row of p:dataTable while rendering the page

I have a dataTable that shows data stored in a database. One of the column contains a commandLink (p:commandLink) to edit selected row which is fine.
I have a problem during the rendering of my xhtml page. It seems that the method of backingBean in the actionListener attribute of commandLink is processed for every row in the table, but the actionListener should be processed only when link is clicked.
Here is my xhtml page (part of):
<h:form id="formElenco">
<p:dataTable id="dt1" value="#{myBean.itemList}" var="item">
<f:facet name="header">
<h:outputText value="header" />
</f:facet>
<p:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="value" />
</f:facet>
<h:outputText value="#{item.value}"/>
</p:column>
<p:column>
<p:commandLink id="lnkItemUpdate" value="Edit"
onstart="document.getElementById('divUpdateItem').style.display = 'block';"
actionListener="#{myBean.updateItemAction(item)}" update=":formUpdateItem" />
</p:column>
</p:dataTable>
</h:form>
<div id="divUpdateItem" style="display:none" >
<h:form id="formUpdateItem">
Nome <h:inputText value="#{myBean.name}" /><br/>
Met <h:inputText value="#{myBean.value}" /><br/>
<h:inputHidden value="#{myBean.id}" />
<h:commandButton action="#{myBean.updateItemAction}" value="Save" />
</h:form>
</div>
Here are myBean's method (myBean is requestScoped):
public String updateItemAction(Entity item){
this.setId(item.getId());
this.setName(item.getName());
this.setValue(item.getValue());
return null;
}
public String updateItemAction() {
Entity entity = new Entity();
entity.setId(this.getId());
entity.setName(this.getName());
entity.setVAlue(this.getValue());
updateEntityQueryMethod(entity);
return null;
}
This isn't a valid method signature for an actionListener, so it's treated as a value expression by the <p:commandLink>.
You should be using action instead.
<p:commandLink id="lnkItemUpdate" value="Edit"
onstart="document.getElementById('divUpdateItem').style.display = 'block';"
action="#{myBean.updateItemAction(item)}" update=":formUpdateItem" />
Note that you can also just return void instead of a null String.
public void updateItemAction(Entity item) {
this.setId(item.getId());
this.setName(item.getName());
this.setValue(item.getValue());
}
A valid actionListener method signature would be a void method taking javax.faces.event.ActionEvent argument:
public void actionListener(ActionEvent event) {
// ...
}
See also:
Differences between action and actionListener

Resources