I submit some fields with a button:
<p:commandButton value="#{msgs['label.button.editPropertiesSave']}" update=":editPropertyFormId:editPropertiesDialogContentId #(.resultlistActionGrid) " process=":editPropertyFormId:editPropertiesDialogContentId #this" action="#{editPropertyBL.save()}" oncomplete="resetDocValueChangedIfValidationOk();" />
function resetDocValueChangedIfValidationOk(args) {
if (args) {
if (!args.validationFailed) {
resetDocValueChanged();
}
}
}
If I submit it with valid input the backing bean method editPropertyBL.save() is called but args.validationFailed is true and my javascript is not executed.
I have a p:messages autoUpdate="true" in the page which shows an info message about the saving but it does not show any validation error.
Why can args.validationFailed be true at this situation?
Regards
Oliver
Related
I got a <h:commandButton like:
<h:commandButton id="login"
actionListener="#{bean.login}" value="Login"
styleClass="btn btn-primary btn-sm">
<f:ajax execute="#form" render="#form"/>
</h:commandButton>
and a
<p:blockUI id="block" block=":form" trigger="login" />
It is not working. The block is never shown up.
It does work with a <p:commandButton>.
How can I achieve it with a <h:commandbutton>. If that is not possible: Is there any workaround?
The <p:blockUI> listens on PrimeFaces/jQuery-specific pfAjaxSend and pfAjaxComplete events only. Those events are triggered by all PrimeFaces ajax components, but not by standard JSF <f:ajax>.
You've 3 options:
Replace <f:ajax> by <p:ajax> to let the <h:commandButton> send a PF/jQuery ajax request instead of a standard JSF one.
<h:commandButton id="login" value="Login" action="#{bean.login}">
<p:ajax process="#form" update="#form" />
</h:commandButton>
(note: carefully read Differences between action and actionListener)
Attach a global listener on <f:ajax> which auto-triggers the PF/jQuery-specific events.
jsf.ajax.addOnEvent(function(data) {
if (data.status === "begin") {
$(document).trigger("pfAjaxSend", [null, data]);
}
else if (data.status === "success") {
$(document).trigger("pfAjaxComplete", [null, data]);
}
});
Might have some undesired side-effects, though.
Manually trigger a specific <p:blockUI> during <f:ajax> events.
<f:ajax ... onevent="triggerBlockUI" />
...
<p:blockUI widgetVar="widgetBlockUI" ... />
With this JS function.
function triggerBlockUI(data) {
if (data.status === "begin") {
PF("widgetBlockUI").show();
}
else if (data.status === "success") {
PF("widgetBlockUI").hide();
}
}
Needless to say that option 1 is the most straightforward choice.
Try p:commandlink Instead. I had the same problem for h:commandlink and its solved
I have a p:dialog which is displayed by oncomplete of a commandButton
<p:commandButton value="Update" id="update"
actionListener="#{serviceTypeViewBean.beforeUpdate}"
oncomplete="updatedlg.show();)">
</p:commandButton>
This dialog has a list which is updated in the 'beforeUpdate' method. I want to add a condition in the oncomplete that if the list is not empty show the dialog
if(list != empty){
updatedlg.show()
};
How to add this condition in the oncomplete of commandButton?
You can do it as #Xtreme Biker suggested. The other solution is to use callbackParam:
Add to your beforeUpdate method code like the following:
if(list != empty){
RequestContext.getCurrentInstance().addCallbackParam("emptyList", false);
} else {
RequestContext.getCurrentInstance().addCallbackParam("emptyList", true);
}
Then you can check the param in your oncomplete attribute like this:
<p:commandButton value="Update" id="update"
actionListener="#{serviceTypeViewBean.beforeUpdate}"
oncomplete="if(!args.emptyList) { PF('updatedlg').show(); }">
</p:commandButton>
Please notice that callbackParam is flexible and you can find usage for it in many cases.
You can use EL evaluation in order to render/hide javascript code:
oncomplete=#{not empty serviceTypeViewBean.list ? 'updatedlg.show()' : '' }
See also:
Need help Using EL in javascript to get value from model
I have this following piece of code:
<h:form id = "fm-rewDet">
<ui:repeat var="review" value="#{controller.reviewStatusList}">
<h:commandLink value = "TestLink" action = "#{controller.rewDetail}" />
</ui:repeat>
</h:form>
The controller contains the following:
public void rewDetail(){
System.out.println("I'M HERE");
}
The following HTML code is rendered:
<form id="fm-rewDet" enctype="application/x-www-form-urlencoded" action="/project/overview.xhtml" method="post" name="fm-rewDet">
<a onclick="mojarra.jsfcljs(document.getElementById('fm-rewDet'),{'fm-rewDet:j_idt224:0:j_idt255':'fm-rewDet:j_idt224:0:j_idt255'},'');return false" href="#">TestLink</a>
//...
</form>
This simple example does not work at all. When the link is pressed some action takes place but weirdly the I'M HERE message fails to appear.
What is the cause of this?
Using PrimeFaces p:gmap component.
I have a page with a gmap component with a set of markers.
I want to display the street address in the gmapInfoWindow and pass it to the backing bean as well.
When I click on the map marker, I call a javascript function to get the reverse geocoder address.
I can fetch the address and display it in a javascript alert dialog, but I can't get it to fill the backing bean variable or in the info marker.
The variable does get filled, but it does not get updated until the next time I click on the marker.
As a result, the addresses are always one marker click behind.
Does anyone know how I can get the address to update during the current page session?
Thanks.
The backing bean code onMapMarkerSelect just has a System.out.println statement to show the mapAddress variable.
Here is the page code:
<h:form prependId="false" >
<p:gmap id="gmap" center="#{mappingSessionBean.mapCenter}" zoom="#{mappingSessionBean.mapZoom}" type="HYBRID" rendered="true"
style="#{mappingSessionBean.polygonGmapStyle}" onPointClick="handlePointClick(event);"
model="#{mappingSessionBean.mapModel}" fitBounds="#{mappingSessionBean.fitBoundsFlag}"
widgetVar="map" >
<p:ajax id="gmapAjax" event="overlaySelect" immediate="true" onstart="handlePointClick(event);" listener="#{mappingSessionBean.onMapMarkerSelect}" />
<p:gmapInfoWindow id="infoWindow" >
<p:outputPanel >
<h:panelGrid columns="1" >
<h:outputText id="infoWindowTitle" value="#{mappingSessionBean.selectedMarker.title}" />
<h:outputText id="infoWindowAddress" value="#{mappingSessionBean.mapAddress}" rendered="true" />
<p:commandButton value="Zoom In" action="#{mappingSessionBean.selectedViewInfoListener}" update="gmap" />
</h:panelGrid>
</p:outputPanel>
</p:gmapInfoWindow>
</p:gmap>
<h:inputHidden id="address" value="#{mappingSessionBean.mapAddress}" />
</h:form >
<script type="text/javascript" >
function handlePointClick(event) {
if(navigator.geolocation)
{
browserSupportFlag = true;
var latlng = event.latLng;
geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': latlng}, function(results, status)
{
if( status == google.maps.GeocoderStatus.OK )
{
alert( results[0].formatted_address );
document.getElementById('address').value = results[0].formatted_address;
document.getElementById('infoWindowAddress').value = results[0].formatted_address;
}
else
{
alert( "Geocoder failed due to: " + status );
}
});
}
else
{
alert( "No Geolocation");
}
}
</script>
Here is a general solution, I guess you can do better if you will find a way to trigger an event on inputHidden without the use of the button
b.t.w : jQuery comes with primefaces so you can use it without any additional includes
instead of
<h:inputHidden id="address" value="#{mappingSessionBean.mapAddress}" />
place
<f:ajax listener="#{mappingSessionBean.myajax}" execute="address">
<h:inputHidden id="address" value="#{mappingSessionBean.mapAddress}" />
<h:commandButton id="addressBtn" style="display:none"/>
</f:ajax>
(you can replace execute="address" with execute="#form")
and in js code replace
document.getElementById('address').value = results[0].formatted_address;
with
jQuery("#address").val(results[0].formatted_address);
jQuery("#addressBtn").click(); // this will trigger the ajax listener
and finally in your bean add the implementation of the ajax listener itself
public void myajax(AjaxBehaviorEvent event) {
System.out.println(getMapAddress());
}
I am using the webflow plugin for Grails for the first time and am having some difficulties.
To summarize, once within the Webflow, no information appears to be returning to the controller from the form. All examples that I have looked at indicate that the params are returned to the controller action normally and then you can put objects into the flow scope as necessary. Unfortunately, the illustrated printlns are both outputting null, and any programatic output of the params shows that the expected 'testField1' and 'testField2' are not in the params object. Excuse the non-uniform text boxes and ways of submitting - they were the result of experimentation.
A simplified version of the controller action flow:
def generateProductVariantsFlow = {
start() {
action {
[productInstance:Product.get(params.id)] //the entry params contains the expected id
}
on ("success").to("selectAttributeValues")
}
selectAttributeValues() {
on("next"){TestCommand tc -> //params does not have testField1 or testField2
println "TEST COMMAND"
println "${tc.testField1}"
println "${tc.testField2}"
}.to("selectProductVariants")
on("cancel").to("finishBeforeStart")
}
selectProductVariants {
on("cancel").to("finish")
on("previous").to("selectAttributeValues")
on("next").to("confirmNewVariants")
}
//other states here
finish {
redirect(action:"list")
}
finishBeforeStart { //somewhat misleading state name, but shouldn't be relevant
redirect(controller:"product",action:"show")
}
}
The GSP and Command are equally simple -
selectAttributeValues GSP:
<%# page import="com.castaway.rigging.Product" %>
<g:form action="generateProductVariants">
<input type="integer" id="testField1" name="testField1" value="test1" />
<g:textField name="testField2" value="test2"/>
<div class="buttons">
<span class="button"><g:actionSubmit class="cancel" name="cancel" value="Cancel"/></span>
<g:link action="generateProductVariants" event="next" >Next</g:link>
</div>
</g:form>
</div>
</body>
Command:
class TestCommand implements Serializable {
def testField1
def testField2
}
Why do you use a link instead of a submit button to trigger the next event?
Clicking that link will do a GET request which will not include the form fields.
You need to use a submit button to trigger the next event.
cheers
Lee