Make WordPress Core

Opened 14 years ago

Closed 9 years ago

Last modified 9 years ago

#16972 closed defect (bug) (fixed)

Input type radio losts its checked focus when metabox is dragged

Reported by: depi's profile depi Owned by: azaozz's profile azaozz
Milestone: 4.5 Priority: normal
Severity: normal Version: 3.0
Component: Administration Keywords: has-patch needs-testing 2nd-opinion commit
Focuses: javascript Cc:

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)

Attachments (6)

switch postbox sortable mode.patch (437 bytes) - added by helgatheviking 12 years ago.
delete mode = 'clone' for sortables
16972.2.diff (622 bytes) - added by lessbloat 12 years ago.
16972.3.diff (1.1 KB) - added by lessbloat 12 years ago.
16972.3.refresh.diff (1.1 KB) - added by voldemortensen 10 years ago.
16972.4.diff (925 bytes) - added by MikeHansenMe 9 years ago.
16972.5.diff (1.1 KB) - added by mdawaffe 9 years ago.
Clone and Rename

Download all attachments as: .zip

Change History (31)

#1 @depi
14 years ago

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

#2 @scribu
14 years ago

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

Confirmed. It happens in WP 3.0 too.

#3 @ldebrouwer
14 years ago

  • 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.

#4 @commentluv
13 years ago

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

#5 @helgatheviking
12 years ago

  • Version changed from 3.0 to trunk

This is still happening for me running the nightly WP 3.5-alpha-21751. Radio buttons in metaboxes lose their visual indication of being checked even though it is still there in the markup.

jqueryui said this bug was fixed years ago with the 1.6 version, but WP is running 1.9 and I'm still seeing this behavior.
http://bugs.jqueryui.com/ticket/2930

#6 @SergeyBiryukov
12 years ago

  • Version changed from trunk to 3.0

Version number indicates when the bug was initially introduced/reported.

@helgatheviking
12 years ago

delete mode = 'clone' for sortables

#7 @helgatheviking
12 years ago

Sorry about the version change.

Removing the helper: 'clone', in the .sortable function reverts jquery ui sortable to its default of 'original'.... which seems to work fine for preserving the radio buttons.

See this fiddle for a live example: http://jsfiddle.net/NW7zD/3/

Then change the helper to 'clone' like it is in postbox.js and you'll see the radio button loses its checked marker.

I'm testing this on my local install of WP and I don't see any negative effects yet.

#8 @scribu
12 years ago

  • Keywords has-patch needs-testing added; needs-patch removed
  • Milestone changed from Future Release to 3.5

#9 @SergeyBiryukov
12 years ago

helper: 'clone' was added in [10834].

@lessbloat
12 years ago

#10 @lessbloat
12 years ago

switch postbox sortable mode.patch appeared to work but it auto-closed the dragged box in FF.

16972.2.diff works in FF, but auto-closed the dragged box in Chrome. :-)

Thought I'd post it anyway to expose the issue.

@lessbloat
12 years ago

#11 @lessbloat
12 years ago

16972.3.diff should fix the issue. Tested in Mac FF & Chrome, Win IE7 & FF.

#12 @MikeHansenMe
12 years ago

Tested 16972.3.diff and it works well. I did not experience any trouble in FF or Chrome.

#13 @nacin
12 years ago

  • Owner changed from ldebrouwer to azaozz

#14 @nacin
12 years ago

  • Milestone changed from 3.5 to Future Release

Remains an issue. Punting pending feedback that 16972.3.diff is the right course.

#15 @ocean90
11 years ago

  • Focuses javascript added

Still an issue in 3.8.

#16 @MZAWeb
10 years ago

Still an issue in 3.9

#17 @voldemortensen
10 years ago

Refreshed lessbloats patch.

#18 @omarreiss
10 years ago

16972.3.refresh.diff tested working with FF, Chrome and Safari on Mac OSX.

#19 @beelde
10 years ago

Still an issue in 3.9.2

#20 @Cybr
9 years ago

Still an issue in 4.4-alpha-34721. It's also affecting Genesis SEO among various plugins. Empty $_POST is sent on submit. Isn't @voldemortensen's patch working?

@MikeHansenMe
9 years ago

#21 @MikeHansenMe
9 years ago

  • Keywords 2nd-opinion added

16972.4.diff is a refresh of lessbloats patch since 16972.3.refresh.diff no longer applies. I think this needs 2nd opinion to decide if this is the correct approach per comment 14.

Last edited 9 years ago by MikeHansenMe (previous) (diff)

@mdawaffe
9 years ago

Clone and Rename

#22 @mdawaffe
9 years ago

attachment:16972.5.diff uses a different approach.

The problem with the clone (current code: helper: 'clone') is that it is inserted into the DOM alongside the original. Since only one radio in a set of radios with the same name can be checked, the clone's copy of the checked radio is checked and the original's becomes unchecked. When the clone is removed after the resorting is done, we're left with no checked radios.

The problem with using the original directly (attachment:16972.4.diff) is, as @lessbloat found out, we run into click and other event handlers.

attachment:16972.5.diff uses a clone, but renames the clone's input element names before the clone is inserted into the DOM. That way, there are never any duplicate radios, so nothing gets unchecked.

#23 @mdawaffe
9 years ago

  • Keywords commit added
  • Milestone changed from Future Release to 4.5

^^^ Ticket changes from lazynacin

#24 @mdawaffe
9 years ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 35809:

Meta Boxes: Preserve radio inputs' state when sorting metaboxes.

When sorting a metabox, a clone of that metabox is created as a drag/drop "helper".
Previously, any checked radio input in the original metabox would become unchecked, when its clone "helper" was inserted into the DOM
(since only one radio within a set of radios of the same name can be checked).

Continued use of the clone helper is important so that the element being dragged isn't subject to the click and other event handlers attached to the real metabox,
so we can't just switch to dragging around the real metabox. See, for example, comment:10:ticket:16972.

Preserve the radios' state via some name attribute trickery.

Fixes #16972

#25 @mdawaffe
9 years ago

Thanks for the patches, @commentluv, @helgatheviking, @lessbloat. They made finding the solution we eventually decided on easier.

Note: See TracTickets for help on using tickets.