Image separator for rows in jsf data table - jsf-2

I want to display an line/image as separator ( as shown here - image attached) between rows conditionally, and I have no idea on how to achieve this, please suggest, this is my sample that I have written to replicate the actual scenario,
<h:panelGrid columns="1" >
<h:dataTable value="#{testBean.myBeanList}" var="myBean">
<h:column>
<f:facet name="header">
<h:outputText value="EMPLOYEE NAME" />
</f:facet>
<h:outputText value="#{myBean.empName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="EMPLOYEE DEPARTMENT" />
</f:facet>
<h:outputText value="#{myBean.empDept}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="EMPLOYEE HR NAME" />
</f:facet>
<h:outputText value="#{myBean.empHRName}"/>
</h:column>
</h:dataTable>
</h:panelGrid>
public TestBean() {
myBeanList = new ArrayList<MyBean>();
for(int i =0;i<8;i++){
MyBean mb = new MyBean();
if(i == 2 || i == 4){
mb.setEmpName("NAME"+i);
}else{
mb.setEmpName("EMPLOYEE NAME"+i);
mb.setEmpDept("EMPLOYEE DEPT"+i);
mb.setEmpHRName("EMPLOYEE HR NAME"+i);
}
myBeanList.add(mb);
}
}

Use the rowClasses attribute of the <h:dataTable>. It takes a commaseparated string of CSS class names which are applied on the subsequent generated <tr> elements. You can then use CSS to put a top border in every cell (<td>) of the <tr> in question (those with "NAME2" and "NAME4" in your example).
<h:dataTable ... rowClasses="#{bean.rowClasses}">
At the same time of populating the data model, you should also populate the row classes. It should for the particular exapmle in the screenshot return something like this:
none,none,separator,none,separator,none,none,none
Then you just have to provide the necessary CSS:
tr.separator td {
border-top: 1px solid gray;
}
No need for an ugly and old fashioned separator image.

Related

How to change the value of <p:dataTable> dynamically based on <p:selectItem>?

I am working with jsf 2.0 et Primefaces. i have a selectOneMenu that have dynamic values of datas that correspond to the user connected. I want that when i choose a data and click on the button view the list of emails related to the data selected will be shown on the dataTable.
<p:panel>
<p:selectOneMenu id="data" value="#{mailMB.database}" styleClass="auto" required="true" effect="fade" >
<f:selectItem itemLabel="Select Data" itemValue="" />
<f:selectItems value="#{dataMB.datas}" var="data" itemLabel="#{data.keyword}" itemValue="#{data.keyword}"/>
</p:selectOneMenu>
<p:commandButton value="View" action="#{mailMB.grabemails()}" ajax="true" update="datas" icon="ui-icon-circle-check" styleClass="ui-priority-primary" />
</p:panel>
<p:panel id="panelform" header="Emails List" >
<p:dataTable value="#{mailMB.emailsByData}" var="item" id="datas" rowsPerPageTemplate="5,10,15,20,25,30"
paginator="true" rows="10"
selectionMode="single" filteredValue="#{mailMB.filteredMails}" rowKey="#{item.id}"
selection="#{mailMB.selectedMail}">
<p:ajax event="rowSelect" update=":form:dataView , :form:confirmDelete, :form:viewButton" listener="#{dataMB.onRowSelect}"/>
<p:ajax event="rowToggle" />
<p:column style="width:2%" exportable="false">
<p:rowToggler />
</p:column>
<p:column sortBy="#{item.email}" filterBy="#{item.email}">
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{item.email}"/>
</p:column>
</p:dataTable>
</p:panel>
and this is my method in the managed Bean that returns the list of emails by data using the named query:
public List<Email> getEmailsByData() {
System.out.println("the database" + getDatabase());
return emailsByData = mailBusinessLocal.mails(getDatabase());
}
public List<Email> grabemails() {
return emailsByData = mailBusinessLocal.mails(database);
}
when i choose a data and click view nothing happens and the databate return null as it shown on the glassfish log.
You need to put your <p:selectOneMenu> inside a <h:form>. That's my first guess.

Rendered attribute has no effect in dropdown, while it works in input text

I have data table with a dropdown and an input text. I have a button which adds a new row to the data table.
On add, I want to show the submitted value of dropdown and input text of previous row as output text, and display the dropdown and input text in the new row only.
I have used rendered attribute on the dropdown, input text and output text. However, when I add a new row, the dropdown and output text are both shown in the previous row.
<h:dataTable id="Table" value="#{bean.orderList}" var="attr" binding="#{bean.orderTable}">
<h:column>
<f:facet name="header">
<h:outputText value="Item"/>
</f:facet>
<h:outputText value="#{attr.orderItem.ItemId}" rendered="#{attr.orderItem.ItemId != null}" />
<h:selectOneMenu value="#{attr.orderItem.ItemId}" rendered="#{attr.orderItem.ItemId == null}">
<f:selectItems value="#{bean.itemList}" var="attrList" itemValue="#{attrList.itemId}" itemLabel="#{attrList.itemName}" />
</h:selectOneMenu>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Price" />
</f:facet>
<h:outputText value="#{attr.price}" rendered="#{attr.orderItem.itemId != null}" />
<h:inputText value="#{attr.price}" rendered="#{attr.orderItem.itemId == null}" />
</h:column>
</h:dataTable>
<a4j:commandButton value="Add" execute="#form" action="#{bean.addAction}" render=":Table" />
Look closer where it fails:
<h:outputText ... rendered="#{attr.orderItem.ItemId != null}">
<h:selectOneMenu ... rendered="#{attr.orderItem.ItemId == null}">
and where it works:
<h:outputText ... rendered="#{attr.orderItem.itemId != null}">
<h:inputText ... rendered="#{attr.orderItem.itemId == null}">
The one says ItemId and the other says itemId. Align it out. Properties always start with lowercase unless they start with 2 uppercased characters by themselves.

form rendered on primefaces isn't calling the manage bean

I'm having problems with a form that is rendered by a booleanButtom on PrimeFaces 3.5
the form appear as expected but when I commit the values of the field come null.
The code of the pag:`
<p:panelGrid>
<p:row>
<p:column>
<h:form id="city">
<p:panelGrid columns="2">
<h:outputText value="Name: "/>
<p:inputText label="Name" value="#{managedBean.city.name}"/>
<h:outputText value="Status: "/>
<p:selectBooleanButton value="#{managedBean.city.status}" onLabel="Enable" offLabel="Disable">
<p:ajax listener="#{managedBean.changeStatusCity()}"/>
</p:selectBooleanButton>
<h:outputText value="Add neighborhood?"/>
<p:selectBooleanButton id="btAddNeighborhood" value="#{managedBean.addNeighborCity}" onLabel="Cancel" offLabel="Yes">
<p:ajax update=":addNeighbor" listener="#{managedBean.addNeighborCity()}"/>
</p:selectBooleanButton>
</p:panelGrid>
</h:form>
</p:column>
</p:row>
<p:row>
<p:column>
<h:form id="addNeighbor">
<p:panel header="Neighborhood" rendered="#{managedBean.addNeighborCity}">
<p:panelGrid columns="2">
<h:outputText value="Name: "/>
<p:inputText label="Name" value="#{managedBean.neighborhood.name}"/>
<h:outputText value="Status: "/>
<p:selectBooleanButton value="#{managedBean.neighborhood.status}" onLabel="Enable" offLabel="Disable" onIcon="ui-icon-check" offIcon="ui-icon-close">
<p:ajax listener="#{managedBean.changeStatusNeighbor()}"/>
</p:selectBooleanButton>
</p:panelGrid>
</p:panel>
</h:form>
<h:form id="formBt">
<p:commandButton id="bt" value="Add" actionListener="#{managedBean.saveNeighborCity()}" update=":addNeighbor, :city:btAddNeighborhood"/>
</h:form>
</p:column>
</p:row>
</p:panelGrid>`
And the manage bean
public void addNeighborCity(){
if(addNeighborCity){
neighborhood = new Neighborhood();
neighborhood .setStatus(true);
neighborhood .setStringStatus("Enable");
}else{
neighborhood = null;
}
}
public void changeStatusNeighbor() {
if (neighborhood .isStatus()) {
neighborhood .setStringStatus("Enable");
} else {
neighborhood .setStringStatus("Disable");
}
}
public void saveNeighborCity(){
city.getNeighborhoods().add(neighborhood );
neighborhood = null;
addNeighborCity = false;
}
All the input inside of the form that was rendered doesn't send the information to the manage bean and when I put the button that add the neighbor to the list of the city the button stop working and doesn't call the manage bean any more.
Does someone knows what I'm doing wrong or what is happening.
I'm using Primefaces3.5, GlassFish4.0 and JSF2.2
As you did not post the whole managed bean, I guess that you're using the default scope of the managed bean: #RequestScoped. In that case you should use #ViewScoped.
I solved the problem, I was using glassfish 4 and it forces the jsf2.2 even when you put the jsf2.1 in our project, then I changed to glassfish 3 and all work just fine, thanks for the answers, and I'm using #ScopeSession.

change color of inputtext at row level on selectOneMenu(Dropdown) change in Datatable

I am using primefaces(v.3.0) datatable in my application.
In Datatable there are two columns , one column is inputtext and other is SelectOneMenu(dropdown).
Now I want to change inputtext color with some cases like..
1.if SelectOneMenu value get selected as "Single" input textbox color will be "green" for that particular pID only.
2.if SelectOneMenu value get selected as "Married" input textbox color will be "red" for that particular pID only.
3.if SelectOneMenu value get selected as "Divorced" input textbox color will be "yellow" for that particular pID only.
So I am trying in this way....
<h:form id="form">
<h:panelGrid columns="2" cellpadding="10" id="h">
<p:dataTable id="table" var="s"
value="#{backingBean.arrayList}"
widgetVar="empTable" rowKey="#{pt.pID}"
paginator="true" rows="15"
style="width: 100%;margin-bottom: 10px;" rowStyleClass="#{s.status}">
<f:facet name="header">
List of Patients Appointments
</f:facet>
<p:column headerText="Status" id="t">
<p:inputText value="#{s.status}" />
</p:column>
<p:column headerText="EmployeeAction">
<p:selectOneMenu id="scAction" value="#{backingBean.obj.empStatus}"
style="width:125px">
<f:selectItem itemLabel="Select" itemValue="" />
<f:selectItems value="#{schedulerBB.scheduleActionSelect}"
itemLabel="#{backingBean.obj.empStatus}"
itemValue="#{backingBean.obj.empStatusID}" />
<p:ajax event="change" listener="#{backingBean.changeColor(s)}" update=":form" />
</p:selectOneMenu>
</p:column>
</p:dataTable>
</h:panelGrid>
</h:form>
In CSS
.Single td:nth-child(1) input {
background-color: green;
}
.Married td:nth-child(1) input {
background-color: red;
}
.Divorced td:nth-child(1) input {
background-color: yellow;
}
In BackingBean:
private Employee obj;
//Getter setter methods
public Employee getObj() {
if(obj==null){
obj=new Employee();
}
return obj;
}
public void setObj(Employee obj) {
this.obj = obj;
}
public void changeColor(Employee e){
if(obj.getEmpStatus().equals("1")){
EmployeeDAO.updateEmpTable(e.getPID,e.getStatus);
}
css
.Single td:nth-child(1) input {
background-color: green;
}
.Married td:nth-child(1) input {
background-color: red;
}
.Divorced td:nth-child(1) input {
background-color: yellow;
}
I am able to change the input text value on change of selectonemenu for that particular pID,but as you can
see I have applied inputtextbox color change logic at column level ,so all columns inputtext color changes.
So how can I apply logic of changing inputtext box color at row level(i.e for particular ID only)
You can use a different style class for rows that match a condition.
Using this in your page a style class will be enabled depended on the status:
<p:dataTable id="table" var="s" value="#{backingBean.arryList}" widgetVar="EmployeeTable" rowKey="#{s.pID}" paginator="true" rows="15" style="width: 100%;margin-bottom: 10px;" rowStyleClass=#{s.status}>
<p:column id="st">
<f:facet name="header">
<h:outputText value="Status" />
</f:facet>
<p:inputText value="#{s.status}" style="width:90px;"/>
</p:column>
<p:column headerText="Employee Status">
<p:selectOneMenu value="#{backingBean.obj.empStatus}" style="width:125px">
<f:selectItem itemLabel="Select" itemValue="" />
<f:selectItems value="#{BackingBean.empStatusActionSelect}"
itemLabel="#{backingBean.obj.empStatus}"
itemValue="#{backingBean.obj.empStatusID}" />
<p:ajax event="change" listener="#{backingBean.changeColor}" update="table"/>
</p:selectOneMenu>
</p:dataTable>
In your CSS you need the following:
.Single td:nth-child(1) input {
background-color: green;
}
.Married td:nth-child(1) input {
background-color: red;
}
.Divorced td:nth-child(1) input {
background-color: yellow;
}
This way an input element in the first column of a table row gets a background color, green, red or yellow.
Note: the outcome of #{s.status} must be "Single", "Married", or "Divorced".
Here the code which worked for me perfectly.
<p:dataTable id="table" var="s" value="#{backingBean.myArraylist}" widgetVar="EmployeeTable" rowKey="#{s.pID}" paginator="true" rows="15" style="width: 100%;margin-bottom: 10px;" >
<p:column id="st">
<f:facet name="header">
<h:outputText value="Status" />
</f:facet>
<p:inputText value="#{s.status}" style="width:90px;" style="#{s.color}"/>
</p:column>
<p:column headerText="Employee Status">
<p:selectOneMenu value="#{backingBean.obj.empStatus}" style="width:125px">
<f:selectItem itemLabel="Select" itemValue="" />
<f:selectItems value="#{BackingBean.empStatusActionSelect}"
itemLabel="#{backingBean.obj.empStatus}"
itemValue="#{backingBean.obj.empStatusID}" />
<p:ajax event="change" listener="#{backingBean.changeColor}" update="table"/>
</p:selectOneMenu>
</p:dataTable>
In Backing bean iterate datatabale arraylist in this way and set color for inputtext.
Delclare color varibale in Employee class with its getter and setters.
myArraylist = myDAO.getEmployeeList();
for (Employee s : myArraylist) {
if(s.getStatus().equals("Single")){
s.setColor("background-color : green");
}
else if(s.getStatus().equals("Married")){
s.setColor("background-color : red");
}
else if(s.getStatus().equals("Divorced")){
s.setColor("background-color : yellow");
}
}
You can use primefaces' rowStyleClass attribute on the datatable.
In the rowStyleClass attrribute you can use a ternary operator (as in your case, something like
#{backingBean.obj.empStatus eq single? green: blue}
The result of the ternary operator should correspond to css style classes you already have loaded on that page

How to make a table with 1 row by default

I have a table and I want that everytime I run the program it show 1 blank row by default. How can i do that?
<h:dataTable cellspacing="0" value="#{editQuestion.answersData}" var="answer">
<h:column>
<f:facet name="header">ID</f:facet>
<h:outputText value="#{answer.answer.id}" />
</h:column>
<h:column>
<f:facet name="header"><h:outputText value="#{i18n['admin.edit.rightanswer']}" /></f:facet>
<h:selectBooleanCheckbox value="#{answer.answer.isRight}"/>
</h:column>
<h:column>
<f:facet name="header"><h:outputText value="#{i18n['admin.edit.answers']}" /></f:facet>
<h:inputTextarea id="answer" rows="3" cols="40" value="#{answer.text}" required="true" label ="Answer">
<f:validateLength maximum="500"/>
</h:inputTextarea>
<div>
<h:message for="answer" style ="color:red"/>
</div>
</h:column>
<h:column>
<h:commandButton image="/resources/imgs/#{editQuestion.buttonDelete}" immediate ="true" action="#{editQuestion.deleteAnswer(answer)}" disabled="#{!editQuestion.possibleToDelete}" alt="delete" title="#{i18n['img.delete']}">
<f:param name="id" value="#{editQuestion.id}"/>
</h:commandButton>
</h:column>
</h:dataTable>`
Just add a new instance of Answer to the list behind #{editQuestion.answerData} during the (post)construction of the bean behind #{editQuestion}.
E.g. during the postconstruct:
private List<Answer> answerData;
#PostConstruct
public void init() {
answersData = new ArrayList<Answer>();
answersData.add(new Answer());
}
Note that the bean needs to be #ViewScoped in order to preserve the right data across submits on the same view.

Resources