diff --git a/app/frontend/controllers/accessible_autocomplete_controller.js b/app/frontend/controllers/accessible_autocomplete_controller.js
index 935594529..b0ee52441 100644
--- a/app/frontend/controllers/accessible_autocomplete_controller.js
+++ b/app/frontend/controllers/accessible_autocomplete_controller.js
@@ -1,24 +1,24 @@
-import { Controller } from "@hotwired/stimulus";
-import accessibleAutocomplete from "accessible-autocomplete";
-import "accessible-autocomplete/dist/accessible-autocomplete.min.css";
-import { enhanceOption, suggestion, sort } from "../modules/search";
+import { Controller } from '@hotwired/stimulus'
+import accessibleAutocomplete from 'accessible-autocomplete'
+import 'accessible-autocomplete/dist/accessible-autocomplete.min.css'
+import { enhanceOption, suggestion, sort } from '../modules/search'
export default class extends Controller {
- connect() {
- const selectEl = this.element;
- const selectOptions = Array.from(selectEl.options);
- const options = selectOptions.map((o) => enhanceOption(o));
+ connect () {
+ const selectEl = this.element
+ const selectOptions = Array.from(selectEl.options)
+ const options = selectOptions.map((o) => enhanceOption(o))
- const matches = /^(\w+)\[(\w+)\]$/.exec(selectEl.name);
- const rawFieldName = `${matches[1]}[${matches[2]}_raw]`;
+ const matches = /^(\w+)\[(\w+)\]$/.exec(selectEl.name)
+ const rawFieldName = `${matches[1]}[${matches[2]}_raw]`
accessibleAutocomplete.enhanceSelectElement({
- defaultValue: "",
+ defaultValue: '',
selectElement: selectEl,
minLength: 2,
source: (query, populateResults) => {
if (/\S/.test(query)) {
- populateResults(sort(query, options));
+ populateResults(sort(query, options))
}
},
autoselect: true,
@@ -28,9 +28,9 @@ export default class extends Controller {
const selectedOption = [].filter.call(
selectOptions,
(option) => (option.textContent || option.innerText) === val
- )[0];
- if (selectedOption) selectedOption.selected = true;
- },
- });
+ )[0]
+ if (selectedOption) selectedOption.selected = true
+ }
+ })
}
}
diff --git a/app/frontend/modules/search.js b/app/frontend/modules/search.js
index 91966be9a..d9d233ab1 100644
--- a/app/frontend/modules/search.js
+++ b/app/frontend/modules/search.js
@@ -1,106 +1,106 @@
const addWeightWithBoost = (option, query) => {
- option.weight = calculateWeight(option.clean, query) * option.clean.boost;
+ option.weight = calculateWeight(option.clean, query) * option.clean.boost
- return option;
-};
+ return option
+}
const clean = (text) =>
text
.trim()
- .replace(/['’]/g, "")
- .replace(/[.,"/#!$%^&*;:{}=\-_`~()]/g, " ")
- .toLowerCase();
+ .replace(/['’]/g, '')
+ .replace(/[.,"/#!$%^&*;:{}=\-_`~()]/g, ' ')
+ .toLowerCase()
const cleanseOption = (option) => {
option.clean = {
name: clean(option.name),
nameWithoutStopWords: removeStopWords(option.name),
- boost: option.boost || 1,
- };
+ boost: option.boost || 1
+ }
- return option;
-};
+ return option
+}
-const hasWeight = (option) => option.weight > 0;
+const hasWeight = (option) => option.weight > 0
const byWeightThenAlphabetically = (a, b) => {
- if (a.weight > b.weight) return -1;
- if (a.weight < b.weight) return 1;
- if (a.name < b.name) return -1;
- if (a.name > b.name) return 1;
+ if (a.weight > b.weight) return -1
+ if (a.weight < b.weight) return 1
+ if (a.name < b.name) return -1
+ if (a.name > b.name) return 1
- return 0;
-};
+ return 0
+}
-const optionName = (option) => option.name;
-const exactMatch = (word, query) => word === query;
+const optionName = (option) => option.name
+const exactMatch = (word, query) => word === query
-const startsWithRegExp = (query) => new RegExp("\\b" + query, "i");
-const startsWith = (word, query) => word.search(startsWithRegExp(query)) === 0;
+const startsWithRegExp = (query) => new RegExp('\\b' + query, 'i')
+const startsWith = (word, query) => word.search(startsWithRegExp(query)) === 0
const wordsStartsWithQuery = (word, regExps) =>
- regExps.every((regExp) => word.search(regExp) >= 0);
+ regExps.every((regExp) => word.search(regExp) >= 0)
const calculateWeight = ({ name, nameWithoutStopWords }, query) => {
- const queryWithoutStopWords = removeStopWords(query);
+ const queryWithoutStopWords = removeStopWords(query)
- if (exactMatch(name, query)) return 100;
- if (exactMatch(nameWithoutStopWords, queryWithoutStopWords)) return 95;
+ if (exactMatch(name, query)) return 100
+ if (exactMatch(nameWithoutStopWords, queryWithoutStopWords)) return 95
- if (startsWith(name, query)) return 60;
- if (startsWith(nameWithoutStopWords, queryWithoutStopWords)) return 55;
+ if (startsWith(name, query)) return 60
+ if (startsWith(nameWithoutStopWords, queryWithoutStopWords)) return 55
const startsWithRegExps = queryWithoutStopWords
.split(/\s+/)
- .map(startsWithRegExp);
+ .map(startsWithRegExp)
- if (wordsStartsWithQuery(nameWithoutStopWords, startsWithRegExps)) return 25;
+ if (wordsStartsWithQuery(nameWithoutStopWords, startsWithRegExps)) return 25
- return 0;
-};
+ return 0
+}
-const stopWords = ["the", "of", "in", "and", "at", "&"];
+const stopWords = ['the', 'of', 'in', 'and', 'at', '&']
const removeStopWords = (text) => {
const isAllStopWords = text
.trim()
- .split(" ")
- .every((word) => stopWords.includes(word));
+ .split(' ')
+ .every((word) => stopWords.includes(word))
if (isAllStopWords) {
- return text;
+ return text
}
const regex = new RegExp(
- stopWords.map((word) => `(\\s+)?${word}(\\s+)?`).join("|"),
- "gi"
- );
- return text.replace(regex, " ").trim();
-};
+ stopWords.map((word) => `(\\s+)?${word}(\\s+)?`).join('|'),
+ 'gi'
+ )
+ return text.replace(regex, ' ').trim()
+}
export const sort = (query, options) => {
- const cleanQuery = clean(query);
+ const cleanQuery = clean(query)
return options
.map(cleanseOption)
.map((option) => addWeightWithBoost(option, cleanQuery))
.filter(hasWeight)
.sort(byWeightThenAlphabetically)
- .map(optionName);
-};
+ .map(optionName)
+}
export const suggestion = (value, options) => {
- const option = options.find((o) => o.name === value);
+ const option = options.find((o) => o.name === value)
if (option) {
- const html = `${value}`;
- return html;
+ const html = `${value}`
+ return html
} else {
- return `No results found`;
+ return 'No results found'
}
-};
+}
export const enhanceOption = (option) => {
return {
name: option.label,
- boost: parseFloat(option.getAttribute("data-boost")) || 1,
- };
-};
+ boost: parseFloat(option.getAttribute('data-boost')) || 1
+ }
+}