jsf validator bean values in parameter lost - validation

<h:dataTable value="#{products.getAllProducts()}"
var="product">
....
<h:column rendered="...">
<f:facet name="header">Quantity</f:facet>
<h:inputText id="basket-qty" value="#{basket.qty}" rendered="#{product.stock.qty > 0}" >
<f:convertNumber integerOnly="true" />
<f:validateLongRange minimum="1" maximum="#{product.stock.qty}" />
</h:inputText>
<h:message id="textmessage" for="basket-qty" />
</h:column>
<h:column rendered="...">
<h:commandButton action="#{basket.addProduct(product)}"
value ="Add to Basket">
</h:commandButton>
</h:column>
</h:dataTable>
Basically the problem is that maximum="#{product.stock.qty}" is evaluating to zero, therefore my range is 0-0?
product.stock.qty evaluates correctly elsewhere in the table.

Related

Update the JSF bean even if the validation fails?

JSF beans are generally not updated when the validation fails, which in some cases causes really ugly effects, for example, when using facet="output" of p:inplace:
<h:form>
<h:panelGrid id="panel" columns="3" cellpadding="2">
<p:outputLabel value="My Field" for="myfield" />
<p:inputText id="myfield" value="#{test.myField}" required="true" />
<p:message for="myfield" />
<h:outputText value="Checkbox: " />
<p:inplace id="checkboxInplace" effect="none">
<f:facet name="output">#{test.myBooleanText}</f:facet>
<f:facet name="input">
<h:selectBooleanCheckbox value="#{test.myBoolean}" />
</f:facet>
</p:inplace>
<p:spacer />
</h:panelGrid>
<p:commandButton id="refresh" icon="ui-icon-refresh" update="panel" process="#form"/>
</h:form>
The output facet defines the inplace labels, which should be localized instead of standard ones:
private boolean myBoolean;
public String getMyBooleanText() {
return myBoolean ? "Ja" : "Nein";
}
However, when the validation fails, the inplace output facet shows the old value of the checkbox, not the actual one. If you click on it, a real value is shown.
How to solve that issue and actualize the output correctly? Submiting the values to the bean would be the best, because I have no problem with consistent state of values on the client and server, as long no action is actually executed (asserted by the validation).
Haven't tried it myself, but give this a chance:
<p:inplace id="checkboxInplace" effect="none">
<f:facet name="output">#{test.myBoolean ? 'Ja' : 'Nein'}</f:facet>
<f:facet name="input">
<h:selectBooleanCheckbox value="#{test.myBoolean}" immediate="true">
<p:ajax update="#parent" />
<h:selectBooleanCheckbox />
</f:facet>
</p:inplace>

How do I display error message for each h:inputText inside h:dataTable?

I need to display error messages after validation has failed for each h:inputText inside h:dataTable. Here is the code:
<h:dataTable value="#{myBean.dataList}" var="dataItem">
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:inputText id="name" value="#{dataItem.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Value" />
</f:facet>
<h:inputText id="value" value="#{dataItem.value}" />
</h:column>
</h:dataTable>
When I tried to put:
<h:inputText id="name" value="#{dataItem.name}" />
<h:message for="name"/>
It returns:
Caused by: java.lang.NullPointerException
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.augmentIdReference(HtmlBasicRenderer.java:196)
Try the following.
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:inputText id="name" value="#{dataItem.name}" required="true" requiredMessage="Mandatory"/>
<h:message for="name" id="msg"/>
</h:column>
You haven't bound your <h:message></h:message> to your <h:inputText></h:inputText>. I have simply made the <h:inputText></h:inputText> to be a mandatory field. You may need to use some validators as and when required to suit your requirements.
You seem to be using a Mojarra 1.2 version older than 1.2_14. This is known as issue 941 which is been fixed in 1.2_14. The currently latest Mojarra 1.2 is 1.2_15. You can download it here. Replace both the jsf-api.jar and jsf-impl.jar and you should be all set. Your code is fine, by the way.

PrimeFaces dataTable doesn''t render when exists binding attribute

I'm creating a dataTable with two dataTable inside :).
But this time I'm having problem to render it when I try use binding attribute in a h:panelGroup that wraps first dataTable.
I'm using binding to help refresh just the panelGroup, like BalusC told in this question. When I remove the binding attribute the dataTable renders normally, but of course nothing is rendered with f:ajax tags inside the dataTables.
Here is the xhtml:
<ui:component>
<h:panelGroup>
<h:panelGroup layout="block;" id="#{id}"
binding="#{painelTabelaContatos}" rendered="true">
<p:dataTable id="tabela#{id}"
value="#{modeloTabelaContatos.listaDeContatos}" var="contato"
selectionMode="single"
rowSelectListener="#{controladorTabelaContatos.processarSelecaoLinha}"
rowUnselectListener="#{controladorTabelaContatos.processarDeselecaoLinha}"
selection="#{modeloTabelaContatos.contatoSelecionado}">
<p:column headerText="Contatos">
<hrgi:editableText style="width:100%" value="#{contato.descricao}" />
</p:column>
<p:column headerText="Telefones">
<h:dataTable value="#{contato.telefones}" var="telefone">
<h:column>
<h:inputText value="#{telefone}" />
</h:column>
<h:column>
<h:graphicImage library="img" name="default_trash.png"
style="cursor:pointer;">
<f:ajax event="click" render=":#{painelTabelaContatos.clientId}"
listener="#{controladorTabelaContatos.removerTelefone(contato, telefone)}" />
</h:graphicImage>
</h:column>
</h:dataTable>
</p:column>
<p:column headerText="e-mails">
<h:dataTable value="#{contato.emails}" var="email">
<h:column>
<h:inputText value="#{email}" />
</h:column>
<h:column>
<h:graphicImage library="img" name="default_trash.png"
style="cursor:pointer;">
<f:ajax event="click" render=":#{painelTabelaContatos.clientId}"
listener="#{controladorTabelaContatos.removerEmail(contato, email)}" />
</h:graphicImage>
</h:column>
</h:dataTable>
</p:column>
<p:column>
<h:graphicImage library="img" name="default_trash.png"
style="cursor:pointer;">
<f:ajax render=":#{painelTabelaContatos.clientId}" event="click"
listener="#{controladorTabelaContatos.removerContato(contato)}" />
</h:graphicImage>
</p:column>
</p:dataTable>
</h:panelGroup>
<h:panelGroup layout="block">
<p:commandButton value="ADICIONAR CONTATO" update="#{id}"
immediate="true"
action="#{controladorTabelaContatos.adicionarContato}" />
<p:commandButton value="ADICIONAR TELEFONE" update="#{id}"
immediate="true"
action="#{controladorTabelaContatos.adicionarTelefone}" />
<p:commandButton value="ADICIONAR E-MAIL" update="#{id}"
immediate="true"
action="#{controladorTabelaContatos.adicionarEmail}" />
</h:panelGroup>
</h:panelGroup>
</ui:component>
I've already tried remove the h:dataTables that are inside p:dataTable, but without success.
This component is just the content of a PrimeFaces tab, and this tab is inside a PrimeFaces dialog. Could someone explain me why is this happening??
I've found the cause of error, after it was easy find a solution...
The problem is caused because I call this component in two different pages:
popupCadastroPessoa.xhtml
<ui:include src="../tabs/abaEdicaoContatos.xhtml">
<ui:param name="id" value="painelContatoPessoa" />
</ui:include>
and in popupCadastroFuncionario.xhtml
<ui:include src="../tabs/abaEdicaoContatos.xhtml">
<ui:param name="id" value="painelContatoFuncionario" />
</ui:include>
cause I didn't really created the binding bean, JSF gets confused. So I've just created two UIPanel beans and passed it as parameter:
<ui:include src="../tabs/abaEdicaoContatos.xhtml">
<ui:param name="id" value="painelContatoPessoa" />
<ui:param name="painelTabelaContatos" value="#{bindingTabelaContatoPessoa}"/>
</ui:include>
Was my fault. Thanks for your attention and sorry for the inconvenience.

richfaces data-table error

I am new to richfaces.
I have a problem with rich:datatable filtering, the source code of my page is like the site example:
<h:form id="form">
<rich:dataTable keepSaved="true" id="richTable" var="record" value="#{citiesBean}" rows="20">
<rich:column >
<f:facet name="header">
<h:commandLink action="#{bean.toggleSort}">
#{bean.sortOrders['cityTitle']}
<a4j:ajax render="richTable" />
<f:setPropertyActionListener target="#{bean.sortProperty}" value="#{'cityTitle'}" />
</h:commandLink>
<br />
<h:inputText value="#{citiesBean.filterValues['cityTitle']}">
<a4j:ajax render="richTable#body scroller" event="keyup" />
</h:inputText>
</f:facet>
<h:outputText value="#{record['cityTitle']}" />
</rich:column>
<rich:column >
<f:facet name="header">
<h:commandLink action="#{bean.toggleSort}">
#{bean.sortOrders['cityCode']}
<a4j:ajax render="richTable" />
<f:setPropertyActionListener target="#{bean.sortProperty}" value="#{'cityCode'}" />
</h:commandLink>
<br />
<h:inputText value="#{citiesBean.filterValues['cityCode']}">
<a4j:ajax render="richTable#body scroller" event="keyup" />
</h:inputText>
</f:facet>
<h:outputText value="#{record['cityCode']}" />
</rich:column>
<f:facet name="footer">
<rich:dataScroller id="scroller" />
</f:facet>
</rich:dataTable>
</h:form>
everything seems OK but it has some problems.
1- datascroller does not work without render attribute set to 'richTable' but it works on demo!!!
2-when i type something on filter input, the table does not get updated!, i have checked the request and response on firebug,
the response does not have a valid id, i mean it look like this:
<update id="form:richTable:tb"><tbody id="form:richTable:0:tb" ....
what is wrong with my codes?!
I am using, richfaces 4, Glassfish 3.1, Firefox 3.6
thanks in advance.
I think it was a kind of bug. Now it is fine with version 4.1 M1.

How to re-render <ui:repeat> using <f:ajax render>

I have implemented a list created by a repeater:
<ui:repeat value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
and a Button that filters my list:
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
</h:commandLink>
So, is there an easy way to render only my repeater after clicking the command link (with AJAX) :-)
I tried following:
<f:ajax render="repeater">
ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<f:ajax />
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax event="click" render="repeater"/>
</h:commandLink>
but that did not work..
Update
<h:form>
ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax event="click" render="repeater"/>
</h:commandLink>
</h:form>
doesn't work either... Maybe I hav to put the action method (overviewController.filterNew) into the ajax tag?
Update 2
<f:ajax event="click" render="repeater">
<h:commandLink action="#{overviewController.filterEBus}">
<h:outputText value="EBusiness" />
</h:commandLink>
</f:ajax>
Doesn't work either!
Maybe it's not possible to rerender a repeater ? is there another element like a div tag or something that can be rerendered???
...
Thank you for your help
The <ui:repeat> itself does not generate any HTML to the output. The <f:ajax render> expects an ID which is present in the HTML DOM tree. Put it in a <h:panelGroup> with an id and reference it instead.
<h:form>
<h:panelGroup id="projects">
<ui:repeat value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
</h:panelGroup>
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax execute="#form" render="projects" />
</h:commandLink>
</h:form>
Yes:
using Richfaces <a4j:commandButton reRender="targetId" />
using JSF 2.0 <f:ajax event="click" render="targetId">
using Primefaces <p:ajax>
<f:ajax render="repeater">
ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<f:ajax />
why did you wrap it with f:ajax? It's redundant in this case.
Make sure that your components are surrounded by <h:form> tag
<h:form>
<ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax event="click" render="repeater"/>
</h:commandLink>
</h:form>
How about this:
<ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<h:commandLink>
<h:outputText value="Filter List" />
<f:ajax render="repeater" listener="#{overviewController.filterNew}" />
</h:commandLink>

Resources