show dialog in PrimeFaces based on value in bean - jsf-2

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

Related

Make button enabled if checkboxes are checked in ASP.NET mvc

In my project I have created a few checkboxes in a for loop:
for(int i=0; i<10; i++)
{
{<input type="checkbox" name="check"/> #i<br>}
}
I also have a button called "Delete" which is supposed to delete the selected items:
<input type="button" id="DelButton" disabled value="Delete" />
For now the button will always be disabled, but I would like to know how it can become enabled if one or more checkboxes become checked.
Though you don't explicitly mention the use of jQuery, it does come with ASP.NET MVC by default. So here goes...
First, respond to the change event for the checkboxes:
$('input[type="checkbox"]').change(function() {
// respond to change
});
This would be invoked any time any checkbox on the page changes its state. Then within this event handler all you want to know is if any checkbox is checked, right? For that you can just select all checked ones and see if there are any. Something like this:
if ($('input[type="checkbox"]:checked').length > 0) {
// at least one is checked
}
Then in your if/else structure you just want to enable/disable the button. That would look something like this:
$('#DelButton').prop('disabled', false);
Putting it all together, you might have something like this:
$('input[type="checkbox"]').change(function() {
if ($('input[type="checkbox"]:checked').length > 0) {
$('#DelButton').prop('disabled', false);
} else {
$('#DelButton').prop('disabled', true);
}
});
Example
You can do that of JQuery code like this:
$('.checkbox_class').change(function() {
if ($('.checkbox_class:checked').length > 0) {
$('#DelButton').prop('disabled', false);
} else {
$('#DelButton').prop('disabled', true);
}
});
Html code :
<input type="checkbox" class="checkbox_class" />
<input type="checkbox" class="checkbox_class" />
<input type="button" id="DelButton" disabled value="Delete" />
I hope to help you.
Live Demo here : http://jsfiddle.net/CdwpA/1656/
You have to initiate an event
Something like :
<input type="submit" name="DelButton" class="inputButton" id="DelButton" value=" DelButton" />
<input type="checkbox" onchange="document.getElementById('DelButton').disabled = !this.checked;" />

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

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

Making Kendo Datepicker readonly but also selectable

I´ve been struggling to make my Kendo Datepicker without user-text-input and the only solution I´ve come up with was making the tag "readonly". However I want to be able to select the date from the selector with the mouse without being able to input text directly to the picker, therefore making the datepicker readonly but selectable.
Any ideas how?
<div>
#(Html.Kendo().DatePicker()
.Start(CalendarView.Year)
.Name("DatePicker")
.Value(DateTime.Now.AddDays(-365))
.Max(DateTime.Now)
.HtmlAttributes(new { style = "width: 125px;" })
.Events(e => e.Change("onDateChange")))
</div>
After a while I found a very simple solution using javascript. I simply declared a script that prevents any user input without disabling or making the input readonly. Something like this:
$("#inputId").keypress(function (evt) {
var keycode = evt.charCode || evt.keyCode;
if (keycode == 9) { //allow Tab through
return true;
} else {
return false;
}
});
It was easier than I thought :)
########### EDITED ####################
As suggested in a comment, it is probably not good practice to suppress all the keystrokes so I will paste almost the same code but suggesting that I open the datePicker instead (but still kind of suppressing the user text input as well).
$("#inputId").keypress(function (evt) {
var keycode = evt.charCode || evt.keyCode;
if (keycode == 9) { //allow Tab through
return true;
} else {
// Allow the datepicker to open instead
var datePicker = $("#inputId").data("kendoDatePicker");
datePicker.open();
return false;
}
});
You can do something like this:
#(Html.Kendo().DatePicker().Name("FollowUpDate").HtmlAttributes(new{onkeydown="javascript:return false;" }))
when someone clicks the datepicker it returns false hence does not allow to type anything while it still remains selectable.
If you want to just select data from opening calendar which kendoDatePicker show you but user not allow to enter date
<link href="http://cdn.kendostatic.com/2015.1.408/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2015.1.408/styles/kendo.default.min.css" rel="stylesheet" />
<input type="text" onkeydown="return false" placeholder="Enter Date" class="DatePicherKendo" />
<script src="~/bower_components/DataPicker-Kendo/JalaliDate.js"></script>
<script src="~/bower_components/DataPicker-Kendo/kendo.web.js"></script>
$(".DatePicherKendo").kendoDatePicker();
Add a maxlength attribute of 0 in HtmlAttributes.

commandLink action call failes in ui:repeat compinent

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?

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

Resources