JS Tweak to the Drupal 7 Menu Management Screen

I tweaked Drupal Menu management screen today.
Previously after editing a menu item the menu page would reload and you’d be at the top of the menu list, essentially losing your place.

This was a problem for one of our admin users when digging through 390 menu items, so I thought I’d give it a quick fix.

Now when you edit a menu item and land back on the menu page, the JS below will scroll you to that last element and highlight the row.

Here’s a screenshot:

Screen Shot of menu management screen after editing a menu item

Sample JS to try in your console:

function scrollToReferrer(){
  //get the referrer URL
  referrerArr = document.referrer.split('/');
  //check if referrer was menu item edit screen
  if(referrerArr[3] == "admin" && referrerArr[5] == "menu" && (referrerArr[8] == "edit")) {
    referrerArr.pop(); //ditch edit
    //capture mlid - alt referrerArr[6]
    referrerMlid = referrerArr.pop();
    //scroll to mlid
    location.hash = "#edit-mlid"+referrerMlid+"-operations-edit";
    //slide up a "pinch" to keep the element visable (in the case of Admin Menu)    
    var x = pageXOffset, y = pageYOffset;
    scrollTo(x,y-60);
    //remove 'drag-previous' class from tr's on the page
    jQuery('tr').removeClass('drag-previous');
    //set waring class on this tr to highlight it
    jQuery("#edit-mlid"+referrerMlid+"-operations-edit").parents('tr').addClass('drag-previous');
    return true;
  }else{
    return false;
  }
}
scrollToReferrer();

And here’s the code in D7 Drupal.behaviours format as I implemented it:

(function ($) {
  Drupal.behaviors.scrollToReferrer = {
    //for use on admin/structure/menu/manage/main-menu
    attach: function(context) {
      if(typeof context !== 'undefined'){ //run only if there is a context var
        if(typeof context == 'object' && context.toString().indexOf('HTMLDocument')!=-1){ //Page Load
          //get the referrer URL
          referrerArr = document.referrer.split('/');
          //check if referrer was menu item edit screen
          if(referrerArr[3] == "admin" && referrerArr[5] == "menu" && (referrerArr[8] == "edit")) {
            referrerArr.pop(); //ditch edit
            //capture mlid - alt referrerArr[6]
            referrerMlid = referrerArr.pop();
            //scroll to mlid
            location.hash = "#edit-mlid"+referrerMlid+"-operations-edit";
            //slide up a "pinch" to keep the element visable (in the case of Admin Menu)    
            var x = pageXOffset, y = pageYOffset;
            scrollTo(x,y-60);
            //remove 'drag-previous' class from tr's on the page
            jQuery('tr').removeClass('drag-previous');
            //set waring class on this tr to highlight it
            jQuery("#edit-mlid"+referrerMlid+"-operations-edit").parents('tr').addClass('drag-previous');
            return true;
          }else{
            return false;
          }
        }//end if(typeof context == 'object' && context.toString().indexOf('HTMLDocument')!=-1){ //Page Load
      }//end typeof context !== und
    }//end function(context)
  }//end Drupal.behaviors
})(jQuery);

Now, the way to implement this correctly would be a custom module or perhaps adding the js to the themes’ .js file.

I added it via Code Per Node (cpn) to a new block that has user and page restrictions in our admin theme.
Here are the specifics:

Block title:
None;
Block description:
JS Seven Menu Page Scripts
Block body:
 
Text format:
Code input (custom type allowing html)
Pages – Only the listed pages:
admin/structure/menu/manage/main-menu;
CSS:
#block-block-53 {
    display: none;
    visibility: hidden;
    }

*Note the specific block ID in that id selector

JS:
As pasted above

A quick fix out and out.

Leave a Comment