fix: Allow searching for non-alphanumeric characters (#4266)
* fix: Allow searching for non-alphanumeric characters Fixes #3675 @rjsparks, this avoids us needing to fork list.js. If you prefer a fork, let me know. * Add a TODO
This commit is contained in:
parent
aea533e4dd
commit
28b8ed0c84
|
@ -197,14 +197,18 @@ $(document)
|
|||
hook = parent[0];
|
||||
}
|
||||
|
||||
list_instance.push(
|
||||
new List(hook, pagination ? {
|
||||
let newlist = new List(hook, pagination ? {
|
||||
valueNames: fields,
|
||||
pagination: pagination,
|
||||
page: items_per_page
|
||||
} : {
|
||||
valueNames: fields
|
||||
}));
|
||||
});
|
||||
// override search module with a patched version
|
||||
// see https://github.com/javve/list.js/issues/699
|
||||
// TODO: check if this is still needed if list.js ever sees an update
|
||||
newlist.search = require("./listjs-search")(newlist);
|
||||
list_instance.push(newlist);
|
||||
});
|
||||
|
||||
if (enable_search) {
|
||||
|
|
137
ietf/static/js/listjs-search.js
Normal file
137
ietf/static/js/listjs-search.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
module.exports = function (list) {
|
||||
var item, text, columns, searchString, customSearch
|
||||
|
||||
var prepare = {
|
||||
resetList: function () {
|
||||
list.i = 1
|
||||
list.templater.clear()
|
||||
customSearch = undefined
|
||||
},
|
||||
setOptions: function (args) {
|
||||
if (args.length == 2 && args[1] instanceof Array) {
|
||||
columns = args[1]
|
||||
} else if (args.length == 2 && typeof args[1] == 'function') {
|
||||
columns = undefined
|
||||
customSearch = args[1]
|
||||
} else if (args.length == 3) {
|
||||
columns = args[1]
|
||||
customSearch = args[2]
|
||||
} else {
|
||||
columns = undefined
|
||||
}
|
||||
},
|
||||
setColumns: function () {
|
||||
if (list.items.length === 0) return
|
||||
if (columns === undefined) {
|
||||
columns = list.searchColumns === undefined ? prepare.toArray(list.items[0].values()) : list.searchColumns
|
||||
}
|
||||
},
|
||||
setSearchString: function (s) {
|
||||
s = list.utils.toString(s).toLowerCase()
|
||||
// see https://github.com/javve/list.js/issues/699
|
||||
// s = s.replace(/[-[\]{}()*+?.,\\^$|#]/g, '\\$&') // Escape regular expression characters
|
||||
searchString = s
|
||||
},
|
||||
toArray: function (values) {
|
||||
var tmpColumn = []
|
||||
for (var name in values) {
|
||||
tmpColumn.push(name)
|
||||
}
|
||||
return tmpColumn
|
||||
},
|
||||
}
|
||||
var search = {
|
||||
list: function () {
|
||||
// Extract quoted phrases "word1 word2" from original searchString
|
||||
// searchString is converted to lowercase by List.js
|
||||
var words = [],
|
||||
phrase,
|
||||
ss = searchString
|
||||
while ((phrase = ss.match(/"([^"]+)"/)) !== null) {
|
||||
words.push(phrase[1])
|
||||
ss = ss.substring(0, phrase.index) + ss.substring(phrase.index + phrase[0].length)
|
||||
}
|
||||
// Get remaining space-separated words (if any)
|
||||
ss = ss.trim()
|
||||
if (ss.length) words = words.concat(ss.split(/\s+/))
|
||||
for (var k = 0, kl = list.items.length; k < kl; k++) {
|
||||
var item = list.items[k]
|
||||
item.found = false
|
||||
if (!words.length) continue
|
||||
for (var i = 0, il = words.length; i < il; i++) {
|
||||
var word_found = false
|
||||
for (var j = 0, jl = columns.length; j < jl; j++) {
|
||||
var values = item.values(),
|
||||
column = columns[j]
|
||||
if (values.hasOwnProperty(column) && values[column] !== undefined && values[column] !== null) {
|
||||
var text = typeof values[column] !== 'string' ? values[column].toString() : values[column]
|
||||
if (text.toLowerCase().indexOf(words[i]) !== -1) {
|
||||
// word found, so no need to check it against any other columns
|
||||
word_found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// this word not found? no need to check any other words, the item cannot match
|
||||
if (!word_found) break
|
||||
}
|
||||
item.found = word_found
|
||||
}
|
||||
},
|
||||
// Removed search.item() and search.values()
|
||||
reset: function () {
|
||||
list.reset.search()
|
||||
list.searched = false
|
||||
},
|
||||
}
|
||||
|
||||
var searchMethod = function (str) {
|
||||
list.trigger('searchStart')
|
||||
|
||||
prepare.resetList()
|
||||
prepare.setSearchString(str)
|
||||
prepare.setOptions(arguments) // str, cols|searchFunction, searchFunction
|
||||
prepare.setColumns()
|
||||
|
||||
if (searchString === '') {
|
||||
search.reset()
|
||||
} else {
|
||||
list.searched = true
|
||||
if (customSearch) {
|
||||
customSearch(searchString, columns)
|
||||
} else {
|
||||
search.list()
|
||||
}
|
||||
}
|
||||
|
||||
list.update()
|
||||
list.trigger('searchComplete')
|
||||
return list.visibleItems
|
||||
}
|
||||
|
||||
list.handlers.searchStart = list.handlers.searchStart || []
|
||||
list.handlers.searchComplete = list.handlers.searchComplete || []
|
||||
|
||||
list.utils.events.bind(
|
||||
list.utils.getByClass(list.listContainer, list.searchClass),
|
||||
'keyup',
|
||||
list.utils.events.debounce(function (e) {
|
||||
var target = e.target || e.srcElement, // IE have srcElement
|
||||
alreadyCleared = target.value === '' && !list.searched
|
||||
if (!alreadyCleared) {
|
||||
// If oninput already have resetted the list, do nothing
|
||||
searchMethod(target.value)
|
||||
}
|
||||
}, list.searchDelay)
|
||||
)
|
||||
|
||||
// Used to detect click on HTML5 clear button
|
||||
list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'input', function (e) {
|
||||
var target = e.target || e.srcElement
|
||||
if (target.value === '') {
|
||||
searchMethod('')
|
||||
}
|
||||
})
|
||||
|
||||
return searchMethod
|
||||
}
|
Loading…
Reference in a new issue