Test Fuse for fuzzy searching

This commit is contained in:
Josh Johnson 2016-05-03 14:55:38 +01:00
parent d4cf42c33e
commit c359ed3e47
4 changed files with 28 additions and 24 deletions

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@ import { createStore } from 'redux';
import rootReducer from './reducers/index.js';
import { addItem, removeItem, selectItem, addOption, filterOptions, activateOptions, addGroup } from './actions/index';
import { isScrolledIntoView, getAdjacentEl, findAncestor, wrap, isType, strToEl, extend, getWidthOfInput, debounce } from './lib/utils.js';
import Sifter from 'sifter';
import Fuse from 'fuse.js';
/**
* Choices
@ -329,28 +329,24 @@ export class Choices {
});
if(this.input === document.activeElement) {
if(this.input.value && this.input.value.length > 1) {
const options = this.getOptionsFiltedBySelectable();
const sifter = new Sifter(options);
// If we have a value, filter options based on it
const handleFilter = debounce(() => {
const results = sifter.search(this.input.value, {
fields: ['label', 'value'],
sort: [{field: 'label', direction: 'asc'}],
limit: 10
});
this.store.dispatch(filterOptions(results));
}, 500);
handleFilter();
if(this.input.value) {
const options = this.getOptionsFiltedBySelectable();
const fuse = new Fuse(options, {
keys: ['label', 'value'],
shouldSort: true,
include: 'score',
});
const results = fuse.search(this.input.value);
this.store.dispatch(filterOptions(results));
} else if(hasUnactiveOptions) {
// Otherwise reset options to active
this.store.dispatch(activateOptions());
}
}
}
}
} q
/**

View file

@ -9,6 +9,7 @@ const options = (state = [], action) => {
disabled: action.disabled,
selected: false,
active: true,
score: 9999,
}];
case 'ADD_ITEM':
@ -40,20 +41,26 @@ const options = (state = [], action) => {
}
case 'FILTER_OPTIONS':
const filteredResults = action.results.items;
let firstActive = false;
const newState = state.map((option, index) => {
const filteredResults = action.results;
const filteredState = state.map((option, index) => {
// Set active state based on whether option is
// within filtered results
option.active = filteredResults.some((result) => {
return result.id === index;
if(result.item.id === option.id) {
option.score = result.score;
return true;
}
});
return option;
}).sort((prev, next) => {
return prev.score - next.score;
});
return newState;
console.log(filteredState);
return filteredState;
case 'ACTIVATE_OPTIONS':
return state.map((option) => {

View file

@ -34,6 +34,7 @@
"babel-preset-stage-0": "^6.5.0",
"csso": "^1.7.0",
"eslint": "^2.4.0",
"fuse.js": "^2.2.0",
"node-sass": "^3.4.2",
"nodemon": "^1.9.1",
"opn-cli": "^3.1.0",