Is it possible to bind a value to more than one field? - jsf

I have the following piece of markup:
<h:selectOneMenu value="#{myBean.upperBound}">
<f:selectItems value="#{myBean.getValues(filterItem)}" />
</h:selectOneMenu>
And the following managedBean:
public class MyBean{
private FilterItem lowebBound;
private FilterItem upperBound;
public List<SelectItem> getValues(FilterItem filterItem){
//Some stuff
}
//GET, SET
}
How can I initialize the property lowerBound with the value that was selected in the selectOneMenu now. I need to reinitialize that value every time it's changed.

You need to keep the selectOneMenu and the property synched with an AJAX call.
One basic tutorial in the Oracle KB (visited 2015-04-13):
The f:ajax tag is a JavaServer Faces core tag that provides Ajax functionality to any regular UI component when used in conjunction with that component. In the following example, Ajax behavior is added to an input component by including the f:ajax core tag:
<h:inputText value="#{bean.message}">
<f:ajax />
</h:inputText>
Related reading:
The f:ajax listener method in h:selectOneMenu is not executed
Updating text component via selectOneMenu from inside a JSF2/Facelets subview
In your case, your component would look like this:
<h:selectOneMenu value="#{myBean.upperBound}">
<f:selectItems value="#{myBean.getValues(filterItem)}" />
<f:ajax listener="#{bean.listener}" />
</h:selectOneMenu>
The listener method will be called when the action is performed; you can update the lowerBound inside it.
The name of the listener method that is called when a javax.faces.event.AjaxBehaviorEvent has been broadcast for the listener.

Related

How to update value of EditableValueHolder in action listener?

I have this JSF (Java EE 7, provided by GlassFish 4.1 + PrimeFaces 5.1) form containing database connection information like host name, port number, etc. Also part of this form is a URL field. I want this field to be editable, but I also want to be able to set the value based on the other fields.
To do so I created a button with an action listener where I'm reading the posted data from the request parameter map and generate the new URL value. Then I want to put the new value in the URL field and use that value instead of the posted data. What I tried is to get the component as EditableValueHolder and set the submitted value and render the response. I also tried setting the component's value and calling resetValue.
The best result was the URL field being updates after two clicks.
XHTML:
<p:inputText id="url"
size="50"
value="#{database.url}"/>
<p:commandButton icon="ui-icon-arrowrefresh-1-w"
immediate="true"
actionListener="#{database.createConnectionURL('namingContainer')}">
<p:ajax update="url" />
</p:commandButton>
Bean (using OmniFaces):
UIComponent urlComponent = Faces.getViewRoot().findComponent(namingContainer + "url");
if (urlComponent instanceof EditableValueHolder) {
EditableValueHolder editValHolder = (EditableValueHolder) urlComponent;
editValHolder.setSubmittedValue(urlValue);
}
Faces.getContext().renderResponse();
The immediate="true" is a leftover from JSF 1.x, when it was not possible to process only a specific set of inputs and/or buttons. It was then more than often abused to process only a specific set of inputs and/or buttons instead of to prioritize validation. You'd better not use it when you've JSF2 ajax at hands.
With JSF2 ajax you can just use execute="..." or in case of PrimeFaces process="..." to execute/process only a specific set of inputs/buttons.
<p:inputText id="url"
size="50"
value="#{database.url}" />
<p:commandButton icon="ui-icon-arrowrefresh-1-w"
process="#this"
action="#{database.createConnectionURL('namingContainer')}"
update="url" />
Then you can just update the model value.
public void createConnectionURL(String namingContainer) {
// ...
url = urlValue;
}
Note that I moved back <p:ajax update> into the <p:commandButton>. Perhaps you was mixing with <h:commandButton>.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
Unrelated to the concrete problem, to deal with components with OmniFaces, better use Components utility class.

Set bean value on click of selectbooleancheckbox

I have a bean class and a selectBooleanCheckbox in xhtml page. I want that on the click of the box the value should be set in the backing bean.
Here is code:
<h:selectBooleanCheckbox id="provisioningTargetCollector"
value="#{targetSource.provisioningTargetCollector}">
</h:selectBooleanCheckbox>
Bean Class:
public boolean isProvisioningTargetCollector() {
return _provisioningTargetCollector;
}
public void setProvisioningTargetCollector(boolean provisioningTargetCollector) {
_provisioningTargetCollector = provisioningTargetCollector;
}
But the getter and setter are called only on page load. How can I set the value in bean method on click of checkbox.
The model with be filled with form data only when submit button will be pressed. If you want to do partial update to the server you need to send an AJAX request. Luckily, starting from JSF 2 it has been quite simple with the introduction of <f:ajax> tag. It adds ajax capabilities to UIComponent instances that implement the ClientBehaviorHolder interface, i.e. components that are capable of triggering ajax requests.
To do partial update of compenets you need to specify their client ids in execute attribute of <f:ajax> tag. As the default value of execute attribute evaluates to #this, or the component to which the tag is attached it. As soon as you want to update only the given <h:selectBooleanCheckbox> you can do it as simple as nesting a pure <f:ajax /> tag within you checkbox, i.e.:
<h:selectBooleanCheckbox id="provisioningTargetCollector" value="#{targetSource.provisioningTargetCollector}">
<f:ajax />
</h:selectBooleanCheckbox>

Can't render SelectManyCheckbox from my SelectOneMenu with an ValueChangeListener

I have a Map (Integer, List) which I want to fill from a JSF page. I'm only using JSF, no Primefaces or such.
On my JSF page there is a selectOneMenu that displays each keys of my Map, and a selectManyBox to choose the values for each key.
I want to be able to save each state before submitting the whole Map.
See my bean:
#ManagedBean(name="myBean")
#SessionScoped
public class MyBean implements Serializable {
(...)
public void refresh(ValueChangeEvent e)
{
if (idRole==-1){ //to check if its just the first selection
setKey((int)e.getNewValue());
}
else{
myObject.getMap().put(key,listOfValuesSelected); //put current manycheckbox values in last selected key
setKey((int)e.getNewValue()); //get new key
listOfValuesSelected=MyObject.getMap().get(Key); //refresh the
//selectManyCheckbox for the newly selected key
}
}
My JSF Page
<h:selectOneMenu id="idRole" value="#{myBean.key}" onchange="submit()" valueChangeListener="#{myBean.refresh}" render="checkbox"> >
<f:selectItem itemLabel="" itemValue="" />
<f:selectItems value="#{myBean.listKeys}" />
</h:selectOneMenu>
<fieldset id="checkbox">
<h:selectManyCheckbox value="#{myBean.listOfValuesSelected}">
<f:selectItems value="#{myBean.listeOfValues}" var="n"
itemLabel="#{n.title}" itemValue="#{n.key}"/>
</h:selectManyCheckbox>
</fieldset>
My real code is kind of a mess, I rearranged it a bit to fit the needs of my question but I can give you the real code if needed.
My problem is that the selectmanycheckbox doesn't "react" at all. I see that the listOfValuesSelected is modified when I am in debug mode.
Do you use AJAX somewhere? And what kind of form do you use?
With "doesn't react", do you mean it's not re-rendered, or that nothing happens when you select one or more items in it?
If you use AJAX then with the given code the select many checkbox will indeed not re-render (refresh). The reason is that SelectOneMenu doesn't have an attribute "render" that causes something to be re-rendered. Third party components often have such a thing, but the standard components only do that via an f:ajax tag. Also, you can't use a non-component ID as a re-render target. Fieldset is not a component.
See http://docs.oracle.com/javaee/6/tutorial/doc/gkabr.html on how to use f:ajax

Can we create textbox right next to selectonemenu component when we fire selectoneMenu valueChangeListener event

want to create textbox on the fly is it possible?
Select Report to run:
<h:selectOneMenu value="#{reportBean.selectReport}">
<f:selectItems value = "#{reportBean.allReports}" />
<f:ajax listener="#{reportBean.getReqID}" render="reqID"> </f:ajax>
</h:selectOneMenu>
Seems like you want to show/hide the <h:inputText> based on the selected value on your <h:selectOneMenu>. Yes, this can be easily achieved with plain JSF.
Note that if you use set the rendered attribute as false the component won't appear in the component tree, so there will be no way it can't be referenced for any call (not even ajax calls). In order to update it, you should wrap the component inside another component like <h:panelGroup> and render the wrapper. Basic example:
<h:form id="frmRep">
<h:selectOneMenu value="#{reportBean.selectReport}">
<f:selectItems value = "#{reportBean.allReports}" />
<!--
assuming your reportBean.getReqID method will change the value of
reportBean.showReqID attribute to render/not render it and works well
-->
<f:ajax listener="#{reportBean.getReqID}" render="pnlRepName" />
</h:selectOneMenu>
<h:panelGroup id="pnlRepName">
<h:inputText id="reqID" rendered="#{reportBean.showReqID}"
value="#{reportBean.reportName}" />
<h:panelGroup>
</h:form>
For this specific requirement instead, I won't recommend using an ajax call since it has to go to the server to only check if the component should or should not be showed to the user. I would opt for a JavaScript solution to handle this just on client side.

Listening to onSelect events from Autocomplete (Primefaces) component

I am trying to listen to select event from autocomplete using attribute selectListener.
I am passing a remoteCommand as select listener. But the selectListener never calls this remoteCommand method.
My code follows:
<h:form>
<p:autoComplete autocomplete="true" completeMethod="#{search.fetchSuggestions}" value="#{search.selectedSuggestion}" selectListener="moveToSelectedPage()"/>
<p:remoteCommand name="moveToSelectedPage" action="firstPage.xhtml?faces-redirect=true" />
</h:form>
All I am trying to do is, navigating to a different page after the user selects a particular suggested item among suggestions made by autocomplete.
Looking at PrimeFaces version 3.5, it appears that the selectListener attribute is no longer available for the AutoComplete component. The link in BalusC's answer leads to the correct place, where it shows the new approach to be to include a <p:ajax> tag inside the <p:autocomplete>:
<p:autoComplete id="acSimple" value="#{autoCompleteBean.txt1}" completeMethod="#{autoCompleteBean.complete}">
<p:ajax event="itemSelect" listener="#{autoCompleteBean.handleSelect}" update="messages" />
</p:autoComplete>
The selectListener attribute should refer to a managed bean method taking SelectEvent and returning void, not to some arbitrary JavaScript function.
See also the PrimeFaces <p:autoComplete> showcase page.
<p:autoComplete selectListener="#{autoCompleteBean.handleSelect}" ... />
with
public void handleSelect(SelectEvent event) {
// ...
}

Resources