<a4j:commandLink> its not calling the action - jsf-2

i am trying to create a link to the newly created record, and the link i am including inside the success message panel after successful creation of the link, But i am unable to call the action using tag.
following is my peace of code:
<div class="panel-success">
<a4j:outputPanel id="succes_submit">
<rich:notify stayTime="1000" rendered="#{user.accountsSaved}"
styleClass="panel-success fsgui-input-panel-success">
<f:facet name="summary">
<a4j:commandLink ajaxSingle="true" action="#{user.metod}"
value="#{user.accSeriesInfo.number} :"oncomplete="#{rich:component('details-update')}.show();">
<f:setPropertyActionListener target="#{orgseries.accSeriesInfo}" value="#{dataItem}" />
</a4j:commandLink>
<h:outputText value="Record updated successfully "></h:outputText>
</f:facet>
</rich:notify>
</a4j:outputPanel>
</div>
instead of a4j:commandLink i tried with h:commandLink here i am able to call the action but unable to render or perform onComplete operations.
Can any body tell me where is the mistake,
Thanks in advance.

I found the solution to include the link in rich:notify tag
<div class="panel-success" id="success_submit_div">
<a4j:outputPanel id="stru_succes_submit">
<rich:notify stayTime="1000" rendered="#{emp.saveSuccess}">
<f:facet name="summary">
<h:form>
<a4j:commandLink immediate="true" action="#{emp.getInfo}" value="# {emp.empId}:" oncomplete="#{rich:component('edit-Emp-Details')}.show();">
</a4j:commandLink>
<h:outputText value="#{ isEdit ? messages['common.app.save.success'] : messages['employee.create.success']}"></h:outputText>
</h:form>
</f:facet>
</rich:notify>
</a4j:outputPanel>
</div>

Related

DataTable clearFilter() not working properly

I have a complicate JSF that contain dataTable with filter in each one of the columns.
In order to make sure that the generate button will fetch all the data first I need to clear all the filters when the user press the button.
I try to do use onclick but then I couldn’t see the blockUI I also try on complete (ajax) but again it was not working properly with all the other items (blockUI ,message).
I decided to try to clear the filters via server side but only dataTable.reset() is working.
I have no more ideas how to clean the filters ???
Is this API working ?
Appreciate your help
Thanks
<h:panelGrid columns="1" style="width: 100%">
<p:panel id="vt-panel">
<h:panelGrid columns="5" cellpadding="2" >
<h:outputText value="Start Date" />
<p:calendar id="vt-start" value="#{vtRepBean.startDate}" binding="#{startDateComponent}" maxlength="9" size="9" pattern="dd-MMM-yy" title="dd-MMM-yy" required="true" maxdate="#{vtRepBean.endDate}">
<p:ajax event="dateSelect" listener="#{vtRepBean.handleStartDateSelect}" update=":mainForm:vt-end"/>
</p:calendar>
<h:outputText value="End Date" />
<p:calendar id="vt-end" value="#{vtRepBean.endDate}" maxlength="9" size="9" pattern="dd-MMM-yy" title="dd-MMM-yy" required="true" mindate="#{vtRepBean.startDate}">
<p:ajax event="dateSelect" listener="#{vtRepBean.handleEndDateSelect}" update=":mainForm:vt-start"/>
</p:calendar>
<p:commandButton
id="genVtBtn"
value="Generate"
actionListener="#{vtRepBean.handleVTGenerateButton}"
update=":mainForm:vt-panel,:mainForm:vt-panel-table">
</p:commandButton>
</h:panelGrid>
</p:panel>
</h:panelGrid>
<p:growl id="vt_message" showDetail="true" autoUpdate="true"/>
<h:panelGroup id="vt-panel-table">
<p:dataTable id="vtDataTable"
widgetVar="vtWidget"
var="reportObject"
value="#{vtRepBean.reportObjectsList}"
rendered="#{vtRepBean.renderVTReport}"
filteredValue="#{vtRepBean.filteredVTList}"
paginator="true"
paginatorPosition="bottom"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="50,100,200"
rows="50"
style="width: 100%">
<p:columnGroup type="header">
<p:row>
<p:column colspan="5" headerText="VT request"/>
<p:column colspan="1" headerText="Dis" />
</p:row>
<p:row>
<p:column headerText="CREATE DATE" sortBy="#{reportObject.log.createDate}" filterBy="#{reportObject.log.createDate}" filterMatchMode="contains"/>
<p:column headerText="IP" sortBy="#{reportObject.log.ip}" filterBy="#{reportObject.log.ip}" filterMatchMode="contains"/>
</p:row>
</p:columnGroup>
<p:column >
<h:outputText value="#{reportObject.log.createDate}"/>
</p:column>
<p:column >
<h:outputText value="#{reportObject.log.ip}"/>
</p:column>
</p:dataTable>
<p:commandLink rendered="#{vtRepBean.renderVTReport}" ajax="false" onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)">
<p:graphicImage value="resources/images/excel.png" title="excel" style="border-color: white"/>
<p:dataExporter id="xlsReport"
type="xls"
target="vtDataTable"
fileName="VTReport"
postProcessor="#{vtRepBean.postProcessXLS}"/>
</p:commandLink>
</h:panelGroup>
<p:blockUI widgetVar="blockVTPanel" trigger="genvtBtn" block="vt-panel">
<div class="disable-scroll">
<p:graphicImage value="resources/images/ajax-loader.gif"/>
</div>
</p:blockUI>
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:vtDecomDataTable");
if (!dataTable.getFilters().isEmpty()) {
logger.info("dataTable.getFilters().isEmpty() :" + dataTable.getFilters().isEmpty());
dataTable.getFilters().clear();// not working
dataTable.getFilteredValue().clear();// not working
dataTable.setFilteredValue(null);// not working
dataTable.setFilters(null);// not working
dataTable.setFilterMetadata(null);// not working
dataTable.reset();// working
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("mainForm:vtDecomDataTable");
}
To clear all the inputs of the filters you can do it by javascript:
<p:commandButton onclick="PF('vtWidget').clearFilters()" />
vtWidget is the widgetVar of the datatable.
Basically clearFilters() will clear the fields for you and call filter(), and the filter function would update your datatable, which in turns will empty the filtered list.
Note: This would work only if the filters were inputText. If you have custom components then you should implement your own clear based on the components that you have.
Sometimes if you have custom components, you need to empty the filtered list manually, as you did in the comments!
This is how i solved my problem.
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.execute("PF('widget_orderDataTable').clearFilters()");
Hope its help.
For clearing custom filters you can use primefaces resetInput, along with clearFilters() discussed in other answers, and a custom actionListener method. See code snippets below:
<p:dataTable id="dataTable" widgetVar="dataTable"
value="#{bean.listOfObjects}" var="object">
<p:commandButton value="Clear All Filters"
onclick="PF('dataTable').clearFilters()"
actionListener="#{controller.clearAllFilters}"
update="dataTable">
<p:resetInput target="dataTable" />
</p:commandButton>
Controller.java
public void clearAllFilters() {
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("form:dataTable");
if (!dataTable.getFilters().isEmpty()) {
dataTable.reset();
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.update("form:dataTable");
}
}
I hope this helps anyone looking to clear custom filters.
For Primefaces 7 and above, use the following:
public void clearAllFilters() {
DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("form:dataTable");
if (!dataTable.getFilters().isEmpty()) {
dataTable.reset();
PrimeFaces.current().ajax().update("form:dataTable");
}
}

How to fetch validation error messages using FacesContext?

My xhtml contains input fields, where user can input numeric or alphabet values. Using an ajax call I am validating the input value and throwing a validation error on the . But even after entering invalid characters and error message, user may still hit the 'Save' button. Once the user hits the Save button it triggers a method in the Controller. Is there a way I can check for validation errors on p:messages inside the controller using the FacesContext.getCurrentInstance().
xhtml code
<!-- Messages -->
<p:messages id="errorMessages" globalOnly="false" showDetail="true" showSummary="false" closable="true" />
<!-- Column input field-->
<p:column>
<f:facet name="header">
<h:outputText value="Input Amount" escape="false" />
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{row.amount}" escape="false">
<f:convertNumber maxFractionDigits="3" minFractionDigits="3"
maxIntegerDigits="5" />
</h:outputText>
</f:facet>
<f:facet name="input">
<p:inputText id="input" value="#{row.amount}" maxlength="10"
size="10">
<f:convertNumber maxFractionDigits="3" minFractionDigits="3"
maxIntegerDigits="5" />
<f:validator validatorId="hourlyValueValidator" for="input" />
<p:ajax event="change" partialSubmit="true" process="input"
update=":#{p:component('errorMessages')}" />
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<!-- Save Button -->
<p:commandButton id="btnSubmit" value="Save"
update=":#{p:component('tblScrollPnl')} :#{p:component('errorMessages')}"
action="#{controller.saveValues()}" ajax="true" />
Controller in ViewScope
public void saveValues() throws Exception {
FacesContext context = FacesContext.getCurrentInstance();
List<FacesMessage> errorMsgList = context.getMessageList("globalMessages");
......
......
......
}
You don't need to get messages from the bean side for validation, as you experienced, view side validation occur but doesn't block your action.
There is couple of thing wrongs in your view, to fix your problem you need to change the process attribute of your p:commandButton, ortherwise only the button is processed (by default process="#this", so the validation is skipped.
<p:commandButton id="btnSubmit" value="Save" process="#form" update=":tblScrollPnl :errorMessages" action="#{controller.saveValues()}" />
Also note that I've removed ajax="true" since it is by default and fixed major problems in update="".
You should also rearrange your validators :
<p:inputText id="input" value="#{row.amount}" maxlength="10" size="10" validator="hourlyValueValidator">
<f:convertNumber maxFractionDigits="3" minFractionDigits="3" maxIntegerDigits="5" />
</p:inputText>

PrimeFaces second dialog window not opening from first dialog

I have a issue trying to open a second dialog from the first dialog. The first dialog opens fine but the second dialog does not seem to open at all. I have tried with the form tag inside and outside of the dialog but get neither seems to open the dialog. On clicking the OPen dialog button from the first nothing seems to happen. I am using PrimeFaces 3.5.
Code for dialog is as below
<p:dialog id="dialog" header="New Submission" widgetVar="dlg" resizable="false" modal="true" closable="true">
<h:form id="createDialogForm">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="projectDropDown" value="Project:" />
<h:selectOneMenu id="projectDropDown" value="#{newSubmissionBean.submission.project}" required="true">
<f:selectItem itemLabel="Choose project" noSelectionOption="true" />
<f:selectItems value="#{newSubmissionBean.projectEntities}" var="project" itemLabel="#{project.name}" itemValue="#{project}" />
</h:selectOneMenu>
<f:facet name="footer">
<p:commandButton id="createButton" value="Create" update=":newSubmissionForm :createDialogForm"
actionListener="#{newSubmissionBean.createSubmission}"
oncomplete="handleRequest(xhr, status, args)"
/>
<p:commandButton id="chooseBatchButton" value="OPen dialog" update=":batchChooserForm"
actionListener="#{newSubmissionBean.fetchAvailability}" />
</f:facet>
</h:panelGrid>
</h:form>
</p:dialog>
<p:dialog id="batchDialog" header="Batch Chooser" widgetVar="bdlg" resizable="false" modal="true" closable="true">
<h:form id="batchChooserForm">
<p:fieldset legend="#{messages['label.legend.sample.available']}">
<p:dataTable id="availableSamples" var="sample" value="#{newSubmissionBean.availableSamples}">
<p:column style="width:20px">
<h:outputText id="dragIcon"
styleClass="ui-icon ui-icon-arrow-4" />
<p:draggable for="dragIcon" revert="true" />
</p:column>
<p:column headerText="#{messages['label.sample.batch']}">
<h:outputText value="#{sample.sampleId}" />
</p:column>
</p:dataTable>
</p:fieldset>
<p:fieldset id="selectedSamples" legend="#{messages['label.legend.sample.selected']}" style="margin-top:20px">
<p:outputPanel id="dropArea">
<h:outputText value="#{messages['label.drop.text']}"
rendered="#{empty newSubmissionBean.selectedSamples}"
style="font-size:24px;" />
<p:dataTable var="sample" value="#{newSubmissionBean.selectedSamples}"
rendered="#{not empty newSubmissionBean.selectedSamples}">
<p:column headerText="#{messages['label.sample.batch']}">
<h:outputText value="#{sample.sampleId}" />
</p:column>
<!-- p:column style="width:32px">
<p:commandButton update=":carForm:display"
oncomplete="carDialog.show()"
icon="ui-icon-search">
<f:setPropertyActionListener value="#{car}"
target="#{tableBean.selectedCar}" />
</p:commandButton>
</p:column-->
</p:dataTable>
</p:outputPanel>
</p:fieldset>
<p:commandButton id="confirmBatch" value="Confirm Selection" update=":newSubmissionForm :createDialogForm"
actionListener="#{newSubmissionBean.confirmSelection}"
oncomplete="handleRequest(xhr, status, args)"/>
<p:droppable for="selectedSamples" tolerance="touch" activeStyleClass="ui-state-highlight" datasource="availableSamples" onDrop="handleDrop">
<p:ajax listener="#{newSubmissionBean.onSampleDrop}" update="dropArea availableSamples" />
</p:droppable>
</h:form>
</p:dialog>
the javascript function for on complete is
<script type="text/javascript">
function handleRequest(xhr, status, args) {
if(args.validationFailed) {
dlg.show();
}
else {
dlg.hide();
}
}
</script>
And the code in the action listener where I try to open the second dialog. This method does get called as I have break pointed on it.
public void fetchAvailability(ActionEvent actionEvent) {
RequestContext.getCurrentInstance().execute("batchDialog.show()");
}
Can anyone advise what I have done wrong? Thanks in advance
You're using the id of the dialog in your javascript, you need to use the widgetVar as such:
public void fetchAvailability(ActionEvent actionEvent) {
RequestContext.getCurrentInstance().execute("bdlg.show()");
}
For future debuggning, try executing the javascript in your web browser console. In this case it should say "batchDialog is not defined" or something similar, giving you a hint.
Ok figured out what the issue was just in case anybody has the same thing. The Primefaces showcase example code has not defined the handledrop javascript function thus object undefined error is thrown. So I added the following to my code and now my pop up shows up.
function handleDrop(event, ui) {
var selectedSample = ui.draggable;
selectedSample.fadeOut('fast');
}
Thanks

Primefaces dialog doesn't show up

I want a dialog to show up after I click a commandButton, but it doesn't show up at all.
I think the button is submitting the form instead of showing up a dialog. What's more I've tried to make a 'Cancel' commandButton and it is also not working as it should - it works only if I click it first (if I click commandButton which is suppoused to open a dialog first, the cancel button won't work anymore).
Here's my .xhtml:
<ui:define name="content">
<p:dialog id="dlg" header="#{messages.chooseSkillLevel}" widgetVar="dlg" modal="true" dynamic="true">
<h:form>
<h:dataTable value="#{editSkills.skillsAndLevels}" var="skillslevel">
<h:column>
#{skillslevel.skill.umiejetnosc}
</h:column>
<h:column>
<p:selectOneMenu value="#{skillslevel.level}" >
<f:selectItems value="#{editSkills.levels}" var="level" itemLabel="#{level.stopien}" itemValue="#{level.id}" />
</p:selectOneMenu>
</h:column>
</h:dataTable>
<p:commandButton value="#{messages.confirm}" action="#{editSkills.showSkillsAndLevels}" oncomplete="dlg.hide();" />
<p:commandButton value="#{messages.cancel}" onclick="dlg.hide()"/>
</h:form>
</p:dialog>
<h:form>
<p:messages/>
<p:pickList value="#{editSkills.skills}" var="skill" effect="none" converter="#{picklistConverter}"
itemValue="#{skill.id}" itemLabel="#{skill.umiejetnosc}"
showSourceFilter="true" showTargetFilter="true" filterMatchMode="contains"
addLabel="#{messages.add}" removeLabel="#{messages.remove}" removeAllLabel="#{messages.removeAll}" >
<f:facet name="sourceCaption">#{messages.skillsList}</f:facet>
<f:facet name="targetCaption">#{messages.yourSkills}</f:facet>
<p:ajax event="transfer" listener="#{editSkills.onTransfer}" />
<p:column style="width:100%;">
#{skill.umiejetnosc}
</p:column>
</p:pickList>
<p:commandButton value="#{messages.confirm}" actionListener="#{editSkills.afterSubmit}" update=":dlg" oncomplete="dlg.show();" /> THIS IS THE MENTIONED BUTTON
<p:commandButton value="#{messages.cancel}" action="profile" immediate="true"/> THIS IS THE CANCEL BUTTON
</h:form>
</ui:define>
What should I do to make it working well?
Your code seems fine to me :). However, 1 thing you need to note is that the id and widgetVar attributes of the <p:dialog> must not have the same value. Try something like the following:
<p:dialog id="levelDlg" widgetVar="levelDialog">

menupopup event listener not get called?

I'm using ice:menuPopup to create menus on tree nodes. In jspx page I've something like this
<ice:tree id="tree" value="#{tree.model}" var="item" imageDir="./xmlhttp/css/xp
/css-images/">
<ice:treeNode>
<f:facet name="icon">
<ice:panelGroup style="display: inline">
<h:graphicImage value="#{item.userObject.icon}"/>
</ice:panelGroup>
</f:facet>
<f:facet name="content">
<ice:panelGroup style="display: inline" menuPopup="menuPopupEffects">
<ice:commandLink actionListener="#{tree.Url}" value="#
{item.userObject.text}"/>
</ice:panelGroup>
</f:facet>
<ice:menuPopup id="menuPopupEffects">
<ice:menuItem value="Open" actionListener="#{tree.NodeValue}">
<f:param name="effectType" value="Open"/>
</ice:menuItem>
<ice:menuItem value="Close">
<f:param name="effectType" value="Close"/>
</ice:menuItem>
<ice:menuItem value="Send">
<f:param name="effectType" value="Send"/>
</ice:menuItem>
</ice:menuPopup>
</ice:treeNode>
The problem is that the actionListener="#{tree.NodeValue}" never gets called. Can any one tell me Where I'm wrong?
Try to move ice:menuPopup..../ice:menuPopup that block up, insert that block into the line just below:
ice:commandLink actionListener="#{tree.Url}" value="#
{item.userObject.text}"
Thus they in the same panelGroup. It works for me this way, but I am still use icefaces 1.8.

Resources