# All files / src search.js

94.25% Statements 82/87
81.63% Branches 40/49
90.91% Functions 10/11
96.1% Lines 74/77

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    13717x

    90x

    72x
    72x
    72x

    72x
    6x
    66x
    3x
    3x
    63x
    4x
    4x

    59x

    72x
    72x
    65x

    72x
    72x
    72x

    63x
    63x
    138x

    63x

    90x

    40x

    40x
    40x
    2x
    2x

    40x
    40x
    40x
    222x
    222x
    222x
    222x
    233x
    233x
    377x
    377x
    377x
    363x
    363x

    67x
    67x

    233x

    222x

    25x
    25x

    90x
    72x

    72x
    72x
    72x
    72x

    72x
    25x

    47x
    47x
    7x

    40x

    72x
    72x
    72x

    90x
    90x

    90x

    2x
    2x
    2x

    2x

    90x

    90x

     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 () {
          Iif (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()
          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
            Iif (!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
          Eif (!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
    }