How do I have the cursor placed in a dropdown field on page load using jsf? - jsf

when I load a page , the cursor must point to drop-down field , using jsf.I am new to JSF.

When the page is finished loading in webbrowser, JSF has already done its job of generating a bunch of HTML on the webserver and sending it to the webbrowser. It can't do any much more for you after that point. You need to use JavaScript for this job. It is able to execute code when the page is finished loading and it has access to all elements in the HTML DOM tree.
So, if you specify a fixed ID for the dropdown element in JSF,
<h:form id="myform">
<h:selectOneMenu id="mydropdown">
...
</h:form>
then you must be able to grab it by JavaScript:
var mydropdown = document.getElementById('myform:mydropdown');
In JavaScript, you can use element.focus() to set the focus on the element:
mydropdown.focus();
To get it to execute then the page is finished loading, you need to hook a function to window.onload:
window.onload = function() {
var mydropdown = document.getElementById('myform:mydropdown');
mydropdown.focus();
}
That's it. Put it in a <script> somewhere near the bottom of the <head> or a .js file which you include by <script src>.

JSF is a server side technology and this type of behavior requires Javascript. Try to write a Javascript to do this in a regular HTML page first. Once you have figured out how to do this you can try to use this script in your JSF page.

Related

How to trigger click event on command button in JSF, after the evalution of action EL expression [duplicate]

Problem: Sometimes you will want to access a component from javascript with
getElementById, but id's are generated dynamically in JSF, so you
need a method of getting an objects id. I answer below on how you can do this.
Original Question:
I want to use some code like below. How can I reference the inputText JSF component in my Javascript?
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>Input Name Page</title>
<script type="javascript" >
function myFunc() {
// how can I get the contents of the inputText component below
alert("Your email address is: " + document.getElementById("emailAddress").value);
}
</script>
</head>
<h:body>
<f:view>
<h:form>
Please enter your email address:<br/>
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
</h:form>
</f:view>
</h:body>
</html>
Update: this post Client Identifiers in JSF2.0 discusses using a technique like:
<script type="javascript" >
function myFunc() {
alert("Your email address is: " + document.getElementById("#{myInptTxtId.clientId}").value);
}
</script>
<h:inputText id="myInptTxtId" value="backingBean.emailAddress"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
Suggesting that the attribute id on the inputText component
creates an object that can be accessed with EL using #{myInptTxtId},
in the above example. The article goes on to state that JSF 2.0 adds
the zero-argument getClientId() method to the UIComponent class.
Thereby allowing the #{myInptTxtId.clientId} construct suggested
above to get the actual generated id of the component.
Though in my tests this doesn't work. Can anyone else confirm/deny.
The answers suggested below suffer from drawback that the above
technique doesn't. So it would be good to know if the above technique
actually works.
You need to use exactly the ID as JSF has assigned in the generated HTML output. Rightclick the page in your webbrowser and choose View Source. That's exactly the HTML code which JS sees (you know, JS runs in webbrowser and intercepts on HTML DOM tree).
Given a
<h:form>
<h:inputText id="emailAddresses" ... />
It'll look something like this:
<form id="j_id0">
<input type="text" id="j_id0:emailAddress" ... />
Where j_id0 is the generated ID of the generated HTML <form> element.
You'd rather give all JSF NamingContainer components a fixed id so that JSF don't autogenerate them. The <h:form> is one of them.
<h:form id="formId">
<h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
This way the form won't get an autogenerated ID like j_id0 and the input field will get a fixed ID of formId:emailAddress. You can then just reference it as such in JS.
var input = document.getElementById('formId:emailAddress');
From that point on you can continue using JS code as usual. E.g. getting value via input.value.
See also:
How to select JSF components using jQuery?
Update as per your update: you misunderstood the blog article. The special #{component} reference refers to the current component where the EL expression is been evaluated and this works only inside any of the attributes of the component itself. Whatever you want can also be achieved as follows:
var input = document.getElementById('#{emailAddress.clientId}');
with (note the binding to the view, you should absolutely not bind it to a bean)
<h:inputText binding="#{emailAddress}" />
but that's plain ugly. Better use the following approach wherein you pass the generated HTML DOM element as JavaScript this reference to the function
<h:inputText onclick="show(this)" />
with
function show(input) {
alert(input.value);
}
If you're using jQuery, you can even go a step further by abstracting them using a style class as marker interface
<h:inputText styleClass="someMarkerClass" />
with
$(document).on("click", ".someMarkerClass", function() {
var $input = $(this);
alert($input.val());
});
Answer: So this is the technique I'm happiest with. Doesn't require doing too much weird stuff to figure out the id of a component. Remember the whole point of this is so you can know the id of a component from anywhere on your page, not just from the actual component itself. This is key. I press a button, launch javascript function, and it should be able to access any other component, not just the one that launched it.
This solution doesn't require any 'right-click' and see what the id is. That type of solution is brittle, as the id is dynamically generated and if I change the page I'll have to go through that nonsense each time.
Bind the component to a backing bean.
Reference the bound component wherever you want.
So here is a sample of how that can be done.
Assumptions: I have an *.xhtml page (could be *.jsp) and I have defined a backing bean. I'm also using JSF 2.0.
*.xhtml page
<script>
function myFunc() {
var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}")
alert("The email address is: " + inputText.value );
}
</script>
<h:inputText binding="#{backBean.emailAddyInputText}"/>
<h:commandButton onclick="myFunc()" action="results" value="Next"/>
BackBean.java
UIInput emailAddyInputText;
Make sure to create your getter/setter for this property too.
Id is dynamically generated, so you should define names for all parent elements to avoid j_id123-like ids.
Note that if you use jQuery to select element - than you should use double slash before colon:
jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
instead of:
jQuery("my-form-id:my-text-input-block:my-input-id")
In case of Richfaces you can use el expression on jsf page:
#{rich:element('native-jsf-input-id')}
to select javascript element, for example:
#{rich:element('native-jsf-input-id')}.value = "Enter something here";
You can view the HTML source when this is generated and see what the id is set to, so you can use that in your JavaScript. As it's in a form it is probably prepending the form id to it.
I know this is not the JSF way but if you want to avoid the ID pain you can set a special CSS class for the selector. Just make sure to use a good name so that when someone reads the class name it is clear that it was used for this purpose.
<h:inputText id="emailAddresses" class="emailAddressesForSelector"...
In your JavaScript:
jQuery('.emailAddressesForSelector');
Of course you would still have to manually manage class name uniqueness.
I do think this is maintainable as long as you do not use this in reusable components. In that case you could generate the class names using a convention.
<h:form id="myform">
<h:inputText id="name" value="#{beanClass.name}"
a:placeholder="Enter Client Title"> </h:inputText>
</h:form>
This is a small example of jsf. Now I will write javascript code to get the value of the above jsf component:
var x = document.getElementById('myform:name').value; //here x will be of string type
var y= parseInt(x,10); //here we converted x into Integer type and can do the
//arithmetic operations as well

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

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.

PrimeFaces markup remains after navigation in Liferay 7.0

I've noticed that when I navigate via GET from a page with certain PrimeFaces components, the markup of these components will appear in the upper left-hand corner of the next page.
This problem has happened with the following components (and probably others):
p:tooltip
p:columnToggler
p:notifiactionBar
p:selectOneMenu
p:autoComplete
p:confirmDialog
p:dialog
p:draggable
p:menuButton
p:selectCheckboxMenu
p:selectOneMenu
p:splitButton
Is there any way I can stop this markup from appearing after navigation?
Update: This issue has been verified as a bug in the Liferay Faces project and has been fixed as part of Bridge Ext 5.0.3: FACES-3328.
Explanation
This problem is due to an incompatibility between PrimeFaces (which was initially designed for webapps) and Liferay 7.0/SennaJS/Portlets. PrimeFaces assumes that it is being used in a webapp environment where it has control over all markup on the page, so many of the components that use JavaScript to help with rendering attach their markup to the <body> tag.
Here's a super simplified version of what PrimeFaces is doing:
<body>
<script>
var dynDiv = document.createElement("div");
var text = document
.createTextNode("I was created dynamically via JavaScript!");
dynDiv.appendChild(text);
document.body.appendChild(dynDiv);
</script>
</body>
However, in a portlet environment, portlet only has control over the portlet markup which is a <div> inside the <body> tag. But since PrimeFaces assumes a webapp environment, it still appends markup to the <body>:
<body>
<div id="myPrimeFacesPortlet">
<script>
var dynDiv = document.createElement("div");
var text = document
.createTextNode("I was created dynamically via JavaScript!");
dynDiv.appendChild(text);
document.body.appendChild(dynDiv);
</script>
</div>
</body>
Before Liferay 7.0, this was not a problem though since every navigation would cause a full page load and all the dynamic elements created by PrimeFaces' JavaScript would be destroyed. Now with Liferay 7.0 the Single Page Application engine of SennaJS is used to make sure that only necessary parts of the page are loaded and rendered on navigation. Now when you navigate away from the PrimeFaces portlet via SennaJS all PrimeFaces CSS is removed along with the portlet <div>. The dynamic elements are not removed, and the PrimeFaces CSS is unloaded so it cannot hide them anymore.
Solutions
There are several possible solutions to this problem (I've ordered them from best to worst):
If the component has an appendTo attribute, ensure that markup is appended to an element inside the portlet markup: appendTo="#this", appendTo="#id(#{portletNamespace})" (for the outermost <div> of the portlet) or appendTo="#form" should also work (although appendTo="#root" does not appear to work) (see the PF User Guide (p. 558) for more details on the "Search Expression Framework").
Permanently hide the dynamic elements with CSS. To ensure the CSS is not removed on SennaJS navigation, set data-senna-track="permanent":
<h:head>
<!--You'll need to look at the CSS for each element (not just tooltip)
to figure out what CSS classes should be hidden. -->
<style id="hidePrimeFacesLeftoverMarkupWorkaroundCSS"
data-senna-track="permanent">
.ui-tooltip {
display: none;
}
</style>
</h:head>
Disable SennaJS for your Portlet or your entire Portal.
More Info:
https://issues.liferay.com/browse/FACES-2677
https://web.liferay.com/community/forums/-/message_boards/view_message/105009688
https://web.liferay.com/community/forums/-/message_boards/view_message/94179972

Button do not work jsf [duplicate]

I am trying to implement jQuery with PrimeFaces and JSF components, but it's not working properly. When I tried to do the same with HTML tags it;s working properly.
Here is the code with HTML tags which works properly with jQuery:
<input type="checkbox" id="check2"></input>
<h:outputText value="Check the box, if your permanent address is as same as current address."></h:outputText>
<h:message for="checkbox" style="color:red" />
with
$("#check2").change(function() {
if ($("#check2").is(":checked")) {
$("#p2").hide();
} else {
$("#p2").show();
}
});
Here is the code with PrimeFaces/JSF which doesn't work properly with jQuery:
<p:selectManyCheckbox >
<f:selectItem itemLabel="1" value="one" id="rad" ></f:selectItem>
</p:selectManyCheckbox>
with
$("#rad").change(function() {
if ($("#rad:checked").val() == "one") {
$("#p2").hide();
} else {
$("#p2").show();
}
});
You should realize that jQuery works with the HTML DOM tree in the client side. jQuery doesn't work directly on JSF components as you've written in the JSF source code, but jQuery works directly with the HTML DOM tree which is generated by those JSF components. You need to open the page in webbrowser and rightclick and then View Source. You'll see that JSF prepends the ID of the generated HTML input elements with the IDs of all parent NamingContainer components (such as <h:form>, <h:dataTable>, etc) with : as default separator character. So for example
<h:form id="foo">
<p:selectManyCheckbox id="bar" />
...
will end up in generated HTML as
<form id="foo" name="foo">
<input type="checkbox" id="foo:bar" name="foo:bar" />
...
You need to select elements by exactly that ID instead. The : is however a special character in CSS identifiers representing a pseudo selector. To select an element with a : in the ID using CSS selectors in jQuery, you need to either escape it by backslash or to use the [id=...] attribute selector or just use the old getElementById():
var $element1 = $("#foo\\:bar");
// or
var $element2 = $("[id='foo:bar']");
// or
var $element3 = $(document.getElementById("foo:bar"));
If you see an autogenerated j_idXXX part in the ID where XXX represents an incremental number, then you must give the particular component a fixed ID, because the incremental number is dynamic and is subject to changes depending on component's physical position in the tree.
As an alternative, you can also just use a class name:
<x:someInputComponent styleClass="someClassName" />
which ends up in HTML as
<input type="..." class="someClassName" />
so that you can get it as
var $elements = $(".someClassName");
This allows for better abstraction and reusability. Surely those kind of elements are not unique. Only the main layout elements like header, menu, content and footer are really unique, but they are in turn usually not in a NamingContainer already.
As again another alternative, you could just pass the HTML DOM element itself into the function:
<x:someComponent onclick="someFunction(this)" />
function someFunction(element) {
var $element = $(element);
// ...
}
See also:
How can I know the id of a JSF component so I can use in Javascript
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
By default, JSF generates unusable IDs, which are incompatible with the CSS part of web standards
Integrate JavaScript in JSF composite component, the clean way
You also can use the jQuery "Attribute Contains Selector" (here is the url http://api.jquery.com/attribute-contains-selector/)
For example If you have a
<p:spinner id="quantity" value="#{toBuyBean.quantityToAdd}" min="0"/>
and you want to do something on its object you can select it with
jQuery('input[id*="quantity"]')
and if you want to print its value you can do this
alert(jQuery('input[id*="quantity"]').val());
In order to know the real html tag of the element you can always look at the real html element (in this case spinner was translated into input) using firebug or ie developer tools or view source...
Daniel.
If you're using RichFaces you can check rich:jQuery comonent. It allows you to specify server side id for jQuery component. For example, you have component with specified server id, then you can apply any jQuery related stuff to in next way:
<rich:jQuery selector="#<server-side-component-id>" query="find('.some-child').removeProp('style')"/>
For more info, please check doumentation.
Hope it helps.
look this will help you when i select experience=Yes my dialoguebox which id is dlg3 is popup.and if value is No it will not open

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.

Resources