12

I use WTForms with Flask via the Flask.WTF extension. This question isn't Flask-specific, though.

WTForms includes a FieldList field for lists of fields. I'd like to use this to make a form where users can add or remove items. This will require some sort of Ajax framework to dynamically add widgets, but the WTForms documentation makes no mention of it.

Other frameworks like Deform come with Ajax support. Is there a similar framework available for WTForms?

Kiran Jonnalagadda
  • 2,606
  • 1
  • 30
  • 29
  • 1
    Sorry, I don't have code I can easily share - the JavaScript that I used is part of a custom framework based on YUI 2. However, the core operation cloned the last row of the container holding the rows, using `cloneNode`, and then recursively renamed the child elements whose names matched a suitable regex. – Vinay Sajip May 16 '11 at 18:08

2 Answers2

7

I used something like this with my FieldList/FormField to allow adding more entries:

$(document).ready(function () {
    $('#add_another_button').click(function () {
        clone_field_list('fieldset:last');
    });
});

function clone_field_list(selector) {
    var new_element = $(selector).clone(true);
    var elem_id = new_element.find(':input')[0].id;
    var elem_num = parseInt(elem_id.replace(/.*-(\d{1,4})-.*/m, '$1')) + 1;
    new_element.find(':input').each(function() {
        var id = $(this).attr('id').replace('-' + (elem_num - 1) + '-', '-' + elem_num + '-');
        $(this).attr({'name': id, 'id': id}).val('').removeAttr('checked');
    });
    new_element.find('label').each(function() {
        var new_for = $(this).attr('for').replace('-' + (elem_num - 1) + '-', '-' + elem_num + '-');
        $(this).attr('for', new_for);
    });
    $(selector).after(new_element);
}

Remove buttons would be much trickier.

(Code mostly borrowed from answer to Dynamically adding a form to a Django formset with Ajax.)

Community
  • 1
  • 1
Dave
  • 3,171
  • 1
  • 25
  • 23
1

From your description, I can't see why Ajax is particularly needed, though of course you do need JavaScript logic to add/remove rows. I've implemented this functionality using WTForms, but with with no special support from WTForms itself; you just need to ensure that when you create client-side widgets, you do this using field names that WTForms will parse correctly into the server-side list. You can clone an existing row using client-side JavaScript to add rows, so that the rendering of a row is consistent across rows generated server-side and rows created client-side.

Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191