Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

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

2 Answers 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.

share|improve this answer
    
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? –  dunc Jun 29 '11 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 '11 at 11:11
    
Yeah, realised that about 10mins after I posted... :D Thanks. –  dunc Jun 30 '11 at 23:33
up vote 1 down vote accepted

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();
    }

});
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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