dataTable, inputText and value saving of a "not direct" bean variable - jsf-2

I have a dataTable with a list of inputTexts:
<h2>
Attributes
</h2>
<h:dataTable
value="#{detailModel.getAfterObjectAttributeSpecifications()}"
var="specification"
styleClass="waiFormTable" >
<h:column>
#{specification.name}:
</h:column>
<h:column>
<h:inputText id="attribute" value="#{detailModel.getAfterObjectAttribute(specification.name)}" disabled="#{detailModel.mode == detailModel.viewMode}"/>
</h:column>
</h:dataTable>
The value of the inputText is not a direct bean field (detailModel.getAfterObjectAttribute(specification.name)).
If I change the value and want it save, how should I do?
Thank you for any help
Francesco

You can't. It has to be a real property or at least a Map value. E.g.
<h:dataTable
value="#{detailModel.afterObjectAttributeSpecifications}"
var="specification"
styleClass="waiFormTable" >
<h:column>
#{specification.name}:
</h:column>
<h:column>
<h:inputText id="attribute" value="#{detailModel.afterObjectAttributes[specification.name]}" disabled="#{detailModel.mode == detailModel.viewMode}"/>
</h:column>
</h:dataTable>
with
public Map<String, String> getAfterObjectAttributes() {
return afterObjectAttributes;
}

Related

ModalPanel using RichFaces

I'm trying to create a ModalPanel from a dataTable (RichFaces 4.5.1, MyFaces 2.2.6, Spring 3.1.1, Tomcat 7.0.27) but I can't.
The modalPanel has values ​​to be displayed based on the selected row in the table. When I click in a commandLink, trigger a actionListener should feed these values (localidadeMB.carregarColecoes()), but it does't work, because the reference to attributes of bean is null (has not been set by the f:setPropertyActionListener located in commandLink).
What was missing?
*page.xhtml
(...)
<f:view>
<h:form id="formConsulta">
<rich:dataTable id="tabela"
value="#{localidadeMB.getLocalidadesPorPalavra()}" var="loc"
rowKeyVar="row" rows="20" width="800px" render="scroller">
<rich:column>
(...)
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value=""/>
</f:facet>
<a4j:commandLink id="editlink" ajaxSingle="true"
oncomplete="#rich:component('modalEditarLocalidade')}.show()"
actionListener="#{localidadeMB.carregarColecoes}"
render="modalEditarLocalidade">
<h:graphicImage value="/img/edit.png"/>
<f:setPropertyActionListener value="#{loc}" target="#{localidadeMB.localidade}" />
</a4j:commandLink>
</rich:column>
</rich:dataTable>
</h:form>
<ui:include src="modalPanel.xhtml" />
*modalPanel.xhtml
<ui:composition>
<rich:popupPanel id="modalEditarLocalidade" autosized="true"
modal="false" resizable="false">
<f:facet name="header">
<h:outputText value="Alterar localidade" />
</f:facet>
<f:facet name="controls">
<h:graphicImage id="modalClosePNG2" value="/img/close1.png"
style="cursor:default;"
onclick="Richfaces.hideModalPanel('modalEditarLocalidade')" />
</f:facet>
<h:form>
<h:outputLabel value="Nome da localidade:" for="nomeLocalidade" />
<h:inputText id="nomeLocalidade"
value="#{localidadeMB.localidade.nome}" required="true"
immediate="true"/>
</h:inputText>
</h:form>
</rich:popupPanel>
</ui:composition>
*ManagedBean
private Localidade localidade;
public void setLocalidade(Localidade l){
this.localidade = l;
}
public void carregarColecoes(ActionEvent action){
System.out.println(localidade.getNome());
***** print NULL *****
}
If you want to set up a variable first and then execute a method you have to use #action for that method, actionListeners are executed first but since both of your methods are actionListeners the localidadeMB.carregarColecoes is executed before the variable is set. (And btw. h:commandLink has no "ajaxSingle" or "oncomplete" attributes.)
With the suggestion of Makhiel and this link I decided.
The xhtml looked like this:
<a4j:commandLink id="editlink" ajaxSingle="true"
oncomplete="#{rich:component('modalEditarLocalidade')}.show()"
action="#{localidadeMB.carregarColecoes}"
render="modalEditarLocalidade">
<h:graphicImage value="/img/edit.png"/>
<f:setPropertyActionListener value="#{loc}"
target="#{localidadeMB.localidade}" />
</a4j:commandLink>
and ManagedBean like this:
public String carregarColecoes(){
(....)
}

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.

Image separator for rows in jsf data table

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.

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.

JSF 2 view scoped bean not updated when action is called second time

I have a view scoped arrayList as bean. This is used to display the editable columns of dataTable. When the page is displayed initially and I try to update the table contents the update works fine, however when I try to update any column the second time the values which are changed do not reflect in the arrayList bean (verified in the action method using break point). The action method is also a managed bean with view scope.
<managed-bean>
<managed-bean-name>financialListBean</managed-bean-name>
<managed-bean-class>java.util.ArrayList</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
Below is the code for dataTable
<h:form id="myform">
<h:dataTable id="financialListBean1"
value="#{financialListBean}" var="varfinancialListBean"
styleClass="dataTableEx" headerClass="headerClass"
footerClass="footerClass"
rowClasses="rowClass1, rowClass2"
columnClasses="columnClass1" border="0" cellpadding="2"
cellspacing="0">
<h:column id="columnEx17">
<h:selectBooleanCheckbox styleClass="inputRowSelect"
id="rowSelect3"
value="#{varfinancialListBean.rowSelected}"></h:selectBooleanCheckbox>
<f:facet name="header"></f:facet>
</h:column>
<h:column id="amount1column">
<f:facet name="header">
<h:outputText styleClass="outputText" value="Amount"
id="amount1text"></h:outputText>
</f:facet>
<h:inputText styleClass="small8Input" id="amount1"
value="#{varfinancialListBean.amount}" onkeypress="return only5DigitsEntry(this, event);" onkeyup="return checkRequiredFieldsForUpdateFinancialBtn(this.form, event);">
</h:inputText>
</h:column>
<h:column id="type1column">
<h:selectOneMenu styleClass="selectOneMenu" id="menu1" value="#{varfinancialListBean.type}">
<f:selectItem itemLabel="M" itemValue="M" />
<f:selectItem itemLabel="Y" itemValue="Y" />
<f:selectItem itemLabel="Z" itemValue="Z" />
<f:selectItem itemLabel="O" itemValue="O" />
<f:selectItem itemLabel="S" itemValue="S" />
</h:selectOneMenu>
<f:facet name="header">
<h:outputText styleClass="outputText" value="Type"
id="type1text"></h:outputText>
</f:facet>
</h:column>
<h:column id="recDate1column">
<f:facet name="header">
<h:outputText styleClass="outputText"
value="Recieve Date" id="recDate1text"></h:outputText>
</f:facet>
<h:inputText styleClass="outputText" id="recDate1"
value="#{varfinancialListBean.recDate}"
onclick="getClock($(this).attr('id'))" >
<f:convertDateTime pattern="MMM d, yyyy"/>
</h:inputText>
</h:column>
</h:dataTable>
<h:commandButton type="submit"
value="Update Financial Information"
styleClass="commandExButton" id="updateFinancialBtn"
action="#{pc_SocialServicesView.doFinancialUpdateBtnAction}">
<f:param name="mrn" value="#{pc_SocialServicesView.mrn}" />
</h:commandButton>
</h:form>
The action method:
public String doFinancialUpdateBtnAction() {
System.out.println("I am at doFinancialUpdateBtnAction");
try{
if(mrn.length()==0){
mrn=getFacesContext().getExternalContext().getRequestParameterMap().get("mrn");
}
setFinancialListBean(dba.updateFinancialAsistance
(getFinancialListBean(), mrn));
setErrorMsgBean("Updated successfully ...");
doInit(mrn);
}catch (Exception e) {
System.out.println("There is an exception at doFinancialUpdateBtnAction");
Log.out.error("Error in doFinancialUpdateBtnAction: "+e);
setErrorMsgBean("No record was updated ...");
e.printStackTrace();
}
return "";
}

Resources