datatracker/ietf/static/js/listjs-search.js
2022-11-28 10:36:36 -06:00

138 lines
4.3 KiB
JavaScript

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 has already reset 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
}