开发者

Strange behavior with jQuery's clone() and a POST request

Playing around with jQuery, I was trying to dynamically multiply a form element (a file upload box) on the click of a button. Here's the code:

$(document).ready(function () {
    $('#new-image').click(function () {
        var idx = $('.input.file').size();
        var upload = $('.input.file:first-child').clone();
        $(upload.find('label')).attr('for', 'Attachment'+idx+'File');
        $(upload.find('input[type=file]')).attr('name', 'data[Attachment]​['+idx+']​开发者_开发知识库[file]');
        $(upload.find('input[type=file]')).attr('id', 'Attachment'+idx+'File');
        upload.insertBefore('#new-image');
        return false;
    });
});

The problem is that, if I try and modify the input's name I end up with something like this in the post request - taken from Chrome's (dev build) console, also borks on Firefox (3.6).

------WebKitFormBoundaryMXYcXg2mbP1HZsVJ
Content-Disposition: form-data; name="data[Attachment]​[3]​[file]"; filename="logo.png"
Content-Type: image/png

It is not because of the string concatenation, I tried with a hardcoded value and the weirdness in the request was still there. Am I missing something here or is this a bug in jQuery?

(If anyone is wondering, the name attribute format - data[... comes from CakePHP)


Update

It seems the problem is not because of .attr(), but because of .clone(). I modified the question accordingly.

I was under the impression that this worked:

upload.find('input[type=file]').name = 'data[Attachment]​['+idx+']​[file]';
// wrong -> find returns a jQuery object and setting name has no effect

because I did not try to add multiple files, I was just trying the last added field :). It does not work even in the correct form:

upload.find('input[type=file]').get(0).name = 'data[Attachment]​['+idx+']​[file]';
// I still get mumbo-jumbo in the post, between the ][ characters

I just tried without clone() and it works, for real this time :).

$('#new-image').click(function () {
    var idx = $('.input.file').size();
    var upload = $('<div class="input file"><label for="Attachment'+idx+'File">File</label><input type="file" name="data[Attachment]['+idx+'][file]" id="Attachment'+idx+'File"></div>');
    upload.insertBefore('#new-image');
    return false;
});

Does anyone have any idea why clone() behaves this way?


Try this:

<div class="file">
    <div>
        <label for="Attachment0File">File: </label>
        <input type="file" name="data[Attachment][file][]" id="Attachment0File" />
    </div>
</div>
<button type="button" id="new-image">New</button>

$(document).ready(function () {
    $('#new-image').click(function (e) {
        e.preventDefault();
        var idx = $('.file').length;
        $('.file:first-child').clone(true, true)
            .find('label').attr('for', 'Attachment'+idx+'File').end()
            .find('input[type="file"]').attr('name', 'data[Attachment][file][]').attr('id', 'Attachment'+idx+'File').end()
            .insertBefore('#new-image');
    });
});

upload does not need to be wrapped with $() since it is already a jQuery objct

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜