Ticket #16972 (reviewing defect (bug))

Opened 11 months ago

Last modified 7 months ago

Input type radio losts its checked focus when metabox is dragged

Reported by: depi Owned by: ldebrouwer
Priority: normal Milestone: Future Release
Component: Administration Version: 3.0
Severity: normal Keywords: needs-patch
Cc: info@…

Description

This happens when I use a radio button in a metabox. Once I try to drag it to different position or just drag and let it go the checked focus is lost. (in code it of course still remain checked, but visually not)

Bug not happens with other fields I tested (checkboxes, inputs, textareas)

Change History

You can check this behavior for example on the Add Link page in WP-Admin where are some radio buttons.

  • Keywords needs-patch added
  • Version changed from 3.1 to 3.0
  • Component changed from General to Administration
  • Milestone changed from Awaiting Review to Future Release

Confirmed. It happens in WP 3.0 too.

  • Cc info@… added
  • Owner set to ldebrouwer
  • Status changed from new to reviewing

This is a bug/feature in the jQuery UI sortable library ( has been since 1.5.x ). The sortable plugin clones the node being moved which resets the radio buttons.

I was having this exact issue with meta boxes I am adding to a plugin settings page, everything else is cool but radio buttons lose their happy little dot so saving settings after dragging a metabox to a new position loses that radio buttons setting which messes things up.

after much experimentation and being too bloody minded to remove drag and drop entirely and being too lazy to rejigger the settings to use checkboxes instead and failing to find a way to listen to the metabox drop event, I came up with this which, so far, seems to do the job

// global script for commentluv premium settings pages
// workaround for bug that causes radio inputs to lose settings when meta box is dragged.
// http://core.trac.wordpress.org/ticket/16972
jQuery(document).ready(function(){
    // listen for drag drop of metaboxes , bind mousedown to .hndle so it only fires when starting to drag
    jQuery('.hndle').mousedown(function(){                                                               
        // set live event listener for mouse up on the content .wrap and wait a tick to give the dragged div time to settle before firing the reclick function
        jQuery('.wrap').mouseup(function(){store_radio(); setTimeout('reclick_radio();',50);});
    })
});
/**
* stores object of all radio buttons that are checked for entire form
*/
function store_radio(){
    var radioshack = {};
    jQuery('input[type="radio"]').each(function(){
        if(jQuery(this).is(':checked')){
            radioshack[jQuery(this).attr('name')] = jQuery(this).val();
        }
        jQuery(document).data('radioshack',radioshack);
    });
}
/**
* detect mouseup and restore all radio buttons that were checked
*/
function reclick_radio(){
    // get object of checked radio button names and values
    var radios = jQuery(document).data('radioshack');
    //step thru each object element and trigger a click on it's corresponding radio button
    for(key in radios){
        jQuery('input[name="'+key+'"]').filter('[value="'+radios[key]+'"]').trigger('click');
    }            
    // unbind the event listener on .wrap  (prevents clicks on inputs from triggering function)
    jQuery('.wrap').unbind('mouseup');
}

you just need to change jQuery('.wrap') to whatever container your meta boxes appear in

(the variable to store the hack for radios turning out to spell radioshack was purely coincidental) :P

Note: See TracTickets for help on using tickets.