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

git-svn-id: https://develop.svn.wordpress.org/trunk@14852 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Nacin 2010-05-24 19:50:20 +00:00
parent e72dcec869
commit d617ca0f94
8 changed files with 126 additions and 133 deletions

View File

@ -399,17 +399,6 @@ case 'delete-link' :
else
die('0');
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' :
check_ajax_referer( "delete-meta_$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,
.submitdelete,
.submitclose {
.submitcancel {
display:block;
float:left;
font-size: 11px;
@ -422,11 +422,11 @@ body.js .item-order {
-khtml-border-bottom-right-radius: 6px;
-khtml-border-bottom-left-radius: 6px;
}
.menu-item-settings-active {
.menu-item-edit-active .menu-item-settings {
display:block;
}
.menu-item-settings-inactive {
.menu-item-edit-inactive .menu-item-settings {
display:none;
}
@ -473,10 +473,6 @@ body.js .item-order {
.menu-item-actions {
padding-top: 15px;
}
.save-menu-item {
float: right;
padding-left: 10px;
}
#cancel-save { cursor: pointer; }
#cancel-save:hover { color: #fff !important; }
@ -506,13 +502,13 @@ clear:both;
font-size: 11px;
font-style: normal;
}
.submitbox .submitclose {
.submitbox .submitcancel {
color: #21759B;
border-bottom: 1px solid #21759B;
padding: 1px 2px;
text-decoration: none;
}
.submitbox .submitclose:hover {
.submitbox .submitcancel:hover {
background: #21759B;
color: #fff;
}

View File

@ -59,13 +59,8 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
$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 ); ?>">
<dl class="menu-item-bar <?php
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';
?>">
<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">
<dt class="menu-item-handle">
<span class="item-title"><?php echo esc_html( $item->title ); ?></span>
<span class="item-controls">
@ -104,12 +99,7 @@ class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
</dt>
</dl>
<div class="menu-item-settings <?php
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; ?>">
<div class="menu-item-settings" id="menu-item-settings-<?php echo $item_id; ?>">
<?php if( 'custom' == $item->type ) : ?>
<p class="field-url description description-wide">
<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' ) )
),
'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>
<input class="button-primary save-menu-item" name="save_menu_item" type="submit" value="<?php esc_attr_e('Save Menu Item'); ?>" />
); ?>"><?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>
</div>
<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
$(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);
menuItems[listItemDBID] = api.getListDataFromID(listItemDBID);
menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID );
});
// Add the items
api.addItemToMenu(menuItems, processMethod, function(){
@ -143,6 +144,76 @@ var wpNavMenu;
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);
} else if ( -1 != e.target.className.indexOf('item-delete') ) {
return that.eventOnClickMenuItemDelete(e.target);
} else if ( -1 != e.target.className.indexOf('item-close') ) {
return that.eventOnClickCloseLink(e.target);
} else if ( -1 != e.target.className.indexOf('item-cancel') ) {
return that.eventOnClickCancelLink(e.target);
}
}
});
@ -498,7 +569,7 @@ var wpNavMenu;
if ( api.menusChanged )
return navMenuL10n.saveAlert;
};
$('input.menu-save, input.save-menu-item').click(function(){
$('input.menu-save').click(function(){
window.onbeforeunload = null;
});
},
@ -652,20 +723,22 @@ var wpNavMenu;
},
eventOnClickEditLink : function(clickedEl) {
var activeEdit,
var settings, item,
matchedSection = /#(.*)$/.exec(clickedEl.href);
if ( matchedSection && matchedSection[1] ) {
activeEdit = $('#'+matchedSection[1]);
if( 0 != activeEdit.length ) {
if( activeEdit.hasClass('menu-item-edit-inactive') ) {
activeEdit.slideDown('fast')
.siblings('dl').andSelf()
.removeClass('menu-item-edit-inactive')
settings = $('#'+matchedSection[1]);
item = settings.parent();
if( 0 != item.length ) {
if( item.hasClass('menu-item-edit-inactive') ) {
if( ! settings.data('menu-item-data') ) {
settings.data( 'menu-item-data', settings.getItemData() );
}
settings.slideDown('fast');
item.removeClass('menu-item-edit-inactive')
.addClass('menu-item-edit-active');
} else {
activeEdit.slideUp('fast')
.siblings('dl').andSelf()
.removeClass('menu-item-edit-active')
settings.slideUp('fast');
item.removeClass('menu-item-edit-active')
.addClass('menu-item-edit-inactive');
}
return false;
@ -673,8 +746,9 @@ var wpNavMenu;
}
},
eventOnClickCloseLink : function(clickedEl) {
$(clickedEl).closest('.menu-item-settings').siblings('dl').find('.item-edit').click();
eventOnClickCancelLink : function(clickedEl) {
var settings = $(clickedEl).closest('.menu-item-settings');
settings.setItemData( settings.data('menu-item-data') );
return false;
},
@ -699,28 +773,9 @@ var wpNavMenu;
},
eventOnClickMenuItemDelete : function(clickedEl) {
var itemID,
matchedSection,
that = this;
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;
var itemID = parseInt(clickedEl.id.replace('delete-', ''), 10);
api.removeMenuItem( $('#menu-item-' + itemID) );
return false;
},
/**
@ -765,53 +820,15 @@ var wpNavMenu;
},
removeMenuItem : function(el) {
el = $(el);
var children = el.childMenuItems();
el.addClass('deleting').fadeOut( 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;
el.addClass('deleting').animate({
opacity : 0,
height: 0
}, 350, function() {
el.remove();
children.shiftDepthClass(-1).updateParentMenuItemDBId();
});
},
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
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' );
wp_defer_term_counting(true);
// Loop through all the menu items' POST variables
@ -356,7 +361,7 @@ switch ( $action ) {
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>';
unset( $menu_items );
unset( $menu_items, $unsorted_menu_items );
}
}
break;
@ -410,11 +415,6 @@ if ( current_theme_supports('nav-menus') ) {
// Set up nav menu
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>';
// 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();
@ -512,9 +512,11 @@ require_once( 'admin-header.php' );
<?php endif; ?>
</div><!--END .major-publishing-actions-->
</div><!--END #submitpost .submitbox-->
<?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
<?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
<?php wp_nonce_field( 'update-nav_menu', 'update-nav-menu-nonce' ); ?>
<?php
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
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="menu" id="menu" value="<?php echo esc_attr( $nav_menu_selected_id ); ?>" />
</div><!--END #nav-menu-header-->

View File

@ -385,7 +385,7 @@ function wp_default_scripts( &$scripts ) {
) );
// 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(
'home' => _x('Home', 'nav menu home label'),
'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( '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( '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 ) {
$styles->add_data( $rtl_style, 'rtl', true );