I'm using primefaces 5.0 and I have this situation:
<composite:implementation>
<p:dialog id="confirmDialog#{cc.attrs.someParam}"
rendered="#{cc.attrs.nextState.warnRequired}" severity="alert" resizable="false" modal="#{cc.attrs.modal}"
widgetVar="confirmation#{cc.attrs.someParam}">
<p:commandButton value="#{msg[cc.attrs.nextState.buttonKey]}" icon="#{nextStatus.icon}"
action="#{someActionCalled}"
update="#{cc.attrs.update}" process="#{cc.attrs.process}"
oncomplete="if (!args.validationFailed) { PF('confirmation#{cc.attrs.someParam}').hide(); }">
</p:commandButton>
<p:commandButton id="decline" value="#{msg['action.cancel']}" icon="ui-icon ui-icon-cancel"
onclick="PF('confirmation#{cc.attrs.someParam}').hide()" />
</p:dialog>
</composite:implementation>
When i click "decline" / cancel button, confirmDialog is closed / hides. Thats ok.
Obviusly confirmation#{cc.attrs.someParam} can find widgetVar and closes this dialog.
But when i click first button to confirm and take some action in back bean i get :
Widget for var 'confirmationSomeParam' not available!
primef...mefaces (line 1)
detailed error: TypeError: PF(...) is null
{cc.attrs.someParam}
is passed into component. Its evaluated clean and values are there ( obviusly because second button can close dialog.
So its very strange that first button cant find this dialog widgetVar and second one can ?
So i had time again to check this critical part of my application and im posting here so someone in future maybe will find this usefull :)
I have added p:remoteCommand under both buttons in code:
<p:remoteCommand name="somethingToDo" update="#{cc.attrs.update}" />
and in first button i have removed update param.
Why ? Because as error says, it could not find some dialogId ( in this example 'confirmation332m' ) and because of that update param, which was updating whole form, dialog was removed / updated.
So i moved update param from button to remote command and in
onComplete i just call somethingToDo(); after all validation is checked.
Maybe its not best solution but for now it works ;)
PF forum link ( for future problems ): http://forum.primefaces.org/viewtopic.php?f=3&t=37851
Related
Using JSF and PrimeFaces 6.1 I have an inputText field as such:
<p:inputText value="#{backingBean.stringField}">
<p:ajax event="valueChange" update="#form" />
</p:inputText>
and within the same form is a commandButton:
<p:commandButton id="btnDoThatThing"
ajax="true"
immediate="true"
update="#form"
process="#this"
action="#{backingBean.doThatThing}"/>
When I
make a change to the inputText field,
then click somewhere OTHER THAN the command button
click the command button
everything works exactly as expected. BUT if I:
make a change to the inputText field,
immediately the command button
The button is NOT fired since the first click of the commandButton is triggering the valueChange event to happen in the inputText field.
If I click it a second time the button action finally happens.
Now, if i change the p:ajax event="valueChange" to p:ajax event="keyup" the first click of the commandButton work as expected, but unfortunately the keyup event on a inputField is pretty hacky and you lose functionality within the field (copy/paste text, text selection, 'fast' typing' etc)
Any thoughts on how to initiate the change event in the inputText field, AND fire the commandButton action when the user clicks the button immediately from typing in the inputText field?
First your valueChange is triggered. This updates the form including the button. Not 100% sure if this is browser dependent, but in Chromium (Linux), the click on the previously rendered button (before it has been updated) is not executed.
I could get it working when I changed the update expression into a selector. My expression updates the elements I needed to be updated excluding the button(s). In my case:
<p:ajax update="#(form :input:not(button))" />
Note that the change event is default for inputs, so I've removed event="valueChange".
Of course you do not need to use a selector. You can also just update a component (like a panel) which does not contain the button:
<p:ajax update="yourPanel" />
Also, ajax="true" is default for a p:commandButton, so you can remove that.
In my case, I solved the same problem removing the following statement from my page (Primefaces 11.0):
<p:ajaxStatus onstart="PF('statusDialog').show()" onsuccess="PF('statusDialog').hide()"/>
Somehow the onstart event overrides the click event and only one event is processed: change.
Currently I´m struggling with downloading a file after a method finishes.
<p:commandButton id="someID"
icon="ui-icon-folder-collapsed"
actionListener="#{bean.myMethod}"
ajax="true" value="test">
</p:commandButton>
myMethod does some fancy long Process stuff and takes some time. My Need is to offer a download after myMethod finshes.
My Method calls a download a method to do some. Similar to the method here download function SO
As Long as I Processing: myMethod I show a "working indicator"
<p:ajaxStatus onstart="PF('dia').show()"
oncomplete="PF('dia').hide()" />
<p:dialog widgetVar="dia" modal="true" draggable="false"
closable="false" resizable="false" showHeader="false">
<h:outputText value="sometext" />
<p:graphicImage value="./img/ajax-loader.gif"></p:graphicImage></p:dialog>
I learned that I can't start a download from Ajax call (which the command Button from Primefaces starts per default). When changing the attribute ajax to false, myMehtod processes and show the download dialog after. Problem is during this I have no "working indicator" shown.
Primeface has this solution: primeface download
Now my Question is it possible to start a method from the Button (and show the "working indicator") and when the method finishes still show the download dialog via fileDownload ?
I'm developping with Primefaces 4.0, JSF Mojarra 2.1.7 and jBoss_7.1.1_Final.
The tool I'm creating is mainly a dialog window showing a dataTable with dynamic columns (p:columns)
Those dynamic columns show a pSpinner like this :
<p:spinner id="updateQj_#{colIndex}_#{rowQj.idQbt}" widgetVar="updateQjJs_#{colIndex}_#{rowQj.idQbt}" stepFactor="1" min="0" max="#{rowQj.qbtType}"
value="#{rowQj.quantiteDuJour(qjColonne.property)}" onkeydown="return false;"
styleClass="editQj" rendered="#{not verrouille}" title="Cliquez ici pour modifier la quantité journalière" >
<p:ajax listener="#{recherche.updateQj}" update="#this, :formRecherche:growl" process="#this"/>
<f:param name="idQbt" value="#{rowQj.idQbt}"/>
<f:param name="jour" value="#{qjColonne.property}"/>
<f:param name="ligne" value="#{rowIndex}"/>
<f:param name="colonne" value="#{colIndex}"/>
</p:spinner>
</p:column>
</p:columns>
Everything seems to be working fine till for some unknown reason, the click in one of the columns modifies the current value plus the one previously updated in another column. To see it clearly: if I keep clicking/updating spinners in the same column everything works fine. If I click a spinner of another column it updates both. Any idea would be greatly appreciated.
in primefaces4, p:spinner in a cell made of p:columns>p:column doesn't behave like it should, first clicks work but at some moments, a simple click generates incessant ajax calls as if i clicked each spinner in each cell...After several days of workaround, and thinking that pf makes usage of jquery under the cover i tried by myself. Surprisingly, firebug console logged 'spinner is not a function' and jquery.ui.version was 1.10.3 so i downloaded 1.10.4 on jquery's site and included it in my header after other javascripts. jquery.ui.version showed 1.10.4 and no more error message appeared. :)
Finally, i wrote this in each p:column of p:columns in a p:datatable
<input id="updateQj_#{rowIndex}_#{colIndex}_#{rowQj.idQbt}" widgetVar="updateQjJs" class="editQj" value="#{rowQj.listeDesQj[colIndex].quantiteRealisee}">
</input>
<script type="text/javascript">
jQuery("input[id=updateQj_#{rowIndex}_#{colIndex}_#{rowQj.idQbt}]")
.spinner({ min:0,
max:#{rowQj.qMax},
step:1,
change:function(){ rmt_updateQj([parameters]); } });
</script>
I have created a JSF application using Myfaces 2.1.12 and Richfaces 4.3.3. On normal browsers the application works fine, but the client insists that he also needs to use a "browser" - IE8, version 8.0.7601. I am having a bunch of problems.
I have a rich:extendedDataTable on the main form. Clicking a row is to open a popup with the details (that is rendered and filled with the data from the selected row). The popup can also be called from a toolbar, this way it displays the details of the row that was selected when the page was first loaded.
The table is defined as follows (column definition removed for clarity)
<h:form>
<rich:extendedDataTable id="table" rowClass="row" rows="15"
value="#{scheduleController.allSchedules}" var="schedule" selectionMode="single"
selection="#{scheduleListBean.selectedSchedule.selection}" clientRows="15">
<a4j:ajax render="scheduleDetails, toolbar, transferListPopup" event="selectionchange"
listener="#{scheduleController.scheduleSelectionChanged}"
oncomplete="#{rich:component('scheduleDetailsPopup')}.show()"/>
...
</rich:extendedDataTable>
</h:form>
The popup contains a couple of panel grids, one of wich contains some buttons.
<h:panelGrid columns="2" styleClass="alignTop" id="scheduleDetails">
...
<rich:panel header="#{generalProperties.controls}">
<h:panelGrid columns="4">
<a4j:commandLink styleClass="btn" type="button"
render="table#body, transferDetailsPanel, destinationPanel, datesPanel"
oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('scheduleDetailsPopup')}.hide()"
status="pleaseWait" action="#{scheduleController.saveSchedule}"
value="#{generalProperties.save}" />
<h:commandButton class="btn" action="#{scheduleController.changeScheduleStatus}"
value="#{applicationProperties.changeStatus}" status="pleaseWait" type="button"
disabled="#{scheduleController.currentSchedule.id == null}">
<rich:componentControl target="changeScheduleStatusPopup" operation="show" />
</h:commandButton>
<h:commandButton class="btn" value="#{generalProperties.delete}" status="pleaseWait" type="button"
disabled="#{scheduleController.currentSchedule.id == null}">
<rich:componentControl target="removeSchedulePopup" operation="show" />
</h:commandButton>
<a4j:commandButton styleClass="btn" type="button"
render="fileTable, transferDetailsPanel, destinationPanel, datesPanel"
disabled="#{scheduleController.currentSchedule.id == null}"
oncomplete="if (#{facesContext.maximumSeverity == null}) #{rich:component('transferListPopup')}.show()"
status="pleaseWait" value="#{applicationProperties.transferHistory}" />
</h:panelGrid>
</rich:panel>
</h:panelGrid>
The disabled="#{scheduleController.currentSchedule.id == null}" part checks the bean if anything is selected as the popup is also used to add new rows.
Everything works fine on firefox. On IE8:
clicking the commandLink does not work(nothing happens, besides a "#"
that is appended to the url in the browser) when the popup is called from the
extended data table (rendered), but works when it is called from the
toolbar.
clicking the commandButton does not work(page is reloaded instead of an ajax request beeing executed) when the popup is called from the extended data table (rendered), but works when it is called from the
toolbar.
if I remove the type="button" from command buttons, then clicking them causes the entire page to be reloaded
What am I missing?
The answer was in the question itself. I rebuilt the UI so that no buttons are rendered in ajax requests. This way it works both on IE 8 and IE 9.
Ie.: Instead of setting the disabled attribute based on a bean and rendering the buttons I had to use two instances of each of those buttons. I did that by extracting a form into a composite component using composite:insertChildren just to inject buttons in the proper state and having two instances of the form on the page, showing the right one when the user clicked new schedule / edit schedule.
The drawback of this method is that I had to set the render attribute of the components that show the popup to something different then forms (in this case - panels), which would be an issue if I used Mojarra (see this question: javax.faces.ViewState is missing after ajax render)
I have a required input field in a p:dialog. If firstly I submit nothing for the field, a validation error happens on that field. Then I close the dialog and reopen it, the validation error still exists. What can I do to eliminate the validation error when close the dialog?
You should use the p:resetInput on the element that you have to open the dialog.
For example if you use a p:commandButton
<p:commandButton value="Open dialog" update=":dialogId" oncomplete="PF('dialogWidget').show()" >
<p:resetInput target=":dialogId" />
</p:commandButton>
This will reset the cached values (including the validation messages) upon opening the dialog.
I was able to reproduce your case and you could do the following:
Make your dialog closable="false".
Add a Cancel button that will hide the dialog.
Add a resetInput component from Primefaces Extensions inside your Cancel button. This will clear the form validations and values.
Here is an example that assumes your dialog as a widgetVar named wvDialog.
<p:commandButton value="Cancel" immediate="true" onclick="wvDialog.hide()">
<pe:resetInput for="myDialogFormId />
</p:commandButton>
You could even call a bean method in the button actionListener if you need.
I hope it helps.
Update the p:dialog or p:message every time you submit the Form.
You can do that by using update attribute of p:commandButton.
<p:commandButton update="ID_OF_DIALOG" />