-
1. Re: How to pass an argument to the backing-bean?
healeyb Jun 18, 2012 6:01 AM (in response to grattler)1 of 1 people found this helpfulTo get the data table row you need to use:
<rich:dataTable ... var="record">
...
<a4j:ajax .../>
<f:setPropertyActionListener target="#{bean.currentRow}"
value="#{record}"/>
</rich:dataTable>
where the type of currentRow is the generic type of the rich:dataTable value= attribute. I don't see the need for
both a valueChangeListener and an ajax listener. Why not just do the necessary logic in the valueChangeListener
(which as you rightly point out has access to the new value) and have the a4j:ajax without the listener method.
You don't need to "pass" the old value, it's already in the model by definition because you have a value= attribute
in inputText.
Just note that the default event for an input component is actually "valueChange", not "change", and sometimes
"change" doesn't do quite what you want, but it's easily tested. I normally just use the default and not specify
event=.
Regards,
Brendan.
-
2. Re: How to pass an argument to the backing-bean?
grattler Jun 18, 2012 7:38 AM (in response to healeyb)Hi Brendan,
thank you for the tips. I have changed the inputText-tag like followed:
<rich:column>
<h:inputText value="#{record.value}" size="7" rendered="#{record.copy}"
valueChangeListener="#{bean.valueChanged}">
<a4j:ajax event="valueChange" execute="@this"
listener="#{bean.callListener}" render="richTab" />
<f:setPropertyActionListener target="#{bean.selectedEntryToCopy}"
value="#{record}"/>
</h:inputText>
</rich:column>
This does not work. The browser displays an error-message: Parent is not of type ActionSource.
Is it wrong to nest the setPropertyActionListener within the inputText-tag?
In my business logic I sometimes override the setter-value.
Was the valueChangeListener invoked after the setter-method from inputText?
<a4j:ajax execute="@this" render="richTab" /> will call the setter-method too, isn't it?
After finishing my business logic method there should be no further setter-call with the new value.
This was the reason for the ajax-listener to invoke the business logic.
Kind regards
Oliver
-
3. Re: How to pass an argument to the backing-bean?
healeyb Jun 18, 2012 9:08 AM (in response to grattler)Right, a silly mistake on my part. I've got to say that a) I always use a UICommand component in these situations
so that I can use setPropertyActionListener, and b) I'm using extendedDataTable. There is an example from
Practical Richfaces 2, which does this:
<a4j:jsFunction name="updateDetails" render="???">
<a4j:param name="rowKey" assignTo="#{bean.currentRow}"/>
</a4j:jsFunction>
<rich:dataTable rowKeyVar="key" onrowclick="updateDetails(#{key})" ...
currentRow will be an index, so if you have a List<Something> mylist, mylist.get(currentRow) should give you the
row data.
Note <a4j:param name="rowKey", it could be name="slartibartfast" and it would still work. The first a4j:param
matches up with the first parameter to updateDetails which is #{key} etc...
>Was the valueChangeListener invoked after the setter-method from inputText? NO
Regards,
Brendan.
-
4. Re: How to pass an argument to the backing-bean?
grattler Jun 19, 2012 10:01 AM (in response to healeyb)Hi Brendan,
I have switched to extendedDataTable and I am using the <a4j:jsFunction>.
Great approach. It's working, it's easy to understand and I can use the row-key in other methods, too!
Very nice solution. I am excited!
Slartibartfast is a funny name for a param-name, but I prefer jigsaw.
Thank you for your help.
Kind regards
Oliver
-
5. Re: How to pass an argument to the backing-bean?
healeyb Jun 19, 2012 10:38 AM (in response to grattler)1 of 1 people found this helpfulGreat, looks like things are moving in the right direction. With extendedDataTable you can do things a bit differently.
There's a bit of boilerplate code required in the selectionchange listener, and this version only works for
selectionMode="single". Assuming the extendedDataTable has a value= which is a List<MyGenericType> this will
get you the selected row in selectedSomething.
<rich:extendedDataTable
selectionMode="single"
selection="#{bean.selectedRow}"
...
<a4j:ajax render="???"
event="selectionchange"
listener="#{bean.mytableRowSelect}"/>
...
</rich:extendedDataTable>
class Bean ... {
private Collection<Object> selectedRow;
private MyGenericType selectedSomething;
public void memberRowSelect(AjaxBehaviorEvent event) {
UIExtendedDataTable dataTable = (UIExtendedDataTable) event.getComponent();
Object originalKey = dataTable.getRowKey();
Object selectionKey = selectedMember.toArray()[0];
dataTable.setRowKey(selectionKey);
if (!dataTable.isRowAvailable()) {
return;
}
MyGenericType selectedSomething = (MyGenericType) dataTable.getRowData();
dataTable.setRowKey(originalKey);
}
// getters & setters required
}
Regards,
Brendan.
-
6. Re: How to pass an argument to the backing-bean?
grattler Jun 20, 2012 8:11 AM (in response to healeyb)Hi Brendan,
thank you for the selectionchange listener.
I have implemented it and it works, but the difficulty lies in the detail.
One column of my data-table contains a delete-button.
When I delete row 5 (for example), the selectionchange listener was called and my bean was notified with the fifth object.
After that, this object was deleted from my model and the data-table was rendered.
Then I want to delete the fifth row again (which was the sixth row before deleting and rendering occurs).
The selected line was the same as before, and the data-table doesn't fire a selectionchange listener, even though the data-table was rerendered.
The second row-deletion will not work, because the bean contains the wrong selected row.
The bean contains still the stale row that was deleted in the first place.
Without deleting & rerendering the selectionchange listener would work.
But in my case I must use the <a4j:jsFunction> and the row-key.
Kind regards
Oliver
-
7. Re: How to pass an argument to the backing-bean?
healeyb Jun 20, 2012 2:43 PM (in response to grattler)Whenever you make any changes to the underlying data you have to ensure that:
a) the model (i.e. what is referenced by the rich:dataTable value= attribute) is refreshed, and
b) the actual table (the rich:dataTable id=) is refreshed by any ajax render= component that
is making changes to the underlying data.
You shouldn't be accessing the database in getters so hopefully you have another way of
doing this.
Regards,
Brendan.