JSF / CSS attribute conflicts - jsf

It's our first JSF app, and I'm in the middle of integrating our graphic designer's CSS into our facelets files. He tells me that he needs the name and id attributes of the input tags to be the same as the for attribute of the label tag.
His request:
<label for="username">User Name:</label>
<input id="username" type="text" name="username" />
However, when JSF code renders the HTML, I get extra identifiers in these attributes.
My facelet code:
<label for="username">User Name:</label>
<h:inputText value="#{login.username}" id="username" name="username" />
Final XHTML that's sent to the browser:
<label for="username">User Name:</label>
<input id="j_id2:username" type="text" name="j_id2:username" />
It makes sense to me from a JSF standpoint, but is there a way for me to meet our graphic designer's request and make everyone happy? Or is this a bad JSF oversight?
Thanks!

You can use the JSF outputLabel tag, which should handle the ids automatically:
<h:inputText id="username">
<h:outputLabel for="username" value="User Name: "/>
</h:inputText>
Edit: To avoid confusion: You can also put the outputLabel outside the inputText Element. I just use it mostly like this.

Related

Preset checked state of h:selectOneRadio with passthrough elements

I am trying to implement the solution described in
<h:selectOneRadio> renders table element, how to avoid this?
<div class="form-group">
<h:outputLabel styleClass="control-label"
value="#{msgClient.legalPersonality} " />
Selected value : <h:outputText value="#{msgClient['legalPersonality.' += clientBean.clientDto.legalPersonality.label]}" />
<div>
<f:metadata>
<f:viewParam name="legalPersonality" value="#{clientBean.clientDto.legalPersonality}" />
</f:metadata>
<ui:repeat var="legalPersonality" value="#{clientBean.legalPersonalities}">
<label class="radio-inline">
<input type="radio" jsf:id="legal" pt:name="legalPersonality" value="#{legalPersonality}">
<f:ajax execute="#this" render="#form" />
</input>
<h:outputText value="#{msgClient['legalPersonality.' += legalPersonality.label]}" />
</label>
</ui:repeat>
</div>
</div>
Everything seems to work fine, the selected value is correctly updated with the f:ajax component (setter is called with the correct value) BUT radio buttons are never checked. I mean it is checked when I click on it but it goes unchecked immediatly after. Even at page load, with a default value in clientDto.legalPersonality, everything is unchecked.
How it looks like : http://oi58.tinypic.com/242788g.jpg
Any help will be greatly appreciated. Thank you.
Indeed, the example in the question you found was a bit too oversimplified. It was missing the checked attribute which is necessary in order to preset the current selection on page load and/or after ajax render as in your case. In HTML, the checked state of a radio button is achieved by setting the checked attribute.
You can use <f:passThroughAttribute> to set the checked attribute, whereby you make sure that you set #{null} in unchecked case, so that it wouldn't render the checked attribute at all. It's namely a minimized attribute; even if we used checked="false", HTML would still consider it checked.
<input type="radio" jsf:id="legal" pt:name="legalPersonality" value="#{legalPersonality}">
<f:passThroughAttribute name="checked" value="#{legalPersonality eq clientBean.clientDto.legalPersonality ? 'checked' : null}" />
<f:ajax execute="#this" render="#form" />
</input>
The example in the question you found has in the meanwhile been updated. Thanks!

JSF commandButton - passing POST params to an external site

I need a link which redirect me to a different site and send POST parameters. Something like:
<h:form>
<h:commandButton value="submit" action="http://example.com">
<f:param name="user" value="robson">
</h:commandButton>
</h:form>
The code above doesn't work of course.
I'd like to acheive this in HTML:
<form action="http://example.com" method="POST">
<input type="hidden" name="user" value="robson">
<input type="submit" value="submit">
</form>
Is that possible?
Use the vanilla HTML <form> tag, not the JSF tag if you're going to send form data to a non-JSF target.
The JSF form tag is designed to facilitate JSF postback operations, which is why it has no "action" attribute.

Composite components & ID

I want to implement some javas cript into my JSF composite component, but I have problem with id. My java script with:
document.getElementById("myForm:customerId")
does not work, because the id is wrong. I have JSF composite component:
<composite:implementation>
<div id="element_customer">
<h2 class="element_title">Customer</h2>
<h:form id="myForm">
<h:inputText id="customerId" value="#{cc.attrs.customerId}"/>
</h:form>
</div>
</composite:implementation>
and HTML output is:
<div id="element_customer">
<h2 class="element_title">Customer</h2>
<form id="j_idt44:myForm" name="j_idt44:myForm" method="post" ... >
<input type="hidden" name="j_idt44:myForm" value="j_idt44:myForm" />
<input id="j_idt44:myForm:customerId" ... name="j_idt44:myForm:customerId" />
</form>
</div>
Why is "j_idt44" used in HTML output?
Composite components are NamingContainer components like <h:form>, <h:dataTable>, etc. This allows you to have multiple of them in the same view without conflicting IDs.
You need to give the composite component a fixed ID as well. E.g.
<my:composite id="someId" />
I'd also suggest to use <div id="#{cc.id}"> instead of <div id="element_customer">. It will then become someId with the above example.
Unrelated to the concrete problem, this isn't entirely the right purpose of a composite component. A composite component is intented to be of the same kind of <h:inputText>, etc. You seem to rather want a tag file or maybe an include file. See also When to use <ui:include>, tag files, composite components and/or custom components?

How to access html components in JSF EL?

I want some code in facelet (jsf 2.0) to work:
<h:inputText id="q" />
<h:button outcome="/search.xhtml?q=#{q.value}" />
but when I press the button, search page opens without any parameters.
I think, my EL expression is wrong. Is it possible to access inputText value from EL expression? If not, how can I achieve the same functionality?
I've finished with using plain html form:
<form action="faces/search.xhtml" method="get">
<input type="text" name="query" />
<input type="submit" value="Find" />
</form>
In search.xhtml I have view param to get a value of query string:
<f:metadata>
<f:viewParam name="query" />
</f:metadata>
This solution has the problem - "faces/search.xhtml" is hardcoded. Also, when I place this form in search.xhtml and perform several searches I have something like this in browser url:
"http://localhost:8080/Application/faces/faces/faces/search.xhtml"
I think this problem can be solved with PrettyFaces (TODO :)
this is a late answer but I guess many people finding this post will have the same doubt whether EL can access html component and how it can:
Yes, EL can access JSF component which are implicit JSF object.
However, up to now I have only seen and used the example of component.valid:
<h:inputText id="streetNumber" value="#{property.streetNumber}" title="streetNumber" required="true" requiredMessage="Please enter the street number!" validatorMessage="Please enter a street number between 1 and 1000" converterMessage="Please enter a number" pt:placeholder="900">
<f:convertNumber integerOnly="true"/>
<f:validateLongRange minimum="1" maximum="1000" />
</h:inputText>
<h:message for="streetNumber" class="#{!streetNumber.valid ? 'label label-warning' : 'none'}" />
So, I suggest you(Dmitry) change the code to
<h:button outcome="#{"/search.xhtml?q=" + q.value}" />
Please let me know whether it works because I am also curious and anyone who faces the similar problem can follow my example and please let me know the result.

Calling servlet post from jsf in different war

I want to call a Servlet which exists in a different war from my war. When user clicks a button we need to call the post method of the servlet. To implement this I did see an existing example which is slightly different but works in that case.
I am using jsf, so in the jsp there is a h:form with another html form inside of it. Below is the code:
<h:form>
<div id="gform" class="column span-20 append-1">
<h:outputText value="Text." /><br/><br/>
<h:commandLink id="addPaymentButton" styleClass="button" onclick='autorenew();return false;'> <span><h:outputText value="Payment Option"/></span> </h:commandLink>
<a id="noThanksButton" href="#"><span><h:outputText value="No Thanks"/></span></a><br/><br/><br/>
<h:outputText style="color:grey" value="Some text" />
<div> </div>
</div>
<form id="hiddenSubmit" method="post" action="https://localhost.myapp.com/myapp/LoginRouter" >
<input type="hidden" name="redirectUrl" value="/myapp/customers/addNewSavedCCInfo.faces"/>
<input type="hidden" name="jump_message" value="IAmJumpingToCC"/>
<input type="hidden" name="jump_url" value="/premiumServices/myPage.htm"/>
<input id="hiddenSubmitButton" type="submit" name="submit" style="display: none" value='' />
</form>
</h:form>
<script language="javascript">
function autorenew(){
window.alert('In js fnt');
document.hiddenSubmit.getElementById('hiddenSubmitButton').click();
window.alert('In js fnt COMPLETE');
return false;
}
So when the button is clicked, javascript is executed which submits the form to the servlet. However I can see in firebug that the second form which I need to submit does not appear. I am not sure how I can call the post method of a servlet class in a different war. Any ideas welcome, I am really stuck!
Thanks.
As per the HTML specification it's forbidden to nest <form> elements. The (mis)behaviour is browser dependent. Some browsers will send all parameters, some browsers will send only the data of the parent form, other browsers will send nothing.
You want to have a single form here. You can perfectly replace the <h:form> by a plain vanilla HTML <form> with the desired action pointing to the servlet in question.

Resources