I'm thinking that the fields will be contained in a list or fieldset and a hyperlink will cause a new field to be appended. Each appended widget would be identical to the others with the name/id incremented.
"Randall" <rand...@tnr.cc> writes: > I'm wondering if someone has already done this. I'd like to implement > a widget for which the client can append fields similar to this:
> I'm thinking that the fields will be contained in a list or fieldset > and a hyperlink will cause a new field to be appended. Each appended > widget would be identical to the others with the name/id incremented.
I've done it with JavaScript. I would like to use a RepeatingWidget for that because it would make validation easier. When I did it there was no RepeatingWidget (and this was one of the motivations that led Michele and Alberto to implement that kind of widget)...
What I see from a fast look at the docs is that unfortunately you have to pass the number of repetitions at the declaration time. If you pass it on instantiation, then the form won't know how many copies it should validate (I'm talking about using it on the decorator, one might put it on the code and set tg_errors... hmmmm).
Then, you'd use soma AJAJ for inserting a new instance of your form / fieldset / fields into the screen. It shouldn't be hard (validating on the body of the function you'll know how many instances to process).
> I would appreciate any feedback and I'll keep it available for a few > days.
Hi!
Looks very good. A few suggestions:
- focus & select the first field when adding a field set.
- you should be able to remove any field set, not just the last one.
- add the event handlers for the "Add"/"Remove" links with MochiKit's "connect" function. This allows to add other handlers later, if necessary.
- put the "Add"/"Remove" links on a separate <li> item, this makes styling easier.
BTW, where did you get the TG logo and header from? I was searching the TG site recently for better logos than the ones in 1.0b distro and could not them. There should be a "branding/marketing" section on the TG website!
> - focus & select the first field when adding a field set.
Why the first field? Would it make more sense to select the one just added? Or do you mean the first of the set just added?
> - you should be able to remove any field set, not just the last one.
Agreed.
> - add the event handlers for the "Add"/"Remove" links with MochiKit's "connect" > function. This allows to add other handlers later, if necessary.
I'll have to look into this because I haven't used MochiKit's connect function before.
> - put the "Add"/"Remove" links on a separate <li> item, this makes styling easier.
Agreed.
> BTW, where did you get the TG logo and header from? I was searching the TG site > recently for better logos than the ones in 1.0b distro and could not them. > There should be a "branding/marketing" section on the TG website!
>> - focus & select the first field when adding a field set.
> Why the first field? Would it make more sense to select the one just > added? Or do you mean the first of the set just added?
Yes.
>> - you should be able to remove any field set, not just the last one.
> Agreed.
>> - add the event handlers for the "Add"/"Remove" links with MochiKit's "connect" >> function. This allows to add other handlers later, if necessary.
> I'll have to look into this because I haven't used MochiKit's connect > function before.
Very easy:
connect(element or 'element_id', 'onsomething', function);
e.g.
connect(addlink_1, 'onclick', function(event) { /* passes form as element, not as element ID */ addItem(e.src().form); } ); /* or just change 'addItem()' to accept an event object instead of an element ID */
>> BTW, where did you get the TG logo and header from? I was searching the TG site >> recently for better logos than the ones in 1.0b distro and could not them. >> There should be a "branding/marketing" section on the TG website!
> It was the default on a quickstarted 1.0b app.
Ups, I must have used the "static" directory from an old quickstarted app. The strange thing is, my TG installation still only contains the old pictures in its static directory!? I will try to do a clean install again, and see what happens.
> Why the first field? Would it make more sense to select the one just > added? Or do you mean the first of the set just added?
He meant the first field of the added set.
As for the rest, I use this pattern quite a bit (I call it an InputList), though I haven't used it on a TG widget form yet. If you put the code somewhere I can grab it, I'll do the styling and javascript polish.
That would be great since I'm not good with Javascript. Once structural change I'd prefer is that the form fields contained in <div> elements be contained in <ul><li> instead because they're more flexible with CSS. For example, they could be displayed vertically or horizonally and with or without bullets.
- When you add a new field set, the fields are always filled in with the values from the first field set. I would either leave them empty or fill in the values from the bottommost field set.
- The "Add" link ist still not properly embedded in the <ul> list of the form.
> - When you add a new field set, the fields are always filled in with the values > from the first field set. I would either leave them empty or fill in the values > from the bottommost field set.
Yes. They should be empty.
> - The "Add" link ist still not properly embedded in the <ul> list of the form.
I don't understand why this would be a good thing. Currently, the <ul> list is a list of form field sets. A new form field set is simply appended to the list. Adding the link to the list would break the pattern. For specific styling it could be given a class name. I'm not saying I couldn't be convinced, just that I don't yet see the advantage of doing it.
> Christopher Arndt wrote: >> - When you add a new field set, the fields are always filled in with the values >> from the first field set. I would either leave them empty or fill in the values >> from the bottommost field set.
> Yes. They should be empty.
Or you could add another link next to each field set labelled "Clone" that would put a copy of the field set at the bottom of the list (or just below the item). Just an idea, dunno if this is really useful.
>> - The "Add" link ist still not properly embedded in the <ul> list of the form.
> I don't understand why this would be a good thing.
It's just not proper HTML, IMO. But it's just a minor point.
> Currently, the <ul> list is a list of form field sets.
In the example you gave, the link is part of the ListForm, not the widget. It seems important to me that the link be included with the widget. The spans are necessary for styling since the contents of the li can include the fields, error message, and help text, which must be styled separately. Take a look at some of the template strings for widgets included in TG to see examples.
I'm curious as to why you think it's not proper html. It will valildate as XHTML Strict though my examples are published as HTML 4. I'll publish the next example as XHTML Strict.
I've cleaned it up a bit; put the css and js links in the widget definition and appending the fields now puts focus on the new field. There's no 'AJAX' going on, just DOM manipulation.
One big issue I haven't addressed yet. After the form has been submitted, trips back to the form must recreate the extra form fields based on how much data was submitted originally. Examples include displaying validation errors and editing form data.
The feedback has been great. I've included a copy of the entire quickstarted project if you'd like it.
Randall wrote: > I've cleaned it up a bit; put the css and js links in the widget > definition and appending the fields now puts focus on the new field. > There's no 'AJAX' going on, just DOM manipulation.
> One big issue I haven't addressed yet. After the form has been > submitted, trips back to the form must recreate the extra form fields > based on how much data was submitted originally. Examples include > displaying validation errors and editing form data.
> The feedback has been great. I've included a copy of the entire > quickstarted project if you'd like it.
If you post the data, then hit the back buttton, only the original field(s) are present. I can't figure out how to present all of the fields that were present before the POST. It's a cached view, so it would need to be a client side solution I think. Any ideas?
Randall wrote: > If you post the data, then hit the back buttton, only the original > field(s) are present. I can't figure out how to present all of the > fields that were present before the POST. It's a cached view, so it > would need to be a client side solution I think. Any ideas?
This is the problem with AJAX. The state transitions effected by local changes to the content (by setting InnerHTML or otherwise manipulating the DOM) aren't recorded in the browser history, so the back button is never likely to be that helpful, I'm afraid.
Do you think it would be acceptable for this to be an understood limitation for this widget? The other scenarious (prepopulate on edit, etc.) are addressable on the server side and I've already got a good idea how to do it.
Randall wrote: > Do you think it would be acceptable for this to be an understood > limitation for this widget? The other scenarious (prepopulate on edit, > etc.) are addressable on the server side and I've already got a good > idea how to do it.
Don't see any option, really. It's an existing limitation for many AJAX applications, and nobody seems to be screaming. I've never liked the "back" button anyway :-)
Steve Holden <st...@holdenweb.com> writes: > Randall wrote: >> Do you think it would be acceptable for this to be an understood >> limitation for this widget? The other scenarious (prepopulate on edit, >> etc.) are addressable on the server side and I've already got a good >> idea how to do it.
> Don't see any option, really. It's an existing limitation for many AJAX > applications, and nobody seems to be screaming. I've never liked the > "back" button anyway :-)
There are some non-portable options¹ but your code gets ugly or your location bar gets ugly. And you have to code specifically for that.
I won't worry with the back button with this kind of setup. One thing to think is "why would the user hit the back button?" and then try to provide alternative means to get there. Most users will click on an hyperlink saying "Previous Page" instead of the back button and then you could attach some JavaScript to send the values back to the page where they were entered. If you're populating these with data from the database, then it's just a matter of reading them again.
I've done some refactoring and cleanup and I'm happy with the current implementation. Is this something you think might belong in the standard TG widget set? If so, I'll submit it as a feature request. If not, I'll put it in the wiki. For convenience, here's the link again: