X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/3789b528d8dd8aad4558e38e22d775bcab1cbd36..6746dc89c47ed01b165cc1152533605f97eb8e8d:/docs/app/controller/Search.js diff --git a/docs/app/controller/Search.js b/docs/app/controller/Search.js new file mode 100644 index 00000000..7bbebc3b --- /dev/null +++ b/docs/app/controller/Search.js @@ -0,0 +1,156 @@ +/** + * Controller for search. + */ +Ext.define('Docs.controller.Search', { + extend: 'Ext.app.Controller', + + views: [ + 'search.Dropdown' + ], + + stores: ['Search'], + + init: function() { + this.control({ + '#search-dropdown': { + itemclick: function(dropdown, record) { + this.loadRecord(record); + } + }, + '#search-field': { + keyup: function(el, ev) { + var dropdown = this.getDropdown(); + + el.setHideTrigger(el.getValue().length === 0); + + if (ev.keyCode === Ext.EventObject.ESC || !el.value) { + dropdown.hide(); + el.setValue(""); + return; + } + else { + dropdown.show(); + } + + var selModel = dropdown.getSelectionModel(); + var record = selModel.getLastSelected(); + var curIndex = dropdown.store.indexOf(record); + var lastIndex = dropdown.store.getCount() - 1; + + if (ev.keyCode === Ext.EventObject.UP) { + if (curIndex === undefined) { + selModel.select(0); + } else { + selModel.select(curIndex === 0 ? lastIndex : (curIndex - 1)); + } + } + else if (ev.keyCode === Ext.EventObject.DOWN) { + if (curIndex === undefined) { + selModel.select(0); + } else { + selModel.select(curIndex === lastIndex ? 0 : curIndex + 1); + } + } + else if (ev.keyCode === Ext.EventObject.ENTER) { + ev.preventDefault(); + record && this.loadRecord(record); + } + else { + // Wait a bit before actually performing the search. + // When user is typing fast, the value of el.value + // might not right away be the final value. For example + // user might type "tre" but we will get three keyup events + // where el.value === "t". + clearTimeout(this.searchTimeout); + this.searchTimeout = Ext.Function.defer(function() { + this.search(el.value); + }, 50, this); + } + }, + focus: function(el) { + if (el.value && this.getDropdown().store.getCount() > 0) { + this.getDropdown().show(); + } + }, + blur: function() { + // Don't hide the dropdown right away, otherwise + // we don't receive the itemclick event when focus + // was lost because we clicked on dropdown item. + // Not really a good solution, but I can't + // currently think of anything better. Behaves + // badly when you make a long mouse press on + // dropdown item. + var dropdown = this.getDropdown(); + Ext.Function.defer(dropdown.hide, 500, dropdown); + } + } + }); + }, + + getDropdown: function() { + return this.dropdown || (this.dropdown = Ext.getCmp('search-dropdown')); + }, + + // loads class/method corrseponding to the record + loadRecord: function(record) { + var name = record.get("cls"); + if (record.get("type") !== 'cls') { + name += '-' + record.get("type") + '-' + record.get("member"); + } + Docs.App.getController('Classes').loadClass(name); + this.getDropdown().hide(); + }, + + search: function(term) { + // perform search and load results to store + var limit = 10; + var results = this.filterMembers(term); + this.getDropdown().setTotal(results.length); + this.getDropdown().getStore().loadData(results.slice(0, limit)); + // position dropdown below search box + this.getDropdown().alignTo('search-field', 'bl', [-23, 2]); + // hide dropdown when nothing found + if (results.length === 0) { + this.getDropdown().hide(); + } + else { + // auto-select first result + this.getDropdown().getSelectionModel().select(0); + } + }, + + filterMembers: function(text) { + var results = [[], [], [], [], []]; + var xFull=0, nFull=1, xBeg=2, nBeg=3, nMid=4; + var hasDot = /\./.test(text); + var safeText = Ext.escapeRe(text); + var reFull = new RegExp("^" + safeText + "$", "i"); + var reBeg = new RegExp("^" + safeText, "i"); + var reMid = new RegExp(safeText, "i"); + + Ext.Array.forEach(Docs.membersData.data, function(r) { + // when search text has "." in it, search from the full name (e.g. "Ext.Component.focus") + // Otherwise search from just the member name (e.g. "focus" or "Component") + var name = hasDot ? r.cls + (r.type === "cls" ? "" : "." + r.member) : r.member; + + if (r.xtypes && Ext.Array.some(r.xtypes, function(x) {return reFull.test(x);})) { + results[xFull].push(r); + } + else if (r.xtypes && Ext.Array.some(r.xtypes, function(x) {return reBeg.test(x);})) { + results[xBeg].push(r); + } + else if (reFull.test(name)) { + results[nFull].push(r); + } + else if (reBeg.test(name)) { + results[nBeg].push(r); + } + else if (reMid.test(name)) { + results[nMid].push(r); + } + }); + + return Ext.Array.flatten(results); + } + +});