Added new type ahead feature, documented it and tested it.
This commit is contained in:
parent
7c8ce52537
commit
def9a0c837
@ -805,6 +805,89 @@ class IgniteTemplate {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a special event handler to this element that invokes with the content of an input after a certain amount of time has passed after typing.
|
||||
* This function supports inputs, text area's and content editable elements.
|
||||
* @param {Function|IgniteProperty} eventCallback The callback function to be invoked when a typeAhead event occurs, it will be passed the typed value.
|
||||
* @param {Number} minCharacters Min number of characters excluding whitespace that have to be typed before this event is invoked. Default is 2.
|
||||
* @param {Number} callbackDelay The delay in miliseconds between each event callback. Default is 350.
|
||||
* @param {Boolean} callbackReset Whether or not to reset the callback delay on each keypress. Default is true. If true, type ahead only occurrs when typing has stopped.
|
||||
* @param {Boolean} enterCallback Whether or not the enter key should be considered for a type ahead. Default is true.
|
||||
* @returns {IgniteTemplate} This ignite template so function calls can be chained.
|
||||
*/
|
||||
onTypeAhead(eventCallback, minCharacters = 2, callbackDelay = 350, callbackReset = true, enterCallback = true) {
|
||||
var typeAheadTimeout = null;
|
||||
|
||||
var typeAheadRunning = false;
|
||||
|
||||
var lastValue = null;
|
||||
|
||||
var typeAhead = async (target, force) => {
|
||||
var value = null;
|
||||
|
||||
typeAheadRunning = true;
|
||||
|
||||
//Get the value from the target if we can.
|
||||
if (target instanceof HTMLElement) {
|
||||
if (target.tagName == "INPUT" || target.tagName == "TEXTAREA") {
|
||||
value = target.value;
|
||||
} else if (target.contentEditable == "true") {
|
||||
value = target.innerText;
|
||||
}
|
||||
}
|
||||
|
||||
//Trim the value if we can
|
||||
value = value?.trim();
|
||||
|
||||
//If the value has at least the min number of characters after being trimmed invoke the callback.
|
||||
if (value != null && value.length >= minCharacters && (lastValue != value || force)) {
|
||||
try {
|
||||
if (eventCallback instanceof IgniteProperty) {
|
||||
await eventCallback.value(value);
|
||||
} else if (eventCallback instanceof Function) {
|
||||
await eventCallback(value);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error occurred during type ahead callback", error);
|
||||
}
|
||||
|
||||
//Request another type ahead incase the value changed while we were waiting for the event callback to finish.
|
||||
typeAheadTimeout = setTimeout(() => typeAhead(target, false), callbackDelay);
|
||||
} else {
|
||||
typeAheadTimeout = null;
|
||||
}
|
||||
|
||||
lastValue = value;
|
||||
|
||||
typeAheadRunning = false;
|
||||
};
|
||||
|
||||
//Attach a keydown event and handle the type ahead.
|
||||
this.on("keydown", (e) => {
|
||||
//If the key was an enter key, dont allow if it's not allowed.
|
||||
if (e.key == "Enter" && !enterCallback) {
|
||||
return;
|
||||
}
|
||||
|
||||
//If callback reset is true and there's a pending type ahead, clear it.
|
||||
if (callbackReset && typeAheadTimeout && !typeAheadRunning) {
|
||||
clearTimeout(typeAheadTimeout);
|
||||
typeAheadTimeout = null;
|
||||
}
|
||||
|
||||
//Schedule a new type ahead timeout if one isn't already running.
|
||||
if (!typeAheadTimeout) {
|
||||
if (e.key == "Enter") {
|
||||
typeAheadTimeout = setTimeout(() => typeAhead(e.target, true), 0);
|
||||
} else {
|
||||
typeAheadTimeout = setTimeout(() => typeAhead(e.target, false), callbackDelay);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a CSS property to this template with a value and priority.
|
||||
* @param {String} name The name of the CSS property to set.
|
||||
|
Loading…
x
Reference in New Issue
Block a user