JSF2.0: variable list of custom component - custom-component

Is there any way of using JSF2.0 in connection with variable lists of components? For example, lets say I have list o people that I would like to edit. They are presented on the page as list of components PersonEditor, which allow changing person data. Each editor is associated with single Person element. In order for this to work I need to perform following steps:
On initial request:
Get list of people
For each person create PersonEditor and associate it with Person object.
Fill editor's data.
On user action:
When user changes values and presses Save, data is processed by backing bean.
I can either fill editor with data from list of people or bind it to the backing bean, but not at the same time, so I am stuck.
I tried
people.xhtml
<ui:render value="#{bean.people}" var="person">
<example:personEditor person="#{person}"/>
</ui:render>
where personEditor.xhtml:
a) proper association with person object, but no connection to backing bean
<h:form>
<h:outputText value="#{cc.attr.person.name}"/>
<h:commandButton name="Save" actionListener="editorBean.save">
<f:ajax execute="#form" render="#form"/>
</h:commandButton>
</h:form>
b) no association with person object, but there is connection to backing bean - there is no way to pass that person to the backing bean
<h:form>
<h:outputText value="#{editorBean.name}"/>
<h:commandButton name="Save" actionListener="editorBean.save">
<f:ajax execute="#form" render="#form"/>
</h:commandButton>
</h:form>
If I had each editor on separate page, I could pass the person id as url parameter (either using f:param or f:attribute) and initialize it accordingly.
Is there any solution to this problem?

Hm, wondering why nobody answered this so far... Check this out:
http://balusc.blogspot.com/2006/06/communication-in-jsf.html
So your code would look something like this:
<h:form>
<h:outputText value="#{cc.attr.person.name}"/>
<h:commandButton name="Save" actionListener="#{editorBean.save}">
<f:ajax execute="#form" render="#form"/>
<f:setPropertyActionListener target="#{editorBean.editedPersonId}" value="#{cc.attr.person.id}" />
</h:commandButton>
</h:form>
and upon calling editorBean.save the attribute will contain the id of the person edited (or you could pass the person object itself).

Related

Create a popup inside a form

I want to include a popup inside a form. The normal way to do that is to have 2 forms like:
<div class="wrapper" >
<h:form>
<h:panelGroup id="id1" layout="block">
<ui:include src= content1 />
</h:panelGroup>
</h:form>
</div>
<h:form id="modalId">
<ui:include src= popupContent >
</ui:include>
</h:form>
and render with a button inside content1, the form "modalId" that contains the popUp.
I have the popup form in an external component that is included inside "content1". Due to the popup form is inside the other form,it isnt well rendered. How can I fix that? The idea is to use that component that is common for all my xhtml views
The way i was writing my own components was to rely on the existance of the external form. That is, i did not include any form elements inside the component.
If there was a need to reference the outer form element then i would just pass the from id as one of the attributes of the interface. Composite components are really useful for this kind of stuff:
<composite:interface>
<composite:attribute name="formId" type="java.lang.String" />
</composite:interface>
<composite:implementation>
<h:commandButton value="button" action="someaction">
<f:ajax execute="#{cc.attrs.formId}" render="#{cc.attrs.formId}" />
</h:commandButton>
</composite:implementation>
Then you include that in your outer form (assuming 'comp' is your namespace for composite components and 'modal' is the name of the file containing the component):
<h:form id="myForm">
<comp:modal formId="myForm"/>
</h:form>
Go through this tutorial if you are not familiar with them:
http://docs.oracle.com/javaee/6/tutorial/doc/giqzr.html

Ignore custom validation, but not the required="true" depending on button pressed

I am using JSF and I want to validate a form.
In the form is a text field that is validated by required="true" and a validator method.
<h:inputText
required="true" requiredMessage="Please enter a topic"
validator="#{eventController.validateTopic}" />
To submit the form I have two buttons. When clicking on the first, it should be only validate if the field is empty. By the second one the custom validation should be additionally invoked.
Is this possible?
First turn that validation method into a true Validator implementation.
#FacesValidator("topicValidator")
public TopicValidator implements Validator {}
Then you can use it in a <f:validator> which supports disabled attribute.
<h:inputText ...>
<f:validator validatorId="topicValidator" disabled="..." />
</h:inputText>
To let it check if a certain button is pressed, just check the presence of its client ID in the request parameter map.
<h:inputText ...>
<f:validator validatorId="topicValidator" disabled="#{empty param[secondButton.clientId]}" />
</h:inputText>
...
<h:commandButton binding="#{secondButton}" ... />
Note: do absolutely not bind it to a bean property! The above code is as-is. You should only guarantee that the EL variable #{secondButton} is unique in the current view and not shared by another component or even a managed bean.
See also:
How to let validation depend on the pressed button?
How does the 'binding' attribute work in JSF? When and how should it be used?

Is it possible to define a form for a single row in a panelgrid?

Is it somehow possible to have a form for a single row in a panelGrid? If I just put the specific columns in a form-Tag they are (of course) rendered in one single column of my parent panelGrid.
Is there a possibility to solve this problem? It does not matter if a solution use the jsf-tag or the primefaces-tag
I am using Mojarra 2.1.26 and Primefaces 4.0
use partial process/update.
if your requirement is to send only data in specific row (and not sending other http parameters, even if they are not processed) add partialSubmit feature:
<h:form>
<p:panelGrid id="grid">
<p:row id="row1">
<p:column>
<p:inputText value="#{someBean.someProperty}"/>
</p:column>
<p:column>
<p:inputText value="#{someBean.anotherProperty}"/>
</p:column>
</p:row>
<!-- other rows -->
</p:panelGrid>
<p:commandButton action="#{someBean.someAction}" process="#this row1"
update="grid" partialSubmit="true" value="submit"/>
</h:form>
this behave the same (almost) as having a form just for row1.
note that you have to update grid because p:panelgrid renders its child components on its own.
however your desired behavior (exactly) is not possible using plain html either.

How to dynamically add new row to p:dataTable without validating the form?

I'm developing a form for adding/editing product prices with JSF and PrimeFaces. A single product can have multiple prices depending on volume which is shown in a <p:dataTable>.
The backing bean:
#ManagedBean
#ViewScoped
public class ProductBean {
protected Product product;
protected List<ProductPrice> productPrices;
public void addNewPrice() {
ProductPrice productPrice = new ProductPrice();
productPrice.setPrice(new BigDecimal(0));
this.productPrices.add(productPrice);
}
// ...
}
The Facelet page:
<h:form id="productForm">
<p:inputText value="#{productBean.product.name}" required="true">
<f:ajax event="blur" render="nameMessage" />
</p:inputText>
<p:message id="nameMessage" for="name" />
<p:dataTable id="pricesList" ...>
</p:dataTable>
<p:commandButton value="Add another price" update="pricesList" action="#{productBean.addNewPrice()}" />
<p:commandButton value="Submit" action="#{productBean.submit}" />
</h:form>
The first button "Add another price" does, what it is supposed to do: Adding a new row to "pricesList". But only if form is valid (form is invalid, if product-name is not set).
My problem is, that I am having two commandButtons for the form, but I don't know how to get my wished functionallity without a commandButton. I tried a lot of ways: Changing the "Add another price" to a standard <p:button> with ajax-functionality; doesn't work because of buttons' outcome. I tried "type=button" for this button, but in this case simply nothing happens.
Are there any suggestions have to achieve my wished functionality? It is not necessary to have a button solving my problem.
The <p:commandButton> submits and processes by default the entire form. This will indeed validate all input fields. You can control this with the process attribute which thus defaults to #form. In your particular case, you could just use #this so that only the command button's own action is invoked.
<p:commandButton value="Add another price" process="#this" update="pricesList" action="#{productBean.addNewPrice()}" />
what's wrong with using p:commandButton to add rows dynamically?
If i undersatnd your question right, you obviously need a request to your managed bean in order to add your new row information into your datatable list. you could always go for p:commandLink if you are not comfortable with p:commandButton. and for editing the row data you could use p:rowEditor with p:datatable.
check out the showcase example for datatable row editing
hope this helps :)

Execute other form field value in JSF ajax

Consider the following JSF 2.x markup:
<h:form id="form1">
<h:inputText id="input" value="#{testBacking.input}"/>
</h:form>
<h:form id="form2">
<h:commandButton value="go" action="#{testBacking.go()}">
<f:ajax execute="#all" render="output"/>
</h:commandButton>
<h:outputText id="output" value="#{testBacking.input}"/>
</h:form>
The action method as follows:
public void go() {
System.out.println("go() is called");
System.out.println("input: "+ input);
}
The input value does not submitted to the server upon clicking the button.
Are there any ways to submit the input value to the server (while keeping the input in a different form)?
If you can only submit fields from the same form, then what is the different between the following two?
<f:ajax execute="#all" render="output"/>
<f:ajax execute="#form" render="output"/>
A quick search of jsf execute=#all vs execute=#form yields some results:
JSF: Execute values of multiple forms
What is <f:ajax execute="#all"> really supposed to do? It POSTs only the enclosing form
In essence, the JSF processing works ok but HTML only sends the form that contains the ajax (I suspect HTML specifies a separate request for each form).