JSF:
<h:form>
<h:inputHidden id="promo" value="promo-motopair"/>
<h:commandButton value="#{m.buy}" action="#{showProducts.buy}"/>
</h:form>
<h:form>
<h:inputHidden id="promo" value="promo-northduck"/>
<h:commandButton value="#{m.buy}" action="#{showProducts.buy}"/>
</h:form>
Bean, where get clicked id:
String promo = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("promo");
Can't get it because id is equal promo, but prepended with prefix, looks like j_idt40:promo
How to handle such situation?
I need get item by key. I suppose,that key(which is id in inputhidden) should be single. I should rely on promo value only.
Don't use <h:inputHidden>. It's unsuitable for your particular functional requirement. Just use standard HTML <input type="hidden">.
<h:form>
<input type="hidden" name="promo" value="promo-motopair"/>
<h:commandButton value="#{m.buy}" action="#{showProducts.buy}"/>
</h:form>
<h:form>
<input type="hidden" name="promo" value="promo-northduck"/>
<h:commandButton value="#{m.buy}" action="#{showProducts.buy}"/>
</h:form>
It's in a request scoped bean by the way also available by just
#ManagedProperty("#{param.promo}")
private String promo;
without the need to manually grab it from the request parameter map.
Related
Using JSF 2.1
We have a form that encapsulates blocks of search results. Each block has a "Delete" button that talks to the View scoped backing and removes the block (from a Session scoped bean).
Visually something like this:
-- group
-- block (delete button)
-- search result
-- block
-- search result
...
When the last block is deleted the entire group disappears.
Anyways. The follow implementation of a delete works fine:
<h:commandButton
styleClass="delete"
action="#{backing.taBortFranTrafflista(sokning)}"
value="#{backing.getText('trafflista.taBort')}"
onclick="return confirm('#{backing.getText('FR100', sokning.sokbegrepp, backing.aktuelltAntalTraffar(sokning))}');"
rendered="#{backing.javascriptEnabled}"
disabled="#{commons.trafflistaLast}">
<f:ajax render="#form" />
</h:commandButton>
However, the following implementation with a confirmation do in JQuery works but NOT with the last search result whereby the action (assigned to the h:commandButton) is never called:
<ui:fragment rendered="#{backing.javascriptEnabled}">
<div id="dialog#{sokning.hashCode()}" title="Ta bort" class="dialog">
<p>#{backing.getText('FR100', sokning.sokbegrepp, backing.aktuelltAntalTraffar(sokning))}</p>
<h:commandButton
styleClass="delete dialog-button"
action="#{backing.taBortFranTrafflista(sokning)}"
value="#{backing.getText('trafflista.taBort')}"
onclick="closeDialog('dialog#{sokning.hashCode()}')"
disabled="#{commons.trafflistaLast}">
<f:ajax render="#form" onerror="ajaxError"/>
</h:commandButton>
<input
type="submit"
data="dialog#{sokning.hashCode()}"
class="closeDialog dialog-button"
value="#{backing.getText('trafflista.avbryt')}" />
</div>
<ui:fragment rendered="#{not commons.trafflistaLast}">
<input
type="submit"
data="dialog#{sokning.hashCode()}"
class="delete showDialog"
value="#{backing.getText('trafflista.taBort')}" />
</ui:fragment>
<ui:fragment rendered="#{commons.trafflistaLast}">
<input
type="submit"
class="delete showDialog"
value="#{backing.getText('trafflista.taBort')}"
disabled="disabled"/>
</ui:fragment>
</ui:fragment>
Reason faces-redirect=true works is that DOM components inside the form match up with the server representation. The JQuery dialog was rendered outside the form at the bottom of the page. Doing a render equal #all solved the problem. Another solution was to render the dialog inside the form.
I want to pass user input to another page as a parameter. Here is my code:
<h:form>
<h:inputText value="#{indexBean.word}"/>
<h:commandLink value="Ara" action="word.xhtml">
<f:param value="#{indexBean.word}" name="word"/>
</h:commandLink>
</h:form>
Well, this is not working. I can read the inputtext value in my backing bean but I can't send it to word.xhtml.
Here is another approach I tried:
<h:form>
<h:inputText binding="#{indexBean.textInput}"/>
<h:commandLink value="Ara" action="word.xhtml">
<f:param value="#{indexBean.textInput.value}" name="word"/>
</h:commandLink>
</h:form>
This is also not working.
So, what am I doing wrong?
Your concrete problem is caused because the <f:param> is evaluated when the page with the form is requested, not when the form is submitted. So it remains the same value as on the initial request.
The concrete functional requirement is not exactly clear, but the particular functional requirement can be solved in basically two ways:
Use plain HTML.
<form action="word.xhtml">
<input type="text" name="word" />
<input type="submit" value="Ara" />
</form>
Send a redirect in action method.
<h:form>
<h:inputText value="#{bean.word}" />
<h:commandButton value="Ara" action="#{bean.ara}" />
</h:form>
with
public String ara() {
return "word.xhtml?faces-redirect=true&word=" + URLEncoder.encode(word, "UTF-8");
}
I have a contact form at the bottom of a page with required and validated form fields. If validation fails, how can I get the scroll position back to the bottom of the page?
I want this page to work with Javascript disabled, so no AJAX solutions. I have something like this:
<a id="contact"></a>
<h:form id="cform">
<h5>Contact!</h5>
<h:outputLabel for="name">Name:
<h:message id="nameMsg" for="name" />
</h:outputLabel>
<h:inputText id="name" value="#{bean.name}" required="true" requiredMessage="Please enter name!" />
<h:outputLabel for="email">Email:
<h:message id="emailMsg" for="email" />
</h:outputLabel>
<h:inputText id="email" value="#{bean.email}" required="true" requiredMessage="Email is required!">
<f:validator validatorId="myValidator" />
</h:inputText>
<h:outputLabel for="comment">Comment:
<h:message id="commentMsg" for="comment" />
</h:outputLabel>
<h:inputTextarea id="comment" value="#{bean.comment}" required="true" requiredMessage="Please enter a comment!"/>
<h:commandButton action="#{bean.go}" id="send" value="send" />
</h:form>
I thought about doing validations on the bean side and doing manual redirects to the appropriate anchor, but that seems to defeat the purpose of using JSF to begin with. I assume there is an easy way to do this, but I'm having trouble Googling a solution because I'm probably not wording the question right. Any one?
You can use <f:event type="postValidate"> to have a listener hook right after the validations phase. You can use FacesContext#isValidationFailed() to check if validation has failed or not. You can use Flash#setKeepMessages() to let the faces messages survive a redirect (they're namely by default request scoped!). You can use ExternalContext#redirect() to perform a redirect in a non-action method.
So, summarized, this should do:
<h:form id="cform">
...
<f:event type="postValidate" listener="#{bean.postValidate}" />
</h:form>
with:
public void postValidate() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.isValidationFailed()) {
context.getExternalContext().getFlash().setKeepMessages(true);
context.getExternalContext().redirect("contact.xhtml#cform");
}
}
Or we can use f:ajax onerror= for do something if they are an errors :
<p:commandButton **>
<f:ajax onerror="window.scrollTo(0, 0);" />
</p:commandButton>
You don't need an explicit anchor tag for this, the id of the form will do.
You could make Faces render the id at the end of the form action Url.
Eg.
... Your main page content goes here ....
<form id="contact-form" action="/MyView.jsf#contact-form" method="post">
This will cause the browser to scroll to the form after it is submitted.
It shows in the Url too.
You could probably implement a custom Form renderer to do this.
So my team has a jsf and we use an EL statement to read in the value of an input box, works fine but by default we have our value set as what should be filled into the field. How can I set a default value for the input while still having the EL statement work.
Example:
<h:inputText value="#{registrationBean.firstName}" styleClass="formEle"/>
I tried
<h:inputText value="#{registrationBean.firstName}First Name" styleClass="formEle"/>
but this breaks the connection when we submit.
Any ideas?
You're looking for something which is called a "watermark" or "placeholder". At low level, these days this is normally to be done by the HTML5 placeholder attribute:
<input type="text" placeholder="First Name" />
This works of course only in browsers supporting HTML5 and then only with JSF components supporting the new HTML5 attribute. The standard JSF <h:inputText> doesn't support this natively (yet). You'd need to look for 3rd party component libraries supporting this. Among them is PrimeFaces with its <p:watermark>:
<h:inputText id="firstName" value="#{registrationBean.firstName}" />
<p:watermark for="firstName" value="First Name" />
If using PrimeFaces is not an option for some reason, you'd need to reinvent it yourself in flavor of a custom component and/or a custom piece of JS/jQuery, exactly like <p:watermark> is doing under the covers.
You could define default value of <h:inputText> in your backing bean in PostConstrut phase.
#ManagedBean(name="registrationBean")
public class RegistrationBean{
private String firstName;
#PostConstruct
public void init(){
firstName = "your default value";
}
}
After page creation value displayed in h:inputText will be as you defined in backing bean.
It's kind of work around without any third party library maybe it will help someone.
The HTML-Tags rendered by JSF can be modified by JavaScript after loading inserting a placeholder attibute for HTML5:
<script>
window.onload = function() {
document.getElementById('email').setAttribute("placeholder", "Email");
document.getElementById('pwd').setAttribute("placeholder", "Password");
}
</script>
If you decide to use PrimeFaces you are not required to use a watermark, see example below:
<h:form>
<p:panel id="panel" header="Client Details" style="margin-bottom:10px;">
<p:messages id="messages" />
<h:panelGrid columns="2">
<h:outputLabel for="firstName" value="First Name" />
<p:inputText id="firstName" value="#{clientlistpagebean.selectedFieldClient.firstName}" required="true" />
<p:outputLabel for="lastName" value="Last Name" />
<p:inputText id="lastName" value="#{clientlistpagebean.selectedFieldClient.lastName}" required="true" />
</h:panelGrid>
</p:panel>
<p:commandButton value="Submit" update="panel" style="margin-right:20px;" />
</h:form>
I am using jsf2 and richfaces 4.X how can i get the richfaces enabled input field's current value ? equal to getElementById('field_name').vlue
I tried some of the methods named like findcomponent.value and element.value but they give me old value which was while page was loaded b/c findcomponent and element method returns server side UI.components instead client side components ?
I guess you are to use rich:clientId function to render a correct identifier into your java script.
For example:
var myElement = document.getElementById("#{rich:clientId('field_name')}");
See also RichFaces rich:clientId within facelets
If you check the HTML generated, you could see that every JSF / RF element has his id like :. For example:
<h:form id="frmSample">
<h:inputText id="txtSample" value="#{mybean.someTextValue}" />
</h:form>
The HTML generated will be:
<form method="POST">
<input type="text" id="frmSample:txtSample" />
</form>
So, in JavaScript you could reference the element by this id.
var txtValue = document.getElementById('frmSample:txtSample').value;
Also, for the RF composite HTML components like rich:tab or rich:calendar you could use the component ID generated by HTML but I'll recommend "#{rich:clientId('field_name')}" as #DRCB has explained in his post.
To get the richfaces components values use the rich:component and the getValue() methods.
To get the jsf library components values use the rich:element and the value JS methods.
Example:
<h:form>
<h:inputText id="textField" value="#{bean.value1}" />
<a4j:commandButton value="displayTextField" action="doSomething()"
onclick="alert('v:'+ #{rich:element('textField')}.value); return true;" />
<rich:inplaceInput id="richField" value="#{bean.value1}" />
<a4j:commandButton value="displayRichField" action="doSomething()"
onclick="alert('v:'+ #{rich:component('richField')}.getValue()); return true;" />
</h:form>
They both work even in a rich:dataTable, without adding the id of the datatable or something. Richfaces is quite smart and find the ids of the 'current row'
example:
<h:form>
<rich:dataTable id="mydatatable" value="bean.findValues()" var="myvar">
<rich:column>
<h:inputText id="textField" value="#{myvar.text1}" />
<a4j:commandButton value="displayTextField" action="doSomething()"
onclick="alert('v:'+ #{rich:element('textField')}.value); return true;" />
</rich:column>
<rich:column>
<rich:inplaceInput id="richField" value="#{myvar.text2}" />
<a4j:commandButton value="displayRichField" action="doSomething()"
onclick="alert('v:'+ #{rich:component('richField')}.getValue()); return true;" />
</rich:column>
</rich:dataTable>
</h:form>