| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- MODx.SearchBar = function(config) {
- config = config || {};
- Ext.applyIf(config, {
- renderTo: 'modx-manager-search'
- ,listClass: 'modx-manager-search-results'
- ,emptyText: _('search')
- ,id: 'modx-uberbar'
- ,maxHeight: this.getViewPortSize()
- ,typeAhead: true
- // ,listAlign: [ 'tl-bl?', [0, 0] ] // this is default
- ,listAlign: [ 'tl-bl?', [-12, 0] ] // account for padding + border width of container (added by Ext JS)
- ,triggerConfig: {
- tag: 'button'
- ,type: "submit"
- ,"aria-label": "Go"
- ,cls: 'x-form-trigger icon icon-large icon-search'
- }
- ,defaultAutoCreate: {
- tag: "input"
- ,type: "text"
- ,size: "24"
- ,autocomplete: "off"
- ,"aria-label" : _('search')
- }
- ,minChars: 1
- ,displayField: 'name'
- ,valueField: '_action'
- ,width: 259
- ,maxWidth: 437 // Increase to animate + grow when focused
- ,itemSelector: '.x-combo-list-item'
- ,tpl: new Ext.XTemplate(
- '<tpl for=".">',
- // Section wrapper
- '<div class="section">',
- // Display header only once
- '<tpl if="this.type != values.type">',
- '<tpl exec="this.type = values.type; values.label = this.getLabel(values)"></tpl>',
- '<h3>{label:htmlEncode}</h3>',
- '</tpl>',
- // Real result, make it use the default styles for a combobox dropdown with x-combo-list-item
- '<p class="x-combo-list-item"><a href="?a={_action}"><tpl exec="values.icon = this.getClass(values)"><i class="icon icon-{icon:htmlEncode}"></i></tpl>{name:htmlEncode}<tpl if="description"><em> – {description:htmlEncode}</em></tpl></a></p>',
- '</div >',
- '</tpl>'
- ,{
- /**
- * Get the appropriate CSS class based on the result type
- *
- * @param {Array} values
- * @returns {string}
- */
- getClass: function(values) {
- if (values.icon) {
- return values.icon;
- }
- if (values.class) {
- switch (values.class) {
- case 'modDocument':
- return 'file';
- case 'modSymLink':
- return 'files-o';
- case 'modWebLink':
- return 'link';
- case 'modStaticResource':
- return 'file-text-o';
- default:
- break;
- }
- }
- switch (values.type) {
- case 'resources':
- return 'file';
- case 'chunks':
- return 'th-large';
- case 'templates':
- return 'columns';
- case 'snippets':
- return 'code';
- case 'tvs':
- return 'list-alt';
- case 'plugins':
- return 'cogs';
- case 'users':
- return 'user';
- case 'actions':
- return 'mail-forward';
- }
- }
- /**
- * Get the result type lexicon
- *
- * @param {Array} values
- *
- * @returns {String}
- */
- ,getLabel: function(values) {
- if (values.label) {
- return values.label;
- }
- return _('search_resulttype_' + values.type);
- }
- }
- )
- ,store: new Ext.data.JsonStore({
- url: MODx.config.connector_url
- ,baseParams: {
- action: 'search/search'
- }
- ,root: 'results'
- ,totalProperty: 'total'
- ,fields: ['name', '_action', 'description', 'type', 'icon', 'label', 'class']
- ,listeners: {
- beforeload: function(store, options) {
- if (options.params._action) {
- // Prevent weird query on first combo box blur
- return false;
- }
- }
- }
- })
- ,listeners: {
- beforequery: {
- fn: function() {
- this.tpl.type = null;
- }
- }
- ,focus: this.focusBar
- ,blur: this.blurBar
- ,scope: this
- }
- });
- MODx.SearchBar.superclass.constructor.call(this, config);
- this.setKeyMap();
- };
- Ext.extend(MODx.SearchBar, Ext.form.ComboBox, {
- // Initialize the keyboard shortcuts to focus the bar (ctrl + alt + /) and hide it (esc)
- setKeyMap: function() {
- // This keymap is conflicting with typing certain characters, see #11974
- /*new Ext.KeyMap(document, {
- key: [191, 0]
- ,ctrl: true
- ,alt: true
- ,handler: function() {
- this.hideBar();
- this.toggle();
- }
- ,scope: this
- ,stopEvent: true
- });*/
- // Escape to hide SearchBar
- new Ext.KeyMap(document, {
- key: 27
- ,handler: function() {
- this.hideBar();
- }
- ,scope: this
- ,stopEvent: false
- });
- }
- /**
- * Override to support opening results in new window/tab
- */
- ,initList : function() {
- if(!this.list){
- var cls = 'x-combo-list',
- listParent = Ext.getDom(this.getListParent() || Ext.getBody());
- this.list = new Ext.Layer({
- parentEl: listParent,
- shadow: this.shadow,
- cls: [cls, this.listClass].join(' '),
- constrain:false,
- zindex: this.getZIndex(listParent)
- });
- var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
- this.list.setSize(lw, 0);
- this.list.swallowEvent('mousewheel');
- this.assetHeight = 0;
- if(this.syncFont !== false){
- this.list.setStyle('font-size', this.el.getStyle('font-size'));
- }
- if(this.title){
- this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
- this.assetHeight += this.header.getHeight();
- }
- this.innerList = this.list.createChild({cls:cls+'-inner'});
- this.mon(this.innerList, 'mouseover', this.onViewOver, this);
- this.mon(this.innerList, 'mousemove', this.onViewMove, this);
- this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
- if(this.pageSize){
- this.footer = this.list.createChild({cls:cls+'-ft'});
- this.pageTb = new Ext.PagingToolbar({
- store: this.store,
- pageSize: this.pageSize,
- renderTo:this.footer
- });
- this.assetHeight += this.footer.getHeight();
- }
- if(!this.tpl){
- this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
- }
- this.view = new Ext.DataView({
- applyTo: this.innerList,
- tpl: this.tpl,
- singleSelect: true,
- selectedClass: this.selectedClass,
- itemSelector: this.itemSelector || '.' + cls + '-item',
- emptyText: this.listEmptyText,
- deferEmptyText: false
- });
- // Original view listeners
- // this.mon(this.view, {
- // containerclick : this.onViewClick,
- // click : this.onViewClick,
- // scope :this
- // });
- this.view.on('click', function(view, index, node, vent) {
- /**
- * Force node selection to make sure it is available in onViewClick
- *
- * @see Ext.form.ComboBox#onViewClick
- */
- view.select(node);
- if (!window.event) {
- window.event = vent;
- }
- this.onViewClick();
- }, this);
- this.bindStore(this.store, true);
- if(this.resizable){
- this.resizer = new Ext.Resizable(this.list, {
- pinned:true, handles:'se'
- });
- this.mon(this.resizer, 'resize', function(r, w, h){
- this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
- this.listWidth = w;
- this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
- this.restrictHeight();
- }, this);
- this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
- }
- }
- }
- // Nullify the "parent" function
- ,onTypeAhead : function() {}
- /**
- * Go to the selected record "action" page
- *
- * @param {Object} record
- * @param {Number} index
- */
- ,onSelect: function(record, index) {
- var e = Ext.EventObject;
- e.stopPropagation();
- e.preventDefault();
- var target = '?a=' + record.data._action;
- if (e.ctrlKey || e.metaKey || e.shiftKey) {
- return window.open(target);
- }
- MODx.loadPage(target);
- }
- /**
- * Toggle the search drawer visibility
- *
- * @param {Boolean} hide Whether or not to force-hide MODx.SearchBar
- */
- ,toggle: function(hide) {
- var uberbar = Ext.get( this.container.id );
- if (uberbar.hasClass('visible') || hide ) {
- this.blurBar();
- uberbar.removeClass('visible');
- } else {
- uberbar.addClass('visible');
- this.focusBar();
- }
- }
- ,hideBar: function() {
- this.toggle(true);
- }
- ,focusBar: function() {
- this.selectText();
- this.animate();
- }
- ,blurBar: function() {
- this.animate(true);
- }
- /**
- * Animate the input "grow"
- *
- * @param {Boolean} blur Whether or not the input loses focus (to "minimize" the input width)
- */
- ,animate: function(blur) {
- var to = blur ? this.width : this.maxWidth;
- this.wrap.setWidth(to, true);
- this.el.setWidth(to - this.getTriggerWidth(), true);
- }
- /**
- * Compute the available max height so results could be scrollable if required
- *
- * @returns {number}
- */
- ,getViewPortSize: function() {
- var height = 300;
- if (window.innerHeight !== undefined) {
- height = window.innerHeight;
- }
- return height - 70;
- }
- });
- Ext.reg('modx-searchbar', MODx.SearchBar);
|