@@ -32,8 +32,9 @@ export default {
32
32
return {
33
33
// Flag for displaying which empty slot to show and some event triggering
34
34
isFiltered: false,
35
-
// Where we store the copy of the filter citeria after debouncing
36
-
localFilter: null
35
+
// Where we store the copy of the filter criteria after debouncing
36
+
// We pre-set it with the sanitized filter value
37
+
localFilter: this.filterSanitize(this.filter)
37
38
}
38
39
},
39
40
computed: {
@@ -66,57 +67,55 @@ export default {
66
67
// Returns the original `localItems` array if not sorting
67
68
filteredItems() {
68
69
const items = this.localItems || []
69
-
// Note the criteria is debounced
70
-
const criteria = this.filterSanitize(this.localFilter)
70
+
// Note the criteria is debounced and sanitized
71
+
const criteria = this.localFilter
71
72
72
73
// Resolve the filtering function, when requested
73
74
// We prefer the provided filtering function and fallback to the internal one
74
75
// When no filtering criteria is specified the filtering factories will return `null`
75
-
let filterFn = null
76
-
if (this.localFiltering) {
77
-
filterFn =
78
-
this.filterFnFactory(this.localFilterFn, criteria) ||
76
+
const filterFn = this.localFiltering
77
+
? this.filterFnFactory(this.localFilterFn, criteria) ||
79
78
this.defaultFilterFnFactory(criteria)
80
-
}
79
+
: null
81
80
82
81
// We only do local filtering when requested and there are records to filter
83
-
if (filterFn && items.length > 0) {
84
-
return items.filter(filterFn)
85
-
}
86
-
87
-
// Otherwise return all items
88
-
return items
82
+
return filterFn && items.length > 0 ? items.filter(filterFn) : items
89
83
}
90
84
},
91
85
watch: {
92
86
// Watch for debounce being set to 0
93
87
computedFilterDebounce(newVal, oldVal) {
94
-
if (!newVal && this.filterTimer) {
95
-
clearTimeout(this.filterTimer)
96
-
this.filterTimer = null
97
-
this.localFilter = this.filter
88
+
if (!newVal && this.$_filterTimer) {
89
+
clearTimeout(this.$_filterTimer)
90
+
this.$_filterTimer = null
91
+
this.localFilter = this.filterSanitize(this.filter)
98
92
}
99
93
},
100
94
// Watch for changes to the filter criteria, and debounce if necessary
101
-
filter(newFilter, oldFilter) {
102
-
const timeout = this.computedFilterDebounce
103
-
if (this.filterTimer) {
104
-
clearTimeout(this.filterTimer)
105
-
this.filterTimer = null
106
-
}
107
-
if (timeout) {
108
-
// If we have a debounce time, delay the update of this.localFilter
109
-
this.filterTimer = setTimeout(() => {
110
-
this.filterTimer = null
111
-
this.localFilter = this.filterSanitize(this.filter)
112
-
}, timeout)
113
-
} else {
114
-
// Otherwise, immediately update this.localFilter
115
-
this.localFilter = this.filterSanitize(this.filter)
95
+
filter: {
96
+
// We need a deep watcher in case the user passes
97
+
// an object when using `filter-function`
98
+
deep: true,
99
+
handler(newFilter, oldFilter) {
100
+
const timeout = this.computedFilterDebounce
101
+
if (this.$_filterTimer) {
102
+
clearTimeout(this.$_filterTimer)
103
+
this.$_filterTimer = null
104
+
}
105
+
if (timeout) {
106
+
// If we have a debounce time, delay the update of `localFilter`
107
+
this.$_filterTimer = setTimeout(() => {
108
+
this.$_filterTimer = null
109
+
this.localFilter = this.filterSanitize(this.filter)
110
+
}, timeout)
111
+
} else {
112
+
// Otherwise, immediately update `localFilter` with `newFilter` value
113
+
this.localFilter = this.filterSanitize(newFilter)
114
+
}
116
115
}
117
116
},
118
-
// Watch for changes to the filter criteria and filtered items vs localItems).
119
-
// And set visual state and emit events as required
117
+
// Watch for changes to the filter criteria and filtered items vs `localItems`
118
+
// Set visual state and emit events as required
120
119
filteredCheck({ filteredItems, localItems, localFilter }) {
121
120
// Determine if the dataset is filtered or not
122
121
let isFiltered = false
@@ -145,34 +144,34 @@ export default {
145
144
},
146
145
created() {
147
146
// Create non-reactive prop where we store the debounce timer id
148
-
this.filterTimer = null
147
+
this.$_filterTimer = null
149
148
// If filter is "pre-set", set the criteria
150
-
// This will trigger any watchers/dependants
151
-
this.localFilter = this.filterSanitize(this.filter)
152
-
// Set the initial filtered state.
153
-
// In a nextTick so that we trigger a filtered event if needed
149
+
// This will trigger any watchers/dependents
150
+
// this.localFilter = this.filterSanitize(this.filter)
151
+
// Set the initial filtered state in a `$nextTick()` so that
152
+
// we trigger a filtered event if needed
154
153
this.$nextTick(() => {
155
154
this.isFiltered = Boolean(this.localFilter)
156
155
})
157
156
},
158
157
beforeDestroy() {
159
158
/* istanbul ignore next */
160
-
if (this.filterTimer) {
161
-
clearTimeout(this.filterTimer)
162
-
this.filterTimer = null
159
+
if (this.$_filterTimer) {
160
+
clearTimeout(this.$_filterTimer)
161
+
this.$_filterTimer = null
163
162
}
164
163
},
165
164
methods: {
166
165
filterSanitize(criteria) {
167
166
// Sanitizes filter criteria based on internal or external filtering
168
167
if (
169
168
this.localFiltering &&
170
-
!isFunction(this.filterFunction) &&
169
+
!this.localFilterFn &&
171
170
!(isString(criteria) || isRegExp(criteria))
172
171
) {
173
-
// If using internal filter function, which only accepts string or RegExp
174
-
// return null to signify no filter
175
-
return null
172
+
// If using internal filter function, which only accepts string or RegExp,
173
+
// return '' to signify no filter
174
+
return ''
176
175
}
177
176
178
177
// Could be a string, object or array, as needed by external filter function
@@ -210,6 +209,7 @@ export default {
210
209
},
211
210
defaultFilterFnFactory(criteria) {
212
211
// Generates the default filter function, using the given filter criteria
212
+
// Returns `null` if no criteria or criteria format not supported
213
213
if (!criteria || !(isString(criteria) || isRegExp(criteria))) {
214
214
// Built in filter can only support strings or RegExp criteria (at the moment)
215
215
return null
@@ -237,7 +237,7 @@ export default {
237
237
// Users can ignore filtering on specific fields, or on only certain fields,
238
238
// and can optionall specify searching results of fields with formatter
239
239
//
240
-
// TODO: Enable searching on scoped slots
240
+
// TODO: Enable searching on scoped slots (optional, as it will be SLOW)
241
241
//
242
242
// Generated function returns true if the criteria matches part of
243
243
// the serialized data, otherwise false
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4