Skip to content

Commit 165fae7

Browse files
committed
feat(1763): Add new func prop for sorting search results
1 parent 3ec51ba commit 165fae7

File tree

2 files changed

+62
-30
lines changed

2 files changed

+62
-30
lines changed

src/Multiselect.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,11 @@ export default {
327327
type: Number,
328328
default: 0
329329
},
330+
/**
331+
* Adds Required attribute to the input element when there is no value selected
332+
* @default false
333+
* @type {Boolean}
334+
*/
330335
required: {
331336
type: Boolean,
332337
default: false

src/multiselectMixin.js

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,6 @@ function includes (str, query) {
1717
return text.indexOf(query.trim()) !== -1
1818
}
1919

20-
function filterOptions (options, search, label, customLabel) {
21-
return search
22-
? options
23-
.filter((option) => includes(customLabel(option, label), search))
24-
.sort((a, b) => customLabel(a, label).length - customLabel(b, label).length)
25-
: options
26-
}
27-
2820
function stripGroups (options) {
2921
return options.filter((option) => !option.$isLabel)
3022
}
@@ -44,25 +36,6 @@ function flattenOptions (values, label) {
4436
}, [])
4537
}
4638

47-
function filterGroups (search, label, values, groupLabel, customLabel) {
48-
return (groups) =>
49-
groups.map((group) => {
50-
/* istanbul ignore else */
51-
if (!group[values]) {
52-
console.warn('Options passed to vue-multiselect do not contain groups, despite the config.')
53-
return []
54-
}
55-
const groupOptions = filterOptions(group[values], search, label, customLabel)
56-
57-
return groupOptions.length
58-
? {
59-
[groupLabel]: group[groupLabel],
60-
[values]: groupOptions
61-
}
62-
: []
63-
})
64-
}
65-
6639
const flow = (...fns) => (x) => fns.reduce((v, f) => f(v), x)
6740

6841
export default {
@@ -314,10 +287,19 @@ export default {
314287
* Prevent autofocus
315288
* @default false
316289
* @type {Boolean}
317-
*/
290+
*/
318291
preventAutofocus: {
319292
type: Boolean,
320293
default: false
294+
},
295+
/**
296+
* Allows a custom function for sorting search/filtered results.
297+
* @default null
298+
* @type {Function}
299+
*/
300+
filteringSortFunc: {
301+
type: Function,
302+
default: null
321303
}
322304
},
323305
mounted () {
@@ -349,7 +331,7 @@ export default {
349331
if (this.internalSearch) {
350332
options = this.groupValues
351333
? this.filterAndFlat(options, normalizedSearch, this.label)
352-
: filterOptions(options, normalizedSearch, this.label, this.customLabel)
334+
: this.filterOptions(options, normalizedSearch, this.label, this.customLabel)
353335
} else {
354336
options = this.groupValues ? flattenOptions(this.groupValues, this.groupLabel)(options) : options
355337
}
@@ -423,7 +405,7 @@ export default {
423405
*/
424406
filterAndFlat (options, search, label) {
425407
return flow(
426-
filterGroups(search, label, this.groupValues, this.groupLabel, this.customLabel),
408+
this.filterGroups(search, label, this.groupValues, this.groupLabel, this.customLabel),
427409
flattenOptions(this.groupValues, this.groupLabel)
428410
)(options)
429411
},
@@ -723,6 +705,51 @@ export default {
723705
this.preferredOpenDirection = 'above'
724706
this.optimizedHeight = Math.min(spaceAbove - 40, this.maxHeight)
725707
}
708+
},
709+
/**
710+
* Filters and sorts the options ready for selection
711+
* @param {Array} options
712+
* @param {String} search
713+
* @param {String} label
714+
* @param {Function} customLabel
715+
* @returns {Array}
716+
*/
717+
filterOptions (options, search, label, customLabel) {
718+
return search
719+
? options
720+
.filter((option) => includes(customLabel(option, label), search))
721+
.sort((a, b) => {
722+
if (typeof this.filteringSortFunc === 'function') {
723+
return this.filteringSortFunc(a, b)
724+
}
725+
return customLabel(a, label).length - customLabel(b, label).length
726+
})
727+
: options
728+
},
729+
/**
730+
*
731+
* @param {String} search
732+
* @param {String} label
733+
* @param {String} values
734+
* @param {String} groupLabel
735+
* @param {function} customLabel
736+
* @returns {function(*): *}
737+
*/
738+
filterGroups (search, label, values, groupLabel, customLabel) {
739+
return (groups) => groups.map((group) => {
740+
/* istanbul ignore else */
741+
if (!group[values]) {
742+
console.warn('Options passed to vue-multiselect do not contain groups, despite the config.')
743+
return []
744+
}
745+
const groupOptions = this.filterOptions(group[values], search, label, customLabel)
746+
747+
return groupOptions.length
748+
? {
749+
[groupLabel]: group[groupLabel], [values]: groupOptions
750+
}
751+
: []
752+
})
726753
}
727754
}
728755
}

0 commit comments

Comments
 (0)