<t:selectOneRadio submit issue in IE8 - jsf

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)

Related

How does JSF send form component values to another page?

I'm new to JSF, I'm trying to understand what is the standard way for pages to send parameters between each other.
I have one page with some form elements:
form.xhtml:
<h:form>
<p:selectManyButton name="numbers" id="lstNumbers" >
<f:selectItem itemValue="1" itemLabel="1"></f:selectItem>
<f:selectItem itemValue="2" itemLabel="2"></f:selectItem>
<f:selectItem itemValue="3" itemLabel="3"></f:selectItem>
</p:selectManyButton>
<br /><br />
<p:selectManyButton name="letters" id="lstLetters" >
<f:selectItem itemValue="A" itemLabel="A"></f:selectItem>
<f:selectItem itemValue="B" itemLabel="B"></f:selectItem>
<f:selectItem itemValue="C" itemLabel="C"></f:selectItem>
</p:selectManyButton>
<p:commandButton value="Go" action="results">
</p:commandButton>
And my results page where I want to get what items were selected from the form.
results.xhtml:
<h:body>
<br /><br /> param.numbers: "#{ param.numbers }"
<br /><br /> param.letters: "#{ param.letters }"
</h:body>
What am I missing that I cannot get form.xhtml to send the selected items to results.xhtml as parameters (either GET or POST)?
I can get this to work with a flowscoped bean, but that seems overkill for a simple task. Somehow I think I've got the wrong approach to this altogether. Thanks in advance.

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.

Nested ajax with nested rendered attribute in JSF

<h:form action="" prependId="false">
<h:selectOneRadio value="#{managedBean.color}" id="color">
<f:selectItem itemValue="red" itemLabel="Color1 - Red" />
<f:selectItem itemValue="green" itemLabel="Color1 - Green" />
<f:ajax event="click" render="group1" listener="#{managedBean.renderSubQuestions}"/>
</h:selectOneRadio>
<h:panelGroup id="group1">
<h:outputLabel value=" Color Description " rendered="#{managedBean.colorRender}"></h:outputLabel>
<h:inputText rendered="#{managedBean.colorRender}"></h:inputText>
<h:selectOneRadio id="number" value="#{managedBean.integer}" rendered="#{managedBean.colorRender}" >
<f:selectItem itemValue="1" itemLabel="Number1 - 1" />
<f:selectItem itemValue="2" itemLabel="Number1 - 2" />
<f:selectItem itemValue="3" itemLabel="Number1 - 3" />
<f:ajax event="click" render="group2 " listener="#{managedBean.renderSubQuestions}"/>
</h:selectOneRadio>
</h:panelGroup>
<h:panelGroup id="group2">
<h:outputLabel value="Number Description " rendered="#{managedBean.integerRender}"></h:outputLabel>
<h:inputText rendered="#{managedBean.integerRender}"></h:inputText>
</h:panelGroup>
</h:form>
In my scenario I used nested JSF AJAX with nested rendered attribute. If I select a color based on the selection, it rendered some radio button (addition elements) with AJAX. It is working fine, but additional elements with AJAX behavior is not working for me. If I remove rendered attribute in number radio button, it is working fine. I dont know where I did mistake.
It is most likely what your ManagedBean is not in ViewScoped or SessionScoped. When you post back to the bean, you are loosing rendered states. I suggest to change for the ViewScoped one.
Not related :
You should remove the action attribute from the h:form since JSF override it.

valueChangeListener for <h:selectOneMenu> not function when re-render <rich:popupPanel>

I have a popup panel (id=PanelAddQueryCriteria) define on top of jsf page but it only enable it after user select a menu item (id=entityKind) and re-render take pace for that popupPanel. However because of that re-render, select item (id=queryCriteriaAttr) inside that popup panel don't trigger change listener (#{ceaDBBean.queryCriteriaAttrChanged}) in first value change, and only trigger when select again... Any help? Here the code:
<rich:popupPanel id="PanelAddQueryCriteria">
<h:form id="formAddQueryCriteria">
<h:selectOneMenu id="queryCriteriaAttr"
value="#{ceaDBBean.queryCriteriaAttr}" required="true"
valueChangeListener="#{ceaDBBean.queryCriteriaAttrChanged}">
<f:selectItems value="#{ceaDBBean.ceaEntityKindAttrs}"/>
</h:selectOneMenu>
</h:form>
</rich:popupPanel>
<h:panelGrid id="searchPanel">
<h:selectOneMenu id="entityKind"
value="#{ceaDBBean.entityKind}" required="true"
valueChangeListener="#{ceaDBBean.entityKindChanged}">
<a4j:ajax event="valueChange" render="addQueryCriteria" execute="#this" />
<f:selectItems value="#{ceaDBBean.ceaEntityKinds}" />
</h:selectOneMenu>
<a4j:commandLink styleClass="no-decor" id="addQueryCriteria"
render="PanelAddQueryCriteria"
disabled="#{empty ceaDBBean.entityKind}"
execute="#this" action="#{ceaDBBean.initAddQuryCriteria}"
oncomplete="#{rich:component('PanelAddQueryCriteria')}.show()">
<h:graphicImage id="addQueryCriteriaImg"
value="/images/icons/common/new.gif" width="16" height="16"
alt="#{adminMsg.addQueryCriteria}" />
<rich:tooltip value="#{adminMsg.addQueryCriteria}" for="addQueryCriteria" />
</a4j:commandLink>
</h:panelGrid>
Short answer: this problem is caused by JSF issue 790. Change
render="PanelAddQueryCriteria"
by
render="formAddQueryCriteria"
or maybe, if you have actually more into the panel which needs to be updated than the form itself,
render="PanelAddQueryCriteria formAddQueryCriteria"
Long answer: read following related questions:
<a4j:commandbutton> action is only invoked on second click
h:commandButton/h:commandLink does not work on first click, works only on second click

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

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

Resources