OK, I put in a proposal in the wiki with the hotels use case:
http://www.w3.org/MarkUp/Forms/wiki/@context_id
Leigh.
________________________________
From: John Boyer [mailto:boyerj@ca.ibm.com]
Sent: Friday, June 18, 2010 2:28 PM
To: Klotz, Leigh
Cc: public-forms@w3.org
Subject: RE: @context everywhere; applies to ref and value separately, or applies before ref, then ref applies to value?
Hi Leigh,
Yes, I agree that context() would need to be more powerful, but frankly I thought we eventually would need to do that.
So, once we decide there is a real use case, maybe we should discuss how an additional optional parameter could be added to context() to allow it to obtain the inscope eval context of an element other than the default of the immediate ancestor element.
Cheers,
John M. Boyer, Ph.D.
IBM Distinguished Engineer, Interactive Web Applications and Documents
IBM Lotus Forms Architect
Workplace, Portal and Collaboration Software
IBM Canada Software Lab, Victoria
E-Mail: boyerj@ca.ibm.com
Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer <http://www.ibm.com/developerworks/blogs/page/JohnBoyer>
Blog RSS feed: http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw <http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw>
From: "Klotz, Leigh" <Leigh.Klotz@xerox.com>
To: John Boyer/CanWest/IBM@IBMCA
Cc: <public-forms@w3.org>
Date: 06/18/2010 01:56 PM
Subject: RE: @context everywhere; applies to ref and value separately, or applies before ref, then ref applies to value?
________________________________
Thanks for clarifying the context on child elements. That's a relief.
I believe you're right about the expressive power of repeat nodesets and index() being up to the task of the context() function.
The problem I encountered was when the inner repeat used, as a predicate on its nodeset, a value from the outer repeat.
It does turn out to be solvable with index, but it's not pretty.
In fact, I believe that when you get to triply-nested repeats, you have to go back to copying repeat-nodesets and index, and cannot use context(), because index() takes an ID argument but context() does not, so there's no way to get back to the grandparent.
Here's the context example with two nested repeats, using context:
<xf:repeat id="statuses-repeat" nodeset="instance('statuses')/statuses/status">
<xf:repeat id="hotels-repeat" nodeset="instance('hotels')/hotel[status=current()]">
<xf:trigger>
<xf:label>Mark Vacant</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('mark')/status">vacant</xf:setvalue>
<xf:setvalue ref="instance('mark')/name"
value="context()/name" />
<xf:send submission="mark-status" />
</xf:action>
</xf:trigger>
</xf:repeat>
</xf:repeat>
and here it is without context(), using index(), position(), and duplicating the nodesets of the two repeats, including their predicates:
<xf:repeat id="statuses-repeat" nodeset="instance('statuses')/statuses/status">
<xf:repeat id="hotels-repeat" nodeset="instance('hotels')/hotel[status=current()]">
<xf:trigger>
<xf:label>Mark Vacant</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('mark')/status">vacant</xf:setvalue>
<xf:setvalue ref="instance('mark')/name"
value="instance('hotels')/hotel[status=instance('statuses')/statuses/status[index('statuses-repeat')] and position()=index('hotels-repeat')]/name" />
<xf:send submission="mark-status" />
</xf:action>
</xf:trigger>
</xf:repeat>
</xf:repeat>
Now let's add a set of triggers, one for each status, here done with index:
<xf:repeat id="statuses-repeat" nodeset="instance('statuses')/statuses/status">
<xf:repeat id="hotels-repeat" nodeset="instance('hotels')/hotel[status=current()]">
<xf:repeat id="set-status-repeat" nodeset="instance('statuses')/statuses/status">
<xf:trigger>
<xf:label>Mark <output value="." /></xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue ref="instance('mark')/status" value="instance('status')/status[index('set-status-repeat')]" />
<xf:setvalue ref="instance('mark')/name"
value="instance('hotels')/hotel[status=instance('statuses')/statuses/status[index('statuses-repeat')] and position()=index('hotels-repeat')]/name" />
<xf:send submission="mark-status" />
</xf:action>
</xf:trigger>
</xf:repeat>
</xf:repeat>
</xf:repeat>
I don't see that we can handle this with context() though. We can do this line:
<xf:setvalue ref="instance('mark')/status" value="context()" />
but I don't see how the next setvalue can profit from context().
<xf:setvalue ref="instance('mark')/name"
value="???" />
Leigh.
________________________________
From: John Boyer [mailto:boyerj@ca.ibm.com <mailto:boyerj@ca.ibm.com> ]
Sent: Friday, June 18, 2010 11:49 AM
To: Klotz, Leigh
Cc: public-forms@w3.org
Subject: RE: @context everywhere; applies to ref and value separately, or applies before ref, then ref applies to value?
Hi Leigh,
Every element has an in-scope evaluation context, including those child elements you talked about [1]. See especially the text after the list, which indicate that elements that are not binding elements have an in-scope evaluation context equivalent to what they would have if they were binding elements.
[1] http://www.w3.org/TR/xforms11/#expr-eval <http://www.w3.org/TR/xforms11/#expr-eval>
So, yes you actually should be able to use context() in output/mediatype/@value.
Although context() is the "right" answer, can you still let me know whether or not you see a specific problem with using index() in that case you raised earlier, when further amended to be an inner repeat? I'd like to assume it is actually not a problem unless you say otherwise.
Cheers,
John M. Boyer, Ph.D.
IBM Distinguished Engineer, Interactive Web Applications and Documents
IBM Lotus Forms Architect
Workplace, Portal and Collaboration Software
IBM Canada Software Lab, Victoria
E-Mail: boyerj@ca.ibm.com
Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer <http://www.ibm.com/developerworks/blogs/page/JohnBoyer>
Blog RSS feed: http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw <http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw>
From: "Klotz, Leigh" <Leigh.Klotz@xerox.com>
To: John Boyer/CanWest/IBM@IBMCA
Cc: <public-forms@w3.org>
Date: 06/18/2010 11:24 AM
Subject: RE: @context everywhere; applies to ref and value separately, or applies before ref, then ref applies to value?
________________________________
Thank you, John. That's great news. I had gotten confused and thought context was an XForms 1.2 feature; so @context everywhere is, but context() isn't.
I'll note this in the wikipage on @context everywhere.
I have another question about context(), though, and it would have applied equally to my misunderstood @context:
#fn-context says that it applies to "context node of the nearest ancestor element". So, that means it isn't useful for child elemements which allow evaluation of xpath expressions for what would otherwise be static attribute values.
For example, output/mediatype/@value <mailto:output/mediatype/@value> cannot use context().
Leigh.
________________________________
From: John Boyer [mailto:boyerj@ca.ibm.com <mailto:boyerj@ca.ibm.com> ]
Sent: Friday, June 18, 2010 7:19 AM
To: Klotz, Leigh
Cc: public-forms@w3.org
Subject: Re: @context everywhere; applies to ref and value separately, or applies before ref, then ref applies to value?
Hi Leigh,
First, to clarify, you're trying to get the value attr in setvalue to evaluate "name" as the name of the hotel that is both good and cheap, i.e. the value expression evaluates relative to the repeat item node rather than the result of the ref in setvalue.
While the ref sets the starting node of the value, the repeat item node happens to be the "inscope evaluation context node" of the setvalue action, which sets the starting node of the ref.
Therefore, no, the context attribute will not help you with resetting the evaluation node for the value attr. The context attribute allows override of the inscope evaluation context of the element containing the context attribute, so it would only help you to set a context for the ref of the setvalue.
Unfortunately, Mark's blog post is also incorrect, and you are correct, that using the current() function does not work. Later in Mark's post, he does acknowledge that.
The actual fix to the problem is the context() function [1], and you're hitting on the exact reason it was added.
[1] http://www.w3.org/TR/xforms11/#fn-context <http://www.w3.org/TR/xforms11/#fn-context>
In your markup, use this:
<setvalue ev:event="DOMActivate"
ref="instance('home')/hang/your/hat" value="context()/name" />
If Mark's post contained context() where it currently contains current(), then his blog post would work without having to resort to the index() function:
<xf:setvalue bind="testBind" value="context()/VO_ID" />
Finally, note that context() is one of the harder functions to implement, so you may have to file an issue with your flavourite XForms implementer if the above doesn't work. And meanwhile, could you explain further what breaks when you use the alternative method of the index() function to solve this problem in an inner repeat? Offhand, the only reason I can think of why it wouldn't work is that the harder part of implementing the index() function has not been done properly, which would mean another issue for your flavourite XForms implementer.
Cheers,
John M. Boyer, Ph.D.
IBM Distinguished Engineer, Interactive Web Applications and Documents
IBM Lotus Forms Architect
Workplace, Portal and Collaboration Software
IBM Canada Software Lab, Victoria
E-Mail: boyerj@ca.ibm.com
Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer <http://www.ibm.com/developerworks/blogs/page/JohnBoyer>
Blog RSS feed: http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw <http://www.ibm.com/developerworks/blogs/rss/JohnBoyer?flavor=rssdw>
From: "Leigh L. Klotz, Jr." <Leigh.Klotz@Xerox.com>
To: public-forms@w3.org
Date: 06/17/2010 11:37 PM
Subject: @context everywhere; applies to ref and value separately, or applies before ref, then ref applies to value?
________________________________
When we add @context to actions [1], would this work to deal with the
lost repeat context in setvalue problem?
<repeat nodeset="instance('directory')/hotels/hotel[@good='yes' and
@cheap='yes']">
<trigger>
<label>Book <output ref="name" /></label>
<setvalue ev:event="DOMActivate" context="."
ref="instance('home')/hang/your/hat" value="name" />
</trigger>
</repeat>
(You can work around this loss of context with index(), but not in the
case of nested repeats.)
Interestingly, Mark Birbeck suggests [2] that current() solves this
problem, but my understanding was that
<setvalue ref="instance('home')/hang/your/hat" value="current()/name" />
was the same as
<setvalue ref="instance('home')/hang/your/hat" value="./name" />
and current() would be useful only inside predicates.
Am I wrong on this count?
[1] http://www.w3.org/MarkUp/Forms/wiki/@context_everywhere <http://www.w3.org/MarkUp/Forms/wiki/@context_everywhere>
[2] http://www.formsplayer.com/node/200 <http://www.formsplayer.com/node/200>
Leigh.