mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-23 03:59:30 -07:00
autocomplete working
This commit is contained in:
@@ -2,8 +2,7 @@
|
|||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"node": true,
|
"node": true
|
||||||
"jquery": true
|
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"airbnb-base"
|
"airbnb-base"
|
||||||
@@ -12,7 +11,8 @@
|
|||||||
"TravelCities": "readonly",
|
"TravelCities": "readonly",
|
||||||
"RegionalCities": "readonly",
|
"RegionalCities": "readonly",
|
||||||
"StationInfo": "readonly",
|
"StationInfo": "readonly",
|
||||||
"SunCalc": "readonly"
|
"SunCalc": "readonly",
|
||||||
|
"NoSleep": "readonly"
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2023,
|
"ecmaVersion": 2023,
|
||||||
|
|||||||
@@ -37,8 +37,6 @@
|
|||||||
"gulp-s3-upload": "^1.7.3",
|
"gulp-s3-upload": "^1.7.3",
|
||||||
"gulp-sass": "^6.0.0",
|
"gulp-sass": "^6.0.0",
|
||||||
"gulp-terser": "^2.0.0",
|
"gulp-terser": "^2.0.0",
|
||||||
"jquery": "^3.6.0",
|
|
||||||
"jquery-touchswipe": "^1.6.19",
|
|
||||||
"luxon": "^3.0.0",
|
"luxon": "^3.0.0",
|
||||||
"nosleep.js": "^0.12.0",
|
"nosleep.js": "^0.12.0",
|
||||||
"sass": "^1.54.0",
|
"sass": "^1.54.0",
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
rules: {
|
|
||||||
// unicorn
|
|
||||||
'unicorn/numeric-separators-style': 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -50,8 +50,7 @@ const init = () => {
|
|||||||
window.addEventListener('resize', fullScreenResizeCheck);
|
window.addEventListener('resize', fullScreenResizeCheck);
|
||||||
fullScreenResizeCheck.wasFull = false;
|
fullScreenResizeCheck.wasFull = false;
|
||||||
|
|
||||||
document.querySelector(TXT_ADDRESS_SELECTOR).addEventListener('keydown', (key) => { if (key.code === 'Enter') formSubmit(); });
|
document.querySelector('#btnGetLatLng').addEventListener('click', () => autoComplete.directFormSubmit());
|
||||||
document.querySelector('#btnGetLatLng').addEventListener('click', () => formSubmit());
|
|
||||||
|
|
||||||
document.addEventListener('keydown', documentKeydown);
|
document.addEventListener('keydown', documentKeydown);
|
||||||
document.addEventListener('touchmove', (e) => { if (document.fullscreenElement) e.preventDefault(); });
|
document.addEventListener('touchmove', (e) => { if (document.fullscreenElement) e.preventDefault(); });
|
||||||
@@ -80,11 +79,6 @@ const init = () => {
|
|||||||
width: 490,
|
width: 490,
|
||||||
});
|
});
|
||||||
|
|
||||||
const formSubmit = () => {
|
|
||||||
if (autoComplete.suggestions[0]) autoComplete.suggestionsContainer.children[0].trigger('click');
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// attempt to parse the url parameters
|
// attempt to parse the url parameters
|
||||||
const parsedParameters = parseQueryString();
|
const parsedParameters = parseQueryString();
|
||||||
|
|
||||||
|
|||||||
@@ -9,16 +9,17 @@ const KEYS = {
|
|||||||
UP: 38,
|
UP: 38,
|
||||||
RIGHT: 39,
|
RIGHT: 39,
|
||||||
DOWN: 40,
|
DOWN: 40,
|
||||||
|
ENTER: 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_OPTIONS = {
|
const DEFAULT_OPTIONS = {
|
||||||
autoSelectFirst: false,
|
autoSelectFirst: false,
|
||||||
serviceUrl: null,
|
serviceUrl: null,
|
||||||
lookup: null,
|
lookup: null,
|
||||||
onSelect: null,
|
onSelect: () => { },
|
||||||
onHint: null,
|
onHint: null,
|
||||||
width: 'auto',
|
width: 'auto',
|
||||||
minChars: 1,
|
minChars: 3,
|
||||||
maxHeight: 300,
|
maxHeight: 300,
|
||||||
deferRequestBy: 0,
|
deferRequestBy: 0,
|
||||||
params: {},
|
params: {},
|
||||||
@@ -85,8 +86,11 @@ class AutoComplete {
|
|||||||
this.results = results;
|
this.results = results;
|
||||||
this.elem.after(results);
|
this.elem.after(results);
|
||||||
|
|
||||||
// add handlers for typing text
|
// add handlers for typing text and submitting the form
|
||||||
this.elem.addEventListener('keyup', (e) => this.keyUp(e));
|
this.elem.addEventListener('keyup', (e) => this.keyUp(e));
|
||||||
|
this.elem.closest('form')?.addEventListener('submit', (e) => this.directFormSubmit(e));
|
||||||
|
this.elem.addEventListener('click', () => this.deselectAll());
|
||||||
|
this.elem.addEventListener('focusout', () => this.hideSuggestions());
|
||||||
}
|
}
|
||||||
|
|
||||||
mouseOver(e) {
|
mouseOver(e) {
|
||||||
@@ -129,14 +133,29 @@ class AutoComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keyUp(e) {
|
keyUp(e) {
|
||||||
// ignore some keys
|
// reset the change timeout
|
||||||
|
clearTimeout(this.onChangeTimeout);
|
||||||
|
|
||||||
|
// up/down direction
|
||||||
switch (e.which) {
|
switch (e.which) {
|
||||||
case KEYS.UP:
|
case KEYS.UP:
|
||||||
case KEYS.DOWN:
|
case KEYS.DOWN:
|
||||||
|
// move up or down the selection list
|
||||||
|
this.keySelect(e.which);
|
||||||
|
return;
|
||||||
|
case KEYS.ENTER:
|
||||||
|
// if the text entry field is active call direct form submit
|
||||||
|
// if there is a suggestion highlighted call the click function on that element
|
||||||
|
if (this.getSelected() !== undefined) {
|
||||||
|
this.click({ target: this.results.querySelector('.suggestion.selected') });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (document.activeElement.id === this.elem.id) {
|
||||||
|
// call the direct submit routine
|
||||||
|
this.directFormSubmit();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTimeout(this.onChangeTimeout);
|
|
||||||
|
|
||||||
if (this.currentValue !== this.elem.value) {
|
if (this.currentValue !== this.elem.value) {
|
||||||
if (this.options.deferRequestBy > 0) {
|
if (this.options.deferRequestBy > 0) {
|
||||||
@@ -169,7 +188,7 @@ class AutoComplete {
|
|||||||
this.getSuggestions(this.currentValue);
|
this.getSuggestions(this.currentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSuggestions(search) {
|
async getSuggestions(search, skipHtml = false) {
|
||||||
// assemble options
|
// assemble options
|
||||||
const searchOptions = { ...this.options.params };
|
const searchOptions = { ...this.options.params };
|
||||||
searchOptions[this.options.paramName] = search;
|
searchOptions[this.options.paramName] = search;
|
||||||
@@ -190,9 +209,11 @@ class AutoComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// store suggestions
|
// store suggestions
|
||||||
this.cachedResponses[search] = result.suggestions;
|
this.cachedResponses[search] = result;
|
||||||
this.suggestions = result.suggestions;
|
this.suggestions = result.suggestions;
|
||||||
|
|
||||||
|
if (skipHtml) return;
|
||||||
|
|
||||||
// populate the suggestion area
|
// populate the suggestion area
|
||||||
this.populateSuggestions();
|
this.populateSuggestions();
|
||||||
}
|
}
|
||||||
@@ -224,6 +245,63 @@ class AutoComplete {
|
|||||||
this.results.innerHTML = `<div>${this.options.noSuggestionNotice}</div>`;
|
this.results.innerHTML = `<div>${this.options.noSuggestionNotice}</div>`;
|
||||||
this.showSuggestions();
|
this.showSuggestions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the submit button has been pressed and we'll just use the first suggestion found
|
||||||
|
async directFormSubmit() {
|
||||||
|
// check for minimum length
|
||||||
|
if (this.currentValue.length < this.options.minChars) return;
|
||||||
|
await this.getSuggestions(this.elem.value, true);
|
||||||
|
const suggestion = this.suggestions?.[0];
|
||||||
|
if (suggestion) {
|
||||||
|
this.options.onSelect(suggestion);
|
||||||
|
this.elem.value = suggestion.value;
|
||||||
|
this.hideSuggestions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the index of the selected item in suggestions
|
||||||
|
getSelected() {
|
||||||
|
const index = this.results.querySelector('.selected')?.dataset?.item;
|
||||||
|
if (index !== undefined) return parseInt(index, 10);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move the selection highlight up or down
|
||||||
|
keySelect(key) {
|
||||||
|
// if the suggestions are hidden do nothing
|
||||||
|
if (this.results.style.display === 'none') return;
|
||||||
|
// if there are no suggestions do nothing
|
||||||
|
if (this.suggestions.length <= 0) return;
|
||||||
|
|
||||||
|
// get the currently selected index (or default to off the top of the list)
|
||||||
|
let index = this.getSelected();
|
||||||
|
|
||||||
|
// adjust the index per the key
|
||||||
|
// and include defaults in case no index is selected
|
||||||
|
switch (key) {
|
||||||
|
case KEYS.UP:
|
||||||
|
index = (index ?? 0) - 1;
|
||||||
|
break;
|
||||||
|
case KEYS.DOWN:
|
||||||
|
index = (index ?? -1) + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap the index (and account for negative)
|
||||||
|
index = ((index % this.suggestions.length) + this.suggestions.length) % this.suggestions.length;
|
||||||
|
|
||||||
|
// set this index
|
||||||
|
this.deselectAll();
|
||||||
|
this.mouseOver({
|
||||||
|
target: this.results.querySelectorAll('.suggestion')[index],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deselectAll() {
|
||||||
|
// clear other selected indexes
|
||||||
|
[...this.results.querySelectorAll('.suggestion.selected')].forEach((elem) => elem.classList.remove('selected'));
|
||||||
|
this.selectedItem = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AutoComplete;
|
export default AutoComplete;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,8 +26,6 @@
|
|||||||
<script type="text/javascript" src="resources/ws.min.js?_=<%=production%>"></script>
|
<script type="text/javascript" src="resources/ws.min.js?_=<%=production%>"></script>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<link rel="stylesheet" type="text/css" href="styles/main.css" />
|
<link rel="stylesheet" type="text/css" href="styles/main.css" />
|
||||||
<script type="text/javascript" src="scripts/vendor/auto/jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="scripts/vendor/jquery.autocomplete.min.js"></script>
|
|
||||||
<script type="text/javascript" src="scripts/vendor/auto/nosleep.js"></script>
|
<script type="text/javascript" src="scripts/vendor/auto/nosleep.js"></script>
|
||||||
<script type="text/javascript" src="scripts/vendor/auto/swiped-events.js"></script>
|
<script type="text/javascript" src="scripts/vendor/auto/swiped-events.js"></script>
|
||||||
<script type="text/javascript" src="scripts/vendor/auto/suncalc.js"></script>
|
<script type="text/javascript" src="scripts/vendor/auto/suncalc.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user