I have a page that has some options at the top that when changed updates some chart on the same page. Here is the relevant filters part:
<p:fieldset id="filtrosDashboard" legend="Filtros" toggleable="true" toggleSpeed="500" collapsed="#{beanJanela.filtroCollapsed}">
<!--Site filter-->
<div class="ui-g-12 ui-md-12 ui-lg-8">
<p:outputLabel for="ObrasPickList" value="#{beanJanela.tituloLabelSelecaoObrasFiltro}" styleClass="tituloFiltro"/>
<p:pickList id="ObrasPickList" value="#{beanJanela.obras}" var="obra" effect="slide"
itemValue="#{obra}" itemLabel="#{obra.descricao}"
showSourceFilter="true" showTargetFilter="true" showCheckbox="true"
filterMatchMode="contains" converter="obraConverter" responsive="true"
addLabel="Adicionar" addAllLabel="Adicionar tudo"
removeLabel="Remover" removeAllLabel="Remover tudo"
rendered="#{beanJanela.showMultiplasObrasFiltro}">
<f:facet name="sourceCaption">Obras</f:facet>
<f:facet name="targetCaption">Selecionadas</f:facet>
<p:ajax event="transfer" listener="#{beanJanela.atualizaGraficos}" update="@form"/>
<p:column style="width: 92%">
<h:outputText value="#{obra.descricao}" />
</p:column>
</p:pickList>
</div>
<!--Date filter-->
<div class="ui-g-12 ui-md-12 ui-lg-4">
<p:outputLabel for="periodo" value="Período" styleClass="tituloFiltro" rendered="#{beanJanela.showPeriodoFiltro}"/>
<div class="ui-inputgroup">
<p:inputText id="periodo" value="#{beanJanela.periodo}" rendered="#{beanJanela.showPeriodoFiltro}">
<p:ajax event="change" listener="#{beanJanela.atualizaGraficos}" update="@form"/>
</p:inputText>
<span class="ui-inputgroup-addon"><i class="fa fa-fw fa-calendar"></i></span>
</div>
</div>
</p:fieldset>
As you can see there are two filters, one is a pickList with working sites and the other is a inputText that is transformed into a data range picker using a javascript library called daterangepicker.
I defined one <p:ajax/> with the event transfer for the pickList and another <p:ajax/> with the event change for the inputText, the both call the same listener #{beanJanela.atualizaGraficos} and they both update the form that contains the filters and the graphs.
The problem is the following, when I use the pickList it works as expected, the method atualizaGraficos is called on the backing bean only once; however, if I try to filter using the date filter, the method atualizaGraficos is called twice.
Why does this happen? I've seen some other posts relating problems similar to this one, but in my case I have two ajax calls with two different events on two different components inside the same form.
Here is the full page code in case it is needed:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:po="http://primefaces.org/omega">
<h:head>
<f:facet name="first">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta http-equiv="refresh" content="#{session.maxInactiveInterval};url=#{request.contextPath}/index.xhtml"/>
<title>Evop</title>
</f:facet>
<link rel="shortcut icon" type="image/png" href="/evop/resources/imagem/icone_evop.png"/>
<script type="text/javascript">
$(document).ready(function () {
$("form").bind("keypress", function (e) {
if (e.keyCode === 13) {
return false;
}
});
});
$(document).ready(function () {
$(window).keydown(function (event) {
if (event.keyCode === 13) {
return false;
}
});
});
</script>
<h:outputScript name="js/nanoscroller.js" library="resources" />
<h:outputScript name="js/layout.js" library="resources" />
<h:outputScript name="js/script.js" library="resources" />
<h:outputScript name="js/all.js" library="font-awesome" />
<h:outputStylesheet name="css/layout.css" library="resources" />
<h:outputStylesheet name="css/primeflex.css" library="resources" />
<h:outputStylesheet name="css/animate.css" library="resources" />
<h:outputStylesheet name="css/nanoscroller.css" library="resources" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
<h:outputStylesheet name="css/all.css" library="font-awesome"/>
<h:outputStylesheet name="css/styleCadastro.css" library="resources"/>
<h:outputStylesheet name="css/styleDashboards.css" library="resources"/>
<ui:insert name="head"/>
</h:head>
<h:body styleClass="main-body">
<div class="wrapper">
<div class="topbar clearfix">
<a id="omega-menu-button" href="#">
<span class="fa fa-bars"></span>
</a>
<span class="topbar-title">Dashboard</span>
</div>
<h:form id="menuform">
<div class="sidebar">
<div class="nano">
<div class="nano-content sidebar-scroll-content menu-flex">
<!--MENU-->
</div>
</div>
</div>
</h:form>
<div class="main">
<ui:param name="beanJanela" value="#{comprasDashboardsBean}" />
<h:form id="dashboardCompras" prependId="false">
<p:growl id="growl" showDetail="true" showSummary="true" sticky="false" escape="false"><p:autoUpdate/></p:growl>
<div style="margin-top: 15px;">
<div class="ui-g ui-g-fluid dashboard">
<!--Filterns-->
<div class="ui-g-12 filtro_obras filtro_obras2">
<div class="filtro_card clearfix chatSummary">
<p:fieldset id="filtrosDashboard" legend="Filtros" toggleable="true" toggleSpeed="500" collapsed="#{beanJanela.filtroCollapsed}">
<!--Site filter-->
<div class="ui-g-12 ui-md-12 ui-lg-8">
<p:outputLabel for="ObrasPickList" value="#{beanJanela.tituloLabelSelecaoObrasFiltro}" styleClass="tituloFiltro"/>
<p:pickList id="ObrasPickList" value="#{beanJanela.obras}" var="obra" effect="slide"
itemValue="#{obra}" itemLabel="#{obra.descricao}"
showSourceFilter="true" showTargetFilter="true" showCheckbox="true"
filterMatchMode="contains" converter="obraConverter" responsive="true"
addLabel="Adicionar" addAllLabel="Adicionar tudo"
removeLabel="Remover" removeAllLabel="Remover tudo"
rendered="#{beanJanela.showMultiplasObrasFiltro}">
<f:facet name="sourceCaption">Obras</f:facet>
<f:facet name="targetCaption">Selecionadas</f:facet>
<p:ajax event="transfer" listener="#{beanJanela.atualizaGraficos}" update="@form"/>
<p:column style="width: 92%">
<h:outputText value="#{obra.descricao}" />
</p:column>
</p:pickList>
</div>
<!--Date filter-->
<div class="ui-g-12 ui-md-12 ui-lg-4">
<p:outputLabel for="periodo" value="Período" styleClass="tituloFiltro" rendered="#{beanJanela.showPeriodoFiltro}"/>
<div class="ui-inputgroup">
<p:inputText id="periodo" value="#{beanJanela.periodo}" rendered="#{beanJanela.showPeriodoFiltro}">
<p:ajax event="change" listener="#{beanJanela.atualizaGraficos}" update="@form"/>
</p:inputText>
<span class="ui-inputgroup-addon"><i class="fa fa-fw fa-calendar"></i></span>
</div>
</div>
</p:fieldset>
</div>
</div>
<!--End of filters-->
<!-- SOME GRAPHS THAT ARE UPDATED WHEN THE FILTER CHANGES -->
<!-- SCRIPTS FOR THE DATE FILTER -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<h:outputScript name="js/dashboardExtender.js" library="resources" />
<script>
$(document).ready(function () {
var start = moment().subtract(29, 'days');
var end = moment();
function cb(start, end) {
$('#periodo').text(start.format('L') + ' - ' + end.format('L'));
}
$("#periodo").daterangepicker({
startDate: start,
endDate: end,
"locale": {
"format": "DD/MM/YYYY",
"separator": " - ",
"applyLabel": "Salvar",
"cancelLabel": "Cancelar",
"fromLabel": "De",
"toLabel": "Para",
"customRangeLabel": "Definir Período",
"weekLabel": "S",
"daysOfWeek": [
"Dom",
"Seg",
"Ter",
"Qua",
"Qui",
"Sex",
"Sab"
],
"monthNames": [
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro"
],
"firstDay": 1
},
ranges: {
'Últimos 7 Dias': [moment().subtract(6, 'days'), moment()],
'Últimos 15 Dias': [moment().subtract(14, 'days'), moment()],
'Últimos 30 Dias': [moment().subtract(29, 'days'), moment()],
'Esse Mês': [moment().startOf('month'), moment().endOf('month')],
'Último Mês': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
}, cb);
cb(start, end);
});
</script>
</div>
</div>
</h:form>
</div>
</div>
<p:ajaxStatus onstart="PF('statusDialog').show();" oncomplete="PF('statusDialog').hide();">
<p:dialog widgetVar="statusDialog"
modal="true"
draggable="false"
closable="false"
resizable="false"
showHeader="false"
style="margin: 0; padding: 0;">
<p:graphicImage name="/imagem/ajax-loader.gif" />
</p:dialog>
</p:ajaxStatus>
</h:body>