I need to submit a form on which there is a group of inputs(that can be dynamically generated) that needs to be an array of objects(list of dictionaries).

I Dynamically generate the following item when a button is clicked on the form:

var count = 0
$("#add-order-item").on("click", function(){
    count += 1
    console.log(count);
    $("#order_items").prepend('\
        <fieldset id="items" name="items">\
            <legend>\
                Item #'+count+'\
            </legend>\
        <div class="form-group">\
              <label class="control-label col-sm-4" for="item_name">Item Name</label>\
              <div class="col-sm-5">\
                <input class="form-control" placeholder="Item Name" name="items['+count+'][item_name]" id="item_name" required="">\
              </div>\
            </div>\
            <div class="form-group">\
              <label class="control-label col-sm-4" for="item_description">Item Description</label>\
              <div class="col-sm-5">\
                <input class="form-control" placeholder="Item Description" name="items['+count+'][item_description]" id="item_description">\
              </div>\
            </div>\
            <div class="form-group">\
              <label class="control-label col-sm-4" for="quantity">Quantity</label>\
              <div class="col-sm-5">\
                <input class="form-control" id="order-quantity-field" name="items['+count+'][quantity]" placeholder="Quantity" required=""\ pattern="^[0-9]+$" data-bv-regexp-message="Value is not a number" type="text">\
              </div>\
            </div>\
            <div class="form-group">\
              <label class="control-label col-sm-4" for="pn_id">Provider Network</label>\
              <div class="col-sm-5">\
                <input class="form-control" placeholder="PN00" id="order-pn_id-field" name="items['+count+'][pn_id]" \
                placeholder="Provider Network" required="" type="text"\
                data-bv-remote-url='+'{{"stock.orders.new.validate"|route_path()}}'+'\
                    data-bv-remote="true">\
              </div>\
        </div>\
        </fieldset>\
    ')
});

I have viewed this StackOverflow answer, which has helped me a lot, but still the question remains how to create such an array of objects, the suggested answer should work, how ever when I check the data that was sent, it is a list of tuples:

NestedMultiDict([('items[1][item_name]', u'sims'), ('items[1][item_description]', u''), ('items[1][quantity]', u'50'), ('items[1][pn_id]', u'PN02'), ('delivery_address', u'164 Springfield Road\r\nWindermere\r\nDurban\r\n4001'), ('delivery_note', u'')])

  1. How could I get it on the server-side in the desired list of dictionaries or How could I send the name of the list with the form submission?
  2. Could it be something to do with the way I am posting the data in my jquery, i.e. The way I am serializing it.

Form submission using $.post():

$.post(
    post_url,
    $('form[name="add-order-form"]').serializeArray()
).success(function(data) {
    document.location.href=data;
});

Any help will be much appreciated.
If you need more details please ask.

Dani AI

Generated

— the behavior you’re seeing is normal: using names like the bracketed form (for example the pattern you built on the client) produces flat name/value pairs when the browser posts the form. Most Python WSGI frameworks do not automatically turn PHP-style bracketed names into a list-of-dicts. As hinted, you can either (A) assemble and post proper JSON from the browser, (B) keep form-encoding but include one hidden field that contains a JSON string, or (C) reconstruct the list on the server by parsing the flat keys.

Client-side: convert the serialized name/value pairs into an array-of-objects, then POST JSON. Example pattern (uses the same input-name convention but is not a copy of your original code):

var pairs = $('form').serializeArray();
var items = [];
pairs.forEach(function(p){
  var m = p.name.match(/^items\[(\d+)\]\[(.+)\]$/);
  if (m) {
    var i = parseInt(m[1], 10);
    var key = m[2];
    items[i] = items[i] || {};
    items[i][key] = p.value;
  }
});
$.ajax({
  url: postUrl,
  method: 'POST',
  contentType: 'application/json',
  data: JSON.stringify({ items: items /*, other fields */ })
});

Server-side: if you must accept form-encoded data, rebuild the list from request keys. Example Python routine that works with request.form.items() (iterate whatever your framework provides):

import re
def parse_items(form_items):
    buckets = {}
    for k, v in form_items:
        m = re.match(r'^items\[(\d+)\]\[(.+)\]$', k)
        if m:
            idx = int(m.group(1))
            field = m.group(2)
            buckets.setdefault(idx, {})[field] = v
    return [buckets[i] for i in sorted(buckets.keys())]

Extra tips: keep numeric indices sequential (0..n-1) to preserve order, avoid duplicate HTML ids on dynamically generated inputs, and prefer sending JSON if you control both client and server — it’s simpler and less error-prone than relying on parsing bracketed names.

It could help if, rather than posting the JavaScript/JQuery code that generates the form being sent, we could see the Python code that is reading it in from the server. There are several ways that can be done, depending on the libraries and/or frameworks you are using.

Let's step back a bit and look at your goals rather than what you currently have it doing. What is this actually supposed to accomplish? What information are you actually trying to extract from the POSTed form? Why does it have to be in the form of a list of dicts?

Oh, BTW, what version of Python are you working in? That could be relevant.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.