update items in View [duplicate] - jsf

This question already has answers here:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
(6 answers)
Closed 6 years ago.
i'm trying to implement a research of products.
My view is something like this:
<h:form>
<p:layoutUnit position="center">
<ui:include src="/Desktop/Users/Include/featureCheckbox.xhtml"/>
</p:layoutUnit>
<p:layoutUnit position="south" style="border: 0px">
<p:commandButton value="Search"
actionListener="#{productsController.searchProdByFeatures()}"
oncomplete="listProd.show();"/>
</p:layoutUnit>
</h:form>
<p:panel widgetVar="listProd" >
<ui:include src="/Desktop/Users/Include/productsScroller.xhtml"/>
</p:panel>
this is productsScroller.xhtml
OT: i don't know why i have to use to view more data, simply scroll doesn't work...
<h:form prependId="false">
<p:dataScroller value="#{productsController.items}" var="item" chunkSize="10">
<f:facet name="header">
Scroll Down to Load More Wheelchair
</f:facet>
<h:panelGrid columns="1" style="width:100%" >
<p:outputPanel>
<h:outputText value="#{item.name}" style="font-weight: bold"/>
</p:outputPanel>
</h:panelGrid>
<f:facet name="loader">
<p:commandButton type="button" value="View More" />
</f:facet>
</p:dataScroller>
</h:form>
and this is productsController (#Named and #ViewScoped)
...
private Collection<Product> items;
private Collection<Product> selectedItems;
public Collection<Product> getSelectedItems() {
return selectedItems;
}
public void setSelectedItems(Collection<Product> selectedItems) {
this.selectedItems = selectedItems;
}
public Collection<Product> getItems() {
if (items == null) {
items = this.ejbFacade.findAll();
}
System.out.println(items.size());
return items;
}
public void setItems(Collection<Product> items) {
this.items = items;
}
public void searchProdByFeatures (){
List<Product> items= (List<Product>) getItems();
List<Product> newItems;
Collection<Feature> featuresCollection = featureController.getSelectedItems();
List<Feature> selectedFeatures = new ArrayList<>(featuresCollection);
System.out.println(selectedFeatures.size()); //just for debug
try {
for (Feature selectedFeature : selectedFeatures) {
String msg=(selectedFeature.getName()+" / ");
System.out.println(selectedFeature.getName());
}
newItems=productFacade.findProdByFeatures(selectedFeatures, items);
System.out.println("Searched product are "+newItems.size()); //just for debug
setItems(newItems);
System.out.println("New items are "+getItems().size()); //just for debug
} catch (NotFoundException e) {
setItems(null);
JsfUtil.addErrorMessage(e.getMessage());
}
}
the method searchProdByFeatures() works well but the problem is that the dataScroller won't update...
i know there is something wrong in the view... but what?
or it'll be better to update the view from controller? how?

Edit your code to upadate the dataScroller by adding update="yourIddataScroller"
<p:commandButton value="Search"
actionListener="#{productsController.searchProdByFeatures()}"
oncomplete="listProd.show();" update="yourIddataScroller"/>

Related

Cannot successfully update backing bean when not in main page

I am new with JSF/PrimeFacesand now, I'm trying to solve this problem for days.
I have a page with a commandLink which opens a dialog with a TreeTable that displays values from the backing bean. The value of the bean is updated depending on the product.url.
My problem is, I get a successful result when I click on the commandLink from the main page or landing page(/products.xhtml?...ver=2019.000), but when I'm on the other redirected links(/products.xhtml?...ver=2018.000), it just won't work. The passed #{DownloadView.path} is null.
Here's a snippet of my .xhtml with the commandLink:
<div id="features">
<h:form id="form">
<div class="feature-icon fadeInDown animated" style="margin:0px 35px">
<p:commandLink action="/products.xhtml?faces-redirect=true&ver=2019.000" value="2019.000" style="#{fn:startsWith(ProductsView.actVer, '2019.000') ? 'background-color: #e91e63;' : ''}" />
</div>
<div class="feature-icon fadeInDown animated" style="margin:0px 35px">
<p:commandLink action="/products.xhtml?faces-redirect=true&ver=2018.000" value="2018.000" style="#{fn:startsWith(ProductsView.actVer, '2018.000') ? 'background-color: #e91e63;' : ''}" />
</div>
</h:form>
</div>
<div id="promotion" class="clearfix">
. . .
<ui:fragment rendered="#{!empty product.url}">
<ui:fragment rendered="#{fn:startsWith(product.url, 'file')}">
<h:outputText value="#{product.url}"/>
<p:commandLink action="#{DownloadView.listFiles}" update=":download-form:downloadPanel" oncomplete="PF('downloadDialog').show()" title="Details" >
<h:outputText value="#{product.name}" />
<f:setPropertyActionListener target="#{DownloadView.path}" value="#{product.url}" />
</p:commandLink>
</ui:fragment>
</ui:fragment>
. . .
</div>
Here's my dialog:
<h:form id="download-form" >
<p:dialog id="dialog" header="Details" showEffect="fade" widgetVar="downloadDialog" modal="true" resizable="false" dynamic="true">
<p:outputPanel id="downloadPanel">
<p:treeTable value="#{DownloadView.root}" var="download" style="margin-top:0" scrollable="true" scrollHeight="300">
<f:facet name="header">
Document Viewer
</f:facet>
<p:column headerText="Name">
<a href="#{download.path}" > <h:outputText value="#{download.name}" /> </a>
</p:column>
<p:column headerText="Location">
<h:outputText value="#{download.path}" />
</p:column>
</p:treeTable>
</p:outputPanel>
<p:ajax event="open" listener="#{DownloadView.reset()}"/>
</p:dialog>
</h:form>
Here's my DownloadView class:
#SessionScoped
public class DownloadView {
private TreeNode root;
private String path;
private DownloadBI downloadBI;
#PostConstruct
public void init() {
downloadBI = new DownloadBI();
}
public void listFiles() {
downloadBI.setPath(path);
this.root = downloadBI.getFilesTreeNode();
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public void reset() {
this.path = "";
this.root = null;
}
}
When I click on the commandLink from the landing page, the TreeTable is populated and checking the logs, the path is set:
But, if I click on the commandLink, other than the landing page, the TreeTable is empty and path is not set.
Any idea to resolve this problem is greatly appreciated! Thank you!

Add item into Primefaces table

I want to add item into Primefaces table when I create new item. I managed to create this code:
<h:form id="new_item_button">
<p:commandButton id="ajax" value="New Sensor" styleClass="ui-priority-primary" onclick="PF('dlg').show();" type="button"/>
</h:form>
<h:form id="new_sensor">
<p:dialog header="New Sensor" widgetVar="dlg" focus="name" modal="true" showEffect="fade">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="name" value="Name" />
<p:inputText id="name" label="name" value="#{newSensor.sensor.name}" />
.............................
</h:panelGrid>
<f:facet name="footer">
<p:commandButton id="ajax" value="Create Sensor" actionListener="#{newSensor.saveRecord()}" update=":new_sensor"/>
</f:facet>
</p:dialog>
</h:form>
<h:form id="form">
<p:dataTable id="tbl" var="sensor" value="#{sensors.systemSensors}"
.......
paginator="true" rows="12"
rowKey="#{sensor.model}">
<p:column headerText="Name" sortBy="#{sensor.name}" style="text-align: center">
<h:outputText value="#{sensor.name}" />
</p:column>
...................
</p:column>
</p:dataTable>
Beans:
#Named
#RequestScoped
public class Sensors implements Serializable
{
private List<SensorObj> sensors;
#PostConstruct
public void init()
{
sensors = generateSensors();
}
public List<SensorObj> getSystemSensors()
{
return sensors;
}
private List<SensorObj> generateSensors()
{
List list = new ArrayList();
SensorObj obj1 = new SensorObj("Sensor 1", "SBS0212", "Online", true, null);
list.add(obj1);
return list;
}
}
#Named
#RequestScoped
public class NewSensor implements Serializable
{
private SensorObj sensor = new SensorObj();
public SensorObj getSensor()
{
return sensor;
}
public void setSensor(SensorObj sensor)
{
this.sensor = sensor;
}
public void saveRecord(){
.....
}
}
When I submit the dialog with the new sensor I want to update the table. How I can implement this?
Should I use one managed bean for listing the content and adding new items or as it is it's better to use two?

PrimeFaces splitButton: immediate="true" does not seem to work

Sidenote: It works with Command-Buttons.
What I Have:
A simple form where name and address from a customer are entered. In a data-table below, each row contained (in the working version) the following fields:
Name of the customer
A Command-Button which redirects to another page and shows the customers orders (This worked using <p: commandButton immediate="true">)
Another Command-Button which displayed the past orders.
Another Command-Button which was responsible for updating customer-data.
Since I didn't want to have three Command-Buttons in each row I decided to use a Split-Button.
Problem:
<p:splitButton immediate="true">
The form asks me to fill the missing data (name and address) which are set to required="true.
Question:
As far as I understand the attribute immediate="true is used to overcome this issue. So what am I missing ?
Code:
<h:form>
<p:growl id="growl" sticky="false" life="3500" showDetail="false"/>
<h:panelGrid id="customer_grid" columns="2" cellspacing="1" cellpadding="5">
<h:outputLabel id="label" for="name" value="Kunde:" style="font-weight:bold"/>
<p:inputText id="name" value="#{customerController.customer.name}" required="true" requiredMessage="Name eingeben!"/>
<h:outputLabel for="address" value="Adresse:" style="font-weight: bold" />
<p:inputText id="address" value ="#{customerController.customer.address}" required="true" requiredMessage="Adresse eingeben!"/>
<p:commandButton action = "#{customerController.createCustomer}" value="Speichern" style="margin-right:10px"
actionListener="#{growlController.saveMessage}" ajax="true"
onclick="PF('blockUIWidget').block()" oncomplete="PF('blockUIWidget').unblock()" styleClass="save-button"/>
<p:commandButton onclick="history.back(); return false;" value="Abbrechen" ajax="true"/>
<pe:blockUI widgetVar="blockUIWidget">
<h:panelGrid columns="2">
<p:graphicImage id="loader" name="images/ajax-loader.gif" style="margin-right: 12px; vertical-align: middle;" rendered="true"/>
<h:outputText value="Please wait..." style="white-space: nowrap;"/>
</h:panelGrid>
</pe:blockUI>
</h:panelGrid>
<br/>
<br/>
<p:dataTable var="customer" value="#{customerController.allCustomers}" resizableColumns="true" tableStyle="width: auto"
rendered="#{not empty customerController.allCustomers}">
<p:column headerText="customer" style="width: 300px">
<h:outputText value="#{customer.name}" />
</p:column>
<p:column>
<p:splitButton value="current order" action="#{userController.setup(customer, 'lastOrder')}" immediate="true">
<p:menuitem value="old orders" action="#{userController.setup(customer, 'oldOrders')}" immediate="true"/>
<p:menuitem value="edit" action="#{userController.setup(customer, 'update')}" immediate="true"/>
</p:splitButton>
</p:column>
</p:dataTable>
EDIT:
According to the comment of BalusC I've put the two parts in separate forms.
Effect: The message to fill out the above form does not show up, but the redirect is not happening either.
EDIT2:
The purpose of the method userController.setup(customer, 'String') is basically to inject the customer who is represented for each row. The String is returned for redirecting purposes which are set in the faces-config.xml and as I said: It works when I use Command-Buttons instead.
CODE:
#Named
#SessionScoped
public class UserController implements Serializable{
#Inject
private Customer customer;
#EJB
private CustomerService customerService;
public UserController(){
}
public List<Item> getItems(){
return customerService.getItems(customer);
}
public Ordery getCurrentOrder(){
return customerService.getCurrentOrder(customer);
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public CustomerService getCustomerService() {
return customerService;
}
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}
public String setup(Customer customer, String nav){
this.customer = customer;
return nav;
}
public void update(){
customerService.update(customer);
}
}

primefaces commandlink wont show modal dialog

hello I have a commandLink that executes a method in my baking bean, that method calls an ejb that builds a string and place it as an attribute of the bean (with getters and setters), after executing that method should raise a modal dialog to only display the value of that attribute but it does not, I see the method that builds the chain runs but does not lift the dialogue, this is my code:
xhtml:
<ui:composition>
<p:panelGrid columns="3" style="width: 100%" >
<h:form id="headerForm">
<p:column style="width: 15%;height:auto; text-align: center;">
<p:graphicImage value="#{loginBean.url}" style="align:center;"/>
</p:column>
<p:column>
<div align="center">
<h:outputText styleClass="titleHeader" value="#{loginBean.entityName}" />
</div>
</p:column>
<p:column style="width: 15%;height:auto; text-align: center;">
<div align="right">
<h:commandLink onComplete="PF('dlg').show(); return false;" type="button" ajax="false" action="# {xxxxBean.createString}">
<h:outputText value="Contact" />
</h:commandLink>
</div>
</p:column>
</h:form>
</p:panelGrid>
<p:dialog id="dlg" header="Some title here" widgetVar="dlg" modal="true">
<h:outputText value="#{xxxxBean.stringBuild}" />
</p:dialog>
</ui:composition>
Backing bean:
#ManagedBean
#SuppressWarnings("serial")
public class XxxxBean implements Serializable{
private String stringBuild;
private someBeanRemote ejb;
public XxxxBean() {
// TODO Auto-generated constructor stub
try{
ejb = EjbConsumer.getRemoteEjb();
}catch(Exception e){
e.printStackTrace();
}
}
public void createString(){
List<someObject> list = ejb.findAllActiveObjects(Constants.TOP);
String temp = "";
if( list!=null && list.size() > 0 ){
for(int i=0; i < list.size(); i++){
temp += list.get(i).getName() + "<br/>";
}
this.stringBuild= temp;
}
System.out.println(this.stringBuild);
}
public void setStringBuild(String stringBuild) {
this.stringBuild= stringBuild;
}
public String getStringBuild() {
return stringBuild;
}
}
thanks in advance!!!
You are using ajax=false with oncomplete
oncomplete: Client side callback to execute when ajax request is completed.
Change to:
<p:commandLink oncomplete="PF('dlg').show();" action="#{yourBean.youraction}"></p:commandLink>
that is default ajax = true and everything should work

Request doesn't render response in primefaces datatable

I have a datatable with search field and commandLink to sort. The commandLink that I use to trigger sorting is located not in column header but on the header of datatable. When I load my page and use only commandLink to sort everything works ok. Table sorts in two orders and I see result on my page. Problem appears when I search something in globalFilter. It also works, but after that I cant sort my table. I clear inputText of globalFilter and I cant sort table. To sum up, I see result of sorting only when I not use search field. Sort operation works but request not update the datatable. I put my code below. Maybe somebody knows how to solve it.
<ui:composition>
<p:panel header="Moje pomiary" footer="#{msgs.footer}" id="myMeasurement">
<h:form id="form" prependId="false">
<p:dataTable var="m" value="#{myMeasurementTable.measurement}" id="measureList" editable="true"
widgetVar="mTable"
emptyMessage="No files found with given criteria" filteredValue="#{myMeasurementTable.filteredMeasurement}" >
<f:facet name="header">
Sortowanie według: <p:commandLink id="sortByName" actionListener="#{myMeasurementTable.sortByName}" update="measureList">
<h:outputText value="nazwa pliku" />
</p:commandLink>
|<h:commandLink action="#{myMeasurementTable.sortByArchivisationDate}"> data archiwizacji </h:commandLink>
|<h:commandLink action="#{myMeasurementTable.sortByMeasureDate}"> data badania </h:commandLink>
<p:outputPanel styleClass="searchPanel">
<h:outputText value="Szukaj: " />
<p:inputText styleClass="globalFilter" id="globalFilter" onkeyup="mTable.filter()" style="width:150px" />
</p:outputPanel>
</f:facet>
<p:column headerText="Informacje pomiarowe" style="width:125px" filterStyle="display:none" filterBy="#{m.fileName} #{m.measureDate} #{m.place} #{m.archivisationDate}"
filterMatchMode="contains" >
<p:separator styleClass="separatorColumn"/>
Nazwa pliku: <h:outputText value="#{m.fileName}" /><br />
Data badania: <h:outputText value="#{m.measureDate}" /><br />
Data archiwzacji: <h:outputText value="#{m.archivisationDate}" /><br />
Miejscowość: <h:outputText value="#{m.place}"/> <br />
Współrzędne GPS:
</p:column>
<p:column headerText="Wykresy">
<img src="/tmp/21/myfile.xls/myfile.xls_Parametr x.png" width="150"/>
</p:column> </p:dataTable></h:form></p:panel></ui:composition>
and part of my bean
#ManagedBean(name = "myMeasurementTable")
#ViewScoped
public class myMeasurementTable implements Serializable{
private static final long serialVersionUID = -9193902657201234669L;
private List<Measurement> measurement;
private List<Measurement> filteredMeasurement;
private boolean sortAscending = true;
public myMeasurementTable() {
measurement = new ArrayList<Measurement>();
fillTable(measurement);
}
public String sortByName() {
System.out.println("naciskam sortowanie");
if (sortAscending) {
Collections.sort(measurement, new Comparator<Measurement>() {
#Override
public int compare(Measurement m1, Measurement m2) {
return m1.getFileName().compareTo(m2.getFileName());
}
});
sortAscending = false;
} else {
Collections.sort(measurement, new Comparator<Measurement>() {
#Override
public int compare(Measurement m1, Measurement m2) {
System.out.println(m2.getFileName());
return m2.getFileName().compareTo(m1.getFileName());
}
});
sortAscending = true;
}
return null;
}
Ok I found solution on primefaces forum. It's simple. I only added oncomplete="mTable.filter()" to commandButton and everything works as I want.

Resources