How to communicate back and forth between client and server-side in JSF? - jsf

Most of my problems in JSF, so far, seem to boil down to this - communication from (static) client-side to (dynamic) server-side, and vice-versa; for instance, for re-rendering components.
An example: enabling/disabling a button (commandButton) that depends on the selection of a selectoneradio.
What is the correct way to communicate the selection of the selectoneradio (client to server) and then ajaxingly updating the commandButton (server to client)?

By using <f:ajax>.
Here's an example which enables the button when the second item is selected.
<h:selectOneRadio value="#{bean.selectedItem}">
<f:selectItem itemValue="1" itemLabel="First item" />
<f:selectItem itemValue="2" itemLabel="Second item" />
<f:ajax render="button" />
</h:selectOneRadio>
<h:commandButton id="button" disabled="#{bean.selectedItem != 2}" />
Make sure that the #{bean} is a #ViewScoped one so that the state is remembered across postbacks. Else it'll fall back to default values when you press the submit button.
That said, I strongly recommend to go through a decent JSF book. The above is usually already covered in 1st chapter.

Related

Update object in bean without reload

On my page i have form with data from database. I want to implement, as default behaviour, writing all changes to db.
I found such example
<h:selectOneMenu value="#{bean.options}" onchange="submit()"
var="#{bean.options}" valueChangeListener="#{bean.changeListernMethod}">
<f:selectItem itemValue="1" itemLabel="option1" />
<f:selectItem itemValue="2" itemLabel="option2" />
<f:selectItem itemValue="3" itemLabel="option3" />
</h:selectOneMenu>
but it not call listener method and reload all page. I can't reload page on every inputText edit or menu selection change. Do you have idea how to achieve such behaviour? Update objects in bean without page reload.
<f:ajax listener="#{bean.changeListernMethod}" render="#form" event="valueChange"/>
This is how you implement partial submit, or in your words: update objects in bean without page reload. The line I typed will fire ajax and update (only) the form whenever a value is selected and is different from the previous selected.
For more info:
https://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/ajax.html

Can i use immediate property in JSF to refresh my html page without calling any backing bean methods??

Can i use immediate property in JSF to refresh my html page without calling any backing bean methods?? i am new to jsf please suggest & also explain use of immediate
Imagine that you have this code:
<h:form>
<h:selectOneMenu id="subscriptions"
value="#{subscriptionController.subscriptions}"
immediate="true">
<f:selectItem id="item1" itemLabel="News" itemValue="1" />
<f:selectItem id="item2" itemLabel="Sports" itemValue="2" />
<f:selectItem id="item3" itemLabel="Music" itemValue="3" />
<f:selectItem id="item4" itemLabel="Java" itemValue="4" />
<f:selectItem id="item5" itemLabel="Web" itemValue="5" />
</h:selectOneMenu>
</h:form>
Regarding the immediate attribute is a boolean flag indicating that component events should be sent to registered event listeners immediately rather than after the validation phase of the JSF request processing lifecycle. The immediate flag allows you bypass JSF validation for a particular component. Reference here.
JSF life cycle is not easy to understand but you can check a good explanation here: JSF Life cycle
At a next level of experience you can add ajax to improve even more your performance. And the most recommended is to use libraries in that case, for example RichFaces and PrimeFaces.
Regards,
According to your requirement it seems that you don't need to use immediate attribute.
Just use f:ajax to process(execute) and update(render) particular elements or group of elements. It will not harm the performance.
And to know JSF Lifecycle and detail of immediate attribute please check Baluc's Blog
Use reRender attribute by using richfaces components for refresh the page or particular region of a page.

Richfaces: rich:select click event fails

I am using a rich:select, which I want to repopulate when it is clicked on the page. I tried this using a4j:ajax listening for the onClick-Event, but it seems like it is never received. For testing purposes I added an alert to the control, that is shown after an unpredictable number of clicks. The code in my Backing Bean is never called.
If I change the control to h:selectOneMenu it works, but the list collapses immediately so that the users cannot select an item. Additionally the manual input is a required feature.
Code in my JSF-Page:
<rich:select id="auftragsIdsCombo" value="#{einsatzController.einsatz.auftrag.id}" enableManualInput="true" onclick="alert('hi')">
<f:selectItem itemLabel="" noSelectionOption="true" />
<f:selectItems value="#{einsatzController.auftragsIds}" />
<a4j:ajax event="click" render="auftragsIdsCombo" listener="#{einsatzController.loadAuftragsIds()}"/>
</rich:select>
Maybe there is another way of doing this, wich I am not aware of. I just want to load the items after clicking on the Dropdownbox, so that the users can either select one or use autocompletion by typing into the control.
Regards

ValueChangeListener problem

While calling the ValueChangeListener in JSF based on value change in dropdown, it is calling all the ValueChangeListner that are on that page.
There are two valueChangeListener in DataTable, while changing value in one dropdwon the 2nd one also executing.
<t:column id="avlId" styleClass="coltextcenteralign">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="#{bundle['travelLocalAccommodation.title.availability']}" />
<h:outputText value="*" style="color:red" />
</h:panelGroup>
</f:facet>
<t:selectOneMenu value="#{accomDtls.availability}" immediate="true"
valueChangeListener="#{TravelProcessingBB.localAccommodationBB.setAvailableFlag}" forceid="true" id="avl"
onchange="return availabilityAlert('#{accomDtls.prepopulatedFlag}','avl[#{table_count}]')"
styleClass="dropDownStyle" style="width:50">
<f:selectItem itemValue="Y" itemLabel="Yes" />
<f:selectItem itemValue="N" itemLabel="No" />
</t:selectOneMenu>
</t:column>
The value change alone won't automatically call the valueChangeListener. You need to submit the form as well. A commonly used "hack" is to call form.submit() using JavaScript during the onchange event. This will however submit the entire form. Truly the valueChangeListener will be triggered for all changed fields of the form.
To fix this in JSF 1.x, you need to hassle somewhat with the immediate attribute to skip all other form components from validating and with component binding so that you can properly get/set the other component's value. Long story short, I ever wrote an article about that: populate child menus in JSF 1.2.
In JSF 2.0, this is however easier to achieve with help of <f:ajax> tag. If you're really using JSF 2.0 (your current question doesn't indicate that), then let me know if you need an example.

Attach rich:toggleControl to radio buttons or select items

Has anyone had any success attaching a rich:toggleControl component to a radio button component (h:selectOneRadio) or alternatively any of its children select items (in this case s:enumItem).
Basic code example:
<h:selectOneRadio value="#{backingValue}">
<s:enumItem enumValue="VAL_1" itemLabel="Value One" />
<s:enumItem enumValue="VAL_2" itemLabel="Value Two" />
<s:convertEnum />
</h:selectOneRadio>
The ideal thing would be to attach the toggle control to the s:enumItems so I could have it switch to a particular state. However at this point I'd be happy if the toggle control can just be attached to the h:selectOneRadio. I've tried the toggle control as a child of the h:selectOneRadio and s:enumItems; neither works. I've also tried wrapping the toggleControl around the h:selectOneRadio, the toggle control works in this case but the radio buttons don't.
Just tie your rich:togglePanel to the same value on your backing bean, and use an a4j support tag to update the value and re-render the panel.
One thing to keep in mind is that the rich:togglePanel #value attribute must resolve to a String, so you'll probably need to bind to #{backingValue.name()} (don't use toString() since somone might override it on you later...)
something like this should work:
<h:selectOneRadio id="radioButtons" value="#{backingValue}">
<a4j:support event="onclick"
ajaxSingle="true"
reRender="radioButtons, togglePanel"/>
<s:enumItem enumValue="VAL_1" itemLabel="Value One" />
<s:enumItem enumValue="VAL_2" itemLabel="Value Two" />
<s:convertEnum />
</h:selectOneRadio>
<rich:togglePanel id="togglePanel"
switchType="ajax"
value="#{backingValue.name()}" >
<f:facet name="VAL_1">
<h:outputText value="Selected enum value 1"/>
</f:facet>
<f:facet name="VAL_2">
<h:outputText value="Selected enum value 2"/>
</f:facet>
</rich:togglePanel>
You might have to play with the ajax support event binding as well. I've found that the "onchange" and "onselect" events with radio buttons can be a little bit spotty where AJAX4JSF is concerned. I've done this with Strings, where an action in my backing bean changes the toggle panel state by setting the value - but it SHOULD Work with enum's as well.
This isn't strictly an answer to my above question but it's a work around I'm using for now until I figure out how to do it 'better' re- above.
Anyway the workaround: add an onclick event to the h:selectOneRadio which calls the rich:togglePanel's javascript API:
onclick="TogglePanelManager.toggleOnClient('TOGGLE_PANEL_ID_HERE',null);"
Still I would like to do this 'properly' using the rich:toggleControl component if possible ...

Resources