Merge pull request #17322 from eileenmcnaughton/ids
[civicrm-core.git] / js / crm.menubar.js
index 9fa49f63d69a5fc0d23f4bdf21f3c9ea74eec42f..eba37ed3c46d6c90b6281b3be088900ce874018a 100644 (file)
             })
             .on('show.smapi', function(e, menu) {
               // Focus menu when opened with an accesskey
-              $(menu).siblings('a[accesskey]').focus();
+              if ($(menu).parent().data('name') === 'Home') {
+                $('#crm-menubar-drilldown').focus();
+              } else {
+                $(menu).siblings('a[accesskey]').focus();
+              }
             })
             .smartmenus(CRM.menubar.settings);
           initialized = true;
           CRM.menubar.initializeResponsive();
           CRM.menubar.initializeSearch();
+          CRM.menubar.initializeDrill();
         });
       }
     },
     getItem: function(itemName) {
       return traverse(CRM.menubar.data.menu, itemName, 'get');
     },
+    findItems: function(searchTerm) {
+      return findRecursive(CRM.menubar.data.menu, searchTerm.toLowerCase().replace(/ /g, ''));
+    },
     addItems: function(position, targetName, items) {
       var list, container, $ul;
       if (position === 'before' || position === 'after') {
         return !$('ul.crm-quickSearch-results').is(':visible:not(.ui-state-disabled)');
       });
     },
+    initializeDrill: function() {
+      $('#civicrm-menu').on('keyup', '#crm-menubar-drilldown', function() {
+        var term = $(this).val(),
+          results = term ? CRM.menubar.findItems(term).slice(0, 20) : [];
+        $(this).parent().next('ul').html(getTpl('branch')({items: results, branchTpl: getTpl('branch'), drillTpl: _.noop}));
+        $('#civicrm-menu').smartmenus('refresh').smartmenus('itemActivate', $(this).closest('a'));
+      });
+    },
     treeTpl:
       '<nav id="civicrm-menu-nav">' +
         '<input id="crm-menubar-state" type="checkbox" />' +
           '<% }) %>' +
         '</ul>' +
       '</li>',
+    drillTpl:
+      '<li class="crm-menu-border-bottom" data-name="MenubarDrillDown">' +
+        '<a href="#"><input type="text" id="crm-menubar-drilldown" placeholder="' + _.escape(ts('Find menu item...')) + '"></a>' +
+        '<ul></ul>' +
+      '</li>',
     branchTpl:
       '<% _.forEach(items, function(item) { %>' +
         '<li <%= attr("li", item) %>>' +
             '<% } %>' +
           '</a>' +
           '<% if (item.child) { %>' +
-            '<ul><%= branchTpl({items: item.child, branchTpl: branchTpl}) %></ul>' +
+            '<ul>' +
+              '<% if (item.name === "Home") { %><%= drillTpl() %><% } %>' +
+              '<%= branchTpl({items: item.child, branchTpl: branchTpl}) %>' +
+            '</ul>' +
           '<% } %>' +
         '</li>' +
       '<% }) %>'
   function getTpl(name) {
     if (!templates) {
       templates = {
-        branch: _.template(CRM.menubar.branchTpl, {imports: {_: _, attr: attr}}),
+        drill: _.template(CRM.menubar.drillTpl, {}),
         search: _.template(CRM.menubar.searchTpl, {imports: {_: _, ts: ts, CRM: CRM}})
       };
+      templates.branch = _.template(CRM.menubar.branchTpl, {imports: {_: _, attr: attr, drillTpl: templates.drill}});
       templates.tree = _.template(CRM.menubar.treeTpl, {imports: {branchTpl: templates.branch, searchTpl: templates.search, ts: ts}});
     }
     return templates[name];
     return found;
   }
 
+  function findRecursive(collection, searchTerm) {
+    var items = _.filter(collection, function(item) {
+      return item.label && _.includes(item.label.toLowerCase().replace(/ /g, ''), searchTerm);
+    });
+    _.each(collection, function(item) {
+      if (_.isPlainObject(item) && item.child) {
+        var childMatches = findRecursive(item.child, searchTerm);
+        if (childMatches.length) {
+          Array.prototype.push.apply(items, childMatches);
+        }
+      }
+    });
+    return items;
+  }
+
   function attr(el, item) {
     var ret = [], attr = _.cloneDeep(item.attr || {}), a = ['rel', 'accesskey', 'target'];
     if (el === 'a') {