JSF2: Is there any way to use a4j:param with rich:select or h:selectOneMenu - ajax

Is it possible to use with dropdown menus or is it also dependent on the parent object implementing ActionSource as the f:setPropertyActionLister is?
Ideally I would have done something like the following:
<h:selectOneMenu value="#{myCustomBean.selectedItemIndex}">
<f:selectItems value="#{adminLetterAdminBean.missingSettings}" var="n" itemValue="#{n.id}" itemLabel="#{n.name}"/>
<f:setPropertyActionListener value="42" target="#{adminLetterAdminBean.someProperty}" />
<a4j:ajax />
</rich:select>
However this does not work because h:selectOneMenu does not implement javax.faces.component.ActionSource. The page does not render and it gives me a friendly stack trace to tell me about this dependency.
Not seeing anything in the Richfaces documentation about this constraint, I tried the following:
<h:selectOneMenu value="#{myCustomBean.selectedItemIndex}">
<f:selectItems value="#{adminLetterAdminBean.missingSettings}" var="n" itemValue="#{n.id}" itemLabel="#{n.name}"/>
<a4j:param assignTo="#{adminLetterAdminBean.someProperty}" value="42" name="randomRequestParamName"/>
<a4j:ajax />
</rich:select>
This does not blow up, but it also does not set the property. I was wondering if there is a set a (or multiple) properties in a similar fashion.

a4j:param can only be nested inside an action component such as a4j:commandButon, a4j:commandLink and a4j:jsFunction. You can also use it with the standard button/link components.

I had a similiar problem. My page has to transfer information about the autocomplete before the autocomplete request is done. I achieved this by using jsFunction. My autocomplete looks like:
<rich:autocomplete mode="ajax" showButton="true" value="#{conf.fieldValue}"
autocompleteMethod="#{BackingBean.search.autocomplete}"
minChars="3" onfocus="sendInfo('#{conf.label}')">
</rich:autocomplete>
Depending on conf.label (conf is a forEach variable) different data is fetched by the backing bean in the autocomplete method.
The transfer of this information is done by jsFunction (just after the autocomplete declaration):
<a4j:jsFunction name="sendInfo">
<a4j:param name="param1" assignTo="#{BackingBean.search.currentAutocomplete}"/>
</a4j:jsFunction>
Just, when the user puts the focus on a specific autocomplete "sendInfo" is executed with one parameter which is bound to the backing bean.

Related

Trigger AJAX on the Select All Check boxes Primefaces DataTable

I need to execute a backing bean method when the user selects that checkbox on the top (the one that selects all the check-boxes).
I'm talking about this one:
As for the regular check boxes:
I was able to execute a backing bean method by adding the following tags inside the <p:dataTable><p:dataTable/>:
<p:ajax event="rowSelectCheckbox" listener="#{beanJanela.atualizaVariacaoSaldo}" update="variacaoSaldo" />
<p:ajax event="rowUnselectCheckbox" listener="#{beanJanela.atualizaVariacaoSaldo}" update="variacaoSaldo" />
It almost seems like it would be a matter of just adding another <p:ajax .. /> with an event like rowSelectAllCheckbox, unfortunately that event does not exist.
So how would I go about executing #{beanJanela.atualizaVariacaoSaldo} when that first checkbox is selected? Thank you.
The Primefaces User Guide (Version 6.2), page 181 offers the following event on p:datatable:
Event: toggleSelect
Listener Parameter: org.primefaces.event.ToggleSelectEvent
Fired: When header checkbox is toggled.
So try using
<p:ajax event="toggleSelect" .../>
on the datatable.

Can a p:ajax component be used with p:outputLabel?

I have a p:dataTable with some columns that contain p:outputLabel components.
I want to add p:ajax functionality so that if the user clicks on the outputLabel, I can call a server-side process to do some stuff - in the simple case it would gather some information and display that in a dialog.
I'm looking for something like this
<p:outputLabel value="#{term.explanation}" >
<p:ajax event="click" listener="#{backingBean.myListener}" />
</p:outputLabel>
Obviously, this doesn't work, so I was wondering if someone might be able to give me a hint on how I can get something like this. The constraint is that the dataTable needs to keep the p:outputLabel components - just need some way to ajaxify them.
Thanks in advance.
Dave J.
Try to use
<p:commandLink actionListener="#{backingBean.myListener}"">
<p:outputLabel value="#{term.explanation}" > </p:outputLabel>
</p:commandLink>
You could use p:remoteCommand here. You can use it to execute backing bean methods using JavaScript. For example:
<p:remoteCommand name="onLabelClick"
actionListener="#{backingBean.myListener}"/>
<p:outputLabel value="#{term.explanation}"
onclick="onLabelClick()"/>
If you need to be able to know the specific p:outputLabel that was clicked you can add parameters to p:remoteCommand and use #{component.clientId} as the value.
See also:
Pass parameter to p:remoteCommand from JavaScript
What exactly is #{component} in EL?

How to disable the required tag on a selectOneMenu when p:ajax event=change?

Here is my configuration:
PrimeFaces: 4.0.4 (elite)
OmniFaces: 1.6.3
JSF: MyFaces 2.0.2
Server: WebSphere 8.5.0.2
Some code (I only post the relevant part for better clarity):
<p:selectOneMenu value="#{viewModel.selectedContact}" required="true" converter="omnifaces.SelectItemsConverter">
<p:ajax event="change" listener="#{viewModel.updateContact}" update="area"/>
<f:selectItem itemValue="#{null}" itemLabel="#{msg.no_contact}" noSelectionOption="true" />
<f:selectItems value="#{viewModel.contacts}"/>
</p:selectOneMenu>
So here, we have a simple p:selectOneMenu that contains a list of Contact objects as well as a "No Contact" option. This field is required if I want to submit the form.
When a contact is selected in the list, the updateContact method is called. This method will generate data that will be displayed in the area section of the page updated by the AJAX call.
If I select the "No Contact" option, a validation error is triggered as this field is required, so the updateContact method is not called. I would like the method to be called as I would need to reset some data then hide the area section of the page.
I have tried using process="#this", immediate="true", but it doesn't work. With immediate="true", the selected Contact is not passed to the updateContact method.
So, what is the best way to bypass the validation of this field when selecting a null value?
Let the required attribute check if the command button is invoked. You can check that by the presence of the button's client ID in the request parameter map.
<p:selectOneMenu ... required="#{not empty param[save.clientId]}" />
...
<p:commandButton binding="#{save}" ... />
(note: code is as-is, you don't need a bean property for this)
If the command button is not invoked (but instead the ajax change listener is invoked), then the required attribute will evaluate false and everything will go as you intented.
Update: as per the comments, you intend to make them appear like required during render response all time. So, just add that check:
<p:selectOneMenu ... required="#{not empty param[save.clientId] or facesContext.currentPhaseId.ordinal eq 6}" />
...
<p:commandButton binding="#{save}" ... />

Containing div for JSF composite components

I have a number of composite components in my application, and from time to time, I need to reference those components as a whole. By default, composite components don't generate any additional mark up over their child components, so if you give a composite component an id attribute, it simply appends that id to the generated ids of the child components. I would like to reference the whole component by id (i.e. for use in jquery manipulation). JSF components do not allow EL in the id attribute, so to accomplish this, I have so far been wrapping my composite components in plain html divs as follows:
<ui:component ...
xmlns:cc="http://java.sun.com/jsf/composite"
...>
<cc:interface componentType="myComponent">
<cc:attribute name="process" type="java.lang.String" required="false" default="#form"/>
<cc:attribute name="update" type="java.lang.String" required="false" default="#form"/>
...
</cc:interface>
<cc:implementation>
<h:outputStylesheet name="myComponent.css" library="css/components" target="head"/>
<div id="#{cc.clientId}" class="myComponent #{cc.attrs.styleClass}">
... composite component implementation here ...
<p:dataTable id="note-history" styleClass="entity-notes-history" value="#{cc.notes}" var="note" paginator="true" paginatorAlwaysVisible="false"
paginatorPosition="bottom" rows="5" rendered="#{not empty cc.notes}" rowStyleClass="#{note.noteBaseType.word}">
...
<p:column rendered="#{note.noteBaseType == 'Warning' and not cc.attrs.displayOnly}" style="width: 8em;">
<p:commandButton actionListener="#{cc.cancelSeverity(note.id)}" process="#{cc.attrs.process}" update="#{cc.attrs.update} update="note-history" value="Reduce Severity"/>
</p:column>
</p:dataTable>
</div>
</cc:implementation>
And the component would be used as follows:
....
<ppa:myComponent id="myId" update="myId" />
....
Unfortunately, if I have any ajax (specifically p:ajax from primefaces) calls within the composite component, when I try to have them update the composite component by ID I get a "Cannot find component with identifier" exception. Is there any way to get JSF to auto generate a valid component and container for my composite components? I would really hate to have to generate two containing divs or spans (i.e. adding an h:panelGroup around the plain html div) just to get ajax working. Alternatively, is there a way to force JSF to allow dynamic ids on components?
Edit:
In response to BallusC's answer, I've edited the example code to be more clear in how the component is built and used, since given his answer it's entirely possible I'm just doing something that isn't allowed.
when I try to have them update the composite component by ID I get a "Cannot find component with identifier" exception
It's unfortunate that you didn't show how exactly you did that, because it should work just fine, provided that you used the composite's client ID in the update which is enclosed in the composite itself:
<f:ajax render=":#{cc.clientId}" />
Or, that you just used composite's own ID in the update which is performed outside the composite inside the same naming container parent:
<f:ajax render="myId" />
Most likely you did it the wrong way. E.g. you forgot the : prefix, or you used #{cc.id} instead of #{cc.clientId}, etc. The above has as far as I know always worked in all Mojarra 2.x versions released so far.
See also:
Referring composite component ID in f:ajax render
Is it possible to update non-JSF components (plain HTML) with JSF ajax?
Alternatively, is there a way to force JSF to allow dynamic ids on components?
You can just use EL in id attribute, provided that it's available during view build time and thus not only during view render time. See also JSTL in JSF2 Facelets... makes sense? for related background information.
Update as per your question update wherein you finally show how you tried to achieve it;
With
<ppa:myComponent id="myId" update="myId" />
and
<p:commandButton ... update="#{cc.attrs.update}" />
you're effectively ultimately doing a
<p:commandButton ... update="myId" />
which is basically looking for a component with ID myId inside the context of the composite itself! It would only have effect on e.g. a <h:outputText id="myID"> next to the <p:commandButton> inside the same <cc:implementation>.
The functional requirement is understood, but the solution is not so nice. Your closest bet is (ab)using #this and conditionally checking for that in update:
<ppa:myComponent id="myId" update="#this" />
with something like this
<p:commandButton ... update="#{cc.attrs.update == '#this' ? ':'.concat(cc.clientId) : cc.attrs.update}" />

Action not triggered when button is enabled/disabled with ajax

I am stuck with a problem that doesnt make any sense to me. I have a listbox which fires selectionChange-Events with simple Ajax. The idea is that the edit-button isnt enabled until a item in the list is selected. So I created the following code.
<h:form>
<h:selectManyListbox value="#{bean.selectedIds}">
<f:selectItems value="#{bean.listOfItems}" />
<f:ajax render="edit"
listener="#{bean.selectionChanged}" />
</h:selectManyListbox>
<br />
<h:commandButton id="add" value="#{msgs.add}"
action="#{bean.addNew}" />
<h:commandButton id="edit" value="#{msgs.edit}"
disabled="#{bean.editButtonDisabled}"
action="#{bean.edit}" />
</h:form>
The button is enabled and disabled as I wish but as it turns out, the edit-button isnt triggering any action (I added some sysout to the add- and edit-method in the bean and the edit-method is never called)...instead the html changes. The above code is nested in a simple div. When I click edit, the whole form is outside of that div.
When I add this ajax-behavior to the add-button, the same happens there and vice versa, when I remove the disabled-attribute from the edit-button everything works???
I already had a look at BalusC answer here but I couldnt find any mistake related to that list. No nested forms and so on...its just a simple page with a template.
I am using Mojarra 2.1.2 on JBoss 7.1.Final.
Any help is appreciated. Thanks
This issue is covered by point 5 of the answer which you've linked.
The rendered attribute of the component and all of the parent components should not evaluate to false during the apply request values phase of the form submit request. JSF will namely recheck it then as part of safeguard against tampered/hacked requests. Putting the bean in the view scope and/or making sure that you're preinitializing the condition in (post)constructor of the bean should fix it. The same applies to the disabled attribute of the component, which should not evaluate to true during processing the form submit.
I suggest to change #RequestScoped on BikeManagementPanelBean to #ViewScoped.
try something like this
<h:commandButton id="edit" value="#{msgs.edit}"
disabled="#{bikeManagementPanelBean.editButtonDisabled eq false}"
action="#{bean.edit}" />
try to wrap it again with the <h:panelGroup> and render the instead of the button...

Resources