Rendering a data-table only when the bean returns a list - jsf

I have been trying to render a rich:dataTable, but fails, when it comes to its conditional rendering.I wanted to render it only if the size of the list, the backing-bean fetches from DB, is greater than zero.
JSF-2.0, RichFaces-4 are what i use.

You have to use the "render" attribute of the datatable. With it you can define if the component is rendered to the client or not. So check by EL if the list is populated.
you can do something like:
rendered="#{not empty listObject}"
and all is fine.
I always implement my database query method to never return null, if the query has no result I return an empty list. This way i'm sure I never get a nullpointerexception and I prefer then to show an empty table. Because it's easer to layout the page, when you are sure the table always exist.
Hope that helps.

The scenario is I have a groupId which I rightclick on. On the context menu, I choose Display CTNs and it should then render all the CTNs of this group in a data-table. It starts with a JavaScript call, which I call once I choose "Display CTNs". It takes care of supplying the GroupId to the a4j:jsFunction.
<rich:dataTable value="#{ctnGrpMgmtController.ctnDetailsList}"
var="ctnVar" id="ctnTable" rows="5"
rendered="#{not empty ctnDetailsList}">
The above should be rendered after the below a4j:jsFunction executes.
<a4j:jsFunction name="selectGroupForManagingCtns"
action="#{ctnGrpMgmtController.loadCTNsForAGroup}"
render="ctnListPanel,ctnTable">
<a4j:param name="name"
assignTo="#{ctnGrpMgmtController.groupId}" />
</a4j:jsFunction>
I have to do an F5 to see the component "ctnTable", which is where the problem starts.

It looks like the attribute name on the a4j:jsFunction is reRender instead of just render. Should fix it.

Related

rich:suggestionbox how to call bean in case user aborts selection

Old SuggestionBox component for RichFaces (version 3.3... yes, I have to maintain legacy code, weep for my fate) is pretty useful, but has one downside.
If user enter some text in input component and then click somewhere else than entry on list of suggestion, partially filled input is left as is. It is ugly and can be confusing, giving impression that something is selected when it is not.
I want to have separate call to bean in this case, allowing me to remove text, if nothing got selected.
Example code:
<h:inputText id="selectorInput" value="#{backingBean.inputText}" label="Select something:" />
<rich:suggestionbox id="suggestion" for="selectorInput" suggestionAction="#{backingBean.resolveSuggestions}" var="sug">
<a4j:support event="onselect" reRender="someForm" action="#{backingBean.select(sug)}" />
<h:column>#{sug.name}</h:column>
</rich:suggestionbox>
I tried to add a4j:support for h:inputText with event="onblur", but it is called before backingBean.select(sug) and has no way to know if something was selected or not, making it almost useless. Adding other events to suggestionbox itself appear to not work at all or even break suggestionbox.
Is there any other way?
The backing JavaScript object has a getSelectedItems() method. It returns an empty array if nothing was selected.
To get the object use
document.getElementById(clientId).component

jsf inputtext doesn't show value from bean

I have the follow situation:
I have a bean that send to form some data, but only in outputlabel the data from the bean is displayed.
I tried to use primefaces, but the same problems persist.
my code:
<h:outputLabel value="#{Bean.name}" id="name2" />
<h:inputText value="#{Bean.name}" id="name" />
<p:inputText value="#{Bean.name}" id="name3" />
Any idea why?
You should have given the bean's code also, to help us better analyze the problem.
Normally you should check for the following:
Check whether you are specifying a correct bean name. Normally
bean's name is same as that of class, except that first letter
should be lowercase. In your case it should be #{bean.name} or else,
specify your custom name with #Named("Bean").
Check whether the getters and setters such as getName() are properly
provided. It may happen that you might have reset the name property in
your bean in the get method itself. Because of which first time it
shows you properly in outputLabel and then in next call to getName it may give you null or empty String. To check this, try put your inputText tag first, and check.
I solve my problem.
When I tried show the values, I was trying recover data from database by pass an ajax action. So, When I clicked at button to retrieve the datas, some of my inputText were set as a required. And because this the data is just displaying into label and not inside of inputtext with required. But because ajax, the request were not called correctly.
When I remove the required from inputtext, it works fine.

pass parameter from f:selectItems in h:selectOneListbox

I have a selectOneListbox that, when clicked, should pass an additional parameter (id) to the server. As it is now, the user sees a list of names and when they select one I can get the name. But, each name also has a unique id associated with it that I don't want the user to see - how can I pass the unique id of the selected name to the backing bean without the user ever seeing it? Is it possible? I was trying to figure out how to use the f:param but I don't see how that will work here.
<h:selectOneListbox id="listBox" value="#{ScheduleMB.clients}" size="5"
rendered="#{ScheduleMB.showClients}" >
<f:selectItems value="#{ScheduleMB.clientList}" var="c"
itemLabel="#{c.lastName} #{', '} #{c.firstName}" itemValue="#{c.lastName}" />
<f:ajax event="click" listener="#{ScheduleMB.clickListener}"
render="group" />
</h:selectOneListbox>
The <f:param> serves a different purpose. Even if the <f:param> was possible, it would still end up being visible in the generated HTML output. The enduser would just do rightclick and View Source and then see the IDs being definied as option values.
Your best bet is to retrieve the ID from the DB based on a different unique identifier, perhaps the unique combination of firstname+lastname.
It does by the way not make any sense to me why you would like to hide the ID from the output. It'd be so much easier if you used that as option value, even more if you used a converter so that you can just pass the whole #{c} as option value. The enduser can't spoof/change it in any way. JSF will revalidate the submitted value against the list of available options (which are definied in server side anyway).

rendered attribute on inputText

I have a search form tied to a backing bean that contains 4 input text fields. The design i am working from indicates that the user should be able to see the search results, but they should not be editable. i decided to use the rendered attribute to show the inputs if the managed bean is empty, and to show an output text tag if it's not:
<t:inputText styleClass="inputText" id="name" rendered="#{not searchCriteria.fieldsEntered}"
value="#{searchCriteria.name}" autocomplete="off"></t:inputText>
<h:outputText value="#{searchCriteria.name}" rendered="#{searchCriteria.fieldsEntered}"></h:outputText>
The display part works correctly, but I am noticing that only the first field is stored in the managed bean when more than 1 search field is entered.
I removed a rendered attribute from an inputText, and sure enough that's causing my problems. I can infer what's going on here, but I don't understand why.
I believe in this situation I will just remove the outputText tags and change rendered to disabled. I am just curious why my initial plan is incorrect.
The rendered="false" will cause the input element not being rendered and thus its value will not be submitted to the server side. If you're using a request scoped bean, the initial value will not be set. You'd like to either put the bean in session scope or to add a h:inputHidden along the h:outputText which transfers the value to the subsequent request.
Since you're already using Tomahawk's t:inputText I'd suggest to rather use its displayValueOnly attribute instead of the rendered attribute and a complementary h:outputText.
In a nut:
<t:inputText displayValueOnly="#{searchCriteria.fieldsEntered}" ... />

JSF: How to get the selected item from selectOneMenu if its rendering is dynamic?

At my view I have two menus that I want to make dependent, namely, if first menu holds values "render second menu" and "don't render second menu", I want second menu to be rendered only if user selects "render second menu" option in the first menu. After second menu renders at the same page as the first one, user has to select current item from it, fill another fields and submit the form to store values in database. Both the lists of options are static, they are obtained from the database once and stay the same. My problem is I always get null as a value of the selected item from second menu. How to get a proper value? The sample code of view that holds problematic elements is:
<h:selectOneMenu id="renderSecond" value="#{Bean.renderSecondValue}"
valueChangeListener="#{Bean.updateDependentMenus}"
immediate="true"
onchange="this.form.submit();" >
<f:selectItems value="#{Bean.typesOfRendering}" />
</h:selectOneMenu><br />
<h:selectOneMenu id="iWillReturnYouZeroAnyway" value="#{Bean.currentItem}"
rendered="#{Bean.rendered}" >
<f:selectItems value="#{Bean.items}" />
</h:selectOneMenu><br />
<h:commandButton action="#{Bean.store}" value="#Store" />
However, if I remove "rendered" attribute from the second menu, everything works properly, except for displaying the menu for all the time that I try to prevent, so I suggest the problem is in behavior of dynamic rendering. The initial value of isRendered is false because the default item in first menu is "don't render second menu". When I change value in first menu and update isRendered with valueChangeListener, the second menu displays but it doesn't initialize currentItem while submitting.
Some code from my backing bean is below:
public void updateDependentMenus(ValueChangeEvent value) {
String newValue = (String) value.getNewValue();
if ("render second menu" == newValue){
isRendered = true;
} else {
isRendered = false;
}
}
public String store(){
System.out.println(currentItem);
return "stored";
}
If you're using the rendered attribute on UIInput and UICommand components, then you have to make sure that the rendered condition evaluates exactly the same way in the subsequent request (during submitting the form) as it was during the initial request (during displaying the form). When it evaluates false, then the request values won't be applied/validated and the model values won't be updated and no action will be invoked for the component(s) in question.
An easy fix is to put the bean in the session scope, but this has caveats as well (poor user experience when opening same page in multiple browser tabs/windows). On JSF 2.0 you could use the view scope instead. On JSF 1.x you would use Tomahawk's t:saveState for this.
The problem arises only when we have "don't render" as a first option. I decided to change the values in the database and now I have "render second menu" as a first one. With such an approach, everything works fine.

Resources