Ajax requests are a great technology, but they tend to be slow, especially in Drupal. I prefer to avoid them, if the same effect can be achieved with plain javascript.
The "Add another item" button for multivalue fields is a typical example:
Why not just clone existing fields using jQuery?
Maybe it does not always work, but it would be a great time saver!
Draft:
$('.content-multiple-table').each(function(){
var table = this;
var tbody = $('tbody', table).get(0);
var parent = this.parentNode;
// create a clone
var sample_tr = $($('tr', this).get(0)).clone();
// TODO: reset form values
$('.content-add-more input', parent).click(function(){
var new_tr = sample_tr.clone();
// TODO: adjust names of form items
$(tbody).append(new_tr);
});
});
Another possibility would be to load a clean sample with ONE json request, and clone that. The json request can be fetched on page load, and it can be browser-cached.
It could be wise to implement both, and use one or the other depending on the situation. And as a last resort use Ajax.
(PS: I am sorry for not checking how this works in D7.)
Comments
Comment #1
markus_petrux commentedAHAH is needed because the Forms API version of the form needs to be rebuilt. Otherwise, Forms API will ignore any additional fields added client-side. This is for security reasons. You cannot submit data the server does not expect.
In addition to this, adding more elements to the form may involve complex processing that is only known server-side, and it may make no sense to replicate client-side.
PS: Switching to CCK2 because CCK3 is just an experimental branch related to multigroups, and this is firstly related to "Add more stuff" for multiple value fields.
Comment #2
dman commentedIt's probably not entirely impossible, if someone wanted to work on it.
AFAIK, even FAPI doesn't check for elements it didn't expect when it's been told to expect an array of results - as in multi-valued CCK fields. At least it didn't last time I looked, which was a while ago.
Back then I DID find a problem with cloning elements because they had IDs in them, and just copying the rows client-side required me to go through and swap out a few attributes. Not impossible, but did get more awkward than I'd hoped.
Not sure about more complex processes. I imagine someone may want to implement a rule that allowed "no more than 5" fields, or had some other validation that, as markus says, may not make sense.
But still, I think the DOM-only clientside feature would be something to optionally consider - if someone wanted to try it. There's a bunch of us out in the world who DON'T have super-fast broadband, and waiting 6 seconds just to get another field added to the UI is so 90's
EDIT: Here's the (pre-jquery) code I was using - may not work when viewing from CVS repo like that
Comment #3
markus_petrux commentedAside from DOM ids, and FAPI and form state issues, there may also be problems with Drupal.settings that are generated server-side for each item and Drupal.behviors that depend on them. That's enough stuff to make me feel this is something a bit more complex that it seems.
I'm afraid something like this won't happen for D6 because it could potentially break a lot of existing sites, and other contrib/custom modules that assume how things work now.
Maybe this could be explored under the context of Fields in D7, maybe. Not sure if it is even too late for such a change.
Comment #4
donquixote commentedWhat if this was an optional feature that can be enabled under "controlled conditions" ? For instance, if it is known that it is nothing but an innocent text field.
Another solution would be to send some hidden fields that can be activated via javascript. We don't even need to send these fields as full html. It's enough to send the extra information that javascript needs to reconstruct the html from a clone of an existing field. And store the extra field in the form array.
Comment #5
markus_petrux commentedEven an inocent text may involve a lot of processing that we have no control, for example if someone else was altering this inocent element using hook_form_alter() to provide additional stuff. We may potentially break too much things.
That's why I think this needs to be explored for future versions.
Comment #6
donquixote commentedhehe ok then what if the user ticks a checkbox saying "yes this field is innocent, by my mother's beard." I mean, the admin user in the CCK manage fields backend.
Comment #7
markus_petrux commentedI guess you could try this using a separate module that implements a widget for text fields.
Comment #8
giorgio79 commentedWas just thinking about this.
Check out this jquery module
http://plugins.jquery.com/project/tableAddRow
demo here
http://cloudgen.w0ng.hk/jquery/table.addrow.php
Very nice and fast.
Comment #9
donquixote commentedAdding a table row doesn't need a plugin, imo.
Here is my approach:
http://drupal.org/project/multicrud
It does nothing with CCK so far, but it could be used for CCK in some cases.
Comment #10
giorgio79 commentedThat is pretty sweet, it could even be used for single item fields with multiple instances in addition to multi item fields like Tablefield, Flexifield and Multigroup :)
+1 for some kind of deeper integration :)
Comment #11
another_sam commentedThis dependency is a pain in the ass for the humankind. I accepted a job based on Drupal thinking it would be a sweet addition to my knowledge. Now I'm near to regret.
The whole Drupal should be built with Progressive Enhancement in mind.
http://en.wikipedia.org/wiki/Progressive_enhancement
The difference here would be that of Ajax providing _additional_ comfort to the user, but not being a _requirement_ to read/write any given content.
Comment #12
donquixote commented#11, I think you are missing the point.
If you want to add field items for a multi-value field without javascript, you just have to submit the form more than once.
This feature request does not change this any bit.