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);
}
}
Related
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?
i am using jsf and i am trying to show a hidden panel this what i tried
<h:commandButton update=":outPanel" actionListener="#{SelectBean.mod1()}" image="Ressources/images/update.png" style="vertical-align:middle" >
Modifier
</h:commandButton>
<p:panel visible="#{SelectBean.bol}" closable="true" toggleable="true" id="outPanel" styleClass="outPanel" widgetVar="outpanel">
<h:outputLabel value="Nom " />
<h:inputText value="#{SelectBean.nom}" />
<br/>
<h:outputLabel value="Experience " />
<h:inputText value="#{SelectBean.exp}" />
<br/>
<h:commandButton value="Modifier"/>
</p:panel>
my bean is
private boolean bol=false;
public boolean getBol() {
return bol;
}
public void setBol(boolean bol) {
this.bol = bol;
}
public String mod1()
{
bol = true;
return "success";
}
but this thing not working the panel is always hidden.
Try like this, your panel will be shown if bol is true
<p:panel rendered="#{selectBean.bol}" closable="true" toggleable="true" id="outPanel" styleClass="outPanel" widgetVar="outpanel">
Also i think you have wrong syntax, you should call methods and variables of your class through selectBean but not SelectBean
I need to generate textboxes through a loop as follows.
<p:panel id="dataPanel" closable="true" toggleOrientation="horizontal" toggleable="true" header="Data">
<h:panelGrid id="dataPanelGrid" columns="3" cellpadding="5">
<c:forEach var="row" items="#{zoneChargeManagedBean.list}">
<p:outputLabel for="txtCharge" value="#{row[1]}"/>
<p:inputText id="txtCharge" value="#{row[2]}" converter="#{bigDecimalConverter}" onkeydown="return isNumberKey(event, this.value);" label="#{row[1]}" required="false" maxlength="45">
<f:validator validatorId="negativeNumberValidator"/>
<f:attribute name="isZeroAllowed" value="false"/>
<f:validator validatorId="bigDecimalRangeValidator"/>
<f:attribute name="minPrecision" value="1"/>
<f:attribute name="maxPrecision" value="33"/>
<f:attribute name="scale" value="2"/>
</p:inputText>
<p:message for="txtCharge" showSummary="false"/>
</c:forEach>
<p:commandButton id="btnSubmit" update="dataPanel messages" actionListener="#{zoneChargeManagedBean.insert}" icon="ui-icon-check" value="Save"/>
<p:commandButton value="Reset" update="dataPanel" process="#this">
<p:resetInput target="dataPanel" />
</p:commandButton>
</h:panelGrid>
</p:panel>
The value of the given textbox is a type of BigDecimal from the database.
When the given command button is pressed, the values held by these textboxes should be retrieved from the corresponding JSF managed bean so that they can either be inserted or updated in the database.
It would be even better, if it is possible to retrieve the values of all of these text fields at once in some kind of collection (like java.util.List), when the given button is pressed.
<ui:repeate>, a render time tag works correctly but not <c:foreEach>, a view build time component (I can't clarify why) but in this particular case, I found <p:dataGrid> is more suitable. The XHTML has been modified accordingly as follows.
<p:panel id="dataPanel" rendered="#{zoneChargeManagedBean.renderedDataPanel}" closable="true" toggleOrientation="horizontal" toggleable="true" header="Data">
<p:dataGrid columns="3" value="#{zoneChargeManagedBean.list}" var="row" paginator="true" paginatorAlwaysVisible="false" pageLinks="10" rows="15">
<p:watermark for="txtCharge" value="Enter charge."/>
<p:tooltip for="lblCharge" value="Some message."/>
<p:column>
<p:outputLabel id="lblCharge" for="txtCharge" value="#{row[1]}"/><br/>
<p:inputText id="txtCharge" value="#{row[2]}" onkeydown="return isNumberKey(event, this.value);" converter="#{bigDecimalConverter}" label="#{row[1]}" required="false" maxlength="45">
<f:validator validatorId="negativeNumberValidator"/>
<f:attribute name="isZeroAllowed" value="false"/>
<f:validator validatorId="bigDecimalRangeValidator"/>
<f:attribute name="minPrecision" value="1"/>
<f:attribute name="maxPrecision" value="33"/>
<f:attribute name="scale" value="2"/>
</p:inputText>
<h:message for="txtCharge" showSummary="false" style="color: #F00;"/>
</p:column>
</p:dataGrid>
<p:commandButton id="btnSubmit" update="dataPanel messages" actionListener="#{zoneChargeManagedBean.insert}" icon="ui-icon-check" value="Save"/>
<p:commandButton value="Reset" update="dataPanel" process="#this">
<p:resetInput target="dataPanel" />
</p:commandButton>
</p:panel>
The managed bean:
#Controller
#Scope("view")
public final class ZoneChargeManagedBean implements Serializable
{
#Autowired
private final transient ZoneChargeService zoneChargeService=null;
private ZoneTable selectedZone; //Getter and setter
private List<Object[]>list; //Getter and setter
private boolean renderedDataPanel; //Getter and setter
public ZoneChargeManagedBean() {}
public void ajaxListener() {
if(this.selectedZone!=null){
list=zoneChargeService.getZoneChargeList(this.selectedZone.getZoneId());
renderedDataPanel=true;
}
else {
renderedDataPanel=false;
}
}
public void insert() {
//Just do whatever is needed based on the list with new values which is retrieved when <p:commandButton> as shown in the given XHTML is clicked.
if(selectedZone!=null&&zoneChargeService.addOrUpdate(list, selectedZone)) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Message Summary", "Message"));
}
else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Message Summary", "Message"));
}
}
}
The service method as in the ajaxListener() method returns a list of type of an array of objects - List<Object[]>.
public List<Object[]>getZoneChargeList(Long id) {
return entityManager.createQuery("select w.weightId, w.weight, zc.charge from Weight w left join w.zoneChargeSet zc with zc.zoneTable.zoneId=:id order by w.weight").setParameter("id", id).getResultList();
}
I can't use the corresponding JPA criteria query which is intended because the with operator which doesn't seem to be supported by the JPA criteria API.
This method is invoked when an item from <p:selectOneMenu> is selected which is not covered in this question.
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.
I have a jsf page that I can't update the value of some checkboxes in a list of userDamain objects, in fact this is a part of my jsf page :
<h:outputText value="USER's rights list: "></h:outputText>
<p:dataTable id="userss" var="userr" value="#{userMB.userListe}">
<p:column>
<f:facet name="header"><h:outputText value="FirstName" /></f:facet>
<h:outputText value="#{userr.firstName}" />
</p:column>
<p:column>
<h:panelGrid columns="1" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="Basic Usage: " />
<p:selectBooleanCheckbox value="#{userr.deletee}" immediate="true" actionListener="#{userr.deletee}" />
</h:panelGrid>
<p:commandButton value="Submit" update="display" oncomplete="dlg.show()" />
<p:dialog header="Selected Values" modal="true" showEffect="fade" hideEffect="fade" widgetVar="dlg">
<h:panelGrid columns="1" id="display">
<h:outputText value="Value 1: #{userr.deletee}" />
</h:panelGrid>
</p:dialog>
</p:column>
when I click on the boolean button 'Submit', the value of the userr.deletee is always false ( the default value ) and it's not updated anyway, I tried to use the Listner and actionListener in the booleanButton but it doesn't work, I also tried the postValidate event, so if someone has any idea of that, I would be graceful.
this is a part of my managed bean:
private List<UserDomain> userListe ;
public List<UserDomain> getUserListe() {
return this.userListe;
}
public void loadUserListe(){
this.userListe = new ArrayList<UserDomain>();
this.userListe.addAll(getUserServicee().getAll());
}
public void setUserListe(List<UserDomain> userListe) {
this.userListe = userListe;
}
a part of the userDomain bean:
...
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#Transient
private boolean deletee;
public boolean isDeletee() {
return deletee;
}
public void setDeletee(boolean deletee) {
this.deletee = deletee;
}
I found out a solution which seems logic to me, I added to my checkbox an ajax behavior to execute a method and an attribute which called in this method to get the whole userDomain object, so on I can get the user.deletee value, here is a part of the code I m talking about:
<h:panelGrid columns="1" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="Delete Right: " />
<p:selectBooleanCheckbox value="#{userr.deletee}">
<f:ajax execute="#this" listener="#{userMB.saveUserRights}" />
<f:attribute name="user" value="#{userr}" />
</p:selectBooleanCheckbox>
</h:panelGrid>
I hope this will be helpful for you