Show dialog when the input data is validated <p:confirmDialog> [duplicate] - jsf-2

This question already has an answer here:
How to display dialog only on complete of a successful form submit
(1 answer)
Closed 6 years ago.
For my school project I have to realize a mini website where I use primefaces framework. In a form I want after pressing the Save button two things:
1 - Validate the data entered. that's why I put
<p:message for="date" /> and <p:message for="zone" />
As the values ​​are not correct, the dialog box should not be displayed.
2 - When all data is correct, and I click Save, I want to display my dialog box.
Now I can not. Can you help me? I use version 4 primefaces.
<h:form>
<p:panel id="panel" header="Create" style="margin-bottom:10px;border-color:blueviolet" >
<p:messages id="messages" />
<h:panelGrid columns="3">
<h:outputLabel for="date" value="Date : *" />
<p:calendar locale="fr" id="date" value="#{newBusinessCtrl.exercice.debut}" required="true" label="date" showButtonPanel="true"/>
<p:message for="date" />
<h:outputLabel for="zone" value="Zone Monétaire: *" />
<p:selectOneMenu id="zone" value="#{newBusinessCtrl.exercice.zoneChoice}" >
<f:selectItem itemLabel="Choice " itemValue="" />
<f:selectItems value="#{newBusinessCtrl.exercice.zones}" var="azone"
itemLabel="#{azone}" itemValue="#{azone}" >
</f:selectItems>
<p:message for="zone" />
</p:selectOneMenu>
<p:message for="zone" />
</h:panelGrid>
</p:panel>
<p:commandButton update="panel" value="Save" icon="ui-icon-check" style="color:blueviolet" onclick="choice.show()"/>
<p:confirmDialog message="Would you like to create accounts automatically ?"
header="Account creation" severity="alert"
widgetVar="choice" appendTo="#(body)">
<p:button outcome="personalizeAccount" value="Personalize" icon="ui-icon-star" />
<p:button outcome="autoAccount" value="Continue" icon="ui-icon-star" />
</p:confirmDialog>

Just show the dialog in Backing Bean like this:
Page:
<p:commandButton update="panel" value="Save"
icon="ui-icon-check"
style="color:blueviolet"
action="#{newBusinessCtrl.showDlg('choice')}"/>
Backing Bean:
public void showDlg(String dlgName){
RequestContext.getCurrentInstance().execute(dlgName+".show()");
}
Once the validation failed, the action won't execute and thus the dialog will not show.

If validation hasn't failed. PrimeFaces puts a global args object in the JavaScript scope which in turn has a boolean validationFailed property. You can check it before showing the dialog So you can use it this way:
<p:commandButton value="save" oncomplete="if (args && !args.validationFailed) saveDialog.show()"/>

Related

JSF "rendered" - strange behavior

I can't explaine this well - it's need to see:
Video screencast
Please explain me what happens?
next code work and return true or false but when I put this to rendered="" this not work.
#{!empty detailsBean.goods.pictures}
rendered="true" rendered="false" rendered="#{true}" - work
<p:commandButton id="btn_details" value="#{msg.btn_details}" oncomplete="PF('dlg-detailed').show()" update=":dlg-detailed-id">
<f:setPropertyActionListener target="#{detailsBean.goods}" value="#{goods}" />
<f:param name="id" value="#{goods.id}"/>
</p:commandButton>
Dialog - where I try render text with condition.
<p:dialog id="dlg-detailed-id" widgetVar="dlg-detailed" header="#{msg.btn_details}" dynamic="true" modal="true" draggable="false" width="800" height="600">
<h:outputText value="Some Text For Rendering" rendered="#{!empty detailsBean.goods.pictures}" />
</p:dialog>
Mojarra 2.1.7-jbossorg-1
JBoss AS 7.1.1
I apologize for my mistakes in English
in this case, solution is: add < h:form> tag and then rendered="#{!empty detailsBean.goods.pictures}" work
<h:form id="form-detailed" >
<p:dialog id="dlg-detailed-id" widgetVar="dlg-detailed" header="#{msg.btn_details}" dynamic="true" modal="true" draggable="false" width="800" height="600">
<h:outputText value="Some Text For Rendering" rendered="#{!empty detailsBean.goods.pictures}" />
</p:dialog>
</h:form>

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">

How to skip the validation for component which is being hidden?

I have a scenario like the below..
<h:selectOneRadio id="someId" value="#{myBean.type}" required="true">
<f:ajax event="valueChange" execute="#form" render="myPanel">
<f:selectItem itemLabel="Existing Type" itemValue="Existing Type" />
<f:selectItem itemLabel="New Type" itemValue="New Type" />
<h:selectOneRadio>
<h:panelGroup id="myPanel" rendered="#{myBean.checkforNewType()}">
<h:inputText id="txtval" value="#{mybean.val}" required = "true" requiredMessage="Some message">
<h:message for="txtval" styleClass="error"/>
<h:panelGroup>
Basically the panel containing the textbox should be hidden if the value of the property type is "Existing Type".
But the issue I am facing is if user leave the box blank the panel is not hidden as it fails the validation.
Is there anyway to avoid the validation when the panel containing the textbox is being hidden?
Better check the request parameter value instead. The model value is namely not updated when the validation has failed in general and thus your rendered condition will fail when being bound to a request scoped bean.
<h:selectOneRadio id="someId" value="#{myBean.type}" required="true">
<f:ajax event="valueChange" execute="#form" render="myPanel">
<f:selectItem itemLabel="Existing Type" itemValue="Existing Type" />
<f:selectItem itemLabel="New Type" itemValue="New Type" />
<h:selectOneRadio>
<h:panelGroup id="myPanel" rendered="#{param['formId:someId'] == 'New Type'}">
<h:inputText id="txtval" value="#{mybean.val}" required="true" requiredMessage="Some message">
<h:message for="txtval" styleClass="error"/>
<h:panelGroup>
Here, I assume that the parent <h:form> has an id="formId".

Resources