Fix for some of the issues discussed in issue #33 #77

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
4 participants

I've added support for field arrays as discussed in felixge/node-formidable#33

This will turn any field (not file) with a name ending with "[]" into an array of all the fields with same name.

Fields with the same name but with no "[]" suffix will still overwrite each other.

The above functionality is supported by the tests that I added in "test/simple/test-incoming-form.js".

The way this has been implemented adds minimal complexity to the module, and adds much needed functionality that is supported by every mainstream HTTP parser for Node as well as other languages.

I haven't added the ability to do the same thing with files because you expressed concern against it, but I can see it being another needed feature (I've implemented bulk uploaders in other languages using file arrays). The implementation would be very similar to how I've done this one.

I did not even know that multipart fields are allowed to be arrays. Is this documented somewhere?

I don't know about documentation, but PHP and Ruby certainly support it. I use it to create bulk uploaders and to tag files, thats about the only two uses for me. You can try it out.

# upload.php
<?php
    if ($_POST) {
        var_dump($_POST);
    }
    if ($_FILES) {
        var_dump($_FILES);
    }
?>
<form action="" method="post" enctype="multipart/form-data">
    <label for="file-one">File One:</label>
    <input type="file" name="files[]" id="file-one" />

    <label for="name-one">Name One:</label>
    <input type="text" name="names[]" id="name-one" />

    <label for="file-two">File Two:</label>
    <input type="file" name="files[]" id="file-two" />

    <label for="name-two">Name Two:</label>
    <input type="text" name="names[]" id="name-one" />

    <label for="file-three">File Three:</label>
    <input type="file" name="files[]" id="file-three" />

    <label for="name-three">Name Three:</label>
    <input type="text" name="names[]" id="name-three" />

    <button type="submit">Upload</button>
</form>

Create that file in your local server's folder, (I'm just assuming you have some form work LAMP, MAMP, or WAMP stack available) and open it up. Upload some files and put something in the text inputs, click "Upload", view source and you'll see a var_dump of $_POST and $_FILES, both containing arrays of strings and files.

I'm afraid I do not have PHP installed, but I believe you ;) I always thought that multi file uploads were handled in parts, which is why it's called multi part.

Am I mistaken here?

It's multipart because it literally has multiple parts to the request, separated by delimiters (see RFC 2388). Each field (files are fields too) is in it's own kind of mini-request, and the fields/mini-requests are split by delimiters.

Anyway, glad I explained it well, hope it was enjoyed :)

vlucas commented Jul 25, 2011

PLEASE merge this in. I just ran into this issue myself, and the code supplied as a patch seems minimal and easy to merge. This feature needs to be supported.

This actually supports more ruby esque form fields....

this
      .on('field', function(name, value) {
        // check for arrays
        var oldName = name;
           name = name.replace(/\[\]/g, '');

           if (name.indexOf('[') >= 0) {
            var innerName = name.match(/.*\[(.*)\]/)[1];
            var outerName = name.split("[")[0];
            if (fields[outerName]) {
                if (fields[outerName][innerName]) {
                    if (!fields[outerName][innerName].push) {
                        fields[outerName][innerName] = [fields[outerName][innerName]];
                    }
                    fields[outerName][innerName].push(value || '');
                }
                else {
                    console.log(name);
                    if ((oldName).indexOf('[]') >= 0) {
                        fields[outerName][innerName] = [value] || '';
                    }
                    else {
                        fields[outerName][innerName] = value || '';
                    }
                }
            }
            else {
                fields[outerName] = {};
                if (fields[outerName][innerName]) {
                    if (!fields[outerName][innerName].push) {
                        fields[outerName][innerName] = [fields[outerName][innerName]];
                    }
                    fields[outerName][innerName].push(value || '');
                }
                else {
                    console.log(name);
                    if (oldName.indexOf('[]') >= 0) {
                        fields[outerName][innerName] = [value] || '';
                    }
                    else {
                        fields[outerName][innerName] = value || '';
                    }
                }
            }
           }
           else {
            if (fields[name]) {
                if (!fields[name].push) {
                    fields[name] = [fields[name]];
                }
                fields[name].push(value || '');
            } else {
                fields[name] = value || '';
            }
        }



      })

you can do things like name="user[email]"

@FluffyJack FluffyJack closed this Feb 10, 2016

ChALkeR pushed a commit to ChALkeR/node-formidable that referenced this pull request May 13, 2016

ChALkeR pushed a commit to ChALkeR/node-formidable that referenced this pull request May 13, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment