]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/form/GlobalSearchField.js
b28ce9975ad1c44352efaac99fbd5a8a8d223b2e
2 * This is a global search field
3 * it loads the /cluster/resources on focus
4 * and displays the result in a floating grid
6 * it filters and sorts the objects by the algorithm in
7 * the customFilter function
9 * also it does accept key up/down and enter for input
10 * and it opens to ctrl+shift+f and ctrl+space
12 Ext
.define('PVE.form.GlobalSearchField', {
13 extend
: 'Ext.form.field.Text',
14 alias
: 'widget.pveGlobalSearchField',
16 emptyText
: gettext('Search'),
17 enableKeyEvents
: true,
23 focusOnToFront
: false,
25 emptyText
: PVE
.Utils
.noneText
,
34 model
: 'PVEResources',
37 url
: '/api2/extjs/cluster/resources'
41 ptype
: 'bufferedrenderer',
42 trailingBufferZone
: 20,
49 if (!me
.textfield
.hasFocus
) {
54 setFocus: function() {
60 rowclick: function(grid
, record
) {
62 me
.textfield
.selectAndHide(record
.id
);
68 focusenter
: 'setFocus'
73 text
: gettext('Type'),
76 renderer
: PVE
.Utils
.render_resource_type
79 text
: gettext('Description'),
84 text
: gettext('Node'),
88 text
: gettext('Pool'),
94 customFilter: function(item
) {
100 // different types of objects have different fields to search
101 // for example, a node will never have a pool and vice versa
102 switch (item
.data
.type
) {
103 case 'pool': fieldArr
= ['type', 'pool', 'text']; break;
104 case 'node': fieldArr
= ['type', 'node', 'text']; break;
105 case 'storage': fieldArr
= ['type', 'pool', 'node', 'storage']; break;
106 default: fieldArr
= ['name', 'type', 'node', 'pool', 'vmid'];
108 if (me
.filterVal
=== '') {
109 item
.data
.relevance
= 0;
113 // all text is case insensitive and each word is
115 // for every partial match, the row gets
116 // 1 match point, for every exact match
119 // results gets sorted by points (descending)
120 fields
= me
.filterVal
.split(/\s+/);
121 for(i
= 0; i
< fieldArr
.length
; i
++) {
122 var v
= item
.data
[fieldArr
[i
]];
123 if (v
!== undefined) {
124 v
= v
.toString().toLowerCase();
125 for(j
= 0; j
< fields
.length
; j
++) {
126 if (v
.indexOf(fields
[j
]) !== -1) {
128 if(v
=== fields
[j
]) {
135 // give the row the 'relevance' value
136 item
.data
.relevance
= match
;
140 updateFilter: function(field
, newValue
, oldValue
) {
142 // parse input and filter store,
144 me
.grid
.store
.filterVal
= newValue
.toLowerCase().trim();
145 me
.grid
.store
.clearFilter(true);
146 me
.grid
.store
.filterBy(me
.customFilter
);
147 me
.grid
.getSelectionModel().select(0);
150 selectAndHide: function(id
) {
152 me
.tree
.selectById(id
);
158 onKey: function(field
, e
) {
160 var key
= e
.getKey();
163 case Ext
.event
.Event
.ENTER
:
164 // go to first entry if there is one
165 if (me
.grid
.store
.getCount() > 0) {
166 me
.selectAndHide(me
.grid
.getSelection()[0].data
.id
);
169 case Ext
.event
.Event
.UP
:
170 me
.grid
.getSelectionModel().selectPrevious();
172 case Ext
.event
.Event
.DOWN
:
173 me
.grid
.getSelectionModel().selectNext();
175 case Ext
.event
.Event
.ESC
:
182 loadValues: function(field
) {
187 me
.grid
.textfield
= me
;
188 me
.grid
.store
.load();
189 me
.grid
.showBy(me
, 'tl-bl');
192 hideGrid: function() {
196 if (!me
.grid
.hasFocus
) {
207 focusenter
: 'loadValues',
214 toggleFocus: function() {
223 initComponent: function() {
227 throw "no tree given";
230 me
.grid
= Ext
.create(me
.grid
);
234 /*jslint confusion: true*/
235 /*because shift is also a function*/
236 // bind ctrl+shift+f and ctrl+space
237 // to open/close the search
238 me
.keymap
= new Ext
.KeyMap({
239 target
: Ext
.get(document
),
254 // always select first item and
255 // sort by relevance after load
256 me
.mon(me
.grid
.store
, 'load', function() {
257 me
.grid
.getSelectionModel().select(0);
259 property
: 'relevance',