Setting a variable in JSF [duplicate] - jsf

This question already has an answer here:
How to use Parameterized MessageFormat with non-Value attributes of JSF components
(1 answer)
Closed 6 years ago.
I have something like this in my jsf:
<div title="Percentage: #{myBean.numberToBeConvertedToPercentage}"></div>
I wanted to make something like this:
<h:outputText value="#{myBean.numberToBeConvertedToPercentage}">
<f:convertNumber maxFractionDigits="2" type="percent"/>
</h:outputText>
Of course, not inside an output text, but instead setting the converted number to a variable, so I can use it inside my div.
I don't want to take this converted number direct from my bean, since I use it in another places of my view without formatting it, and creating a get just for this, I don't like the idea. There is any way to make this only in my view?

To go with <h:outputText> + converter, it is the best approach for this purpose in JSF. You can redesign your Html to separate the label "Percentage: " and the data. to use rendered value in JS code to pass it to 'title' attribute.
<div id="titleDiv" />
<script type="text/javascript">
$('#titleDiv').title = 'Percentage: <h:outputText value="#{myBean.numberToBeConvertedToPercentage}"><f:convertNumber maxFractionDigits="2" type="percent"/></h:outputText>';
</script>
If you still want to stay without converters, then you can create one more bean per your view and render values in get methods.
Other option is to use EL 2.2 Method call feature and to call your own format bean
<div title="Percentage: #{formatBean.formatNumber(myBean.numberToBeConvertedToPercentage, 2)}"></div>

I have not checked this, but maybe you can use ui:param and assign a converter to it.
and then use it in your page
<div title="Percentage: #{myVar}></div>
see Defining and reusing an EL variable in 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

create links dynamically

I have a user-defined text, such as
#SessionScoped
public class MyBean {
private String text = "Life’s but a walking shadow, a poor player
that struts and frets his hour upon the stage and
then is heard no more.";
public String getText() {
return text;
}
}
Of course the text is not static, but will be loaded from somewhere else. I want the text to be displayed one the page, as in
<h:form id="myForm">
<h:outputText value="#{myBean.text}" />
</h:form>
Now have a logic in the bean which marks certain words, e.g. every noun, in the text. These words should be rendered as links, as if they were commandLinks.
That is, the form should be submitted and I should be able to find out which link was clicked.
Something similar was already asked here, here and here, but I am not sure if the solutions given there suit my case.
My best guess right now is to split the text at the marked words into a list of snippets in the bean, e.g.
List<TextSnippet> textSnippets;
class TextSnippet {
private String precedingText;
private String markedWord;
...
}
such that each text snippet ends with a marked word. Then I would be able to iterate over the list in the xhtml, e.g.
<h:form id="myForm">
<ui:repeat var="snippet" value="#{myBean.textSnippets}">
<h:outputText value="#{snippet.precedingText}" />
<h:commandLink action="#{myBean.clickedOn(snippet.markedWord)}">
<h:outputText value="#{snippet.markedWord}">
</h:commandLink>
</ui:repeat>
</h:form>
However, I feel that this tightly couples the bean (logic of splitting) to the view. Any better ideas?
What I would personally do is try to keep the jsf tree small and implement something like the lines below that I think is more performant (disclamer: no full code coming )
Prepare the text serverside in a bean as This is a <div class="linkedWord">specific</div> word that needs a link and so is <div="linkedWord">this</div>
Output this in plain html via an <h:outputText value="#{myBean.text}"> (for escaping!)
Add a jquery dynamic eventhandler on the class="linkedWord" (so it works for each link) and call a javascript function
In that javascript function read the content of the div (or maybe add the text as a data- attribute aas well (like <div class="linkedWord" data-word="specific">specific</div>
and call a <h:commandScript> (JSF 2.3 and up) or a o:commandScript for previous JSF versions (or the `p:remoteCommand) and pass the content of the div (or the value of the attribute) as a parameter to a serverside method.
Keep in mind that there is no explicit reason to do everything in a 'JSF' way. Using client-side features and some small integration with JSF is very valid usage. People not doing this often 'blame' JSF but they themselves are effectively the cause of the less optimal behaviour)
See also:
Event binding on dynamically created elements?
http://omnifaces.org/docs/javadoc/2.6/org/omnifaces/component/script/CommandScript.html
https://javaserverfaces.github.io/docs/2.3/vdldocs/facelets/h/commandScript.html
You seem to go the right way, but I think I can suggest you some improvements. Don't know your exact requirements, but your current structure limits the marked word (which I guess acts as a mere link) to be at the end of the paragraph. What would happen if you have text after it? What about having two marked words? This class might suit better:
class TextSnippet {
private String text;
private String linkUrl;
...
}
You'll need to build the List<TextSnippet> the way you do, but evaluate the links before, so ui:repeat can access them.
Then, iterate over it. Instead of performing a POST to evaluate where to go, you've got it already, so you can use a h:link if you want to point to somewhere in your application or h:outputLink if it's outside it:
<ui:repeat var="snippet" value="#{myBean.textSnippets}">
<h:outputText value="#{snippet.text}" rendered="#{empty snippet.linkUrl}" />
<h:link outcome="#{snippet.linkUrl}" rendered="#{not empty snippet.linkUrl}">
<h:outputText value="#{snippet.text}">
</h:link>
</ui:repeat>

Component in JSF that preserve new lines and whitespaces [duplicate]

This question already has an answer here:
h:outputText seems to trim whitespace, how do I preserve whitespace?
(1 answer)
Closed 7 years ago.
Mojara 2.1.21, Primefaces 3.5, Omnifaces 1.5
Is it possible in JSF to use a component that preserve whitespaces and new lines ?
I have something like that:
<c:forEach items="{bean.items}" var="item">
<h:outputText value="#{item.text}" />
<p:inputText value="#{item.getText[item.id]}" />
</c:forEach >
Instead of staring at JSF source code, you should first investigate how the generated HTML output should look like in order to achieve the concrete UI requirement. In plain HTML terms, you can achieve that by either putting the text content in a HTML <pre> element, or to apply CSS white-space:pre style on the parent element.
None of them have a JSF component equivalent. But that's also not necessary. You can just write HTML and CSS the usual way in JSF.
<pre><h:outputText value="#{item.text}" /></pre>
or
<h:outputText value="#{item.text}" style="white-space: pre;" />
(note: above example is intented as kickoff, normal practice is to use a normal CSS class)

Calling Managed Bean Method From JavaScript [duplicate]

This question already has an answer here:
How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?
(1 answer)
Closed 4 years ago.
I have an application with a client-side image map with multiple sections defined. I need to call a method in the Managed Bean from the <area> onclick attribute.
This doesn't work:
<area id="ReviewPerson" shape="rect" coords="3, 21, 164, 37" href="#"
onclick="#{personBean.method}" alt="Review Person" id="reviewPersonArea"
title="Review Person" />
Since my hands are tied on the image map (unfortunately), how can I call a managed bean method from within the <area> tag?
If you use primefaces, you don't need jquery. You use remoteCommand with a name attribute, and call that name from javascript, so:
<area... onclick="somejavascript();"... />
<p:remoteCommand name="myCommand" actionListener="#{personBean.method}" style="display: none;" />
Javascript:
function somejavascript(){
myCommand();
}
You have a few options. If you are using JSF 2.0 you can build a composite component around these area tags.
The easiest way however would be to invoke a hidden JSF input button.
<h:commandButton id="hdnBtn" actionListener="#{personBean.method}" style="display: none;" />
This will render as an input HTML element on the page that you can access from Javascript and invoke its click event.
onclick="jQuery('#form:hdnBtn').click();"
If you use Seam, Remoting can do this for you: http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/remoting.html
Another approach would be do expose the methods as REST services, and call them from your JavaScript using something like jQuery. Here's a good article on this approach: http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/
If you want complete ADF Faces solution you can try this:
function doClick(){
var button = AdfPage.PAGE.findComponentByAbsoluteId("aButton");
ActionEvent.queue(button,true);
}
This is the most up to date answer, for Java EE 8 (JSF 2.3)
use <h:commandScript> this will create a javascript function which will under the hood invoke the jsf backing bean method, and because it's a javascript you can invoke it from your js code
example
jsf
<h:form>
<h:commandScript id="submit"
name="jsFunction"
action="#{bean.method}"/>
</h:form>
and the js code
</script>
function invoke()
{
jsFunction();
}
</script>
for more visit Ajax method invocation
If you use primefaces, you can use a hidden input field linked to a managed bean, and you can initialize its value using javascript, for PrimeFaces, the PF function can be used to access a widget variable linked to the hidden input, in this way:
<script>
function codeLoginAddress() {
PF('wvLoginLat').jq.val( lat1 ); // set in getLocation
PF('wvLoginLng').jq.val( lng1 )
}
<script>
<p:inputText type="hidden" widgetVar="wvLoginLat" value="#{userSession.lat}" />
<p:inputText type="hidden" widgetVar="wvLoginLng" value="#{userSession.lng}" />
<script>
// at end of page, initialization code
getLocation(); // sets lat1 and lng1
codeLoginAddress(); // sets the value of the widget variables
</script>

JSF <h:outputFormat>: use array values as parameters

On my JSF2 page, i'm using internationalized error messages.
In my backing bean, i'm putting the messages into the flash Scope:
flash.put("error", exception.getType());
On the page, this string gets translated this way:
<h:outputText value="#{bundle[flash.error]}"/>
Works fine.
NOW i want to be also able to put (an arbitrary number of) parameters into the message text, that get inserted into the placeholders in the i18n-property in my message.properties. Therefore, i'm putting the parameters as a String array into the Flash Scope, like this:
//exception.getParameters returns String[]
flash.put("errorParams", exception.getParameters())
Now i also want to be able to use this String array as parameters for an outputFormat element, to insert them into a property like Welcome, {0} {1}.
So i tried to achieve this by using ui:repeat:
<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
<ui:repeat value="#{flash.errorParams}" var="_param">
<f:param value="#{bundle[_param]}"/>
<!-- also doesn't work: <f:param value="#{_param}"/>-->
</ui:repeat>
</h:outputFormat>
Unfortunately, the param value is ignored and the placeholders of the i18n-property aren't replaced, so the rendered output is Welcome, {0} {1}. When using a "regular" repeater, displaying the array elements just as an outputtext, it works. So the outputFormat tag doesn't seem to support the use of a repeat as a child.
Damn, so close ;) Anyone knows a good way to do what i want, or is there any component library supporting something like that?
The problem here is that ui:repeat is a render-time child of h:outputFormat which it indeed doesn't support at all. You'd like to put multiple f:param elements directly as children of h:outputFormat during build time.
The c:forEach is suitable for this task. The JSTL core tags (which are already included in Facelets, so you don't need to install any extra JARs) do their job during building the view tree, right before it's JSF turn to process/render the view tree.
<html xmlns:c="http://java.sun.com/jsp/jstl/core">
...
<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
<c:forEach items="#{flash.errorParams}" var="_param">
<f:param value="#{bundle[_param]}"/>
</c:forEach>
</h:outputFormat>

Resources