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

markus_petrux’s picture

Version: 6.x-3.x-dev » 6.x-2.x-dev
Status: Active » Closed (works as designed)

AHAH 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.

dman’s picture

It'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

markus_petrux’s picture

Aside 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.

donquixote’s picture

What 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.

markus_petrux’s picture

Even 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.

donquixote’s picture

hehe 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.

markus_petrux’s picture

I guess you could try this using a separate module that implements a widget for text fields.

giorgio79’s picture

Was 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.

donquixote’s picture

Adding 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.

giorgio79’s picture

That 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 :)

another_sam’s picture

This 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.

donquixote’s picture

#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.