Maybe I'm dense. OK, probably I'm dense, but if you're passing a Task
object into the composite component, why not have that object also have
the save and delete method on it? There's no need for a method to have
a parameter if it's already a part of the object it acts on.
So, instead of delete(task), you'd have task.delete(). Isn't that
possible?
Then, you should be able to use those passed methods as your action and
valueChange targets right?
What am I missing?
Jim
P.S. Not that it wouldn't be handy to execute arbitrary methods on the
server - in one of my examples (poll, I think), I did resort to a hidden
button that I call click() on to do just that. Icky.
On 8/12/09 3:31 PM, Lincoln Baxter, III wrote:
Ok, so perhaps I should explain my dataTable/ui:repeat use case a
little
bit more, since it seems like some of these options are not going very
smoothly for me. I've labeled 3 questions, just to keep this long
message slightly more organized.
*The Scenario:*
-----------------------------------------------------------------------
Everything on your website is RequestScoped -- There are no stateful
pages or SessionScoped beans whatsoever. That means that data is loaded
every time a user accesses a page via GET, POST, etc... if an ajax event
on a page updates some value - it actually needs to be updated via a
service call on the back-end.
You have an Object: "Task" -- a Task has an Assignee, a few Dates, and a
Status.
In order to keep the look and feel of Tasks consistent on the UI, you've
created a "taskBlock.xhtml" composite component to handle the layout.
However -- you would like inline editing and updating of the Task data
to work via Ajax.
Each taskBlock component instance needs to be able to save, delete its
given Task object instance. Hence, you need:
* a delete(Task) action to occur on a commandButton action event (this
part is easy thanks to JBoss Seam/EL2)
* a save(Task) method to be called on a ValueChangeEvent for each
editable field
The latter is the hard part, because the task object may have come from
a list, it may have been passed in by itself. A workaround would be to
have a "Save" button, but that's an extra click for the user, and ugly,
etc, lots of reasons why you wouldn't want this. ValueChanceListeners do
not accept properties, or allow user-specified ValueChange Methods to be
supplied.
*Solutions?*
-----------------------------------------------------------------------
I tried including a hidden commandLink in the Ajax execute="" attribute
in order to trigger the action after the ValueChangeEvent, but it never
fires -- not sure if that's a bug or intended.
***Question 1: *Almost every AJAX framework I know of allows you to
simply execute a method on the server side, with or without params, and
return a result... is this possible with JSF's Ajax framework?
What would be optimal, would be if you could supply, as mentioned in a
previous message in this chain, a ValueChangeMethod:
<h:inputText>
<f:valueChangeMethod method="saveTask(t)" />
</h:inputText>
or
<f:valueChangeMethod method="saveTask(event, t)" />
Which is even more powerful if you consider the new EL, or JBoss EL. If
the method contains a "ValueChangeEvent event" in the method signature,
it should be injected into the call.
Thus, you would not have to write extra classes, or bind any objects, or
retrieve any rows from a DataModel or DataTable.
***Question 2:* Without changing the Spec, how would you achieve this
and ensure the user interaction is the same? The value needs to be saved
via Ajax when they change it on the UI... without clicking a save
button. If there is no way to support this type of functionality in the
spec currently, then I propose we add it.
***Question 3:* Is this really an uncommon use case? Does everyone make
a separate view/edit page for lists of items?
The UI JavaScript, CSS, and HTML is not my strong point -- perhaps a
component writer would invest more time with JSF's Ajax JavaScript in
order to get the behavior right via custom JS, CS, and HTML..?
I'm basically trying to figure out if I'm way off base here, and need a
paradigm readjustment. It seems like nobody else is raising issues like
this online, so it's possible that JSF doesn't need to change; I'd just
like to know what everyone else is eating before I push for a change ;)
--Lincoln
On Fri, 2009-08-07 at 14:14 -0700, Alexander Smirnov wrote:
> ui:repeat is a normal JSF component that supports binding but
> <c:forEach> is compilation directive only that has no component
> associated with tag.
> The question just recalls me one forgotten problem: h:dataTable and
> ui:repeat is complete different components that doing similar jobs.
> While ui:repeat knows about UIDataTable and works well inside it,
> DataTable itself has no clue what UIRepeat is iteration component,
> therefore rendering a set of tables using ui:repeat is not possible.
>
>
> On 08/03/2009 12:54 PM, Lincoln Baxter, III wrote:
> > So here's one of those,"why is this different than that?"
questions:
> >
> > Unless I'm mistaken, ui:repeat is not a component and therefore cannot
> > be bound to a backing bean, but -- would it make sense to support
> > something *like*<h:dataTable> in order to support determining the
> > selected row on action events and value change events? A component that
> > would privide a bindable DataModel / List<Object> row access like
> > <h:dataTable>?
> >
> > *My use case is this:*
> >
> > * Managed Bean contains a List of objects
> > * Each object rendered to screen with input field
> > * User submits the input field (with a command link or button, etc)
> > * ManagedBean needs to take action on the appropriate row values
> >
> >
> > I have a list of objects - I need to render them onto the screen (not
> > necessarily in an HTML table, maybe a<ul> would be nicer) but I
can't
> > use<ui:repeat> because each row has a commandLink, and I need to be
> > able to determine which row the user clicked on in order to take the
> > appropriate action.
> >
> > EL2 helps with this, but... now what if I have a ValueChangeEvent for an
> > input field on each<li> row? Now I can no longer use EL2 to pass the
> > row into the ValueChangeListener, and I would have to use something like
> > <f:setPropertyActionListener> which is not only getting increasingly
> > complicated, but I'd also have to set an attribute /inside/the VCL
> > itself, or in a bean VCL knows about - then referencing it - which is
> > terribly ugly. Now try to fit all that into a composite component and it
> > gets really ugly to try attaching tons of VCLs or ALs or SPALs to values
> > inside the component.
> >
> > Am I attacking this problem in the wrong way? Is this one of those
> > things that has an easy solution I'm not seeing? Or is this a genuine gap?
> >
> > --Lincoln
> >
> >