calendar value coming even if it is empty on change using JSF - jsf

I've a calendar tag on my xhtml, initially it has some value, and when I select the information using mouse and delete it, the change event still passes the old bean object data. How can I get it as null or empty
Here is my code
<p:calendar id="effDate" yearRange="c:c+1"
pattern="MM/dd/yyyy" styleClass="effDate"
style="box-shadow : inset 0 -1px 2px #8f8f8f;position:relative; left:20px;" immediate="true"
value="#{myBean.calDate}">
<f:convertDateTime pattern="MM/dd/yyyy" />
<p:ajax event="change" listener="#{myBean.onDateModified}" ></p:ajax>
</p:calendar>
How to achieve this?

Related

Primefaces Calendar Listener not affecting data to variable

I have two Datepicker/Calendar(Primefaces) , what I want to do is when I'll click on the second Calendar I'll call a Listener that will caclulate the days between the two dates. So this is what I've did:
Web Page
<a:column span="4" >
<a:label value="Begining Date" span="4" required="true" ></a:label>
<a:column span="8">
<p:calendar id="idBegDate" value="#{addController.enti.begDate}"
pattern="dd/MM/yyyy" label="Begining Date"
readonlyInput="true" locale="fr" navigator="true"
required="true" >
</p:calendar>
</a:column>
</a:column>
<a:column span="4" >
<a:label value="End Date" span="4" required="true" ></a:label>
<a:column span="8">
<p:calendar id="idDateFin" value="#{addController.enti.dateFinAbsAgt}"
pattern="dd/MM/yyyy" label="End Date"
readonlyInput="true" locale="fr" navigator="true"
required="true" >
<p:ajax event="dateSelect" listener="#{addController.doCalculate()}" update="jourCalendaire" />
</p:calendar>
</a:column>
</a:column>
Backing Bean
public void doCalculate()
{
//..Some Stuffs
}
The problem is that when the listener is called it says that the dateOfBegining is NULL while it shouldn't be.
I found the solution to this issue by adding an empty listener to the first calendar:
public void emptyListener()
{
}
I think this is not logical, so I want to know why the webpage/backingBean had this behavior ? Is there a way in which I can use only the listener of the second calendar ?
Thanks
On the p:ajax of the second calendar, you need to add process="#this idBegDate" so JSF knows to take the value of #this (the second calendar) and idBegDate (the first calendar) and put it into your model object.
Nothing from the view will come back to the server unless you process it. Adding a p:ajax to the first calendar processed it for you.

PrimeFaces dataTable filter by date

I'm using PrimeFaces 6.0.
My problem is when I'm trying to filter my dataTable by a date, it doesn't filter correctly all my lines.
Code
<p:column headerText="Target Date" filterMatchMode="contains" filterBy="#{myBean.targetDate}">
<f:facet name="filter">
<p:calendar pattern="MM/yy">
<p:ajax event="dateSelect" oncomplete="PF('dateTable').filter()"/>
</p:calendar>
</f:facet>
<h:outputText value="#{myBean.targetDate}">
<f:convertDateTime pattern="MM/yy"/>
</h:outputText>
This piece of code works partially. Actually, it doesn't show all the results it should be given.
When I select a date in the calendar, I want to filter by month and year ("MM/yy") without caring about the day.
How can I achieve this? Should I use a converter or my own filter method?
Thank you for your help.

JSF- <p:dataTable> issue with the Ajaxmethod

I am having a <p:dataTable> and In a row I am having an date field where I need to show dialogue to user whenever the user changes the date by systematically or by manually an Ajax method will called to update the message from backing bean.
Here is the code for that specific row that I am using.
<p:calendar value="#{dets.exceptionDueDate}" pattern="MM/dd/yyyy"
size="10" navigator="true"
rendered="#{systemDetailsBean.editCmdActionflg==true and (dets.firstColumn!='1' or dets.secondColumn!='1')}">
<f:convertDateTime pattern="MM/dd/yyyy" />
<p:ajax event="dateSelect"
listener="#{systemDetailsBean.showPopup}"
process="#this :SystemDetailsinfoForm:line :commentsform:commentsdt"
partialSubmit="true" />
<p:ajax event="change" listener="#{systemDetailsBean.showPopup}"
process="#this :SystemDetailsinfoForm:line :commentsform:commentsdt"
partialSubmit="true" />
<f:attribute name="index" value="_#{index}" />
<f:attribute name="componentId" value="exe" />
</p:calendar>
As you can see the calendar is calling two event methods namely "dateselect" and "change"
I have added two methods coz' the user may able to provide the date in both ways maually and systematically.
The Ajax method in the backing bean is given below
public void showPopup(ActionEvent event) {
String compId = (String) event.getComponent().getAttributes()
.get("componentId");
int index = Integer.parseInt(((String) event.getComponent()
.getAttributes().get("index")).replace("_", ""));
//Blah blah...
}
My problem is consider the <p:dataTable> is having 12 rows the when I change the date column in a specific row, the AjaxMethod is called for 12 times.So due to this I could not able to process some message in the Ajax method in the backing bean.
How can I able to restrict the calling of Ajax method for only one time,when I select a date column in a specific row.As you can see I can able to get the index of the row.
But I dont know how to restrict the method calling in XHTML.
Any suggestions will be really helpful to solve this issue.
I resolved this issue by replacing the "process" attribute with "update" attribute and I added "execute=#this" attribute.
Here is my updated code
<p:ajax event="dateSelect" execute="#this"
listener="#{systemDetailsBean.showPopup}"
update="#this :SystemDetailsinfoForm:line :commentsform:commentsdt"
partialSubmit="true" />
<p:ajax event="change" listener="#{systemDetailsBean.showPopup}" execute="#this"
update="#this :SystemDetailsinfoForm:line :commentsform:commentsdt"
partialSubmit="true" />

Allowing a certain range of dates dynamically in primefaces

I have used maxdate and mindate to select the dates dynamically for two date fields(from date and to date) using the below code-
<p:calendar id="FromDate" value="#{controller.fromDt}" showOn="button"
maxdate="#{controller.toDt}" >
<p:ajax event="dateSelect" update="ToDate"></p:ajax>
</p:calendar>
<p:calendar id="ToDate" value="#{controller.toDt}" showOn="button"
mindate="#{controller.fromDt}">
<p:ajax event="dateSelect" update="FromDate"></p:ajax>
</p:calendar>
Everything seems to work fine if a date is selected. The restrictions are applied to the other dependent calendar. Like if fromDate is set, then restrictions are applied to the todate. But once the fromdate is deleted using backspace or delete, still the restrictions are there in toDate field.
I understand that when the date is deleted, then it is not a dateSelect event, but even trying to place a valueChange event won't work because valueChangeEvent is triggered only when the page is submitted.
Can someone suggest me an idea how to solve this. Thanks in advance.
Simply add another p:ajax with a change event.
<p:calendar id="FromDate" value="#{controller.fromDt}" showOn="button"
maxdate="#{controller.toDt}" >
<p:ajax event="dateSelect" update="ToDate"></p:ajax>
<p:ajax event="change" update="ToDate"></p:ajax>
</p:calendar>

How update just specific cell in primefaces dataTable

I'm creating a dynamic datatable full of input fields. Sometimes when user insert values in some inputs, an specific cell should be updated, and only this cell. I thought it could be simple, but yet didn't make it work.
The cell I want update is "valor total", this cell should be updated when the value of two others cell change:
EDITED
I've tryied f:ajax with complete id and got "Component with id:lancamentoNF:popupLancamentoNF:tabelaItensNF:0:valorTotalItem not found". Changed to p:ajax and no errors happen but it doesn't update!!
<h:panelGroup id="painelItensNF" layout="block" styleClass="hrgi-div-form aba-lancamento-nf clearfix" style="overflow:auto;">
<h:panelGroup layout="block" style="width: 1700px;">
<p:dataTable id="tabelaItensNF" value="#{modeloTabelaDinamicaItemNF.itens}" var="itemEmbrulhado" styleClass="tabelaDinamica" height="174" style="width: 100%;" rowIndexVar="indice">
... (some columns)
<p:column style="width: 5%"
headerText="quantidade">
<hrgi:spinner id="quantidadeItem"
value="#{itemEmbrulhado.item.produto.detalheTributavel.quantidade}"
dinheiro="false"
fator="#{itemEmbrulhado.item.produto.detalheTributavel.unidadeFracionada?0.01:1}"
local="pt-BR" min="0.00" width="70">
<p:ajax event="change"
update="lancamentoNF:popupLancamentoNF:tabelaItensNF:#{indice}:valorTotalItem"
listener="#{controladorPopupLancamentoNF.calcularValorTotalItem(itemEmbrulhado)}" global="false" />
<f:convertNumber
maxFractionDigits="#{itemEmbrulhado.item.produto.detalheTributavel.unidadeFracionada?2:0}"
minFractionDigits="#{itemEmbrulhado.item.produto.detalheTributavel.unidadeFracionada?2:0}"
locale="pt-BR"
for="quantidadeItem"/>
</hrgi:spinner>
</p:column>
<p:column style="width: 5%"
headerText="valor unitario">
<hrgi:spinner id="valorUnitarioItem"
value="#{itemEmbrulhado.item.produto.detalheTributavel.valorUnitario}"
dinheiro="true" fator="0.01" local="pt-BR" min="0.00" width="70">
<p:ajax event="change"
update="lancamentoNF:popupLancamentoNF:tabelaItensNF:#{indice}:valorTotalItem"
listener="#{controladorPopupLancamentoNF.calcularValorTotalItem(itemEmbrulhado)}" global="false"/>
<f:convertNumber type="currency" currencyCode="BRL" currencySymbol="R$ "
maxFractionDigits="10" minFractionDigits="2" locale="#{cc.attrs.local}"
for="valorUnitarioItem"/>
</hrgi:spinner>
</p:column>
<p:column style="width: 3%"
headerText="valor total">
<h:outputText id="valorTotalItem" value="#{itemEmbrulhado.item.produto.valorTotal}">
<f:convertNumber type="currency" currencyCode="BRL" currencySymbol="R$ "
maxFractionDigits="2" minFractionDigits="2" locale="pt-BR"
for="valorUnitarioItem"/>
</h:outputText>
</p:column>
... (more columns)
</p:dataTable>
</h:panelGroup>
</h:panelGroup>
It works when I update the panelGroup "painelItensNF" with complete id, but the focus is lost and user should find the input he was working to continue...
Just use update="valorTotalItem". It's relative to the current row already.
So, replace
<p:ajax ... update="lancamentoNF:popupLancamentoNF:tabelaItensNF:#{indice}:valorTotalItem" />
by
<p:ajax ... update="valorTotalItem" />
I don't think it's possible to update a single cell. It's id is autogenerated, so you can't update this component by id.
You can try switching to primefaces 3.3 (not final release yet, but you can start working with the snapshot), and try if you can do what you want using primefaces selectors: http://www.primefaces.org/showcase-labs/ui/selectors.jsf
you'll have more changes with that, but I'm not sure if you'll be able to do it.
Or, you could update the panel and add some javascript to set the focus to the appropiate component. execute the javascript in the "oncomplete" method of the p:ajax component.
EDIT:
Remove the index from the update, so it looks like this: ":lancamentoNF:popupLancamentoNF:tabelaItensNF:valorTotalItem"
And of course BalusC is right, you may also just use "valorTotalItem"

Resources