Is there a way to have a JSF Backing bean cause an update of a component on the page? I am not looking to use an ajax component with update attribute to update a component on the page. I need to trigger an update from within a JSF backing bean method. Note the update on the page can happen after this method completes or prior to its completion. I am using PrimeFaces, if there is a solution that can be had from using PrimeFaces.
Using standard JSF API, add the client ID to PartialViewContext#getRenderIds().
FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add("foo:bar");
Using PrimeFaces specific API, use PrimeFaces.Ajax#update().
PrimeFaces.current().ajax().update("foo:bar");
Or if you're not on PrimeFaces 6.2+ yet, use RequestContext#update().
RequestContext.getCurrentInstance().update("foo:bar");
If you happen to use JSF utility library OmniFaces, use Ajax#update().
Ajax.update("foo:bar");
Regardless of the way, note that those client IDs should represent absolute client IDs which are not prefixed with the NamingContainer separator character like as you would do from the view side on.
I also tried to update a component from a jsf backing bean/class
You need to do the following after manipulating the UI component:
FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(componentToBeRerendered.getClientId())
It is important to use the clientId instead of the (server-side) componentId!!
The RequestContext is deprecated from Primefaces 6.2. From this version use the following:
if (componentID != null && PrimeFaces.current().isAjaxRequest()) {
PrimeFaces.current().ajax().update(componentID);
}
And to execute javascript from the backbean use this way:
PrimeFaces.current().executeScript(jsCommand);
Reference:
https://github.com/primefaces/primefaces/wiki/Migration-Guide
https://forum.primefaces.org/viewtopic.php?t=53129
Everything is possible only if there is enough time to research :)
What I got to do is like having people that I iterate into a ui:repeat and display names and other fields in inputs. But one of fields was singleSelect - A and depending on it value update another input - B.
even ui:repeat do not have id I put and it appeared in the DOM tree
<ui:repeat id="peopleRepeat"
value="#{myBean.people}"
var="person" varStatus="status">
Than the ids in the html were something like:
myForm:peopleRepeat:0:personType
myForm:peopleRepeat:1:personType
Than in the view I got one method like:
<p:ajax event="change"
listener="#{myBean.onPersonTypeChange(person, status.index)}"/>
And its implementation was in the bean like:
String componentId = "myForm:peopleRepeat" + idx + "personType";
PrimeFaces.current().ajax().update(componentId);
So this way I updated the element from the bean with no issues. PF version 6.2
Good luck and happy coding :)
In order to updte the component from backing bean, we can achieve as below
RequestContext.getCurrentInstance().update('updatePanelGroup');
<h:panelGroup id="updatePanelGroup">
.....
....
</h:panelGroup>
Updating the component differs with respect to prima face version.
Related
Sorry, really really basic question...
I've got a list of 'messageboard threads' that I display on a page. I want to be able to click on one of them and redirect to a page which displays the details for that thread. I'm struggling despite googling it for a while...
(I'm using PrimeFaces by the way)
Here's the relevant code from my 'list' page:
<p:commandLink value="#{thread.title}" action="#{messageboardBean.showThread()}">
<f:param name="threadId" value="#{thread.id}" />
</p:commandLink>
(it's in an h:form element)
This is part of my named bean (other methods work fine)
...
#ManagedProperty(value="#{param.threadId}")
private Long threadId;
...
public String showThread() {
System.out.println("id is " + getThreadId());
return "messageboard/list";
}
...
As you can see my method isn't implemented yet, but it's not even being called. Please can someone tell me why?
I tried with an h:link too by the way, same (or similar) problem.
Thanks!
UPDATE - Solved
Thanks to the help below, here is my solution (I've renamed 'messageboard' to 'discussion').
The link is generated using this code
value: what to display on the page, in my case the title of my discussion
outcome: refers to edit.xhtml, the faces file I want to go to
...and the [request] param is going to be called 'threadId' and has a value of the id attribute in my 'thread' object.
In the edit.xhtml page, I've got this
<f:metadata>
<f:viewParam name="threadId" value="#{viewDiscussionBean.threadId}" />
<f:event type="preRenderView" listener="#{viewDiscussionBean.loadDiscussion}" />
</f:metadata>
Note that 'threadId' is the same as the param name in the first page, and it is bound to my viewDiscussionBean's threadId property.
Then once the params are all set on my bean, I call the loadDiscussion method of my viewDiscussionBean. Since it now has the threadId property, it's able to do this (see below)
My viewDiscussionBean has the following managed property (I think the viewParam tag sets this, rather than the other way around).
#ManagedProperty(value="#{param.threadId}")
private Long threadId;
private Discussion thread;
So once that's set, this method is able to run (because it now has an ID)
public String loadDiscussion() {
thread = mbDao.find(threadId);
return "edit";
}
This just uses a DAO (using Hibernate) to look up the discussion thread with that ID, and set it in the bean. And then...
In my edit.xhtml page, I can access values in the discussion thread using things like
<h:outputText value="#{viewDiscussionBean.thread.message}" />
Voila! Thanks.
There are many possible caused for an UICommand action not being invoked. You can find them all here: commandButton/commandLink/ajax action/listener method not invoked or input value not updated Among others a missing form, a nested form, or a conversion/validation error elsewhere in the form, being in a datatable whose datamodel is not properly preserved, etcetera.
As to your particular functional requirement, better is to use a <h:link>. A command link issues a POST request which does in your particular case not end up with a bookmarkable URL with the thread ID in the URL. A <h:link> creates a fullworthy link which is bookmarkable and searchbot-indexable.
E.g.
<h:link value="#{thread.title}" outcome="messageboard/list">
<f:param name="threadId" value="#{thread.id}" />
</h:link>
This doesn't require a form nor an action method. You only need to move that #ManagedProperty to the bean associated with messageboard/list, or maybe replace it by <f:viewParam> in the messageboard/list view which allows for finer-grained validation/conversion.
See also:
Communication in JSF2 - Processing GET request parameters
When should I use h:outputLink instead of h:commandLink?
ViewParam vs #ManagedProperty(value = "#{param.id}")
Your best bet it probably to go with BalusC's answer and use <h:link>. However, I have some thoughts about the behavior you're seeing.
Primefaces <p:commandLink> (like <p:commandButton>) uses ajax by default. Therefore, there won't be any actual navigation resulting from returning an outcome from your action. This could make it look like your action isn't being invoked. Try adding ajax=false to your <p:commandLink>.
When using <h:link>, navigation is resolved when the link is rendered rather than when it's clicked. Modifying your example:
<h:link value="#{thread.title}" outcome="#{messageboardBean.showThread()}">
<f:param name="threadId" value="#{thread.id}" />
</h:link>
showThread() will be called (I think) when the view containing the link is being rendered. If you're not checking at the right time, this may also make it look like the method is being called.
In both cases, this doesn't explain why you wouldn't see the message to System.out at all, but I know I've tried that thinking it was fail-safe and still not seen the output, which all depends on your container, configuration, how you launched it, etc.
This question already has answers here:
How to populate options of h:selectOneMenu from database?
(5 answers)
Closed 6 years ago.
Up until now, I have always been using JSP to display pages. When a user request for a page such as "Add Item", I will load all Item Category in an Array List and display them as options in select box like this:
<select name="category>
<%
ArrayList<Category> categories = (ArrayList<Category>) request.getAttribute("categories");
for (Category c : data) {
%>
<option value="<%= c.getId() %>"><%= c.getName() %></option>
<%
}
%>
</select>
From the book "JavaServer Faces 2.0, The Complete Reference", I learnt that: "JSF enforces clean Model-View-Controller separation by disallowing the inclusion of Java code in markup pages". Hence, I'd be very grateful if someone could show me how I can handle the above task using JSF since I cannot use Java code as I have always done anymore.
Best regards,
James Tran
JSF 2.0 uses Facelets as the templating method, which in a nutshell is XHTML with some additional elements.
While technically you can perform method calls from Facelets, in general the idea is to access a JavaBean with proper geter/setter methods to perform your data moving. You can accomplish this as the below segment of code shows:
<h:selectOneMenu value="#{backingBean.selectedCategory}">
<f:selectItems value="#{backingBean.categoryList}"/>
</h:selectOneMenu>
On the bean side of things, you want to expose a bean to JSF using either faces-config (which is largely discouraged) or a mechanism such as CDI or the Managed Bean infrastructure. I highly recommend you look into using SEAM if you go the CDI route, as it will unify the (currently really strangely disparate) Managed Bean and CDI frameworks, so you can use JSF scopes in CDI, and have CDI beans available in JSF scopes.
#ManagedBean(name="backingBean")
#ViewScoped
public class MyJavaBackingBean {
#ManagedProperty("#{param.categories}")
protected List<String> categoryList
public void setSelectedCategory(String value) {
this.selectedCategory = value;
}
public String getSelectedCategory() {
return this.property;
}
...
}
You can also make the getters do lazy initialization of your values (for pulling categoryList from a database for example), and use some other JSF annotations to do various initialization tasks.
You can also code action methods which return a String representing the JSF action (this gets coded into your faces-context.xml file) to take after returning. Phase listeners on the backing bean can also be called at various stages of page rendering, validation and submission, getting you very fine grained control.
categoryList in the above example is not limited to basic types of course, and <f:selectItems> also has some syntax for writing out the textual version of your select items, so you can make some quite complex expressions to display each item in a friendly way.
Create a bean and make it known with e.g. #Named so you can refer to it from your JSF script. Then give that bean a method returning the data you want to show, and invoke that method from your JSF script in a location where that data is expected e.g. a loop construct.
Store the data you want to display in a Java list, and expose that list as a property of a backing bean. The use the appropriate JSF tag to display that property.
In JSF 2.0 you can include the tag h:selectOneMenu in which you get the value where you store the item value selected. The value in f:selectItems could be a collection of any object the most of times SelectItem in this object your declare value object and the label to display.
<h:selectOneMenu value="#{backingBean.selectedvalue}">
<f:selectItems value="#{backingBean.List}"/> </h:selectOneMenu>
if you required values and labels of another object in you must declare
<h:selectOneMenu value="#{backingBean.selectedvalue}">
<f:selectItems value="#{backingBean.ListCar}" var="car" itemLabel="#{car.model}" itemValue="#{car.modelId}"/>
</h:selectOneMenu>
This question already has answers here:
How to dynamically add JSF components
(3 answers)
Closed 7 years ago.
I'm writing an application that serves as an admin panel using JSF 2.0 and Hibernate. I have a JSP page with a JSF form which elements are added dynamically using javascript (jQuery to be specific). So I cannot make any assumption on how much data do I have to process. I have a managed bean but I don't know how to put the getters and setters for the dynamic fields that I want to save in a database. The solution seems to use a list rather than a single element but how do I use the value tag of the JSF element? Could it be something like this:
<h:form>
<h:inputText id="i1" value="#{UserBean.list}" />
<h:inputText id="i2" value="#{UserBean.list}" />
<h:commandbutton id="submit" value="Submit" action="#{UserBean.submit}"/>
</h:form>
And the managed bean:
#ManagedBean(name="UserBean")
#RequestScoped
public class UserBean {
public UserBean() {
List<String> list = null;
}
public List getList() {
return list;
}
public List setList(List<String> newlist) {
list = newList;
}
}
However, the above code does not seem correct and certainly does not work. I need to bind two or more values of the inputtext to the same list. Does anyone have any suggestions how to solve it? Thanks in advance.
Regards,
sass.
You can't directly add JSF components dynamically using jQuery. All jQuery can is traversing and manipulating "plain vanilla" HTML DOM tree at the client side. It has totally no notion of the JSF component tree as it is generated and maintained in the server side. JSF in turn knows nothing about the state changes in the HTML DOM tree done by "plain vanilla" jQuery/JavaScript since it doesn't notify JSF on the server side about the changes. JSF relies on the JSF component tree to process form submits, not the HTML DOM tree.
You want to change the JSF component tree dynamically using JSF. Since this is going to be a long story to explain in detail, here are some links to similar questions I answered before to get you started:
How to add JSF components dynamically - This should be exactly what you need.
How to create dynamic JSF form - This does it the "other way round", just in case you're interested.
You can use primefaces extension dynaform. where you can create form dynamic.
See this link
http://fractalsoft.net/primeext-showcase-mojarra/views/dynaForm.jsf
I have problem with JSF (1.2) + primefaces (1.1). I have written classic site on JSF, and I have for every article request scoped backing bean. The problem is, that when I try to rate the article, the backing bean no longer exists.
So i want to force the JSF to output result of this expression during the render phase (so the ranking code will send the rendered Id), but if I use the dolar sign, everything works exacly as if I used the # (i thing that this might be bug in MyFaces).
Other solution wold be to session scope the backing bean, but user could have opened more pages (and he wold rate the last opened), other problem is what would happen, when the session expires....
Thanks for your help
<p:rating stars="5" value="#{articleClientBean.userRating}" update="ratingCount, avgRating" rateListener="#{articleClientBean.handleRate}">
<f:param value="#{articleClientBean.articleId}" name="articleId"/>
</p:rating>
Use h:inputHidden instead.
<p:rating stars="5" value="#{articleClientBean.userRating}" update="ratingCount, avgRating" rateListener="#{articleClientBean.handleRate}" />
<h:inputHidden value="#{articleClientBean.articleId}" />
I may be missing a couple of points, but I've hacked together a jsf/richfaces app and want to be able to do the simplest ajax-based nav:
main page contains ref to my backing bean's menu
<h:form>
<rich:dropDownMenu binding="#{PrismBacking.nodeMenu}" />
</h:form>
this refers to the code for the backing bean methods
this is my main page ajax panel
<rich:panel id="content">
<a4j:include viewId="#{PrismBacking.viewId}" />
</rich:panel>
i can't work out how to get the backing bean to use the selected item from the rich:dropDownMenu to update that which is returned by getViewId.
i guess:
1) i need to ensure the menu items in the getNodeMenu method have the right payload so setViewId is called with the correct String and my rich:panel id="content" is reRendered.
any pointers as to how to do this would be greatly appreciated.
mark
You are not setting the reRender attribute anywhere in your code (in the menu items) so the panel is not going to be updated after you select an item from the dropdown.
You also have to set the ajaxSubmit attribute en each menuItem to true in order to execute an ajax request. Also check that your listener is executed.
Take a look at the example http://livedemo.exadel.com/richfaces-demo/richfaces/dropDownMenu.jsf?c=dropDownMenu . You can download the code if you want from the richfaces site.
Using binding should be avoided if possible. Take a look at the RichFaces demo - there are source codes for each example, and see how it is achieved.
(This doesn't answer your question, and for better :) )