Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jQuery to Populate a Text Field Based on Checkboxes ID?

Context

I'm trying to build an answer to this WordPress question.

I'm generating dynamic checkboxes in the media upload thickbox window. And they should serve to populate a text field where the user can copy/paste its value.

The final output of the text field is the include attribute in this shortcode [gallery include="23,39,45"].

Mainly, I need a helping hand to build this last part: Checkbox -> Populate/Unpopulate Text Field...


Layout

  1. Dynamic checkboxes

  2. Point of insertion of the text field (after the last <tr> shown in the console)

  3. Text field to be populated, should be include=" + CheckBoxID1 comma CheckBoxID2 comma etc + "

    enter image description here


Actual Code

<?php
add_action( 'admin_head-media-upload-popup', 'wpse_53803_script_enqueuer' );

function wpse_53803_script_enqueuer() {
    if( $_GET['tab'] == 'gallery' ) 
    {
        ?>
            <style>#media-upload th.order-head {width: 5%} #media-upload th.actions-head {width: 10%}</style>
            <script type="text/javascript">
            jQuery(document).ready( function($) {
    
                /* Iterate through the media items */
                $('.filename.new').each(function(i,e){
                    var id = $(this).next('.slidetoggle').find('thead').attr('id').replace(/media-head-/, '');
                    var filename = $('<label>Add to gallery list <input type="checkbox" name="gal-item-'+id+'" id="gal-item-'+id+'" value=""  /></label>').insertBefore($(this));
                    filename.css('float','right').css('margin-right','40px');

                    filename.id = id; // PROBLEM: not sure how to do this in Javascript
                    
                    // BUG: the alert is being fired twice
                    filename.click(function() {
                        alert('Handler for img id = '+filename.id+' called.');
                    });
                });                 
            });
            </script><?php
    }
}

Missing Parts

  • Create a dynamic text field to be populated.
  • Solve the problem and the bug noticed in the comments.
  • Make the filename.click(function() build the desired string inside the text field.
like image 354
brasofilo Avatar asked Nov 14 '22 04:11

brasofilo


1 Answers

You can do this using something similar to this

 $(document).on('change','input[type="checkbox"][name^="gal-item"]',function(){
    var checkedIds = $('input[type="checkbox"][name^="gal-item"]:checked')
                       .map(function(){
       return parseInt($(this).prop('name').replace(/gal-item-/,''));
    }).get();

    $('#shortcode').val('include="'+checkedIds.join(',')+'"');

});

You can replace document with any closer static container which you have to find by inspecting the add media markup. ​ And You have find a element where you want to add the input field, add it like

$('<span>[gallery</span><input type="text" id="shortcode" /><span>]</span>')
 .appendTo(TARGETIDORCLASS);

Working DEMO

And based on this your rewritten code would be something like

jQuery(document).ready( function($) {
     //add input field
     $('<span>[gallery</span><input type="text" id="shortcode" /><span>]</span>')
 .appendTo(TARGETIDORCLASS);
    //bind checkbox change handler


     $(document).on('change','input[type="checkbox"][name^="gal-item"]',function(){
         var checkedIds = $('input[type="checkbox"][name^="gal-item"]:checked').map(function(){
       return parseInt($(this).prop('name').replace(/gal-item-/,''));

    }).get();

    $('#shortcode').val('include="'+checkedIds.join(',')+'"');

    });


    /* Iterate through the media items */
    $('.filename.new').each(function(i,e){
        var id = $(this).next('.slidetoggle')
                        .find('thead')
                        .attr('id')
                        .replace(/media-head-/, '');
       var filename = $('<label>Add to gallery list <input type="checkbox" name="gal-item-'+id+'" id="gal-item-'+id+'" value=""  /></label>')
              .insertBefore($(this));
       filename.css('float','right').css('margin-right','40px');

                });                 
            });

This should work. I am in a hurry, couldn't test much, check and let me know if you find any error, I would love to fix those.

like image 97
Prasenjit Kumar Nag Avatar answered Dec 27 '22 09:12

Prasenjit Kumar Nag