I’ve been working on a new project, the front-end of which I’m coding up in ES6 with Mithril.js (using 1.0.x now after spending the better part of a day migrating from 0.2.x). I wanted to implement “search as you type” functionality, since I’m using Elasticsearch on the back-end for its full-text search capability.

Took me a bit of trial-and-error, but I came up with this mithril component that provides a simple text field that automatically fires a callback periodically (the timing is configurable)
export let SearchInputComponent = {
/**
* attributes:
* helpText - small text to display under search box
* callback - callback to be fired when timeout/minchar conditions are met
* minchars - min number of characters that must be present to begin searching
* inputId - DOM ID for input field
* @param vnode
*/
oninit: function(vnode) {
vnode.attrs = vnode.attrs || {};
// Search box caption
vnode.attrs.helpText = vnode.attrs.helpText || "Enter search text here";
//Callback to fire when user is done typing
vnode.attrs.callback = vnode.attrs.callback || function(){};
//Minimum number of characters that must be present to fire callback
this.minchars = vnode.attrs.minchars || 3;
this.timeout = vnode.attrs.timeout || 1e3; //default 1 second for input timeout
this.inputId = vnode.attrs.inputId || "searchTextInput";
this.timeref = null;
this.err = stream(false);
this.doneTyping = function(){
let searchString = $('#' + this.inputId).val();
if (this.timeref && searchString.length >= this.minchars){
this.timeref = null;
vnode.attrs.callback(searchString);
}
}.bind(this);
this.oninput = function(event){
if (this.timeref){
clearTimeout(this.timeref);
}
this.timeref = setTimeout(this.doneTyping, this.timeout);
}.bind(this);
},
view: function(vnode) {
return m("fieldset", {class: "search-input-box"}, [
m("input", {type: "text", class: "form-control", id: vnode.state.inputId,
autofocus: true, "aria-describedby": "searchHelp", oninput: vnode.state.oninput,
onblur: vnode.state.doneTyping}),
m("small", {id:"searchHelp", class: "form-text text-muted"}, vnode.attrs.helpText)
]);
}
};
Pretty basic. In my case, I wanted to avoid firing my search callback (which makes a request to my back-end search service) until a certain number of characters had been entered.
Thanks this was helpful! 🙂
LikeLike