Is it possible to show only the confirm, and not the cancel button icon in Prime Faces DataTable rowEditor? - jsf

Is it possible to show only the confirm, and not the cancel button icon in Prime Faces DataTable rowEditor?

I ended myself with this approach
As stated by #Kukeltje it's possible to manage similar problems on client using
some css to hide it (it is all html, css and javascript on the client).
I choose jquery to handle html, css, and javascript (I'm relatively new to jsf/primefaces but I read it's based on jquery).
So in managed bean I was able launch scripts like this:
PrimeFaces.current().executeScript("$('#myForm\\\\:myContainer .ui-row-editor-close').eq(-1).remove();");
or even in XHTML/JS script like this:
<h:outputScript library="js" name="myScripts.js" />
$(document).ready(function() {
$("#myForm\\:myContainer .ui-row-editor-close").last().remove();
});
Anyway with this approach you need to be carefull, any ajax call which update part of the page involved reset to default, so cancel button will re-appear.

Related

React to a MenuButton being clicked

We have code that periodically refreshes our document. We also have as part of the JSF page, menuButtons (primefaces), originaly as part of dataTable cell/s in a column. We want to disable the refresh when the menuButton is clicked (the menu is expanded), and re-enable it when the menuButton is closed (to prevent page refresh from closing menu).
I've attempted to catch menuButton events using java script, but to no avail. Part of the problem is that I do not know how to identify the JSF component uniquely from javascript, as ID does not seem to work when attempting to catch events. There also does not exist any satisfactory event attributes (as part of Primefaces menuButton) that I can hook up to javascript.
Below is the minimal code that I could extract. I have extracted the menu to be on its own (not part of dataTable) for simplicity, as the question still stands. I may have a reference to a bean and dictionary files in there, but you should get the idea:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:form id="virtualMachineTableForm">
<!-- Lazy load table -->
<p:remoteCommand name="lazyload"
update=":vmGroupTabs:virtualMachineTableForm:testMenu"
actionListener="#{backupGroupController.refreshHard()}" />
<!-- Refresh hard button -->
<p:commandButton id="refreshButton"
update=":vmGroupTabs:virtualMachineTableForm:testMenu"
icon="ui-icon-refresh"
immediate="true"
title="#{msg.action_refresh}"
actionListener="#{backupGroupController.refreshHard()}"/>
<p:menuButton
id="testMenu"
value="#{msg.menuButton_SelectItem}">
<p:menuitem
value="Toggle refresh"
onclick="toggleRefreshState()">
</p:menuitem>
</p:menuButton>
<!-- Poller -->
<p:poll interval="5" listener="#{backupGroupController.refreshSoft()}"
update=":vmGroupTabs:virtualMachineTableForm:testMenu" widgetVar="poll" />
</h:form>
<script type="text/javascript">
var toggleRefreshState = function(){
if (poll.isActive()) {
poll.stop();
alert("Poller stopped" );
}
else {
poll.start();
alert("Poller started" );
}
};
$(document).ready(function(){
poll.start();
setTimeout("lazyload();", 100);
});
//
// $("???SomeWayToIdentifyMenu???").on({
// onMenuOpen???: function(){
// alert("Opening menu - stopping refresh");
// }
// onMenuClose???: function(){
// alert("Closing menu - starting refresh");
// }
// });
</script>
</ui:composition>
Is it possible to catch menu open/close (or for that matter any) events for jsf primefaces menu buttons on the client side using Java script?
Is it possible to determine if the menubutton is open/closed for the purpose of disabling refresh to prevent menu from disappearing.
Your help appreciated, Thank you,
Werner
In the end it is all html, javascript and css. Javascript in PF is mainly jquery and all components have javascript code behind them to function on the client side.
There are several ways to plug into this. Attaching plain jquery event handlers to the right element (checkable via your browser developer tool and/or checking what the PrimeFaces javascript does) is an option, but you have to reapply them over and over again when e.g. ajax calls take place. Another option is to override the basic menu button functionality without changing the PF original source.
Since the code is open source, you can try to find the javascript source of the PrimeFaces MenuButton. It is in this case all defined in menu.js and this can be fairly easily looked at (and is cleanly written)
In there you can see all events that are added to the component and also if there e.g. are onBeforeShow handlers or not (some components in PrimeFaces have those, the MenuButton not which is unfortunate for you, but I've not seen a usecase like this up to now).
The downside of overriding the basic functionality unfortunatly is that this will then be true for all menu buttons. So you have to implement some logic to decide if you actually need to perform some custom action or not. There are several ways to do that, but the easiest in my opinion is to check for the presence of a specific style class (e.g. 'stopPoll').
Now to the actual overriding:
var oldPFShow = PrimeFaces.widget.MenuButton.prototype.show
PrimeFaces.widget.MenuButton.prototype.show = function() {
alert("before show");
oldPFShow.apply(this, arguments);
}
var oldPFHide = PrimeFaces.widget.MenuButton.prototype.hide
PrimeFaces.widget.MenuButton.prototype.hide = function() {
oldPFHide.apply(this, arguments);
alert("after hide");
}
(do not forget to call the original functions)
Where I put the alerts, you have to implement checking for the presence of a class or leave that out if you have one menu button on that page or want the behaviour for all menubuttons
Some general comments: (Will be removed later on, but difficult to format in the comments)
I've attempted to catch menuButton events using java script, but to no
avail.
Posting attempts can help, since sometimes you are close and just have some small oversight). In those cases it is easier to write an answer for people trying to give support
Part of the problem is that I do not know how to identify the
JSF component uniquely from javascript,
This is a generic PrimeFaces thing (and differs from component sets). Apply a widgetVar attribute and with PF('') you have a handle to the specific components.
And as you can see the explicit fact that you use a PrimeFaces menuButton is of the highest importance. Having a small piece of code (smaller then you have now, but compliments for the mcve) is confirmation of this (assumption is the mother of all... ) Adding 'javascript' as a very generic tag, often attracts the 'wrong' people, as does 'java' So please next time leave those out
The easiest way to achieve this is to add javascript to the menuButtons to change a global variable and have the periodic refresh read that global variable and act accordingly. As you have no code or indication what components you are using I can't get more specific then that. Here would be the javascript code I would expect to see
window.preventRefresh = false;
function doPeriodicRefresh() {
if(!preventRefresh) {
window.location.reload();
}
}
setInterval(doPeriodicRefresh, 60000);
function showMenu() {
window.preventRefresh = true;
menu.show();
}
function hideMenu() {
window.preventRefresh = false;
menu.hide();
}
Your mouseovers/mouseout for the menu should call showMenu and hideMenu, any parameters would have to be proxied through.
This also depends on how you are doing your periodic refresh. If you are using the refresh header or metatag I don't believe you will be able to stop these from javascript.

Render a jsf element on mouseover

I have a <h:panelGrid> and a h:commandLink(link is basically a image).Now I want that on mouseover event , Then link should be render(render='true') and on mouseout event, it gets removed render='false'.But I am unable to create the logic that How can I do this with these events as the approach I am using is To set the values of bean true and false on this event.
Here is my code
<h:form>
<h:panelGrid mouseover='** we cannot call a bean method here which changes the bean value **'>
This is the Div On which I want to apply mouseover event
</h:panelGrid>
<h:commandLink id="btn" render={renderBean.renderLink}>
<h:graphicImage url="image.jpg"/>
</h:commandLink>
</h:form>
The default value of renderLink attribute of renderBean is false. Now I want to know the way that How can I change its value to true on mouseover event? Is it possible? OR Anyother solution in JSF w.r.t this requirement
You have to remember in JSF that the page will first be processed server-side by the JSF engine in the web server. At that time all JSF tags will be converted into their HTML equivalent. The render attribute tells the server-side engine whether or not to output an HTML a (anchor) link in the place of the <h:commandLink> element.
The behavior you're looking for, namely responding to mouse events, is client-side functionality. It happens in the browser, not at the web server, so no JSF is involved. The solution is to handle the mouse events in JavaScript, not JSF. You will typically set (or remove) the CSS attribute display:none on the id called btn (unfortunately it's slightly more complex as JSF will mangle the element id a bit). There are lots of posts here on StackOverflow that deal with how to handle client-side events in JavaScript. Using jQuery for example is a really common approach.
I recommend to get started you take a look at the blog of one of our best JSF resources and long-time StackOverflow user BalusC: http://balusc.blogspot.com.
There's a lot to learn and you'll get a good start by going there first (and searching for his posts on SO).
Good luck.

Render a disabled button in JSF

I'm trying to render a button that should be initially rendered disabled and at some point enabled by client side actions. I'm using the component from a4j with the following code:
<a4j:commandButton id="myButton" disabled="true" onclick="myFunction()">
The problem is when the disabled attribute is set to true, the events are not attached to the component, resulting in this html code:
<input type="button" onclick="return false" ... />
So when I try to enable via javascript, the button is enabled, but the buttons don't have the event listeners attached.
So far, the only two solutions I can think about are:
Assigning the value of the disabled attribute to a bean property and rerender the button.
Render initially enabled and disabled on the load page through javascript
Both options would work but they are not very clean, I don't want to make a petition to the server every time I enable the button.
That's just how stateful component based MVC frameworks like JSF works. As part of safeguard against tampered/hacked requests, the framework re-evaluates the disabled (and rendered) attribute of an input element whenever it's about to apply the request values. Otherwise endusers would be able to invoke actions or submit values they're not allowed to do by server side restrictions which would potentially put doors wide open to attacks.
The two solutions which you mentioned are perfectly fine. I'd opt for the first one if you don't want to allow the enduser to tamper/hack it. It can easily be done by ajax.

Can I replace h:commandLink with h:link

I'm creating a mobi-site using jsf. I got right to the end and found that more primitive phone browsers can't handle the javascript that commandLink creates. Is it possible to circumvent this with h:link or do you have any other suggestion as to how to get around this?
The <h:commandLink> generates a HTML <a> element with JS code in onclick to submit a POST form.
If your functional requirement is to submit a form with some data, then better use <h:commandButton>, it doesn't generate JS code.
If your functional requirement is to navigate to other page, then you should definitely use <h:link>, or <h:outputLink>, or just plain HTML <a>.

richfaces how to detect mouse events

sorry if the answer to this is obvious but I couldn't find it.
How do I detect if the user has clicked, dragged etc. on an image (or other element)?
Thanks in advance!
There are several way of doing this:
In HTML it would be something like:
<img src="images/myImage.jpg" onclick="someJSFunc()"/>
In the case of Richfaces you'd probably want to invoke some sort of server side logic through an Ajax request after your image has been clicked, so, the most appropriate thing would be:
<img src="images/myImage.jpg">
<a4j:support event="onclick" action="#{myBean.someActionMethod}" reRender="someComponent"/>
</img>
For more information of how to add Ajax behavior to standard HTML components tags with Richfaces see the a4j:support component description.

Resources