What events are available for PrimeFaces DataList [duplicate] - jsf

This question already has answers here:
Using the page event with p:dataList in PrimeFaces
(2 answers)
Closed 8 years ago.
I'm trying to capture the Page event when users click through pages using the Paginator on a DataList. The user guide doesn't mention any Ajax behaviors for this component, but I tried <p:ajax event="page"> anyway and found that event "page" is not supported.
Are there any events available for DataList? If not, has anyone got an idea how I can save each page as the user pages through?
Thanks :)
Neil

You can hook into the the component's rendering lifecycle (the component is rerendered with each pagination operation) with the generic preRenderComponent event on the datalist. Just add the following to your datalist:
<p:dataList>
<f:event type="preRenderComponent" listener="#{yourBean.operation}"/>
</p:dataList>

Its possible to override the standard PrimeFaces javascript function which is called if you click the pagelinks. From there you may call a remoteCommand or whatever you want to...
I know it´s not the best practice, but a possibility ;)
PrimeFaces.widget.Paginator.prototype.bindPageLinkEvents = function(){
var $this = this;
this.pagesContainer.children('.ui-paginator-page').on('click.paginator', function(e) {
var link = $(this);
if(!link.hasClass('ui-state-disabled')&&!link.hasClass('ui-state-active')) {
$this.setPage(parseInt(link.text()) - 1);
}
// your code goes here
})
.on('mouseover.paginator', function() {
var item = $(this);
if(!item.hasClass('ui-state-disabled')&&!item.hasClass('ui-state-active')) {
item.addClass('ui-state-hover');
}
})
.on('mouseout.paginator', function() {
$(this).removeClass('ui-state-hover');
})
.on('focus.paginator', function() {
$(this).addClass('ui-state-focus');
})
.on('blur.paginator', function() {
$(this).removeClass('ui-state-focus');
})
.on('keydown.paginator', function(e) {
var key = e.which,
keyCode = $.ui.keyCode;
if((key === keyCode.ENTER||key === keyCode.NUMPAD_ENTER)) {
$(this).trigger('click');
e.preventDefault();
}
});
};
Or look at this answer. I like it very much!
https://stackoverflow.com/a/25930991/2265727

Related

Render PrimeFaces <p:focus> component only if the browser window has a certain size

Is there a way to render the PrimeFaces <p:focus> component (or let it do its job) only when the browser window has a certain size? To do this I understand that maybe I have to have access the browser window size in server code and use the component rendered attribute to access this code.
In client code, I get the window width with code like this: $(window).width() > 480.
The reason for this is that I don't want to focus the first component in mobile devices, which most of the time have small screens.
Today I'm doing this with the client code below, but I'd like to use the <p:focus> component for the task, as it also has the benefit to focus the first invalid component when validation fails.
$(
function()
{
if (bigWindow())
{
focusFirstInput();
}
}
)
function bigWindow()
{
return $(window).width() > 480;
}
function focusFirstInput()
{
$("#form input:text, #form input[type=number], #form input[type=password], #form textarea").
first().focus();
}
I've found a way using the <p:focus> component:
$(
function()
{
let primeFacesOriginalFocusFunction = PrimeFaces.focus;
PrimeFaces.focus =
function(id, context)
{
if (!isMobile())
{
primeFacesOriginalFocusFunction(id, context);
}
}
}
)
function isMobile()
{
return ...
}

JSF Open dialog on value change

I have multiple views in my web application. On each view, I need to check for a "change event". As soon as a value is changed (without submit), I want to set a boolean in my bean true. Is this possible? There are many inputs so a on every component would be annoying.
I'm working on a Wildyfly server and use Primefaces 6.2, JSF 2.2.
Thx and greetings!
I think that can be achieved with jquery + remote command, for example:
<script type="text/javascript">
$(document).ready(function () {
$(".ui-input").on('change', function (event) {
setBooleanValue()
});
});
</script>
and then the remoteCommand which will trigger a method on managed bean responsible for setting the boolean value:
<h:form>
<p:remoteCommand name="setBooleanValue" action="#{myBeann.callMethodToSetBoolean}"/>
</h:form>
The remoteCommand will be called on every (primefaces) input change.
Also if you have ajax updates on the page you'll need to re-register the jquery change event on inputs after the ajax call:
<script type="text/javascript">
$(document).ready(function () {
$(".ui-input").on('change', function (event) {
setBooleanValue()
});
});
$(document).on("pfAjaxComplete", function () {
$(".ui-input").on('change', function (event) {
setBooleanValue()
});
});
</script>

Decouple navigation and selection with JSF tree-like widget

I'm looking for a good approach to realize a tree-like JSF widget with the following requirements:
means to expand and collapse tree branches
ajax navigation through clicking on a tree node
multi-selection of nodes / branches via tri-state checkboxes
the former three features must work independent from each other
the solution must be compatible with PrimeFaces
I don't want to fork the framework in terms of writing a custom component
What I've come across:
PrimeFaces p:tree and p:treeTable
built-in selection feature provides a nice implementation with tri-state checkboxes but is tightly coupled to clicking on a node, which makes it unusable in terms of navigation (the selection also changes)
alternatively a custom implementation of the checkbox-column must reinvent the whole tri-state checkbox logic even with pe:triStateCheckbox (PrimeFaces Extensions)
OmniFaces o:tree seems to offer a high level of customization, but also leaves a lot of needle crafting remaining
Any hints, experiences are welcome.
I ended up with a solution build on p:treeTable with selectionMode="checkbox" and p:commandLink for navigation.
To disable the 'full row' mouse click trigger also causing selection changes the JavaScript has been adjusted like this (PrimeFaces 5.3):
<script type="text/javascript">
//<![CDATA[
PrimeFaces.widget.TreeTable.prototype.bindSelectionEvents = function() {
var $this = this,
rowSelector = '> tr.ui-treetable-selectable-node';
this.tbody.off('mouseover.treeTable mouseout.treeTable click.treeTable', rowSelector)
.on('mouseover.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.addClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').addClass('ui-state-hover');
}
}
})
.on('mouseout.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.removeClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').removeClass('ui-state-hover');
}
}
})
.on('click.treeTable', rowSelector, null, function(e) {
//$this.onRowClick(e, $(this));
e.preventDefault();
});
if(this.isCheckboxSelection()) {
var checkboxSelector = this.cfg.nativeElements ? '> tr.ui-treetable-selectable-node > td:first-child :checkbox':
'> tr.ui-treetable-selectable-node > td:first-child div.ui-chkbox-box';
this.tbody.off('click.treeTable-checkbox', checkboxSelector)
.on('click.treeTable-checkbox', checkboxSelector, null, function(e) {
var node = $(this).closest('tr.ui-treetable-selectable-node');
$this.toggleCheckboxNode(node);
});
//initial partial selected visuals
if(this.cfg.nativeElements) {
this.indeterminateNodes(this.tbody.children('tr.ui-treetable-partialselected'));
}
}
};
//]]>
</script>
I also changed some CSS, mainly:
.ui-treetable .ui-treetable-data tr.ui-state-highlight,
.ui-treetable .ui-treetable-data tr.ui-state-hover {
cursor: default;
}

How to integrate Stripe "Pay with Card" in backbonejs

I am trying to integrate Stripe "Pay with Card" checkout into backbone Node environment. On the server side, I am using Stripe Node code - that part works good. However, on the client side, I am unable to capture the event.
I would like to capture the submit event from the Stripe popup to call "paymentcharge" method in the view.
Here is my code:
<!-- Stripe Payments Form Template -->
<form id="stripepaymentform" class="paymentformclass">
<script
src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button"
data-key="pk_test_xxxxxxxxxxxxx"
data-amount="0299"
data-name="MyDemo"
data-description="charge for something"
data-image="assets\ico\icon-72.png">
</script>
</form>
Backbone View Class
myprog.PaymentPanelView = Backbone.View.extend({
initialize: function () {
this.render();
},
render: function () {
$(this.el).html(this.template());
return this;
},
events : {
"submit" : "paymentcharge"
},
paymentcharge : function( event) {
this.model.set({stripeToken: stripeToken});
}
});
Backbone Model Class
var PaymentChargeModel = Backbone.Model.extend({
url: function(){
return '/api/paymentcharge';
},
defaults: {
}
})
Setup/Call the View from header menu event
if (!this.paymentPanelView) {
this.paymentPanelView = new PaymentPanelView({model: new PaymentChargeModel()});
}
$('#content').html(this.paymentPanelView.el);
this.paymentPanelView.delegateEvents();
this.selectMenuItem('payment-menu');
I think the problem has to do with your View's el and the event you are listening for.
You never explicitly define your View's el, which means it gets initialized to a detached <div> element. You then use your template to fill that <div> with the form element from the template. Even though your <div> is detached, you get to see the content, because you add the content of you el to #content using jquery.
I think the problem is that you are listening for a submit event on the <div> in your el, not the contained <form>. Try changing your events hash to this:
events: {
'submit form#stripepaymentform': 'paymentcharge'
}
Basically, listen for events on the contained element like in jquery's .on. You can also go right to a button click, something like this:
'click #mysubmitbutton': 'paymentcharge'
Hope this helps!

Disable commandButton in JSF

This seems like it should be pretty straightforward but I'm not feeling it.
I have a JSF CommandButton that executes a long running serverside task (10-15 seconds). I've seen forms where the button context changes after it's been clicked (The label on the button changes and the button becomes disabled until the processing is complete).
I'm using ICEFaces and have the disabled property set to a boolean on the underlying page code.
The action listener bound to the button changes that boolean to disable it but alas, no changes on the JSP.
Anyone?
What you can do is to change the status of the button using Javascript:
<h:commandButton ... onclick="this.disabled=true"/>
Edit regarding the comment:
If the previous code does not submit the form, then you have to disable the button a little time after the click, not "during" the click itself. You can do that using the following code:
<h:commandButton ... onclick="setTimeout('this.disabled=true', 100);"/>
I'm not sure if the fact to use the this keyword directly in the setTimeout method will work correctly. If not, you can use another way to do that:
<h:commandButton ... onclick="disableButton(this.id);"/>
with the following Javascript function:
function disableButton(buttonId) {
setTimeout("subDisableButton(" + buttonId + ")", 100);
}
function subDisableButton(buttonId) {
var obj = document.getElementById(buttonId);
if (obj) {
obj.disabled = true;
}
}
(I'm sure this code can be enhanced, thus)
You should use an ice:commandButton instead of h:commandButton, since it has the partialSubmit property, which will perform the action as an AJAX call. This should refresh your button's state, so if the property on the server has been set to false, your button should be disabled.
do a javascript submit(); first and then disable the button
Similar to the solution from romaintaz
For a Firefox specific solution, the following works (it does not work in IE):
<h:commandButton ... onclick="disableButton(this.id);" />
Using Javascript function:
function disableButton(buttonId) {
var obj = document.getElementById(buttonId);
if (obj) {
setTimeout(function(thisObj) { thisObj.disabled=true; }, 50, obj);
}
}
do it after icefaces has updated the DOM. you can use ice.onAfterUpdate(callback):
Here with jQuery
ice.onAfterUpdate(function(){
updateButtons();
});
function updateButtons(){
if(!isButtonEnabled()){
jQuery(".myButton").attr('disabled', true);
jQuery(".myButton").removeClass("iceCmdBtn").addClass("iceCmdBtn-dis");
}else{
jQuery(".myButton").removeAttr('disabled');
jQuery(".myButton").removeClass("iceCmdBtn-dis").addClass("iceCmdBtn");
}
}

Resources