0

Tearing my hair out a little bit here! I'm trying to create multiple image-selection boxes so users can upload as many images as they like to the species profile they've created.

I'm using the following code in a .js file:

jQuery(document).ready(function() {

    var i = 2;

    jQuery('a#add_media').click(function() {
        input_code = '<p>' +
            '<input id="upload_image-' + i + '" type="text" size="36" name="upload_image" value="" />' +
            '<input id="upload_image_button-' + i + '" type="button" value="Upload Image" />' +
            '</p>';
        jQuery(input_code).appendTo('#upload_wrapper');
        i++;
    });

    jQuery('[id^="upload_image_button"]').click(function() {
        str = jQuery(this).attr('id');
        substring = str.substring(str.length, str.length - 1);
        id_to_pass = 'upload_image-' + substring;
        alert(id_to_pass);
        tb_show('', 'media-upload.php?type=image&amp;TB_iframe=true');
        return false;
    });

    window.send_to_editor = function(html) {
        imgurl = jQuery('img',html).attr('src');
        jQuery('#' + id_to_pass).val(imgurl);
        tb_remove();
    }

});

If I then view the DOM using Firebug, I can see that my input boxes appear correctly:

<div id="upload_wrapper" style="margin:0; padding:0;">
<label>Attach Image</label>
<p>
<input id="upload_image-1" type="text" value="" name="upload_image" size="36">
<input id="upload_image_button-1" type="button" value="Upload Image">
<span>
</p>
<p>
<input id="upload_image-2" type="text" value="" name="upload_image" size="36">
<input id="upload_image_button-2" type="button" value="Upload Image">
</p>
<p>
<input id="upload_image-3" type="text" value="" name="upload_image" size="36">
<input id="upload_image_button-3" type="button" value="Upload Image">
</p>

Yet only the first button opens the upload frame?

Thanks in advance.

2
  • Is this your full code? If not please upload the rest. If it is applicable, a demo page would be great.
    – EnexoOnoma
    Jun 28, 2011 at 21:22
  • 1
    Did you ensure you are free of javascript errors in the console?
    – chrisjlee
    Jun 29, 2011 at 19:04

2 Answers 2

2
jQuery('a#add_media').click(function() {
    input_code = '<p>' +
        '<input id="upload_image-' + i + '" type="text" size="36" name="upload_image" value="" />' +
        '<input id="upload_image_button-' + i + '" type="button" value="Upload Image" />' +
        '</p>';
    jQuery(input_code).appendTo('#upload_wrapper');
    i++;
});

jQuery('[id^="upload_image_button"]').click(function() {
    ...
});

Okay, here's your basic problem.

The first bit of the code adds a function to the click handler on the add_media link, which adds another bit of input HTML code to the page.

The second bit of the code adds a function to the click handler of anything starting with the upload_image_button ID's.

The problem is that you're misunderstanding how javascript works in the DOM.

At the time that the above code runs, only two things are happening: a) The a#add_media button is getting its click handler modified, and b) Any element in the DOM starting with upload_image_button is getting its click handler modified.

However, the inputs that you're adding later aren't in the DOM yet. They don't exist as elements on the page... yet. So when you add them to the page later, they don't have the modified click handlers.

jQuery().click() is a direct modification to the DOM. It's modifying the elements specified, but it's not retroactive. Adding things to the page later doesn't make it magically reverse time and add the functions to the new elements added to the page.

To fix it, you need to modify your code to have it add your click handler to the newly created elements as well, after you append them to the upload_wrapper.

Also, your inputs all have the same name="upload_image" bits, which won't work if you're trying to save that resulting information later. name="upload_image[]" will work though, because of PHP array handling.

3
  • Thanks for that Otto. I suspected something along those lines may have been the problem. I presumed that the [id^] selector and click function would've worked on any elements in the DOM - i.e. the extra inputs are added to the DOM then the id selector picks them up. I'll be honest though - not sure what to do to fix it. Can you point me along the right lines? As for the "upload_image" bits - they all have a unique identifier on the end (in this case, i) which PHP should pick up easily enough, unless I'm mistaken?
    – turbonerd
    Jun 29, 2011 at 10:34
  • 1
    They have a unique identifier on the end of the ID, not on the NAME. The name is what is used when submitting the form, not the ID.
    – Otto
    Jun 30, 2011 at 11:11
  • Yeah, realised that about 10mins after I posted... :D Thanks.
    – turbonerd
    Jun 30, 2011 at 23:33
1

OK, I've made the changes Otto suggested and it's working nicely - thanks.

var uploadClickHandler = function() {
    str = jQuery(this).attr('id');
    substring = str.substring(str.length, str.length - 1);
    id_to_pass = 'upload_image-' + substring;
    tb_show('', 'media-upload.php?type=image&amp;TB_iframe=true');
    return false;
};

jQuery(document).ready(function() {

    // Find the number of elements using our unique button name
    var i = jQuery('[id^="upload_image_button"]').size() + 1;

    jQuery('a#add_media').click(function() {
        // Variable to store the HTML for adding a new image
        input_code = '<p>' +
            '<input id="upload_image-' + i + '" name="upload_image[' + i + ']" type="text" size="36" name="upload_image" value="" />' +
            '<input id="upload_image_button-' + i + '" type="button" value="Upload Image" />' +
            '</p>';

        // Upon being clicked, append the input_code variable to our #upload_wrapper DIV
        jQuery(input_code).appendTo('#upload_wrapper');

        // Use our uploadClickHandler function to add the iFrame functionality to our "on-the-fly" text boxes
        jQuery('[id="upload_image_button-' + i + '"]').click(uploadClickHandler);
            i++;
    });

    // Add click functionality to the pre-JS-created HTML text boxes on our main page
    jQuery('[id^="upload_image_button"]').click(uploadClickHandler);

    // iFrame and return value functionality
    window.send_to_editor = function(html) {
        imgurl = jQuery('img',html).attr('src');
        jQuery('#' + id_to_pass).val(imgurl);
        tb_remove();
    }

});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.