<h:selectOneMenu> with temporary disabled SelectItems - jsf

I have a <h:selectOneMenu> that renders the value of the cardStatus from my object model.
A CardStatus has an boolean attribute 'temporaryDisabled' that means that the value is still valid but should not be used by the user.
Now, if my model has cardStatus set to a temporary disabled value, how can I show this value in the dropdown combobox and still prevent the user from changing the value to another temporary disabled status?
If I just delete the disabled card statuses from the list of SelectItems that I feed to <h:selectOneMenu> then when the select gets rendered it will automatically select the first item in the list an submit it next time consequently wrongly changing my value in the model.
If I include the disabled card statuses in the list of SelectItems but set the value of the disabled attribute to true for their corresponding items, they are rendered in HTML disabled and not submitted so I get a null value in my model which is also wrong.
I am stuck. Any advice is kindly appreciated.
Best regards,
Dan.

Finally what I did was to use a piece of jQuery code that gets executed after the page is loaded.
<h:selectOneMenu
id="cardStatus"
value="#{someBean.cardStatus}"
converter="selectItemConverter">
<f:selectItem itemValue="E|A" itemLabel="Active" />
<f:selectItem itemValue="E|S" itemLabel="Stolen" />
<f:selectItem itemValue="D|B" itemLabel="Blocked" />
<f:selectItem itemValue="E|L" itemLabel="Lost" />
<f:selectItem itemValue="D|C" itemLabel="Counterfeit" />
</h:selectOneMenu>
What the javascript code does is to scan all the items and for each item with a value starting with the prefix D| hide the item using jQuery's hide() function. This way the combobox is acting as all values would be valid/enabled, but the user will not be able to select inactive values because they are not visible. Furthermore, if the default selected value is one of the values starting with D|, the value will still be shown as default value but the user is not able to see it in the list of options he/she can choose from.

"that means that the value is still valid but should not be used by the user"
Help me understand this piece. You want to display these choices in an h:selectOneMenu but not allow the user to select them? I guess I don't understand why you would present them to the user if they are invalid options for them?
You could always create a validator that validates against "temporaryDisabled" if that's what you're trying to accomplish ... let me know more about what you want the end-user to see and I can probably help.

<h:selectOneMenu
id="cardStatus"
value="#{someBean.cardStatus}"
converter="selectItemConverter">
<f:selectItem itemValue="#{null}" itemLabel="" />
<f:selectItems
value="#{cardStatusBean.cardStatuses}"
var="cardStatus"
itemValue="#{cardStatus}"
itemLabel="#{cardStatus.name}"
itemDisabled="#{cardStatus.temporaryDisabled}"/>
</h:selectOneMenu>
This would give you a default choice with a value of null and an empty label. Would that accomplish what you are looking for?

For the record, if using JSF 2.0, f:selectItem and f:selectItems have an "itemDisabled" attribute that produces the desired behavior.

Related

h:selectOneMeny valueChangeListner is not working

I am using h:selectOneMenu for dropdown but the valueChangeListner is not firing.
I can not use submit() onChange as it will refresh my entire page and i will lose the selected values for other components. Please suggest how to fire valueChangeListner without affecting other components on the page.
The h:selectOneMenu implemented like below:
<h:selectOneMenu id="Q1List"
value="#{myBean.q1Value}" onclick="showHideQ1()"//To open another field based on value selected, working fine
valueChangeListener="#{myBean.q1ValueChangeListner}">
<f:selectItem itemValue="" itemLabel="Make a selection"/>
<f:selectItems value="#{RateComparision.q1OptionsList}" id="dr1"/>
</h:selectOneMenu>
Note: i can not use ajax or anything like that as my page is not supporting them.
Any JS solution or component property may help me.
Thanks,
Mahesh

How to get a confirmation box when value change in h:selectOneMenu

I'm having trouble trying to get a confirmation box when someone change the value in a h:selectOneMenu and if the person accept, then the value changes, otherwise it return to its original value.
I do not know how to manage to do this, I have made some research but most of the answer I found were for PrimeFaces (which I do not use).
Here's the relevant part of code with the selectOneMenu :
<ui:repeat value="#{CommandeBean.choixMetaProprietes}" var="choixMetaProprietes">
<h:selectOneMenu value="#{choixMetaProprietes.metaProprieteSelectionnee}">
<f:selectItems noSelectionValue="#{CommandeBean.retrieveDefaultMetaProprietesValue()}" value="#{choixMetaProprietes.metaProprietes}" var="metaPropriete" itemLabel="#{metaProprieteConverter.getMetaProprieteLabel(metaPropriete)}" itemValue="#{metaPropriete}"/>
<f:converter converterId="com.festo.didactic.ca.webapp.entreecommandes.converter.MetaProprieteConverter"/>
</h:selectOneMenu>
</ui:repeat>
I'm open to any idea that could help me solve this problem.
I finally manage to do it by storing the data in an input hidden and then compare the actual value of the selectOneMenu with the input in query.
i was then able to call a confirmation box via confirm('blabla bla').
the result would then tell me if i need to keep the value or put the previous one.

How to change order in which the components are processed

I have a selectOneMenu and an editor. What I want is to submit the value of the editor before the value of the selectOneMenu. The code looks like this
<p:selectOneMenu value="#{myBB.selectedItem}">
<f:selectItems value="#{myBB.selectItems}"/>
<p:ajax event="change" process="itemText #this" update=":mainForm"/>
</p:selectOneMenu>
<p:editor id="itemText" value="#{myBB.selectedItem.text}"/>
It looks like the order of elements in process="itemText #this" doesn't matter, because when I change it, the values are submitted in unchanged order.
The problem is, that the selectedItem of the editor is changed by the selection before the value from the editor is submitted.
Am I right, that the order doesn't matter and it is submitted based on the order in the DOM tree? (When I change order of the input fields it's working as I would like to)
What is the best way to work around this?
You shouldn't rely on things like layout or processing order in your code. If the problem is that itemText value is reset when selectedItem is changed, then bind the text to separate String text bean variable, and update selectedItem.text in some other code, maybe <p:ajax listener="#{...}".

Best way to add a "nothing selected" option to a selectOneMenu in JSF

I was wondering what would be the best or easiest way to allow a user to select nothing in a selectOneMenu.
My example: I have a list of registered users and the administrator should be able to filter the list of displayed users by some criterias. These criterias, like the usertype (employee, customer, ...) can be chosen by selectOneMenus, like this:
<h:selectOneMenu value="#{myBean.selectedUsertype}" converter="#{usertypeConverter}">
<f:selectItems value={myBean.usertypes}" />
</h:selectOneMenu>
When the corresponding selectOneMenu is being backed by a list of POJOs using a converter, how can I add an item to the list indicating that the user didn't choose any specific item? Currently I have a dummy usertype object displaying the label "---", but this is causing several problems in other areas of my application and I don't think that this is the best solution.
Just explicitly set the select item value to null.
<h:selectOneMenu value="#{bean.selectedItem}">
<f:selectItem itemValue="#{null}" itemLabel="--select--" />
<f:selectItems value="#{bean.availableItems}" />
</h:selectOneMenu>
No, an empty string like itemValue="" is not sufficient. It really has to be null. Otherwise you run into trouble as described in this Q&A: Using a "Please select" f:selectItem with null/empty value inside a p:selectOneMenu.
If the item happen to be required="true" and you're using JSF 2.x, then you could add noSelectionOption="true" to the select item. This is only useful if you also set hideNoSelectionOption="true" on the selection component. It will then hide the empty option in the list once the enduser selects a different item, hereby making it impossible to re-select the empty option.
<h:selectOneMenu value="#{bean.selectedItem}" hideNoSelectionOption="true">
<f:selectItem itemValue="#{null}" itemLabel="--select--" noSelectionOption="true" />
<f:selectItems value="#{bean.availableItems}" />
</h:selectOneMenu>
See also page 114 of The Definitive Guide to JSF under section "SelectItem tags":
Note that a select item with value of #{null} can be used to present the default selection in case the bean property associated with selection component's value attribute is null. If you have consulted the tag documentation of <f:selectItem>, then you'll perhaps have noticed the noSelectionOption attribute and have thought that it was intended to represent a "no selection option". Actually, this isn't true. Many starters indeed think so, as you can see in many forums, Q&A sites, and poor-quality tutorials on the Internet. In spite of the misleading attribute name, it does not represent a "no selection option".
A better attribute name would have been hideWhenOtherOptionIsSelected, and even then it works only when the parent selection component has explicitly a hideNoSelectionOption="true" attribute set. So, hideWhenOtherOptionIsSelectedAndHideNoSelectionOptionIsTrue would ultimately have been the most self-explanatory attribute name. Unfortunately, this wasn't very well thought out when the noSelectionOption was implemented in JSF 1.2. Requiring two attributes for this attribute to function shouldn't have been necessary. The primary purpose of this attribute pair is to prevent the web site user from being able to re-select the "no selection option" when the component has already a non-null value selected. For example, by having it prepared in a #PostConstruct method, or by re-rendering the component after a form submit with a non-null value.
Copyright disclaimer: book is written by me.
Add a single selectItem with null value;
<h:selectOneMenu value="#{bean.question}" required="true" requiredMessage="Please select a question">
<f:selectItem itemValue="#{null}" itemLabel="Select" />
<f:selectItems value="#{bean.questions}" />
</h:selectOneMenu>
We can in primefaces (when we have to use <p:selectOneMenu... from some reason like using <p:ajax..) add the following empty item:
<f:selectItem itemValue="#{null}" itemLabel="--select--" itemDisabled="#{Mybean.value ne null}" />
Note: In such case we don't need the following two tags:
hideNoSelectionOption="true"
and
noSelectionOption="true"

Displaying read-only forms (values are shown as text instead of disabled input controls) with JSF?

I have a data entry form where user enters lots of data. When user comes to the page to view existing data, the page should be displayed in read-only mode (all values shown as text), when he clicks 'Edit' button, normal form with all input controls should be shown so that user can change and save data.
We are using JSF 2.0 with PrimeFaces library. It is easy to achieve above behavior for text box and text area but not for Checkbox, multi-select, radio,..... controls. Is there any easy way available to achieve above behavior rather than writing our own code (which may run into lot of lines thus making backing bean code ugly)
Thanks for your help...
I'm not sure why you think that you need additional backing bean code for this. You've all the needed values in the backing bean already. Your problem is more in the presentation of those values. Just display them in the desired format by writing the view code accordingly. Perhaps you were thinking it too the hard way.
Instead of a select boolean checkbox, you could display for example a "Yes" or "No" value.
<h:selectBooleanCheckbox value="#{bean.checked}" rendered="#{bean.edit}" />
<h:outputText value="#{bean.checked ? 'Yes' : 'No'}" rendered="#{not bean.edit}" />
Instead of a select one menu/radio, you could just display the value in an output text.
<h:selectOneMenu value="#{bean.selectedItem}" rendered="#{bean.edit}">
<f:selectItems value="#{data.availableItems}" />
</h:selectOneMenu>
<h:outputText value="#{bean.selectedItem}" rendered="#{not bean.edit}" />
Instead of a select many listbox/checkbox, you could just display for example all values comma separated in a loop.
<h:selectManyListbox value="#{bean.selectedItems}" rendered="#{bean.edit}">
<f:selectItems value="#{data.availableItems}" />
</h:selectManyListbox>
<h:panelGroup rendered="#{not bean.edit}">
<ui:repeat value="#{bean.selectedItems}" var="selectedItem" varStatus="loop">
#{selectedItem}#{not loop.last ? ', ' : ''}
</ui:repeat>
</h:panelGroup>
You could wrap it all in a tag file or a composite to minimize boilerplate and code repetition.
I've done this in my last project using composite components which has a "preview" attribute and in the implementation I render a text when this attribute is true and the real (editing) when the attribute is false. For checkbox in preview mode you could show the checkbox itself but disabled, for radio - show the selected item.
MyFaces Tomahawk library [1] contains an extended version of the standard components that adds displayValueOnly attribute for this purpose. This might help you (I haven't used them).
[1] - http://myfaces.apache.org/tomahawk-project/tomahawk20/index.html

Resources