Dynamic input values not updated in backing bean - jsf

I have created a dynamic input field which changes depending on the item type.
<h:panelGrid columns="2" cellpadding="10">
<c:forEach items="#{tabVar.items}" var="itmVar">
<h:outputText value="#{itmVar.label}:" />
<c:if test="#{itmVar.isString}">
<p:inputText id="#{itmVar.id}" value="#{itmVar.value}" required="#{itmVar.isEditable}" disabled="#{itmVar.isEditable}" valueChangeListener="#{tabBean.processValueChange}" maxlength="100" size="75" immediate="true" onchange="form1.submit()"/>
</c:if>
<c:if test="#{itmVar.isDate}">
<p:calendar id="#{itmVar.id}" value="#{itmVar.value}" required="#{itmVar.isEditable}" disabled="#{itmVar.isEditable}" valueChangeListener="#{tabBean.processValueChange}" onSelectUpdate="form1.submit();"/>
</c:if>
<c:if test="#{itmVar.isDouble}">
<p:inputText id="#{itmVar.id}" value="#{itmVar.value}" required="#{itmVar.isEditable}" disabled="#{not itmVar.isEditable}" valueChangeListener="#{tabBean.processValueChange}" maxlength="100">
<f:validateDoubleRange minimum="#{itmVar.minDouble}" maximum="#{itmVar.maxDouble}" />
</p:inputText>
</c:if>
<c:if test="#{itmVar.isInteger}">
<p:inputText id="#{itmVar.id}" value="#{itmVar.value}" required="#{itmVar.isEditable}" disabled="#{not itmVar.isEditable}" valueChangeListener="#{tabBean.processValueChange}" maxlength="100">
<f:validateLongRange minimum="#{itmVar.minLong}" maximum="#{itmVar.maxLong}" />
</p:inputText>
</c:if>
</c:forEach>
</h:panelGrid>
Everything renders correctly, but when I change and submit the input values, then it does not get updated in the backing bean. How is this caused and how can I solve it?

#{tabBean.processValueChange} may not right. Its not possiable to use only 1 method for valueChangeListener for all value. Can u post your full code in ManagedBean ? is that on #SessionScope ? The right method for valueChangeListener may be like this:
public void saveStatus(ValueChangeEvent event) {
Integer newValue = (Integer) event.getNewValue();//this is for save Status
itmVar.setStatus(newValue);
}
If you want to save a serial of value, u have to create a serial of method :) good luck!

Related

Pass <p:selectOneListbox var="ch"> as argument of <h:commandLink action>

I'm facing problem with passing object to backing bean from actionListener in commandLink. What I have, is a bean MeasureBean and a xhtml file, that uses the bean.
In the xhtml I have:
<p:selectOneListbox var="ch">
<f:selectItems value="#{MeasureBean.checkpoints}" var="cp" itemValue="#{cp}" />
<p:column>
<h:outputText value="#{ch.name}" />
</p:column>
<p:column>
<h:commandLink actionListener="#{MeasureBean.onCheckpointRemoved(ch)}">
<h:graphicImage library="#{ctx.theme}" name="images/delete.gif" />
<f:ajax event="click" />
</h:commandLink>
</p:column>
</p:selectOneListbox>
In the bean I have method:
public void onCheckpointRemoved(Checkpoint viewCheckpoint) {
System.out.println(viewCheckpoint);
// TODO
}
The problem is, that regardless of whethert I use the tag <f:ajax> or not, the parameter viewCheckpoint of the method in bean is always null. I need to pass that parameter to the bean. It doesn't have to be the whole object, it is allowed to pass just the id of the checkpoint. What I also tried, was:
<h:commandLink actionListener="#{MeasureBean.onCheckpointRemoved(cp)}">
(cp instead of ch). But no difference.
Please help,
Mateusz
You forgot to set the value of <p:selectOneListBox>. Also, you'll have to create a converter.
You can check an example of converter in PrimeFaces Showcase
<p:selectOneListbox var="ch" value="#{MeasureBean.checkPointTest}" converter="checkPointConverter">
<f:selectItems value="#{MeasureBean.checkpoints}" var="cp" itemValue="#{cp}" />
<p:column>
<h:outputText value="#{ch.name}" />
</p:column>
<p:column>
<h:commandLink actionListener="#{MeasureBean.onCheckpointRemoved(ch)}">
<h:graphicImage library="#{ctx.theme}" name="images/delete.gif" />
<f:ajax event="click" />
</h:commandLink>
</p:column>
</p:selectOneListbox>
Checkpoint checkPointTest;
// getter/setter....
public void onCheckpointRemoved(Checkpoint viewCheckpoint) {
System.out.println(viewCheckpoint);
// TODO
}

setting the values of credit/debit textbox in JSF

I have two textbox in jsf
1)creditAmount
2)debit amount
Now if I type in credit textbox, debit textbox should be zero and and viceversa.
How to do it in jsf? I wrote javascript function for it but it's not working. Is there any way to do it in jsf. I am new in jsf?
<p:inputText id="debitAmount" value="#{jvDetailsController.selected.debitAmount}"
title="#{bundle.CreateJvDetailsTitle_debitAmount}" required="true"
requiredMessage="#{bundle.CreateJvDetailsRequiredMessage_debitAmount}">
<f:convertNumber minFractionDigits="2" pattern="#0.000" />
</p:inputText>
You can easily do that with JSF ajax.
<h:inputText id="credit" value="#{bean.credit}">
<f:ajax event="blur" render="devit" listener="#{bean.changeDevit}"/>
</h:inputText>
<h:inputText id="devit" value="#{bean.devit}">
<f:ajax event="blur" render="credit" listener="#{bean.changeCredit}"/>
</h:inputText>
Here is corresponding ManagedBean
#ManagedBean(name="bean")
class Bean{
int devit;
int credit;
public void changeDevit(){
devit=0;
}
public void changeCredit(){
credit=0;
}
//getter & setter
}
You can use primefaces ajax for this like
<h:panelGrid columns="3">
<h:outputText value="Keyup: " />
<p:inputText id="counter">
<p:ajax event="keyup" update="out"
listener="#{counterBean.increment}"/>
</p:inputText>
<h:outputText id="out" value="#{counterBean.count}" />
</h:panelGrid>
Hope it will hep.

p:column rendered attribute does not seem to work with p:dataTable var

I have written a code like:
<p:column headerText="Edit" width="40" rendered="#{(leaveDetails.strLeaveStatus == 'Canceled') or (leaveDetails.strLeaveStatus == 'Availed')}">
<p:commandLink actionListener="#{userLeaveBean.editAppliedLeave}" title="Edit" disabled="true" process="#this" update="leaveDataTable" immediate="false">
<h:graphicImage url="resources/images/edit.JPG"/>
<f:attribute name="userId" value="#{employee.name}"/>
<f:attribute name="editFirstHalf" value="#{leaveDetails.strStartTiming}"/>
<f:attribute name="editSecondHalf" value="#{leaveDetails.strEndTiming}"/>
<f:attribute name="editFrom" value="#{leaveDetails.dtLeaveFromDate}"/>
<f:attribute name="editTo" value="#{leaveDetails.dtLeaveToDate}"/>
<f:attribute name="leaveId" value="#{leaveDetails.strLeaveId}"/>
</p:commandLink>
</p:column>
But the rendered attribute is not working for the condition. How can I use the logical operator to make the condition work?Using PrimeFaces 3.4.2
You can't conditionally render a whole column on a per-row basis. This makes logically no utter sense. You can only conditionally render it on a per-table basis. The <p:column rendered> cannot take a condition based on properties of the iterated row. It can only take a condition based on properties of the parent bean.
If you intend to conditionally hide only the cell of the currently iterated row, then just move the rendered attribute from <p:column> to <p:commandLink> or at least a component which wraps the whole <p:column> content, such as <h:panelGroup>.
Or if you really intend to conditionally hide a whole column, then move the conditions used in rendered attribute of <p:column> to the #{userLeaveBean} parent bean.
first import
<html xmlns:ui="http://java.sun.com/jsf/facelets">
and add a ui fragment inside the column
<p:column headerText="Edit" width="40">
<ui:fragment rendered="#{(leaveDetails.strLeaveStatus == 'Canceled') or (leaveDetails.strLeaveStatus == 'Availed')}">
<p:commandLink actionListener="#{userLeaveBean.editAppliedLeave}" title="Edit" disabled="true" process="#this" update="leaveDataTable" immediate="false">
<h:graphicImage url="resources/images/edit.JPG"/>
<f:attribute name="userId" value="#{employee.name}"/>
<f:attribute name="editFirstHalf" value="#{leaveDetails.strStartTiming}"/>
<f:attribute name="editSecondHalf" value="#{leaveDetails.strEndTiming}"/>
<f:attribute name="editFrom" value="#{leaveDetails.dtLeaveFromDate}"/>
<f:attribute name="editTo" value="#{leaveDetails.dtLeaveToDate}"/>
<f:attribute name="leaveId" value="#{leaveDetails.strLeaveId}"/>
</p:commandLink>
</ui:fragment>
</p:column>
The best way I used to resolve my problem with the help of GOD BalusC is:
<p:column headerText="Edit" width="40">
<p:commandLink actionListener="#{userLeaveBean.editAppliedLeave}" title="Edit" process="#this" update="leaveDataTable"
immediate="false" disabled="#{(leaveDetails.strLeaveStatus == 'Canceled') or (leaveDetails.strLeaveStatus == 'Availed')}">
<h:graphicImage url="resources/images/edit.JPG"/>
<f:attribute name="userId" value="#{employee.name}"/>
<f:attribute name="editFirstHalf" value="#{leaveDetails.strStartTiming}"/>
<f:attribute name="editSecondHalf" value="#{leaveDetails.strEndTiming}"/>
<f:attribute name="editFrom" value="#{leaveDetails.dtLeaveFromDate}"/>
<f:attribute name="editTo" value="#{leaveDetails.dtLeaveToDate}"/>
<f:attribute name="leaveId" value="#{leaveDetails.strLeaveId}"/>
</p:commandLink>
</p:column>
and it works as smooth as butter!

primefaces dialog with inputtext as parameter

I would like to give the content of an inputText as a parameter to a function in a backing bean, I know that I could send the content in the backing bean, but it doesn't make much sense in my object model. I know that in the datatable, you can provide a function with the name of the "var", I thought I could use the same mechanism by passing the ID of the inputText, but it always sends null. Is there a way to do it ?
<p:dialog id="dialog" header="Reason for obsolescence" modal="true" widgetVar="dlg">
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="reason" value="Reason for obsolescence :" />
<p:inputText value="default" id="reason" required="true" label="reason" />
<p:commandButton id="provideReason" value="Ok" update=":form:tabView:table-metadata"
action="#{tableMetadataController.setSelectedObsolete(reason)}"
oncomplete="dlg.hide()"/>
</h:panelGrid>
</h:form>
</p:dialog>
Thanks

Change the properties of an Input within a ui:repeat

I'd like to change the "required" property of an InputText that is located within an ui:repeat, but I'm not able to access to the component from the ManagedBean:
<h:selectManyCheckbox id="required" value="#{test.required}"
layout="lineDirection" converter="javax.faces.Integer">
<f:ajax event="change" listener="#{test.update}" />
<f:selectItems value="#{test.selectable}"></f:selectItems>
</h:selectManyCheckbox>
<ui:repeat value="#{test.names}" var="name" id="repeat">
<h:panelGrid columns="3">
<h:outputLabel id="nameLabel">name:</h:outputLabel>
<h:inputText id="name" value="#{name}"
validator="#{test.validateName}" />
<h:message for="name"></h:message>
</h:panelGrid>
</ui:repeat>
I'm trying to use the findComponent method, but it does not work:
public void update(AjaxBehaviorEvent event) {
for(Integer i: selectable) {
UIViewRoot vr = FacesContext.getCurrentInstance().getViewRoot();
HtmlInputText input = (HtmlInputText)vr.findComponent("form:repeat:"+i+":name");
input.setRequired(required.contains(i));
}
}
The ui:repeat doesn't repeat the components in the view root, it repeats the component's output in the rendered HTML output.
There are several ways to achieve this properly. One of them is to use a value object instead and set the requireness there. E.g. a List<Item> wherein Item has the properties String name and boolean required.
<ui:repeat value="#{test.items}" var="item" id="repeat">
<h:panelGrid columns="3">
<h:outputLabel id="nameLabel">name:</h:outputLabel>
<h:inputText id="name" value="#{item.name}" required="#{item.required}" validator="#{test.validateName}" />
<h:message for="name"></h:message>
</h:panelGrid>
</ui:repeat>
There are more ways, but since the JSF version you're using and the functional requirement is unclear, it's only guessing which way is the most applicable in your case.

Resources