<p:blockUI> does not respond on <h:commandButton><f:ajax> - jsf-2

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

Related

Update view parameter without redirecting the page

Is it possible to update view parameter without redirecting the page? For instance
I have a managed bean which checks if an ID exist
public void signIn(){
Client c = clientFacade.loginDetail(client.getID());
if (c != null) {
loggedIn = true;
}
else{
loggedIn = false;
}
}
and a view which renders just fine if the ID exist.
<h:panelGroup rendered="#{not applicationManager.loggedIn}">
<p:commandLink value="Sign In" onclick="loginDialog.show()" styleClass="login-link"></p:commandLink>
</h:panelGroup>
<h:panelGroup rendered="#{applicationManager.loggedIn}">
<p:menuButton value="#{applicationManager.client.firstname}" />
</h:panelGroup>
<p:dialog widgetVar="loginDialog" >
<h:panelGrid columns="2" cellpadding="5">
ID : <p:inputText value="#{applicationManager.client.id}" />
<p:commandButton value="submit" action="#{applicationManager.signIn()}" update=":loginForm" />
</h:panelGrid>
</p:dialog>
Is it possible to insert the code below at the top of the view and still have an update on the url?
<f:metadata>
<f:viewParam name="input" value="#{applicationManager.client.id}" />
<f:event listener="#{applicationManager.signIn()}" type="preRenderView"/>
</f:metadata>
I tried it, but it's not working, so I guess I might be missing something or doing something wrong.

Clear Date Selection using Primefaces Calendar

Is there any way to clear the date selection using prime faces calendar?
<p:calendar pattern="MM/dd/yyyy" navigator="true" id="endDate" for="endDate"
readonlyInput="true" mindate="#{manageMarketingProgramsBean.currentDate}" showOn="button">
<f:convertDateTime pattern="MM/dd/yyyy" timeZone="America/New_York" />
</p:calendar>
I have readonlyInput="true" because I dont want user to type the date. I force them to pick the date from the calendar, there needs to be another way to provide user the ability to clear the date selected. Please let me know how can I achieve this?
The first approach that comes into my mind would be:
<p:calendar readonlyInput="true" widgetVar="calendarWidget"/>
<p:commandButton value="Reset" onclick="calendarWidget.setDate(null)"/>
This worked for me
<p:calendar widgetVar="calendarWidget" pattern="MM/dd/yyyy" />
<p:commandButton value="Reset" onclick="PF('calendarWidget').setDate(null)"
type="button" />
Primefaces for the calendar component have this property: showButtonBar.
If you set it to true like this:
<p-calendar
appendTo="body"
formControlName="someControl"
id="someID"
[maxDate]="someMaxDate"
[showButtonBar]="true"
[showIcon]="true"
></p-calendar>
Then it will display two buttons on the calendar component. Today and Clear.
Hope it helps somebody.
HTML
<p:calendar
yearRange="c-100:c+100"
readonlyInput="true"
pattern="dd/MM/yyyy"
id="identity"
navigator="true"
mindate="today"
widgetVar="dateWidget"
value="#{bean.fieldname}"
/>
JS
function name() {
var mainID = prefix + collpaseID;
-
-
-
-
clearCalendar(mainID,event);
}
function clearCalendar(collapseId) {
try {
allElements =
document.getElementById(collapseId).getElementsByClassName('hasDatepicker');
for (i = 0, n = allElements.length; i < n; ++i) {
allElements[i].setAttribute('onkeyup',
'clearDate("'+allElements[i].id+'", event)');
}
}
catch(e) {}
}
function clearDate(fieldID, e) {
try{
// 8 - backspace key, 46 - delete key
if(e.keyCode == 8 || e.keyCode == 46) {
//PF(getWidgetVarById(collapseId)).setDate(null);
document.getElementById(fieldID).value="";
}
}
catch(e){}
}
<p:calendar
widgetVar="calendarWidgetStart"
/>
<p:calendar
widgetVar="calendarWidgetEnd"
/>
<p:commandLink
value="Action"
action="#{entity.action}"
onclick="setTimeout('remoteCommand();', 100);"
/>
<p:remoteCommand
name="remoteCommand"
update="#form"
onstart="clearCalendarWidget();"
/>
<script>
function clearCalendarWidget() {
$( PF('calendarWidgetEnd').setDate(null) );
$( PF('calendarWidgetStart').setDate(null) );
}
</script>

Conditional Submit through h:commandButton

We are using JSF 2.0 in our project. Apart from Mojara, we are using Primefaces 3.3 forsome components.
we have a Requirement in our project that we HAVE to do Javascript validations (as part of client side validation) and then only the form submit should happen. The Validation done by JSF will anyway happen (at server side). But the Javascript validtions should also be there.
This was the reason I had asked this question but got no comments.
I am therefore implementing the JavaScript validations and this brings me to the actual problem i am facing.
I have JS functions to do basic validations like "Required" fields, length check etc and calling them at appropiate time (like onblur). But if the user just leaves all the fields empty or does not go into some fields at all(thereby not triggering events like onblur) and clicks on the submit button, these fields are missed out for JS validations.
So how do i conditionally submit the form after all the JS validaitions are done?
Note that we have to use f:ajax for form submit.
I tried the onsubmit function of the form. It works on FF but not on IE9.
I tried the onclick function of the commandbutton. It calls the js but submits the form also.
Few code if that helps
JavaScript functions I am using
var validationErrorFound = false;
function validateRequired(element,form){
if(null == element.value || "" == element.value){
var existingClass = element.getAttribute("class");
var newClass = existingClass + " inputError";
element.setAttribute("class", newClass);
var label = document.getElementById(element.getAttribute("id") + "Lbl");
var labelArray = new Array();
var temp = label.innerText;
labelArray = temp.split(":");
element.setAttribute("title", labelArray[0] + " is Required");
validationErrorFound = true;
}else{
element.className = element.className.replace( /(?:^|\s)inputError(?!\S)/ , '' );
element.setAttribute("title", null);
element.removeAttribute("title");
validationErrorFound = false;
}
}
function validateAllRequired(form){
var all = document.getElementsByTagName("input");
var max=all.length;
for (var i=0; i < max; i++) {
if(null != all[i].onblur ){
validateRequired(all[i],form);
}
}
return validationErrorFound;
}
JSF Page
<h:form id="addUserDetailsForm">
<h:messages/>
<h:panelGrid columns="2">
<p:outputLabel id="userNameLbl" for="userName" value="Username:" />
<p:inputText id="userName" required="true" onblur="validateRequired(this,this.form);"
value="#{userList.addUser.userName}">
<f:param name="req" value="true"/>
</p:inputText>
<p:outputPanel value="" />
<p:outputLabel id="firstNameLbl" for="firstName" value="First Name:" />
<p:inputText id="firstName" required="true" onblur="validateRequired(this,this.form);"
value="#{userList.addUser.firstName}"/>
<p:outputLabel id="lastNameLbl" for="lastName" value="Last Name:" />
<p:inputText id="lastName" required="true" onblur="validateRequired(this,this.form);"
value="#{userList.addUser.lastName}"/>
<h:commandButton styleClass="button" value="Add" onclick="validateAllRequired(this.form);"
action="#{userList.dummyAdd}" >
<f:ajax execute="#form" render=":mainArea :propertiesArea" update=":mainArea :propertiesArea"/>
</h:commandButton>
</h:panelGrid>
Is there any way this can be done?
Thanks

How can I get geocoder address to backing bean?

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());
}

IE Primefaces Enter Key Submit Workaround

I've run into and issue with IE not allowing me to hit the enter key to submit a form. I found a partial solution (http://www.thefutureoftheweb.com/blog/submit-a-form-in-ie-with-enter) but my dialog window closes. My validations are run and the error messages are displayed. How would I keep my dialog open?
<p:dialog id="sgupdlg" header="#{bundle['signUp.HEADER']}" widgetVar="signUpDlg"
modal="true" styleClass="dialog dialog1" draggable="false"
resizable="false" showEffect="fade" hideEffect="fade" position="top">
<h:form id="signUpFrm" binding="#{signUpDetail.signUpFrm}">
<p:growl id="growl" showDetail="true" showSummary="false" life="3000" errorIcon="/images/Validation-Error.png" infoIcon="/images/Validation-Success.png"/>
<p:inputText value="#{signUpDetailBean.firstName}" name="nameInput" required="true" requiredMessage="First Name is Required"/>
<p:inputText value="#{signUpDetailBean.lastName}" required="true" requiredMessage="Last Name is Required"/>
<p:commandButton styleClass="form-btn2"
value="#{bundle['signUp.button.LABEL']}" actionListener="#{signUpDetail.signUp}" onclick="trackingSignUpOverlaySave()"
oncomplete="handleSignUpRequest(xhr, status, args)" update="growl"/>
<p:commandButton type="reset" styleClass="close" />
</h:form>
</p:dialog>
<script type="text/javascript">
$ = jQuery
$(function(){
$('input').keydown(function(e){
if (e.keyCode == 13) {
$('#signUpFrm').submit();
return false;
}
});
});
</script>
function closeWhenValidationSuccesful(dialog, xhr, status, args) {
if (!args.validationFailed) {
dialog.hide();
}
}
<p:commandButton value="Save" action="doSomething" update=":formName:panelContainingValidatedElements"
oncomplete="closeWhenValidationSuccesful(dialogWidgetVar, xhr, status, args)" />
I use the following to keep a dialog open and display validation errors. You will need to move your inputs into a panelGrid so that it can be target by the update attribute.
A simple tag would solve it.
oncomplete="if (args.validationFailed){} else {Professor.show(),Student.hide();}"
you suppose to apply this on Professor widget var

Resources