On 16 Dec 2003, at 12:39, Upayavira wrote:

Jeremy Quinn wrote:

Hi All

I have a similar need and am trying to work out what is going wrong.

I have multiple Rows in a Repeater, each one needs a Button, that when clicked, takes the user to a new screen to choose data for one of the fields of the Row.

This needs to be done in a seperate screen as there is a complex set of information to choose from, which will need to be paginated into a series of screens.

What I have attempted is this:

<wd:repeater id="resources">
<wd:widgets>
<wd:output id="id">
<wd:datatype base="long"/>
</wd:output>
<wd:field id="text" required="true">
<wd:label><i18n:text i18n:catalogue="local">label.text</i18n:text></wd:label>
<wd:datatype base="string">
<wd:validation>
<wd:length min="2" max="1024"/>
</wd:validation>
</wd:datatype>
</wd:field>
<wd:field id="reference" required="true">
<wd:label><i18n:text i18n:catalogue="local">label.reference</i18n:text></wd:label>
<wd:datatype base="string">
<wd:validation>
<wd:length min="2" max="128"/>
</wd:validation>
</wd:datatype>
</wd:field>
<wd:row-action id="up" action-command="move-up"> . . . </wd:row-action>
<wd:row-action id="down" action-command="move-down"> . . . </wd:row-action>
<wd:row-action id="delete" action-command="delete"> . . . </wd:row-action>
<wd:action id="choose" action-command="choose"> <!-- action-command ??? -->
<wd:label><i18n:text i18n:catalogue="local">label.choose.resource</i18n:text></wd:label>
<wd:hint><i18n:text i18n:catalogue="local">hint.choose.resource</i18n:text></wd:hint>
<wd:on-action>
<javascript>changeReference (event, viewData)</javascript>
</wd:on-action>
</wd:action>
</wd:widgets>

</wd:repeater>

The Repeater has Rows with three fields, ID, Text, Reference. The value of Reference is a string that is a reference to an XML:DB document, the purpose of the Chooser is to allow the User to select one of those documents.

Each Row has four buttons, Up, Down, Remove and Choose. They each have JavaScript Event Handlers.
The Choose button is a <wd:action> because there is no equivalent <wd:row-action>.
I am not sure what the @action-command is supposed to refer to .....

I am in the "suck it and see" stage of writing the scripts, but am getting unexpected results, here are the scripts I am playing with.

// event handler called by Woody to change a Resource's Reference
function changeReference (event, viewData) {
var id = event.getSourceWidget ().getParent ().getWidget ("id").getValue ();
try {
var chosen = AlbumPeer.getResourceById (viewData.album, new java.lang.Long (id));
if (chosen != null) {
chooseReference (chosen);
}
} catch (e) {
cocoon.log.error ("Exception in changeReference handler: " + e);
}
}

The event handler above, works as expected.

// shows a screen to choose an XML:DB record to be a Resource's reference
// will not use Woody to display the screens, as they are not forms.
function chooseReference (resource) {
cocoon.log.info ("triggered chooseReference");
while (true) {
cocoon.log.info ("chooseReference, about to send screen");
cocoon.sendPageAndWait ("screen/choose"); // never see this screen
cocoon.log.info ("chooseReference, sent screen"); // never see this log message
}
}

This function does not work as expected (apart from the fact it is not written yet ;).
I see the first two log messages OK, but I never see the choose screen, the user is taken straight back to the original Woody form above.

Now I am clearly inside one of Woody's Continuations when the "Choose" button is clicked and it's event handler is executed. But I would expect a new Continuation to be produced inside of the original one, and I would expect to re-enter the original Continuation once the "Chooser's" Continuation has completed.

Am I making a conceptual mistake in thinking I am able to work this way?
Or, should I be able to do this, if only I did it correctly?

Many thanks for any assistance.

regards Jeremy

I put a bit on the Wiki under http://wiki.cocoondev.org/Wiki.jsp?page=WoodyWidgetReference#ref- WoodyWidgetReference-9
about how to do submit from a row. Check that out and let me know if it gets you going.

Thanks Upayavira

Yes, this makes more sense ......

I replaced the <wd:action id="choose" .... > (above) with :

<wd:submit id="choose" action-command="choose" validate="false">
<wd:label><i18n:text i18n:catalogue="local">label.choose.resource</i18n:text></wd:label>
<wd:hint><i18n:text i18n:catalogue="local">hint.choose.resource</i18n:text></wd:hint>
</wd:submit>

Then in the while loop of the main flowscript for the page:

if ("choose".equals (form.submitId)) {
  chooseReference (form, album);
  continue;
}

Then in this function :

function chooseReference (form, album) {
var id = form.getWidget ().getSubmitWidget ().getParent ().getWidget ("id").getValue ();
var resource = AlbumPeer.getResourceById (album, new java.lang.Long (id));
if (resource != null) {
cocoon.sendPageAndWait ("screen/choose", resource);
}
}

I can extract the ID of the object to be changed, and furthermore, I can see the screen !!

Now to make it do something ;)

Many thanks

regards Jeremy


On 14 Dec 2003, at 16:20, Upayavira wrote:

Sylvain Wallez wrote:

Upayavira wrote:

Bruno Dumon wrote:

On Fri, 2003-12-12 at 11:47, Upayavira wrote:

I need a row submit action, that allows a form to be submitted for a specific line in a repeater.

An example usecase would be on a selling site, you have a repeater showing purchasable items, each with a 'buy' button next to it.

Clicking on a row submit action will submit the form and allow the flowscript code that deals with the submitted form to gain access to either the repeater row object, or at least the row index that was clicked.

Is there anything like this already? Any of you interested in adding it ;-)




Use a wd:submit widget (or wd:action) as child of the repeater. In its event handler you can get the repeater row by getting the parent of the submitted widget:

event.getSourceWidget().getParent()

using getId() on it will return the row number (as a string). You can access other widgets on the repeater row by using the getWidget(id) method on it.

Bruno,

Thanks for this. What I've done is extend the RowAction to give it a 'submit-row' action-command. I've added a property to the repeater for it to store and access the 'submittedRow'. When the submit-row RowAction is clicked, it sets the submitted row on the repeater. Then from flow, the submitted row can be found from flow using form.getWidget("repeatername").getSubmittedRow().

I would rather not do it in an event handler, as I'd have to store the row somewhere for future use outside of the forms flow.

Is this reasonable? Is it a reasonable patch?




IMO, it's better to go through the widget that triggered the submit than asking to the repeater (furthermore, what happens in the case of nested repeaters?).

I you want this to be handled by the flow, The Form object provides a getSubmitWidget() that gives the submitting widget. From there, you can use the same getParent() as outlined by Bruno to access the row, and then the row id, child widgets, etc.


Splendid. That's what I wanted to be able to do, and without any modifications to Cocoon - even better!

Thanks for this.

Upayavira




Attachment: smime.p7s
Description: S/MIME cryptographic signature



Reply via email to