I have Facelet component and I have backing bean for it. When I include my component to some page I pass bean from page to my component:
<ui:include src="./WEB-INF/templates/myTemplate.xhtml">
<ui:param name="pageBean" value="#{thisPageBean}" />
</ui:include>
My component also have backing bean and I try to pass value from invoking page bean to my:
<c:set target="#{componentBean}" property="field" value="#{pageBean.field}" />
But this method doesn't work? There is some way to pass value from one bean to another?
I am trying create difficult custom component that must do some validation and other action on things that was pass to it? Maybe I am in wrong way?
You could pass the bean as an attribute on the component (I assume when you say "component" you are using ui:component).
For a component:
<ui:component binding="#{componentBean.myComponent}">
<f:attribute name="foo" value="#{pageBean.field}" />
<h:outputText value="#{componentBean.something}" />
</ui:component>
You could have a backing bean with these methods:
private Object field;
private UIComponent component;
public void setMyComponent(UIComponent c) { component = c; }
public UIComponent getMyComponent() { return component; }
private void lookupFields() {
field = component.getAttributes().get("foo");
}
public String getSomething() {
if (field == null) {
lookupFields();
}
return "" + field;
}
Not very elegant, but I'm not all that familiar with the mechanics of Facelets includes and this is the first thing that occurred to me. Note that the attributes might be persisted when the view is saved - I can't remember for stuff that gets set on the attributes map.
Usually you assign values to some input controls like:
<h:inputText value='#{pageBean.field}'/>
That implies both getting and setting the value of someField property.
Please provide details on what should determine the value of #{pageBean.field} in your case.
Here is some code from one of my facelets files. As you can see the value of the bean passed as a parameter, ie:
<ui:param name="bean" value="#{thisPageBean}" />
and the property of the bean, dto, can be accessed using the [dto] notation.
<h:panelGroup>
<h:selectOneMenu id="titleMenu" value="#{bean[dto].title}">
<f:selectItems value="#{suburbsMBean.titles}" />
</h:selectOneMenu>
<h:message for="titleMenu" styleClass="error" />
</h:panelGroup>
You can call bean methods with params in JSF 2.0
So you can try to just place the setter method in a comment like this:
<!-- #{componentBean.setField(pageBean.field)} -->
So when the page is loaded the setter method will be triggered.
Related
I'm using Primefaces in a JSF 2 application. I have a <p:dataTable>, and instead of selecting rows, I want the user to be able to directly execute various actions on individual rows. For that, I have several <p:commandLink>s in the last column.
My problem: how can I pass a row ID to the action started by the command link so that I know which row to act on? I tried using an <f:attribute>:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
But it always yields 0 - apparently the row variable f is not available when the attribute is rendered (it works when I use a fixed value).
Anyone has an alternative solution?
As to the cause, the <f:attribute> is specific to the component itself (populated during view build time), not to the iterated row (populated during view render time).
There are several ways to achieve the requirement.
If your servletcontainer supports a minimum of Servlet 3.0 / EL 2.2, then just pass it as an argument of action/listener method of UICommand component or AjaxBehavior tag. E.g.
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
In combination with:
public void insert(Long id) {
// ...
}
This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
You can even pass the entire item object:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
with:
public void insert(Item item) {
// ...
}
On Servlet 2.5 containers, this is also possible if you supply an EL implementation which supports this, like as JBoss EL. For configuration detail, see this answer.
Use <f:param> in UICommand component. It adds a request parameter.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
If your bean is request scoped, let JSF set it by #ManagedProperty
#ManagedProperty(value="#{param.id}")
private Long id; // +setter
Or if your bean has a broader scope or if you want more fine grained validation/conversion, use <f:viewParam> on the target view, see also f:viewParam vs #ManagedProperty:
<f:viewParam name="id" value="#{bean.id}" required="true" />
Either way, this has the advantage that the datamodel doesn't necessarily need to be preserved for the form submit (for the case that your bean is request scoped).
Use <f:setPropertyActionListener> in UICommand component. The advantage is that this removes the need for accessing the request parameter map when the bean has a broader scope than the request scope.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
In combination with
private Long id; // +setter
It'll be just available by property id in action method. This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Bind the datatable value to DataModel<E> instead which in turn wraps the items.
<h:dataTable value="#{bean.model}" var="item">
with
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(making it transient and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean since DataModel doesn't implement Serializable)
Then you'll be able to access the current row by DataModel#getRowData() without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Use Application#evaluateExpressionGet() to programmatically evaluate the current #{item}.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #1 or, when you'd like to support servlet 2.5 containers as well, with #2.
In JSF 1.2 this was done by <f:setPropertyActionListener> (within the command component). In JSF 2.0 (EL 2.2 to be precise, thanks to BalusC) it's possible to do it like this: action="${filterList.insert(f.id)}
In my view page:
<p:dataTable ...>
<p:column>
<p:commandLink actionListener="#{inquirySOController.viewDetail}"
process="#this" update=":mainform:dialog_content"
oncomplete="dlg2.show()">
<h:graphicImage library="images" name="view.png"/>
<f:param name="trxNo" value="#{item.map['trxNo']}"/>
</p:commandLink>
</p:column>
</p:dataTable>
backing bean
public void viewDetail(ActionEvent e) {
String trxNo = getFacesContext().getRequestParameterMap().get("trxNo");
for (DTO item : list) {
if (item.get("trxNo").toString().equals(trxNo)) {
System.out.println(trxNo);
setSelectedItem(item);
break;
}
}
}
Thanks to this site by Mkyong, the only solution that actually worked for us to pass a parameter was this
<h:commandLink action="#{user.editAction}">
<f:param name="myId" value="#{param.id}" />
</h:commandLink>
with
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String idString = params.get("myId");
long id = Long.parseLong(idString);
...
}
Technically, that you cannot pass to the method itself directly, but to the JSF request parameter map.
I'm using Primefaces in a JSF 2 application. I have a <p:dataTable>, and instead of selecting rows, I want the user to be able to directly execute various actions on individual rows. For that, I have several <p:commandLink>s in the last column.
My problem: how can I pass a row ID to the action started by the command link so that I know which row to act on? I tried using an <f:attribute>:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
But it always yields 0 - apparently the row variable f is not available when the attribute is rendered (it works when I use a fixed value).
Anyone has an alternative solution?
As to the cause, the <f:attribute> is specific to the component itself (populated during view build time), not to the iterated row (populated during view render time).
There are several ways to achieve the requirement.
If your servletcontainer supports a minimum of Servlet 3.0 / EL 2.2, then just pass it as an argument of action/listener method of UICommand component or AjaxBehavior tag. E.g.
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
In combination with:
public void insert(Long id) {
// ...
}
This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
You can even pass the entire item object:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
with:
public void insert(Item item) {
// ...
}
On Servlet 2.5 containers, this is also possible if you supply an EL implementation which supports this, like as JBoss EL. For configuration detail, see this answer.
Use <f:param> in UICommand component. It adds a request parameter.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
If your bean is request scoped, let JSF set it by #ManagedProperty
#ManagedProperty(value="#{param.id}")
private Long id; // +setter
Or if your bean has a broader scope or if you want more fine grained validation/conversion, use <f:viewParam> on the target view, see also f:viewParam vs #ManagedProperty:
<f:viewParam name="id" value="#{bean.id}" required="true" />
Either way, this has the advantage that the datamodel doesn't necessarily need to be preserved for the form submit (for the case that your bean is request scoped).
Use <f:setPropertyActionListener> in UICommand component. The advantage is that this removes the need for accessing the request parameter map when the bean has a broader scope than the request scope.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
In combination with
private Long id; // +setter
It'll be just available by property id in action method. This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Bind the datatable value to DataModel<E> instead which in turn wraps the items.
<h:dataTable value="#{bean.model}" var="item">
with
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(making it transient and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean since DataModel doesn't implement Serializable)
Then you'll be able to access the current row by DataModel#getRowData() without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Use Application#evaluateExpressionGet() to programmatically evaluate the current #{item}.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #1 or, when you'd like to support servlet 2.5 containers as well, with #2.
In JSF 1.2 this was done by <f:setPropertyActionListener> (within the command component). In JSF 2.0 (EL 2.2 to be precise, thanks to BalusC) it's possible to do it like this: action="${filterList.insert(f.id)}
In my view page:
<p:dataTable ...>
<p:column>
<p:commandLink actionListener="#{inquirySOController.viewDetail}"
process="#this" update=":mainform:dialog_content"
oncomplete="dlg2.show()">
<h:graphicImage library="images" name="view.png"/>
<f:param name="trxNo" value="#{item.map['trxNo']}"/>
</p:commandLink>
</p:column>
</p:dataTable>
backing bean
public void viewDetail(ActionEvent e) {
String trxNo = getFacesContext().getRequestParameterMap().get("trxNo");
for (DTO item : list) {
if (item.get("trxNo").toString().equals(trxNo)) {
System.out.println(trxNo);
setSelectedItem(item);
break;
}
}
}
Thanks to this site by Mkyong, the only solution that actually worked for us to pass a parameter was this
<h:commandLink action="#{user.editAction}">
<f:param name="myId" value="#{param.id}" />
</h:commandLink>
with
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String idString = params.get("myId");
long id = Long.parseLong(idString);
...
}
Technically, that you cannot pass to the method itself directly, but to the JSF request parameter map.
I'm using Primefaces in a JSF 2 application. I have a <p:dataTable>, and instead of selecting rows, I want the user to be able to directly execute various actions on individual rows. For that, I have several <p:commandLink>s in the last column.
My problem: how can I pass a row ID to the action started by the command link so that I know which row to act on? I tried using an <f:attribute>:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
But it always yields 0 - apparently the row variable f is not available when the attribute is rendered (it works when I use a fixed value).
Anyone has an alternative solution?
As to the cause, the <f:attribute> is specific to the component itself (populated during view build time), not to the iterated row (populated during view render time).
There are several ways to achieve the requirement.
If your servletcontainer supports a minimum of Servlet 3.0 / EL 2.2, then just pass it as an argument of action/listener method of UICommand component or AjaxBehavior tag. E.g.
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
In combination with:
public void insert(Long id) {
// ...
}
This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
You can even pass the entire item object:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
with:
public void insert(Item item) {
// ...
}
On Servlet 2.5 containers, this is also possible if you supply an EL implementation which supports this, like as JBoss EL. For configuration detail, see this answer.
Use <f:param> in UICommand component. It adds a request parameter.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
If your bean is request scoped, let JSF set it by #ManagedProperty
#ManagedProperty(value="#{param.id}")
private Long id; // +setter
Or if your bean has a broader scope or if you want more fine grained validation/conversion, use <f:viewParam> on the target view, see also f:viewParam vs #ManagedProperty:
<f:viewParam name="id" value="#{bean.id}" required="true" />
Either way, this has the advantage that the datamodel doesn't necessarily need to be preserved for the form submit (for the case that your bean is request scoped).
Use <f:setPropertyActionListener> in UICommand component. The advantage is that this removes the need for accessing the request parameter map when the bean has a broader scope than the request scope.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
In combination with
private Long id; // +setter
It'll be just available by property id in action method. This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Bind the datatable value to DataModel<E> instead which in turn wraps the items.
<h:dataTable value="#{bean.model}" var="item">
with
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(making it transient and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean since DataModel doesn't implement Serializable)
Then you'll be able to access the current row by DataModel#getRowData() without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Use Application#evaluateExpressionGet() to programmatically evaluate the current #{item}.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #1 or, when you'd like to support servlet 2.5 containers as well, with #2.
In JSF 1.2 this was done by <f:setPropertyActionListener> (within the command component). In JSF 2.0 (EL 2.2 to be precise, thanks to BalusC) it's possible to do it like this: action="${filterList.insert(f.id)}
In my view page:
<p:dataTable ...>
<p:column>
<p:commandLink actionListener="#{inquirySOController.viewDetail}"
process="#this" update=":mainform:dialog_content"
oncomplete="dlg2.show()">
<h:graphicImage library="images" name="view.png"/>
<f:param name="trxNo" value="#{item.map['trxNo']}"/>
</p:commandLink>
</p:column>
</p:dataTable>
backing bean
public void viewDetail(ActionEvent e) {
String trxNo = getFacesContext().getRequestParameterMap().get("trxNo");
for (DTO item : list) {
if (item.get("trxNo").toString().equals(trxNo)) {
System.out.println(trxNo);
setSelectedItem(item);
break;
}
}
}
Thanks to this site by Mkyong, the only solution that actually worked for us to pass a parameter was this
<h:commandLink action="#{user.editAction}">
<f:param name="myId" value="#{param.id}" />
</h:commandLink>
with
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String idString = params.get("myId");
long id = Long.parseLong(idString);
...
}
Technically, that you cannot pass to the method itself directly, but to the JSF request parameter map.
Can I pass a input text field value to a bean method without binding the value to a bean property?
<h:inputText value="#{myBean.myProperty}" />
<h:commandButton value="Test" action="#{myBean.execute()} />
Can I do this without doing temporary save in #{myBean.myProperty}?
Bind the component as UIInput to the view and use UIInput#getValue() to pass its value as method argument.
<h:inputText binding="#{input1}" />
<h:commandButton value="Test" action="#{myBean.execute(input1.value)}" />
with
public void execute(String value) {
// ...
}
Note that the value is this way already converted and validated the usual JSF way.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
JSF component binding without bean property
You can recover the parameters of the form by getting the Request and using plain Java EE ServletRequest#getParameter. When you use this method, remember to set the id and name of your components:
<h:form id="myForm">
<h:inputText id="txtProperty" /> <!-- no binding here -->
<input type="text" id="txtAnotherProperty" name="txtAnotherProperty" />
<h:commandButton value="Test" action="#{myBean.execute()} />
</h:form>
Managed Bean:
#ManagedBean
#RequestScoped
public class MyBean {
public void execute() {
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
String txtProperty = request.getParameter("myForm:txtProperty");
//note the difference when getting the parameter
String txtAnotherProperty= request.getParameter("txtAnotherProperty");
//use the value in txtProperty as you want...
//Note: don't use System.out.println in production, use a logger instead
System.out.println(txtProperty);
System.out.println(txtAnotherProperty);
}
}
Another thread with more info:
Get request parameter values in JSF
I'm using Primefaces in a JSF 2 application. I have a <p:dataTable>, and instead of selecting rows, I want the user to be able to directly execute various actions on individual rows. For that, I have several <p:commandLink>s in the last column.
My problem: how can I pass a row ID to the action started by the command link so that I know which row to act on? I tried using an <f:attribute>:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
But it always yields 0 - apparently the row variable f is not available when the attribute is rendered (it works when I use a fixed value).
Anyone has an alternative solution?
As to the cause, the <f:attribute> is specific to the component itself (populated during view build time), not to the iterated row (populated during view render time).
There are several ways to achieve the requirement.
If your servletcontainer supports a minimum of Servlet 3.0 / EL 2.2, then just pass it as an argument of action/listener method of UICommand component or AjaxBehavior tag. E.g.
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
In combination with:
public void insert(Long id) {
// ...
}
This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
You can even pass the entire item object:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
with:
public void insert(Item item) {
// ...
}
On Servlet 2.5 containers, this is also possible if you supply an EL implementation which supports this, like as JBoss EL. For configuration detail, see this answer.
Use <f:param> in UICommand component. It adds a request parameter.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
If your bean is request scoped, let JSF set it by #ManagedProperty
#ManagedProperty(value="#{param.id}")
private Long id; // +setter
Or if your bean has a broader scope or if you want more fine grained validation/conversion, use <f:viewParam> on the target view, see also f:viewParam vs #ManagedProperty:
<f:viewParam name="id" value="#{bean.id}" required="true" />
Either way, this has the advantage that the datamodel doesn't necessarily need to be preserved for the form submit (for the case that your bean is request scoped).
Use <f:setPropertyActionListener> in UICommand component. The advantage is that this removes the need for accessing the request parameter map when the bean has a broader scope than the request scope.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
In combination with
private Long id; // +setter
It'll be just available by property id in action method. This only requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Bind the datatable value to DataModel<E> instead which in turn wraps the items.
<h:dataTable value="#{bean.model}" var="item">
with
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
(making it transient and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean since DataModel doesn't implement Serializable)
Then you'll be able to access the current row by DataModel#getRowData() without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by #ViewScoped.
Use Application#evaluateExpressionGet() to programmatically evaluate the current #{item}.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #1 or, when you'd like to support servlet 2.5 containers as well, with #2.
In JSF 1.2 this was done by <f:setPropertyActionListener> (within the command component). In JSF 2.0 (EL 2.2 to be precise, thanks to BalusC) it's possible to do it like this: action="${filterList.insert(f.id)}
In my view page:
<p:dataTable ...>
<p:column>
<p:commandLink actionListener="#{inquirySOController.viewDetail}"
process="#this" update=":mainform:dialog_content"
oncomplete="dlg2.show()">
<h:graphicImage library="images" name="view.png"/>
<f:param name="trxNo" value="#{item.map['trxNo']}"/>
</p:commandLink>
</p:column>
</p:dataTable>
backing bean
public void viewDetail(ActionEvent e) {
String trxNo = getFacesContext().getRequestParameterMap().get("trxNo");
for (DTO item : list) {
if (item.get("trxNo").toString().equals(trxNo)) {
System.out.println(trxNo);
setSelectedItem(item);
break;
}
}
}
Thanks to this site by Mkyong, the only solution that actually worked for us to pass a parameter was this
<h:commandLink action="#{user.editAction}">
<f:param name="myId" value="#{param.id}" />
</h:commandLink>
with
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String idString = params.get("myId");
long id = Long.parseLong(idString);
...
}
Technically, that you cannot pass to the method itself directly, but to the JSF request parameter map.