First pass on better UX for menu item save. props koopersmith, see #13525.

git-svn-id: http://svn.automattic.com/wordpress/trunk@14852 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
nacin 2010-05-24 19:50:20 +00:00
parent 0dc122c58f
commit 7a5d3f2688
8 changed files with 126 additions and 133 deletions

View File

@ -399,17 +399,6 @@ case 'delete-link' :
else else
die('0'); die('0');
break; break;
case 'delete-menu-item' :
$menu_item_id = (int) $_POST['menu-item'];
check_ajax_referer( 'delete-menu_item_' . $menu_item_id );
if ( ! current_user_can( 'edit_theme_options' ) )
die('-1');
if ( is_nav_menu_item( $menu_item_id ) && wp_delete_post( $menu_item_id, true ) )
die('1');
else
die('0');
break;
case 'delete-meta' : case 'delete-meta' :
check_ajax_referer( "delete-meta_$id" ); check_ajax_referer( "delete-meta_$id" );
if ( !$meta = get_post_meta_by_id( $id ) ) if ( !$meta = get_post_meta_by_id( $id ) )

File diff suppressed because one or more lines are too long

View File

@ -214,7 +214,7 @@ body {
.meta-sep, .meta-sep,
.submitdelete, .submitdelete,
.submitclose { .submitcancel {
display:block; display:block;
float:left; float:left;
font-size: 11px; font-size: 11px;
@ -422,11 +422,11 @@ body.js .item-order {
-khtml-border-bottom-right-radius: 6px; -khtml-border-bottom-right-radius: 6px;
-khtml-border-bottom-left-radius: 6px; -khtml-border-bottom-left-radius: 6px;
} }
.menu-item-settings-active { .menu-item-edit-active .menu-item-settings {
display:block; display:block;
} }
.menu-item-settings-inactive { .menu-item-edit-inactive .menu-item-settings {
display:none; display:none;
} }
@ -473,10 +473,6 @@ body.js .item-order {
.menu-item-actions { .menu-item-actions {
padding-top: 15px; padding-top: 15px;
} }
.save-menu-item {
float: right;
padding-left: 10px;
}
#cancel-save { cursor: pointer; } #cancel-save { cursor: pointer; }
#cancel-save:hover { color: #fff !important; } #cancel-save:hover { color: #fff !important; }
@ -506,13 +502,13 @@ clear:both;
font-size: 11px; font-size: 11px;
font-style: normal; font-style: normal;
} }
.submitbox .submitclose { .submitbox .submitcancel {
color: #21759B; color: #21759B;
border-bottom: 1px solid #21759B; border-bottom: 1px solid #21759B;
padding: 1px 2px; padding: 1px 2px;
text-decoration: none; text-decoration: none;
} }
.submitbox .submitclose:hover { .submitbox .submitcancel:hover {
background: #21759B; background: #21759B;
color: #fff; color: #fff;
} }

View File

@ -59,13 +59,8 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
$original_title = $original_object->post_title; $original_title = $original_object->post_title;
} }
?> ?>
<li id="menu-item-<?php echo $item_id; ?>" class="menu-item menu-item-depth-<?php echo $depth; ?> menu-item-<?php echo esc_attr( $item->object ); ?>"> <li id="menu-item-<?php echo $item_id; ?>" class="menu-item menu-item-depth-<?php echo $depth; ?> menu-item-<?php echo esc_attr( $item->object ); ?> menu-item-edit-<?php echo ( isset( $_GET['edit-menu-item'] ) && $item_id == $_GET['edit-menu-item'] ) ? 'active' : 'inactive'; ?>">
<dl class="menu-item-bar <?php <dl class="menu-item-bar">
if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] )
echo 'menu-item-edit-active menu-item-bar-active';
else
echo 'menu-item-edit-inactive menu-item-bar-inactive';
?>">
<dt class="menu-item-handle"> <dt class="menu-item-handle">
<span class="item-title"><?php echo esc_html( $item->title ); ?></span> <span class="item-title"><?php echo esc_html( $item->title ); ?></span>
<span class="item-controls"> <span class="item-controls">
@ -104,12 +99,7 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
</dt> </dt>
</dl> </dl>
<div class="menu-item-settings <?php <div class="menu-item-settings" id="menu-item-settings-<?php echo $item_id; ?>">
if ( isset($_GET['edit-menu-item']) && $item_id == $_GET['edit-menu-item'] )
echo 'menu-item-edit-active menu-item-settings-active';
else
echo 'menu-item-edit-inactive menu-item-settings-inactive';
?>" id="menu-item-settings-<?php echo $item_id; ?>">
<?php if( 'custom' == $item->type ) : ?> <?php if( 'custom' == $item->type ) : ?>
<p class="field-url description description-wide"> <p class="field-url description description-wide">
<label for="edit-menu-item-url-<?php echo $item_id; ?>"> <label for="edit-menu-item-url-<?php echo $item_id; ?>">
@ -178,8 +168,7 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) ) remove_query_arg($removed_args, admin_url( 'nav-menus.php' ) )
), ),
'delete-menu_item_' . $item_id 'delete-menu_item_' . $item_id
); ?>"><?php _e('Remove'); ?></a> <span class="meta-sep"> | </span> <a class="item-close submitclose" id="close-<?php echo $item_id; ?>" href="<?php echo admin_url( 'nav-menus.php' ); ?>"><?php _e('Close'); ?></a> ); ?>"><?php _e('Remove'); ?></a> <span class="meta-sep"> | </span> <a class="item-cancel submitcancel" id="cancel-<?php echo $item_id; ?>" href="<?php echo admin_url( 'nav-menus.php' ); ?>"><?php _e('Cancel'); ?></a>
<input class="button-primary save-menu-item" name="save_menu_item" type="submit" value="<?php esc_attr_e('Save Menu Item'); ?>" />
</div> </div>
<input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" /> <input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />

View File

@ -132,9 +132,10 @@ var wpNavMenu;
// Retrieve menu item data // Retrieve menu item data
$(checkboxes).each(function(){ $(checkboxes).each(function(){
var listItemDBIDMatch = re.exec( $(this).attr('name') ), var t = $(this),
listItemDBIDMatch = re.exec( t.attr('name') ),
listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10); listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10);
menuItems[listItemDBID] = api.getListDataFromID(listItemDBID); menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID );
}); });
// Add the items // Add the items
api.addItemToMenu(menuItems, processMethod, function(){ api.addItemToMenu(menuItems, processMethod, function(){
@ -143,6 +144,76 @@ var wpNavMenu;
t.find('img.waiting').hide(); t.find('img.waiting').hide();
}); });
}); });
},
getItemData : function( itemType, id ) {
itemType = itemType || 'menu-item';
var itemData = {}, i,
fields = [
'menu-item-db-id',
'menu-item-object-id',
'menu-item-object',
'menu-item-parent-id',
'menu-item-position',
'menu-item-type',
'menu-item-title',
'menu-item-url',
'menu-item-description',
'menu-item-attr-title',
'menu-item-target',
'menu-item-classes',
'menu-item-xfn'
];
if( !id && itemType == 'menu-item' ) {
id = this.find('.menu-item-data-db-id').val();
}
if( !id ) return itemData;
this.find('input').each(function() {
var field;
i = fields.length;
while ( i-- ) {
if( itemType == 'menu-item' )
field = fields[i] + '[' + id + ']';
else if( itemType == 'add-menu-item' )
field = 'menu-item[' + id + '][' + fields[i] + ']';
if (
this.name &&
field == this.name
) {
itemData[fields[i]] = this.value;
}
}
});
return itemData;
},
setItemData : function( itemData, itemType, id ) { // Can take a type, such as 'menu-item', or an id.
itemType = itemType || 'menu-item';
if( !id && itemType == 'menu-item' ) {
id = $('.menu-item-data-db-id', this).val();
}
if( !id ) return this;
this.find('input').each(function() {
var t = $(this), field;
$.each( itemData, function( attr, val ) {
if( itemType == 'menu-item' )
field = attr + '[' + id + ']';
else if( itemType == 'add-menu-item' )
field = 'menu-item[' + id + '][' + attr + ']';
if ( field == t.attr('name') ) {
t.val( val );
}
});
});
return this;
} }
}); });
}, },
@ -306,8 +377,8 @@ var wpNavMenu;
return that.eventOnClickMenuDelete(e.target); return that.eventOnClickMenuDelete(e.target);
} else if ( -1 != e.target.className.indexOf('item-delete') ) { } else if ( -1 != e.target.className.indexOf('item-delete') ) {
return that.eventOnClickMenuItemDelete(e.target); return that.eventOnClickMenuItemDelete(e.target);
} else if ( -1 != e.target.className.indexOf('item-close') ) { } else if ( -1 != e.target.className.indexOf('item-cancel') ) {
return that.eventOnClickCloseLink(e.target); return that.eventOnClickCancelLink(e.target);
} }
} }
}); });
@ -498,7 +569,7 @@ var wpNavMenu;
if ( api.menusChanged ) if ( api.menusChanged )
return navMenuL10n.saveAlert; return navMenuL10n.saveAlert;
}; };
$('input.menu-save, input.save-menu-item').click(function(){ $('input.menu-save').click(function(){
window.onbeforeunload = null; window.onbeforeunload = null;
}); });
}, },
@ -652,20 +723,22 @@ var wpNavMenu;
}, },
eventOnClickEditLink : function(clickedEl) { eventOnClickEditLink : function(clickedEl) {
var activeEdit, var settings, item,
matchedSection = /#(.*)$/.exec(clickedEl.href); matchedSection = /#(.*)$/.exec(clickedEl.href);
if ( matchedSection && matchedSection[1] ) { if ( matchedSection && matchedSection[1] ) {
activeEdit = $('#'+matchedSection[1]); settings = $('#'+matchedSection[1]);
if( 0 != activeEdit.length ) { item = settings.parent();
if( activeEdit.hasClass('menu-item-edit-inactive') ) { if( 0 != item.length ) {
activeEdit.slideDown('fast') if( item.hasClass('menu-item-edit-inactive') ) {
.siblings('dl').andSelf() if( ! settings.data('menu-item-data') ) {
.removeClass('menu-item-edit-inactive') settings.data( 'menu-item-data', settings.getItemData() );
}
settings.slideDown('fast');
item.removeClass('menu-item-edit-inactive')
.addClass('menu-item-edit-active'); .addClass('menu-item-edit-active');
} else { } else {
activeEdit.slideUp('fast') settings.slideUp('fast');
.siblings('dl').andSelf() item.removeClass('menu-item-edit-active')
.removeClass('menu-item-edit-active')
.addClass('menu-item-edit-inactive'); .addClass('menu-item-edit-inactive');
} }
return false; return false;
@ -673,8 +746,9 @@ var wpNavMenu;
} }
}, },
eventOnClickCloseLink : function(clickedEl) { eventOnClickCancelLink : function(clickedEl) {
$(clickedEl).closest('.menu-item-settings').siblings('dl').find('.item-edit').click(); var settings = $(clickedEl).closest('.menu-item-settings');
settings.setItemData( settings.data('menu-item-data') );
return false; return false;
}, },
@ -699,28 +773,9 @@ var wpNavMenu;
}, },
eventOnClickMenuItemDelete : function(clickedEl) { eventOnClickMenuItemDelete : function(clickedEl) {
var itemID, var itemID = parseInt(clickedEl.id.replace('delete-', ''), 10);
matchedSection, api.removeMenuItem( $('#menu-item-' + itemID) );
that = this; return false;
matchedSection = /_wpnonce=([a-zA-Z0-9]*)$/.exec(clickedEl.href);
if ( matchedSection && matchedSection[1] ) {
itemID = parseInt(clickedEl.id.replace('delete-', ''), 10);
$.post(
ajaxurl,
{
action:'delete-menu-item',
'menu-item':itemID,
'_wpnonce':matchedSection[1]
},
function (resp) {
if ( '1' == resp )
that.removeMenuItem(document.getElementById('menu-item-' + itemID));
}
);
return false;
}
return true;
}, },
/** /**
@ -765,53 +820,15 @@ var wpNavMenu;
}, },
removeMenuItem : function(el) { removeMenuItem : function(el) {
el = $(el);
var children = el.childMenuItems(); var children = el.childMenuItems();
el.addClass('deleting').fadeOut( 350 , function() { el.addClass('deleting').animate({
el.remove(); opacity : 0,
children.shiftDepthClass(-1).updateParentMenuItemDBId(); height: 0
}); }, 350, function() {
}, el.remove();
children.shiftDepthClass(-1).updateParentMenuItemDBId();
getListDataFromID : function(menuItemID, parentEl) { });
if ( ! menuItemID )
return false;
parentEl = parentEl || document;
var fields = [
'menu-item-db-id',
'menu-item-object-id',
'menu-item-object',
'menu-item-parent-id',
'menu-item-position',
'menu-item-type',
'menu-item-title',
'menu-item-url',
'menu-item-description',
'menu-item-attr-title',
'menu-item-target',
'menu-item-classes',
'menu-item-xfn'
],
itemData = {},
inputs = parentEl.getElementsByTagName('input'),
i = inputs.length,
j;
while ( i-- ) {
j = fields.length;
while ( j-- ) {
if (
inputs[i] &&
inputs[i].name &&
'menu-item[' + menuItemID + '][' + fields[j] + ']' == inputs[i].name
) {
itemData[fields[j]] = inputs[i].value;
}
}
}
return itemData;
}, },
depthToPx : function(depth) { depthToPx : function(depth) {

File diff suppressed because one or more lines are too long

View File

@ -318,7 +318,12 @@ switch ( $action ) {
// Update menu items // Update menu items
if ( ! is_wp_error( $_menu_object ) ) { if ( ! is_wp_error( $_menu_object ) ) {
$menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array('orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID') ); $unsorted_menu_items = wp_get_nav_menu_items( $nav_menu_selected_id, array('orderby' => 'ID', 'output' => ARRAY_A, 'output_key' => 'ID') );
$menu_items = array();
// Index menu items by db ID
foreach( $unsorted_menu_items as $_item )
$menu_items[$_item->db_id] = $_item;
$post_fields = array( 'menu-item-db-id', 'menu-item-object-id', 'menu-item-object', 'menu-item-parent-id', 'menu-item-position', 'menu-item-type', 'menu-item-title', 'menu-item-url', 'menu-item-description', 'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn' ); $post_fields = array( 'menu-item-db-id', 'menu-item-object-id', 'menu-item-object', 'menu-item-parent-id', 'menu-item-position', 'menu-item-type', 'menu-item-title', 'menu-item-url', 'menu-item-description', 'menu-item-attr-title', 'menu-item-target', 'menu-item-classes', 'menu-item-xfn' );
wp_defer_term_counting(true); wp_defer_term_counting(true);
// Loop through all the menu items' POST variables // Loop through all the menu items' POST variables
@ -356,7 +361,7 @@ switch ( $action ) {
do_action( 'wp_update_nav_menu', $nav_menu_selected_id ); do_action( 'wp_update_nav_menu', $nav_menu_selected_id );
$messages[] = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been updated.'), $nav_menu_selected_title ) . '</p></div>'; $messages[] = '<div id="message" class="updated"><p>' . sprintf( __('The <strong>%s</strong> menu has been updated.'), $nav_menu_selected_title ) . '</p></div>';
unset( $menu_items ); unset( $menu_items, $unsorted_menu_items );
} }
} }
break; break;
@ -410,11 +415,6 @@ if ( current_theme_supports('nav-menus') ) {
// Set up nav menu // Set up nav menu
wp_nav_menu_setup(); wp_nav_menu_setup();
$messages[] = '<div id="message" class="error"><p>' . __('The current theme does not natively support menus, but you can use the &#8220;Navigation Menu&#8221; widget to add any menus you create here to the theme&#8217;s sidebar.') . '</p></div>'; $messages[] = '<div id="message" class="error"><p>' . __('The current theme does not natively support menus, but you can use the &#8220;Navigation Menu&#8221; widget to add any menus you create here to the theme&#8217;s sidebar.') . '</p></div>';
// The theme supports neither menus nor widgets.
} else {
remove_meta_box( 'create-menu', 'nav-menus', 'side' );
$messages[] = '<div id="message" class="error"><p>' . __('The current theme does not support menus.') . '</p></div>';
} }
wp_initial_nav_menu_meta_boxes(); wp_initial_nav_menu_meta_boxes();
@ -512,9 +512,11 @@ require_once( 'admin-header.php' );
<?php endif; ?> <?php endif; ?>
</div><!--END .major-publishing-actions--> </div><!--END .major-publishing-actions-->
</div><!--END #submitpost .submitbox--> </div><!--END #submitpost .submitbox-->
<?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?> <?php
<?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?> wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
<?php wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' ); ?> wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' );
?>
<input type="hidden" name="action" value="update" /> <input type="hidden" name="action" value="update" />
<input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" /> <input type="hidden" name="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
</div><!--END #nav-menu-header--> </div><!--END #nav-menu-header-->

View File

@ -385,7 +385,7 @@ function wp_default_scripts( &$scripts ) {
) ); ) );
// Custom Navigation // Custom Navigation
$scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100524' ); $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", false, '20100524a' );
$scripts->localize( 'nav-menu', 'navMenuL10n', array( $scripts->localize( 'nav-menu', 'navMenuL10n', array(
'home' => _x('Home', 'nav menu home label'), 'home' => _x('Home', 'nav menu home label'),
'homeurl' => home_url('/'), 'homeurl' => home_url('/'),
@ -467,7 +467,7 @@ function wp_default_styles( &$styles ) {
$styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' ); $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' );
$styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' ); $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' );
$styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' ); $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' );
$styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100521' ); $styles->add( 'nav-menu', "/wp-admin/css/nav-menu$suffix.css", array(), '20100524' );
foreach ( $rtl_styles as $rtl_style ) { foreach ( $rtl_styles as $rtl_style ) {
$styles->add_data( $rtl_style, 'rtl', true ); $styles->add_data( $rtl_style, 'rtl', true );