Richfaces: rich:select click event fails - jsf

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

Related

How to reset input components on change of <p:selectOneMenu> after certain validations are violated

I'm populating <p:selectOneMenu> from a database which contains a list of zones, when a JSF page loaded.
When a zone in this menu is selected, a set of <p:inputText> is displayed in which a user can insert charge that corresponds to product weight which is to be transferred by a transporter to the selected zone in the menu. This can be shown in the following snap shot.
As can be seen, when non numeric values are entered by a user, validation violations occurs, when the given save button <p:commandButton> is pressed (the numbers displayed on top of each text field correspond to weight).
If a user now change the zone in the menu - the first panel without pressing the reset button, the data corresponds to that newly selected zone is loaded in these text fields only when the reset button is pressed as follows (because of validation violation)..
So, how to load data after previous validation violation, if an item (zone) is changed in the menu?
The change event of <p:selectOneMenu>, in this case should do the function something like which is done by <p:resetInput>.
Hope you will be able to understand what I mean :).
Basically, you need the functionality provided by <p:resetInput> inside <p:ajax> of a <p:selectOneMenu>. This is indeed not possible as <p:resetInput> requires being placed in a component implementing ActionSource such as UICommand components.
Your best bet is to let <p:remoteCommand> take over the <p:ajax> change listener job. Therein you can put a <p:resetInput>.
Imagine that you currently have a:
<h:form>
<p:selectOneMenu id="zone">
<f:selectItems ... />
<p:ajax listener="#{bean.changeZone}" update="data" />
</p:selectOneMenu>
<p:panel id="data">
...
</p:panel>
</h:form>
Then this change should do:
<h:form>
<p:selectOneMenu id="zone" onchange="changeZone()">
<f:selectItems ... />
</p:selectOneMenu>
<p:remoteCommand name="changeZone" process="#this zone" action="#{bean.changeZone}" update="data">
<p:resetInput target="data" />
</p:remoteCommand>
<p:panel id="data">
...
</p:panel>
</h:form>
Don't forget to remove the AjaxBehaviorEvent argument from the listener method. It's useless in this particular case anyway.

JSF onclick event on combobox

I don't know how to implement onclick event on a combobox, my boss want me to do is once the user click a value in the combobox it automatically search and display all the value of the selected/click item. First question is it possible to have an onclick event on a JSF page without using any javascript/jquery? Right now I'm using ADF for designing the interface. Second question how can I implements this onclick event on my combobox?
There are a couple of ways to achieve this:
Use a valueChangeListener and execute your query when it fires.
Set autoSubmit="true" and when the bound value changes, execute your query.
Only selecting a value in a dropdown won't submit your form. This is not about JSF but HTML .. so without any JS i think it's not possible.
I do not know anything about ADF in special but in plain JSF you just have to add an ajax-event to your dropdown (e.g. in primefaces)
<h:form id="id1">
<p:selectOneMenu id="id2" value="#{myBean.value}"
immediate="true" editable="true" >
<f:ajax execute="#this" listener="#{myBean.doSomeAction}" />
<f:converter converterId="myConverter" />
<f:selectItems value="#{myBean.availableOptions}" />
</p:selectOneMenu>
</h:form>

h:selectOneRadio doesn't work with ajax change event

i have two radio buttons and no one is selected by default, and it's mandatory to select one of them, so here's what i did:
<div id="payment_method">
<h:message for="sel_payment_method" style="Color:red;"/>
<h:selectOneRadio id="sel_payment_method" required="true" requiredMessage="Please select a payment method" value="#{myBean.selectedPaymentMethod}">
<f:selectItem itemLabel="Debit or Credit Card" itemValue="credit" />
<f:selectItem itemLabel="Checking Account" itemValue="checking" />
<f:ajax event="change" render="credit_inputs_fragment checking_inputs_fragements" />
</h:selectOneRadio>
</div>
the selectedPaymentMethod property is a string and its default value is null
and the credit_inputs_fragment is a ui:fragement that contains a div
ISSUE: when clicking on a radio buttons the two fragments to be changed are not affected.
please advise, thanks.
You're not entirely clear in describing the concrete problem, but I can see at least two potential problems in the code posted so far:
The <f:ajax event="change"> is wrong in case of radiobuttons and checkboxes. It should be event="click". Or, better, just remove it altogether. It defaults to the right one already. See also What values can I pass to the event attribute of the f:ajax tag?
The component referenced in <f:ajax render> must be a fullworthy JSF UI component and always be rendered to the client side. If the component is by itself never rendered to the HTML, then JavaScript simply can't find it to update its content. You basically need the conditionally rendered components in another component which is always rendered. See also Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
i followed the example code in the following link, and it solved my issue:
JSF: Dynamically change form

Dynamically updating a4j:repeat using data from form

I have a page where the user can upload a file to the server. He can set which groups/users can read/write (to) the file.
This is done by selects. One select holds the names of the groups the user is currently in, and on the same row is a select with options Read and Write. On the second row is the corresponding stuff for selecting users.
When the user selects a group and either Read or Write for said group, he then presses a button. After pressing the button I would like to show the user a list of permissions below the select. The list would have a group name, access setting for said group and a button to remove the permission item.
My problem is, I'm not able to update the page and show the list of permissions. Server side the permissions are added to an ArrayList, but I can't get the contents to show in a4j:repeat. How can I get the repeat tag to update?
Here is what I've been trying to do so far:
<h:form>
<h:selectOneMenu value="#{assetUploadForm.currentGroupName}" valueChangeListener="#{assetUploadForm.groupNameChanged}">
<f:selectItem itemValue="users" itemLabel="users" />
<f:selectItem itemValue="foobar" itemLabel="Foobar" />
<a4j:ajax event="valueChange" render="second" execute="#this" />
</h:selectOneMenu>
<h:selectOneMenu value="#{assetUploadForm.currentGroupRW}" valueChangeListener="#{assetUploadForm.groupRWChanged}">
<f:selectItem itemValue="R" itemLabel="Read"/>
<f:selectItem itemValue="W" itemLabel="Write"/>
<a4j:ajax event="valueChange" render="second" execute="#this" />
</h:selectOneMenu>
<a4j:commandButton action="#{assetUploadForm.addGroupRights}" value="add group" render="groupList"/>
<ul>
<a4j:repeat value="#{assetUploadForm.groupPermissions}" var="permission" id="groupList">
<li><h:outputText value="#{permission.permissionSetItemId}"/></li>
</a4j:repeat>
</ul>
</h:form>
So, the problem is a4j:repeat is never updated. If I replace the repeat with an outputtext, and set the commandbutton to render it, the page is updated "correctly".
The <a4j:repeat> does not render any HTML to the response. The render attribute of <a4j:ajax> however expects a component with that ID being physically present in the HTML DOM tree (it is namely behind the scenes using JavaScript document.getElementById() stuff to get the element which needs to be updated after the ajax response has returned). This is thus not possible in combination with <a4j:repeat>. You would need to specify its parentmost JSF HTML component instead, or at least to wrap it in a new one.
E.g.
<a4j:commandButton action="#{assetUploadForm.addGroupRights}" value="add group" render="groupList"/>
<h:panelGroup id="groupList">
<ul>
<a4j:repeat value="#{assetUploadForm.groupPermissions}" var="permission">
<li><h:outputText value="#{permission.permissionSetItemId}"/></li>
</a4j:repeat>
</ul>
</h:panelGroup>
As a different alternative, you can also just use the <rich:list> component instead which renders the complete <ul><li> for you already. You're then basically updating the <ul> directly.
<a4j:commandButton action="#{assetUploadForm.addGroupRights}" value="add group" render="groupList"/>
<rich:list id="groupList">
<h:outputText value="#{permission.permissionSetItemId}"/>
</rich:list>
To learn about which components all are available and how to use them, peek around in the showcase site and the component reference.
I don't know why it does not work but as a work-around you could probably use h:dataTable for this. With some css tweaking that could be rendered with the same looks.
Or wrap a a4j:outputPanel around the a4j:repeat and try what happens if you render that.
MAG,
Milo van der Zee

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