How to exclusively select a radio button in two p:selectOneRadios - jsf

JSF 2.0,
Primefaces 3.1.1
I have two p:selectOneRadio components:
<p:selectOneRadio id="radio1" value="#{inningBean.lastDeliveryType}">
<f:selectItem itemLabel="Wide" itemValue="1" />
<f:selectItem itemLabel="No Ball" itemValue="2" />
<f:selectItem itemLabel="Normal" itemValue="3" />
</p:selectOneRadio>
<p:selectOneRadio id="radio2" value="#{inningBean.lastDeliveryRunsScored}">
<f:selectItem itemLabel="1" itemValue="1" />
<f:selectItem itemLabel="2" itemValue="2" />
<f:selectItem itemLabel="3" itemValue="3" />
</p:selectOneRadio>
<p:commandButton />
I want that when user clicks the button, first radio button in each selectOneRadio is selected(Without submitting request to server). Just like user himself is selecting first radio button in each p:selectOneRadio, I just want to do it in javascript.

You can do this easily with jQuery. Take a look at these selectors:
input
name
first
And on the prop() function.
Now to the point :
For better manipulation with elements ids use prependId="false" on your form wrapping p:selectOneRadios.
You don't want to reaload page so use ajax="true" in p:commandButton.
<p:commandButton value="select" ajax="true" onclick="selectRadios()" update="#form"/>
If you specify id for p:selectOneRadio primefaces will use it as name attribute for input type="radio" in rendered HTML page. Ofcourse if you don't use prependId="false" on the form element, primefaces will add forms id to the radio name attr., so it looks like name="formId:radio1". With prependId="false" it's name="radio1".
Now when you know that your radio buttons have specific name you can select first of each group specified by this name with simple function:
function selectRadios(){
jQuery('input[name=radio1]:first').prop('checked', true);
jQuery('input[name=radio2]:first').prop('checked', true);
};
So the whole code looks like this :
<script type="text/javascript">
function selectRadios(){
jQuery('input[name=radio1]:first').prop('checked', true);
jQuery('input[name=radio2]:first').prop('checked', true);
};
</script>
<h:form id="formID" prependId="false">
<p:selectOneRadio id="radio1" value="#{testBean.radio1}">
<f:selectItem itemLabel="Wide" itemValue="1" />
<f:selectItem itemLabel="No Ball" itemValue="2" />
<f:selectItem itemLabel="Normal" itemValue="3" />
</p:selectOneRadio>
<p:selectOneRadio id="radio2" value="#{testBean.radio2}">
<f:selectItem itemLabel="1" itemValue="1" />
<f:selectItem itemLabel="2" itemValue="2" />
<f:selectItem itemLabel="3" itemValue="3" />
</p:selectOneRadio>
<p:commandButton value="select" ajax="true" onclick="selectRadios()" update="#form"/>
</h:form>
Note : You can also update each p:selectOneRadio separately if you don't want to update whole form by: update="radio1 radio2"
EDIT
I don't know the way how you can select a radio button in primefaces (while using theme) without a request being made, because after clicking on radio button GET request will be made, in which related UI icon will be obtained (at least for the first click). If you are okay with that keep reading.
Since you don't want to make classic HTTP request nor AJAX request change the type of your commandButton:
<p:commandButton type="button" value="Default select" id="selButtonId" onclick="selectRadios();" />
And use this js function to trigger click on radio button:
function selectRadios(){
jQuery('[for=radio1\\:0]').click();
jQuery('[for=radio2\\:0]').click();
};
ID of radio button will be used as label + :x , where x is the actual order number of the button. (0 being the first).
This is the proper way of using click() function, because you want to click on label instead on button itself, explanation here.
Note: Primefaces ver 3.1.1 are bundled with jQuery ver 1.6.x which doesn't support refresh method of button element (it is supported since ver 1.8). Otherwise you could use :
function selectRadios(){
jQuery('input[name=radio1]:first').prop('checked', true).button("refresh");
jQuery('input[name=radio2]:first').prop('checked', true).button("refresh");
};
So IMHO what is written above is all you can do in your situation. I don't know if there is some alternative to button refresh method. Someone will correct me for sure if I'm wrong.
Regards

Related

JSF component loses CSS style after AJAX render call

I have a big complex form with validation on most of the fields. Somewhere I have <h:selectOneMenu> where if I select a certain value, I want another <h:selectOneMenu> to appear under it. The second list is initially invisible (I set it with rerender property to false and I make it true with clickListener() function and render it an ajax call).
<o:form>
<h:panelGroup id="group" >
<label>Status</label>
<h:selectOneMenu id="status" immediate="true" label="Status" value="#{candidateBean.statusVO}" converter="omnifaces.SelectItemsConverter" required="true" requiredMessage="The field is empty">
<f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
<f:selectItems value="#{settingsBean.settings.statusListVO.statusVO}" var="status" itemValue="#{status}" itemLabel="#{status.name}"/>
<f:ajax event="valueChange" listener="#{candidateBean.clickListener}" execute="form" render="group" />
</h:selectOneMenu>
<h:messages for="status" style="color:red" />
<label>Invalidation Reason</label>
<h:selectOneMenu id="invalidationReason" rendered="#{candidateBean.falseTest}" label="Invalidation Reason" value="#{candidateBean.invalidationReasonVO}" converter="omnifaces.SelectItemsConverter" requiredMessage="The field is empty">
<f:selectItem itemValue="#{null}" itemLabel="-- select one --" />
<f:selectItems value="#{settingsBean.settings.invalidationReasonListVO.invalidationReasonVO}" var="invalidation" itemValue="#{invalidation}" itemLabel="#{invalidation.name}"/>
</h:selectOneMenu>
</h:panelGroup>
</o:form>
I used <o:form> instead of <h:form> because somewhere in the form I used <o:ignoreValidationFailed> because I needed to update a dataTable with values from a <h:selectOneMenu> and force update on my model.
Everything works except when I select a value from the list, the elements inside the panelGroup are rendered without any style at all and I can't figure out why. If I refresh the page the CSS is loaded on the elements but this is not an option.
My bean is #SessionScoped.

Conditionally render other component when radiobutton is changed

I am trying to display a menu if a radiobutton is selected. I'm using the rendered attribute for this purpose.
Model:
private int type; // +getter+setter
View:
<h:selectOneRadio value="#{bean.type}">
<f:selectItem itemLabel="A" itemValue="1"/>
<f:selectItem itemLabel="B" itemValue="2"/>
</h:selectOneRadio>
<h:form id="formMention" rendered="#{bean.type == 1}">
<h:selectOneMenu ...>
<f:selectItems ... />
</h:selectOneMenu>
</h:form>
Nothing shows when I check A. How can I achieve this?
Normally, you'd grab ajax for this, but as you're apparently on dead JSF 1.x, which lacks ajax fanciness, you're resorted to "plain" HTML/JS as long as you don't want to introduce an ajax capable component library. One of the ways is just submitting the form outright on click of the radio button.
<h:form>
<h:selectOneRadio value="#{bean.type}" onclick="this.form.submit()">
<f:selectItem itemLabel="A" itemValue="1"/>
<f:selectItem itemLabel="B" itemValue="2"/>
</h:selectOneRadio>
</h:form>
<h:form id="formMention">
<h:selectOneMenu ... rendered="#{bean.type == 1}">
<f:selectItems ... />
</h:selectOneMenu>
</h:form>

Change Attribute Display Type from Managed Bean in JSF

In my scenario i need to change attribute display type from managed bean using ajax
<h:inputText id="text1" value="#{managedBean.value}" />
<h:selectOneRadio value="#{managedBean.option}">
<f:selectItem itemValue="Yes" itemLabel="Yes" />
<f:selectItem itemValue="No" itemLabel="No" />
<f:ajax listener="#{managedBean.changeAttrDisplayType}" event="click" render="text1"/>
</h:selectOneRadio>
If i click yes in the radio button,then attribute(id=text1) will render as textbox and if i click No then attribute (id=text1) will be render as label.
Is it possible ?Please Guide me ...
Yes! this is possible! put your h:inputText and h:outputLabel in a h:panelGroup and in the ajax event rerender the h:panelGroup. Put the condition of which one you want to render in the respective rendered attribute like bellow:
<h:panelGroup id="changingPanel">
<h:outputLabel id="id1"
rendered="#{managedBean.option == 'Yes'}"
value="This is label"/>
<h:inputText id="id2" value="#{managedBean.input}"
rendered="#{managedBean.option == 'No'}" />
</h:panelGroup>
<h:selectOneRadio value="#{managedBean.option}">
<f:selectItem itemValue="Yes" itemLabel="Yes" />
<f:selectItem itemValue="No" itemLabel="No" />
<f:ajax event="click" render="changingPanel"/>
</h:selectOneRadio>
Assumed that, you want to display outputLabel when "Yes" is selected and inputText when "No" is selected.

JSF input to multiple backing bean properties

I have some cases where I have a JSF page and for a single input I'd like to set more than one value on the backing bean without doing code in the backing bean.
I can set a single value:
<h:selectOneRadio id="selectMembershipLevel" class="TODO_SELECT"
value="#{joinBackingBean.map[joinBackingBean.map.primary_memberInfo_membershipType_code]}">
<f:selectItem id="basic" itemLabel="#{overrideMsg.pbBasic}" itemValue="B" />
<f:selectItem id="plus" itemLabel="#{overrideMsg.pbPlus}" itemValue="P" />
<f:selectItem id="plusRV" itemLabel="#{overrideMsg.pbPlusRV}" itemValue="RV" />
But if I wanted to set more than one at once can that be done on the JSF page?
#{joinBackingBean.map[joinBackingBean.map.primary_memberInfo_membershipType_code]}
#{joinBackingBean.map[joinBackingBean.map.primary_memberInfo_membershipType_desc]}//Bdesc
#{joinBackingBean.map[joinBackingBean.map.primary_memberInfo_membershipType_type]}//Btype
Bind the other properties via <h:inputHidden> and use JavaScript during change event of the first input to manipulate the value of those hidden inputs to the same as the first input's current value.
Here's a kickoff example:
<h:form id="form">
<h:selectOneRadio value="#{bean.input1}" onchange="document.getElementById('form:input2').value = document.getElementById('form:input3').value = this.value">
<f:selectItem itemValue="one" />
<f:selectItem itemValue="two" />
<f:selectItem itemValue="three" />
</h:selectOneRadio>
<h:inputHidden id="input2" value="#{bean.input2}" />
<h:inputHidden id="input3" value="#{bean.input3}" />
...
</h:form>
Obviously, feel free to refactor to a JS function or throw in some jQuery. Keep in mind that this all won't work if client has JS disabled, and that the enduser could manipulate JS code and request parameters. A server side solution is more robust if you absolutely need the values to be equal.

<t:selectOneRadio submit issue in IE8

I'm using tomahawk <t:selectOneRadio> as follows:
<t:selectOneRadio
id="sorid" onclick="myForm.submit();"
value="#{myBean.property}" style="float: left;padding-right: 5px;">
<f:selectItem itemLabel="#{bundle.option_1}"
itemValue="option1" id="option1" />
<f:selectItem itemLabel="#{bundle.option_2}"
itemValue="option2" id="option2" />
<f:selectItem itemLabel="#{bundle.option_3}"
itemValue="option3" id="option3" />
<a4j:support event="oncomplete" reRender="chart"/>
</t:selectOneRadio>
The form is submited but the backing bean property is never changed. This only happens in IE wether or not I give extra clicks on the page. I've tried with event="onclick" also. I've tried adding this.blur(); to the selectOneRadio onclick actions.
Any help will be appreciated!
Thanks.
Remove the onclick handler. It's only colliding with Ajax support. Just let <a4j:support> do the job instead during the click event.
<t:selectOneRadio
id="sorid"
value="#{myBean.property}" style="float: left;padding-right: 5px;">
<f:selectItem itemLabel="#{bundle.option_1}"
itemValue="option1" id="option1" />
<f:selectItem itemLabel="#{bundle.option_2}"
itemValue="option2" id="option2" />
<f:selectItem itemLabel="#{bundle.option_3}"
itemValue="option3" id="option3" />
<a4j:support event="click" reRender="chart"/>
</t:selectOneRadio>
(note that the event name does by itself not have the on prefix, this only applies to attribute names of the HTML elements which should refer a script which should be executed when the event occurs)

Resources