Commit 66328feb authored by joshua-gould's avatar joshua-gould

added search and autocomplete methods

parent 216d55d5
...@@ -180,6 +180,12 @@ morpheus.CheckBoxList = function(options) { ...@@ -180,6 +180,12 @@ morpheus.CheckBoxList = function(options) {
}; };
morpheus.CheckBoxList.prototype = { morpheus.CheckBoxList.prototype = {
searchWithPredicates : function(predicates) {
this.table.searchWithPredicates(predicates);
},
autocomplete : function(tokens, cb) {
this.table.autocomplete(tokens, cb);
},
setHeight : function(height) { setHeight : function(height) {
this.table.setHeight(height); this.table.setHeight(height);
}, },
......
...@@ -241,13 +241,45 @@ morpheus.Table.prototype = { ...@@ -241,13 +241,45 @@ morpheus.Table.prototype = {
} }
} }
}, },
search : function(text) { autocomplete : function(tokens, response) {
if (text === '') { var matches = [];
this.grid.setFilter(null); var token = tokens != null && tokens.length > 0 ? tokens[tokens.selectionStartIndex]
} else { : '';
token = $.trim(token);
var columns = this.columns.filter(function(c) { var columns = this.columns.filter(function(c) {
return c.searchable; return c.searchable;
}); });
var ncolumns = columns.length;
var showField = ncolumns > 1;
if (token === '') {
if (ncolumns <= 1) {
return response(matches);
}
for (var i = 0; i < ncolumns; i++) {
var field = columns[i].name;
matches.push({
value : field + ':',
label : '<span style="font-weight:300;">' + field
+ ':</span>',
show : true
});
// show column names
}
return response(matches);
}
var field = null;
var semi = token.indexOf(':');
if (semi > 0) { // field search?
if (token.charCodeAt(semi - 1) !== 92) { // \:
var possibleField = $.trim(token.substring(0, semi));
if (possibleField.length > 0 && possibleField[0] === '"'
&& possibleField[token.length - 1] === '"') {
possibleField = possibleField.substring(1,
possibleField.length - 1);
}
var columnNameToColumn = new morpheus.Map(); var columnNameToColumn = new morpheus.Map();
var columnNames = columns.map(function(c) { var columnNames = columns.map(function(c) {
return c.name; return c.name;
...@@ -255,13 +287,102 @@ morpheus.Table.prototype = { ...@@ -255,13 +287,102 @@ morpheus.Table.prototype = {
for (var i = 0; i < columnNames.length; i++) { for (var i = 0; i < columnNames.length; i++) {
columnNameToColumn.set(columnNames[i], columns[i]); columnNameToColumn.set(columnNames[i], columns[i]);
} }
var tokens = morpheus.Util.getAutocompleteTokens(text); var c = columnNameToColumn.get(possibleField);
var predicates = morpheus.Util.createSearchPredicates({ if (c !== undefined) {
tokens : tokens, token = $.trim(token.substring(semi + 1));
fields : columnNames columns = [ c ];
ncolumns = 1;
}
}
} else if (ncolumns > 1) {
for (var j = 0; j < ncolumns; j++) {
var field = columns[j].name;
matches.push({
value : field + ':',
label : '<span style="font-weight:300;">' + field
+ ':</span>',
show : true
});
}
}
var set = new morpheus.Set();
var regex = new RegExp('^' + morpheus.Util.escapeRegex(token), 'i');
var items = this.getItems();
var maxSize = matches.length + 10;
for (var i = 0, nitems = items.length; i < nitems; i++) {
var item = items[i];
for (var j = 0; j < ncolumns; j++) {
var field = columns[j].name;
var value = columns[j].getter(item);
if (morpheus.Util.isArray(value)) {
var nvalues = value.length;
for (var k = 0; k < nvalues; k++) {
var val = value[k];
if (regex.test(val) && !set.has(val)) {
set.add(val);
matches
.push({
value : showField ? (field + ':' + val)
: val,
label : showField ? ('<span style="font-weight:300;">'
+ field
+ ':</span>'
+ '<span style="font-weight:900;">'
+ val + '</span>')
: ('<span style="font-weight:900;">'
+ val + '</span>')
});
}
if (matches.length === maxSize) {
return response(matches);
}
}
} else {
if (regex.test(value) && !set.has(value)) {
set.add(value);
matches
.push({
value : showField ? (field + ':' + value)
: value,
label : showField ? ('<span style="font-weight:300;">'
+ field
+ ':</span>'
+ '<span style="font-weight:900;">'
+ value + '</span>')
: ('<span style="font-weight:900;">'
+ value + '</span>')
}); });
if (matches.length === maxSize) {
return response(matches);
}
}
}
}
}
return response(matches);
},
searchWithPredicates : function(predicates) {
if (predicates == null || predicates.length === 0) {
this.grid.setFilter(null);
return;
}
var columns = this.columns.filter(function(c) {
return c.searchable;
});
var columnNameToColumn = new morpheus.Map();
var columnNames = columns.map(function(c) {
return c.name;
});
for (var i = 0; i < columnNames.length; i++) {
columnNameToColumn.set(columnNames[i], columns[i]);
}
var filteredPredicates = []; var filteredPredicates = [];
for (var i = 0, npredicates = predicates.length; i < npredicates; i++) { var npredicates = predicates.length;
for (var i = 0; i < npredicates; i++) {
var predicate = predicates[i]; var predicate = predicates[i];
var filterColumnName = predicate.getField(); var filterColumnName = predicate.getField();
if (filterColumnName != null) { if (filterColumnName != null) {
...@@ -275,7 +396,7 @@ morpheus.Table.prototype = { ...@@ -275,7 +396,7 @@ morpheus.Table.prototype = {
} }
} }
predicates = filteredPredicates; predicates = filteredPredicates;
npredicates = predicates.length;
this.grid this.grid
.setFilter(function(item) { .setFilter(function(item) {
for (var p = 0; p < npredicates; p++) { for (var p = 0; p < npredicates; p++) {
...@@ -307,6 +428,24 @@ morpheus.Table.prototype = { ...@@ -307,6 +428,24 @@ morpheus.Table.prototype = {
return false; return false;
}); });
},
search : function(text) {
if (text === '') {
this.grid.setFilter(null);
} else {
var tokens = morpheus.Util.getAutocompleteTokens(text);
var columns = this.columns.filter(function(c) {
return c.searchable;
});
var columnNames = columns.map(function(c) {
return c.name;
});
var predicates = morpheus.Util.createSearchPredicates({
tokens : tokens,
fields : columnNames
});
this.searchWithPredicates(predicates);
} }
}, },
getSelectedRows : function() { getSelectedRows : function() {
...@@ -469,74 +608,11 @@ morpheus.TableSearchUI = function() { ...@@ -469,74 +608,11 @@ morpheus.TableSearchUI = function() {
$search.on('keyup', _.debounce(function() { $search.on('keyup', _.debounce(function() {
_this.table.search($.trim($(this).val())); _this.table.search($.trim($(this).val()));
}, 100)); }, 100));
morpheus.Util morpheus.Util.autosuggest({
.autosuggest({
$el : $search, $el : $search,
suggestWhenEmpty : false, suggestWhenEmpty : true,
filter : function(terms, response) { filter : function(tokens, response) {
var q = $.trim(terms[terms.length - 1]); _this.table.autocomplete(tokens, response);
if (q === '') {
response([]);
return;
}
var set = new morpheus.Set();
var regex = new RegExp('^' + q, 'i');
var columns = _this.table.columns;
var ncolumns = columns.length;
var items = _this.table.getItems();
var matches = [];
for (var i = 0, nitems = items.length; i < nitems; i++) {
var item = items[i];
for (var j = 0; j < ncolumns; j++) {
if (columns[j].searchable) {
var field = columns[j].name;
var showField = field && ncolumns > 1;
var value = columns[j].getter(item);
if (morpheus.Util.isArray(value)) {
var nvalues = value.length;
for (var k = 0; k < nvalues; k++) {
var val = value[k];
if (regex.test(val) && !set.has(val)) {
set.add(val);
matches
.push({
value : val,
label : showField ? ('<span style="font-weight:300;">'
+ field
+ ':</span>'
+ '<span style="font-weight:900;">'
+ val + '</span>')
: ('<span style="font-weight:900;">'
+ val + '</span>')
});
}
if (matches.length === 10) {
return response(matches);
}
}
} else {
if (regex.test(value) && !set.has(value)) {
set.add(value);
matches
.push({
value : value,
label : showField ? ('<span style="font-weight:300;">'
+ field
+ ':</span>'
+ '<span style="font-weight:900;">'
+ value + '</span>')
: ('<span style="font-weight:900;">'
+ value + '</span>')
});
if (matches.length === 10) {
return response(matches);
}
}
}
}
}
}
return response(matches);
}, },
select : function() { select : function() {
_this.table.search($.trim($search.val())); _this.table.search($.trim($search.val()));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment