From: Sylvain Vieujot [mailto:[EMAIL PROTECTED]
Subject: RE: New "initId" attribute
For my specific email problem, sure I could find a solution.
But the problem is that the solution wouldn't be straightforward and would cause other problems.
Plus it's quite hard to debug as the problem isn't easy to reproduce. It can also have really bad consequences once in production (as it did for me).
For me, this is problem is really a deficiency of JSF.
The initId is the best solution I've found so far, and it should prevent other similar bugs.
 
To me, it sounds like you are trying to do a conceptually wrong thing, i.e. trying to control a mutating list with a static list, and then trying to fix the problem with applying "glue" to something it wasn't intended for, not an actual deficiency in the framework. If people would follow the design principle to create a separate UI list, similar problems wouldn't arise. All this from my own o-o programming skewed view of the world of course :)
 
Kalle
 On Mon, 2005-06-20 at 09:40 -0700, Korhonen, Kalle wrote:
Ok, I understand that you might have a big problem if the list actually changes between the requests - but that's something you can control. You could argue that it shouldn't change between the requests, because it represents conceptually a different object: a list of items displayed to the user, not a list of business items that are constantly changing. Couldn't you make a displayedMails list from your mailsInInbox list and then deal with the UI list instead of dealing with the back-end list, no? Of course, the objects themselves wouldn't need to be copied, only references to them, so performance/memory consumption -wise it shouldn't be that bad.
Kalle



From: Sylvain Vieujot [mailto:[EMAIL PROTECTED]
Sent: Monday, June 20, 2005 9:09 AM
To: MyFaces Development
Subject: RE: New "initId" attribute



I agree with the general statement, but it just doesn't work :-(
If you just use <x:selectBooleanCheckbox value="#{email.checked}"/> and the emails list changes between your 2 requests, then the action isn't performed on the proper email.
That's the all problem I'm facing.

By default, the id's are attributed according to the row number.
So, using the email's id makes sure that the the email's checkbox matching is preserved.
Whether we use the a value linked to the business logic or to the ui isn't the point.
The point is that we have to be able to set an id that is unique for the given email, and not one that's linked to the email's position in the list.
And to do this, you need to be able to set the checkbox's id with an EL formula.

Note that this is not special to checkbox.

Sylvain.

On Mon, 2005-06-20 at 08:26 -0700, Korhonen, Kalle wrote:
Just to comment on the "row numbers required" discussion in general. A
row number is a UI thing and you business logic shouldn't need to care
on which row an object was. You seem to be fixated on identifying the
object based on its row number when a much better practice is to use
unique id of an object for identifying it. If you do that, then your
backend bean also doesn't need to care whether that object was being
displayed on a list or not, it just acts based on the given object id.
If the objects you are displaying don't have a unique id, of course you
can (and should) create a thin wrapper for them in the *back-end* code
that includes a unique id for the objects. The whole point of JSF is to
provide means to clearly separate UI logic from business logic and
generating ids for your objects on the UI doesn't sound like its
following that paradigm too well. Furthermore, the id of the checkbox
shouldn't matter, it's the property that you bind your component value
that matters - and to refer to that property, you should be able and you
*should* use the unique id of the object.

As far as I can see, in the mail example you mentioned, you don't need
to worry about unique ids at all. If in your datatable the var name is
"email", the last column could be just:
<h:column>
	<x:selectBooleanCheckbox value="#{email.checked}"/>
</h:column>

Then in the delete/move action you would just iterate over the
collection of your mail objects and execute the action on the objects
that have the property "checked" set to true.

Kalle


________________________________

	From: Sylvain Vieujot [mailto:[EMAIL PROTECTED]] 
	Sent: Sunday, June 19, 2005 11:35 PM
	To: MyFaces Development
	Cc: [EMAIL PROTECTED]
	Subject: New "initId" attribute
	
	

	The new attribute 

	The id can't be initialized with an EL _expression_, and we can't
allow it if we want to keep all chances to pass the TCK tests.
	But the possibility to initialize a component's id with a
runtime computed value is quite crucial (see bellow).
	
	So I propose to add a new attribute for the x: components that
allow the id to be initialized with a VB _expression_ like :
	<x:myFacesComponent initId="CMP_#{rowVar.id}" .../>
	
	This would set the component's id on creation. Once set, the id
is never changed.
	
	

	Why we need it 

	In dataTables, you sometime need to set the component's ids.
	But as the ids have to be unique, if you can use only constants,
you can't set the ids.
	
	Here is an example where this is highly needed :
	A webmail application displays the inbox with emails received
(last received first).
	On each inbox's row displays the email subject and a checkbox to
be able to delete the email right from the inbox view.
	At the bottom of the page is an update bottom to show the
updated inbox, and to delete checked for delete emails.
	If you check the email on row 3 for deletion and if before you
press the update button, you receive a new email, then when your request
is submitted email #3 is former email #2.
	As the checkbox id's are based on the row number, you end-up
unintentionally deleting the wrong email.
	The best fix to this problem is to set the checkboxes' ids to a
unique string depending upon the email, like : 
	<x:selectBooleanCheckbox initId="Delete_#{email.primaryKey}_CB"
value="#{inboxFace.removeEmailUnid[email.unid]}"/>
	That way, application has no unexpected behavior.
	
	Craig suggested an alternative approach to this particular
problem, involving a hidden field (see bellow).
	I didn't find how to use this, and I'm not sure it's really
feasible.
	Anyway, even if it turns out it could work, it would be a tricky
solution to a commonly found problem.
	Using this initId attribute would be a more elegant and general
solution for this kind of problems.
	
	Any thought ?
	
	Sylvain.
	
	-------- Forwarded Message --------
	From: Sylvain Vieujot <[EMAIL PROTECTED]
<mailto:[EMAIL PROTECTED]%3e> >
	Reply-To: MyFaces Discussion <[email protected]
<mailto:[EMAIL PROTECTED]%3e> >
	To: [EMAIL PROTECTED]
	Cc: [EMAIL PROTECTED], MyFaces Discussion
<[email protected]
<mailto:[EMAIL PROTECTED]%3e> >
	Subject: Re: ForcedID is not working
	Date: Mon, 13 Jun 2005 17:51:20 -0400
	
	Hello Craig,
	
	I understand your concern about the TCK tests.
	But I don't see how to use the hidden field you suggest.
	
	In the table, I have a checkbox for each email, and each email
whose check box is checked should be deleted.
	I had a similar problem with a list of images whose titles could
be edited directly in the table.
	I don't see how with a hidden field (or hidden fields) you can
fix the problem.
	
	Could you give me a clue ?
	
	Thanks,
	
	Sylvain.
	
	On Mon, 2005-06-13 at 09:45 -0700, Craig McClanahan wrote: 

		On 6/13/05, Sylvain Vieujot <[EMAIL PROTECTED]> wrote:
		>  I'm just getting in a problem because the id doesn't
support EL right now.
		>  
		>  I have a table that displays a webmail inbox.
		>  On each row, I have a delete this email checkbox.
		>  
		>  It works fine except that it you receive a new email
before you submit your
		> form, the wrong email is deleted, as the checkbox's
name is based on the row
		> number, and the emails have all been shifted one row
down.
		>  
		>  The only solution I've found to this (and other
similar) problem(s) is to
		> use the email's id in the checkbox's id :
		>  <x:selectBooleanCheckbox id="Delete_#{email.unid}_CB"
		> value="#{inboxFace.removeEmailUnid[email.unid]}"/>
		>  
		>  This doesn't work right now, but I think the only
solution to this problem
		> IS TO ALLOW EL in id attributes.
		>  
		>  The 1.1 & 1.2PR Spec. section 3.1.4 says that "all
properties other than id
		> and parent, are value binding enabled".
		>  But we could partialy enable it. I mean use the value
binding the first
		> time the component's id is used, and then freeze this
value.
		>  
		>  Any thoughts ?
		> 
		
		If the TCK inludes tests to verify that "id" is *not*
value binding
		enabled (which wouldn't surprise me since it is a stated
spec
		requirement), then this solution would just have to be
undone again in
		order to pass the tests.
		
		An alternative appropach would be to include a hidden
field in one of
		the columns that contains the information you need to
identify the
		correct model data (the message identifier for a mailbox
screen, for
		example).  As decoding occurs and events are fired, the
value of this
		hidden field (along with all the others on the current
row) will have
		been restored to what it was, so that if the checkbox is
checked you
		can go find the relevant message to update or delete.
		
		Craig
		
		>  
		>  On Tue, 2005-06-07 at 22:01 +0200, Martin Marinschek
wrote: 
		>  rational explanation:
		> 
		> a value in a value-binding can change
		> 
		> - the unique id must stay the same over the whole
lifetime of a view,
		> if not, where will you post the value of an input to
if its id has
		> changed?
		> 
		> regards,
		> 
		> Martin
		> 
		> On 6/7/05, Mike Burati <[EMAIL PROTECTED]> wrote:
		> > 
		> > > The #{}-_expression_ isn't evaluated in the
id-attribute, why not???
		> > 
		> > The #{} _expression_ support for Value Binding is a
runtime/request-time
		> > facility.
		> > 
		> > The id attributes are used as component identifiers,
by JSF, to build up
		> > a component tree with unique identifiers per naming
container.
		> > 
		> > See Section 3.1 of the JSF1.1 specification for more
information on
		> > component identifiers and value binding. Per the
spec, the id and
		> > parent are the only attributes of the UI components
not enabled for
		> > value binding...
		> > 
		> > 
		> > **********************************
		> > Michael Burati
		> > Senior Software Engineer
		> > Bowstreet
		> > 200 Ames Pond Drive
		> > Tewksbury, MA 01876
		> > T 978-863-1512
		> > F 978-863-1555
		> > www.bowstreet.com
		> > 
		> > Get the latest information on Bowstreet's events and
web seminars.
		> > 
		> > 
		> > 
		> > -----Original Message-----
		> > From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED]]
		> > Sent: Tuesday, June 07, 2005 3:28 PM
		> > To: MyFaces Discussion
		> > Subject: Re: ForcedID is not working
		> > 
		> > *lol*, thanks I'll give it a try ;)
		> > 
		> > By the way: why can't I do something like <tag
		> > id="category-#{node.identifier}" />
		> > 
		> > The #{}-_expression_ isn't evaluated in the
id-attribute, why not???
		> > 
		> > Am Dienstag, 7. Juni 2005 20:03 schrieb Korhonen,
Kalle:
		> > > true to
		> > > guide MyFaces to leave the id as is, to whatever
you've set it to.
		> > > Granted, the name is misleading IMHO as well.
		> >
		> 
		>
		

Reply via email to