Unable to move menu items after migrate from wp

I have just migrated two sites from WP to CP 2.2.0

When I try to reorder menu items I can move one item, but then unable to move any others. If I save the menu after moving the one item I can then move another one. However that is not a good way to work because I do not want the menu live until it is ready.

EDIT: just noticed same issue with moving items in Widgets

Also It is impossible to indent any items to become sub-menu (child) items. This has happened on bother sites and both were fine on WP before migrating. Can anyone please help? Thanks

I think the right person to tag here is @timkaye.
Could it be an issue with sortable.js?

ClassicPress has replaced the old jQuery UI library that used to handle drag, drop, and sort in core with the much more modern and accessible SortableJS. Moving from WP to CP doesn’t cause the issue reported here, though, so the cause must be site specific.

The first thing I suggest is to look in the browser console for errors, and then copy and paste them here. That should provide the answer.

Also make sure all caches are cleared.

If those steps don’t solve the problem, then it suggests to me that there is a plugin being used that is interfering with the drag and drop mechanism. So then try deactivating all plugins, clear caches again, and see if things work then. If they do, reactivate the plugins one by one until you find the culprit.

It is same issue on a couple of sites

All plugins deactivated. Cache cleared

If you could add the line below to your wp-config.php, that would show the exact line in nav-menu.js, making it easier to debug/fix:

define( 'SCRIPT_DEBUG', true );
1 Like

That image doesn’t give us the full picture. We need to see what’s showing on the right of the browser console too. Doing what @Ciprian says will help. And we need to see what the selected element is too.

1 Like

Here:

However I found that if I used Chrome browser instead of safari it all works fine - so Safari must be the issue.

1 Like

Maybe, but one of our core developers uses Safari and he hasn’t reported this issue. Nor does the issue seem likely to be browser-specific since what’s being reported is that a parent item doesn’t have a hidden input that all menu items automatically have.

So that makes me wonder about the theme you’re using. Are you able to switch temporarily to another theme while using Safari and test it then?

To test again as advised I switched to Classicsixteen and Classicpress theme temporarily which I downloaded from here, same issue with both sites (no plugins enabled)

I’m currently preparing for a hurricane so can’t delve into this further right now. But I’d be interested to hear from anyone else using Safari whether they have the same experience.

I can reproduce the menu issue in Safari, but not the widget’s one.

1 Like

So the issue here is that, on line 353 of the ~/wp-admin/js/nav-menu.js file, parent is returning undefined. Which means that Safari doesn’t understand the function getPreviousSibling.

That function is defined from lines 1171. But all that does is find the previousElementSibling and then check, in a while loop, whether it matches the specified CSS selector and, if so, returns it. (If not it moves onto the next previousElementSibling and tries again.) That’s all pretty basic JS. The only possible issue I can guess at is with .matches( ... in the code.

I have found a suggested polyfill for that at JavaScript polyfills for matches,closest, and forEach. · GitHub. Could someone try adding the following to the bottom of the ~/wp-admin/js/nav-menu.js file and see if it works in Safari then?

var ElementPrototype = window.Element.prototype;
if (typeof ElementPrototype.matches !== 'function') {
  ElementPrototype.matches = ElementPrototype.msMatchesSelector || ElementPrototype.mozMatchesSelector || ElementPrototype.webkitMatchesSelector || function matches(selector) {
    var element = this;
    var elements = (element.document || element.ownerDocument).querySelectorAll(selector);
    var index = 0;
    while (elements[index] && elements[index] !== element) {
      ++index;
    }
    return Boolean(elements[index]);
  };
}

It’s not working on my local nistallation.

Sadly no

Thanks to you both for trying. I’ll ponder some more.

Let’s try re-writing the getPreviousSibling function! Could you replace the current function from line 1171 with this?

    function getPreviousSibling( elem, selector ) {

		// Get the previous sibling element
		var sibling = elem.previousElementSibling,
			matchingElements = document.querySelectorAll( selector );

		// If the sibling matches our selector, use it; otherwise move on to the next sibling
		while ( sibling ) {
			for ( var i = 0, n = matchingElements.length; i < n; i++ ) {
				if ( sibling === matchingElements[i] ) {
					return sibling;
				}
			}
			sibling = sibling.previousElementSibling;
		}
	}

Note: you will need to make sure that your site has define( 'SCRIPT_DEBUG', true ); included in its wp-config.php file (just above /* That's all, stop editing! Happy blogging. */) because otherwise this file will be ignored and the minified file will be used instead.

If that doesn’t work, please revert the code and try the following instead. You will still need define( 'SCRIPT_DEBUG', true ); in the wp-config.php file.

Go up to line 223, which begins forceFallback and comment it out. Then uncomment the line below it.

If that still doesn’t work, then comment out BOTH those lines and try again.

With forceFallback all commented out it works for me.

Me too!

//forceFallback: navigator.vendor.match(/apple/i) ? true : false, // forces fallback for webkit browsers
			//forceFallback: 'GestureEvent' in window ? true : false, // forces fallback for Safari

That’s fantastic news! The fallback was there because there was a bug in Safari, which didn’t implement HTML5 drag and drop properly. So SortableJS came up with its own polyfill. When Matt tested this on Safari, it definitely needed the fallback.

So I’m guessing there has been an update to Safari recently, which has fixed its bug.

I will write a PR to take out the fallbacks everywhere.

1 Like