Uses Fuse.js fuzzy search to filter municipalities
Instead of using naive string search to filter the muncipalities we can use the fuzzy search library Fuse.js to filter them. This way incorrect spelling of municipality names won't stop the user from getting the results she is looking for. Fuse.js http://fusejs.io/ contains no dependencies and is quite light weight. This makes it a good library for such a simple site. Signed-off-by: Snorre Magnus Davøen <snorremd@gmail.com>
This commit is contained in:
parent
0030a6e001
commit
068db211d5
|
@ -9,6 +9,7 @@
|
|||
"@types/query-string": "^4.3.1",
|
||||
"@types/react": "^15.0.37",
|
||||
"@types/react-dom": "^15.5.1",
|
||||
"fuse.js": "^3.0.5",
|
||||
"gh-pages": "^1.0.0",
|
||||
"inuitcss": "^6.0.0-beta.5",
|
||||
"node-sass-chokidar": "^0.0.3",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as React from 'react'
|
||||
import * as queryString from 'query-string'
|
||||
import * as Fuse from 'fuse.js'
|
||||
import {
|
||||
municipalities as municipalitiesData,
|
||||
Municipality
|
||||
|
@ -9,6 +10,7 @@ import { MunicipalityCard } from './MunicipalityCard'
|
|||
interface State {
|
||||
filterText: string
|
||||
filterByResource: boolean
|
||||
municipalities: any
|
||||
}
|
||||
|
||||
export default class MunicipalityList extends React.Component<any, State> {
|
||||
|
@ -21,44 +23,47 @@ export default class MunicipalityList extends React.Component<any, State> {
|
|||
super()
|
||||
const stateTemplate = {
|
||||
filterText: '',
|
||||
filterByResource: false
|
||||
filterByResource: false,
|
||||
}
|
||||
this.state = Object.assign(
|
||||
stateTemplate,
|
||||
// parse url to see if state has been persisted there
|
||||
queryString.parse(window.location.hash)
|
||||
queryString.parse(window.location.hash),
|
||||
{
|
||||
municipalities: new Fuse(municipalitiesData, {
|
||||
keys: ['name'],
|
||||
minMatchCharLength: 1,
|
||||
threshold: 0.5,
|
||||
location: 0,
|
||||
distance: 10,
|
||||
shouldSort: true,
|
||||
tokenize: true,
|
||||
matchAllTokens: true,
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const shouldShow = (filterText: string, muni: Municipality) =>
|
||||
JSON.stringify(muni.name)
|
||||
.toLowerCase()
|
||||
.indexOf(filterText.toLowerCase()) !== -1
|
||||
const hasLogo = (muni: Municipality) => !!muni.orgnummer
|
||||
|
||||
// copy array and sort by name
|
||||
let municipalities = municipalitiesData
|
||||
let municipalities = this.state.filterText.length > 0 ?
|
||||
this.state.municipalities.search(this.state.filterText) :
|
||||
municipalitiesData
|
||||
|
||||
municipalities = municipalities
|
||||
.slice()
|
||||
.sort((a, b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1
|
||||
}
|
||||
if (a.name > b.name) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
.reduce((acc, elem: Municipality) => {
|
||||
if (this.state.filterText && !shouldShow(this.state.filterText, elem)) {
|
||||
return acc
|
||||
}
|
||||
.reduce((acc: Array<Municipality>, elem: Municipality) => {
|
||||
if (this.state.filterByResource && !hasLogo(elem)) {
|
||||
return acc
|
||||
}
|
||||
acc.push(elem)
|
||||
return acc
|
||||
}, [] as Municipality[])
|
||||
.sort((municipalityA: Municipality, municipalityB: Municipality) => {
|
||||
return municipalityA.name.localeCompare(municipalityB.name)
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -86,7 +91,7 @@ export default class MunicipalityList extends React.Component<any, State> {
|
|||
Antall: {municipalities.length}
|
||||
</div>
|
||||
<div className="o-layout">
|
||||
{municipalities.map(elem =>
|
||||
{municipalities.map((elem: Municipality) =>
|
||||
<div
|
||||
key={elem.code}
|
||||
className="o-layout__item u-1/1 u-1/3@tablet u-1/6@desktop u-1/10@wide"
|
||||
|
|
|
@ -1771,6 +1771,10 @@ function-bind@^1.0.2:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
|
||||
|
||||
fuse.js@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.0.5.tgz#b58d85878802321de94461654947b93af1086727"
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
|
|
Loading…
Reference in New Issue