datalist improvements - jscancer - Javascript crap (relatively small) | |
git clone git://git.codemadness.org/jscancer | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 9cbdae2212ce9443cee3d20d28d6eeb3d522db6e | |
parent 3c60e3f53de3ffe7c696d316ae627a30cdaa384e | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Sat, 15 Jul 2017 13:43:24 +0200 | |
datalist improvements | |
- add function to get the request url dynamically: this can | |
be used for example to combine fields for autocompletion. | |
- add example for remote url. | |
- for a remote request open the complete list immediately if it is | |
unchanged. | |
- remote url: allow both a list or a dict with { label: "", value: "" } | |
Diffstat: | |
M datalist/README | 7 ++++--- | |
M datalist/datalist.js | 66 +++++++++++++++++++++--------… | |
M datalist/example.html | 10 ++++++++++ | |
3 files changed, 60 insertions(+), 23 deletions(-) | |
--- | |
diff --git a/datalist/README b/datalist/README | |
@@ -8,10 +8,11 @@ FEATURES | |
-------- | |
- Small: | |
- - Filesize: +- 6.7KB. | |
- - Lines: +- 235, not much code, so hopefully easy to understand. | |
+ - Filesize: +- 7.2KB. | |
+ - Lines: +- 250, not much code, so hopefully easy to understand. | |
- No dependencies on other libraries like jQuery. | |
-- (Graceful) fallback to HTML5 datalist if Javascript is disabled. | |
+- (Graceful) fallback to HTML5 datalist if Javascript is disabled for inline | |
+ datalist. | |
- Filtering values: case-insensitively, tokenized (separated by space). | |
- Supports querying a remote server for results using a JSON XMLHttpRequest. | |
- Permissive ISC license, see LICENSE file, feel free to contact me for | |
diff --git a/datalist/datalist.js b/datalist/datalist.js | |
@@ -9,34 +9,54 @@ function datalist_init(input) { | |
dropdown = document.createElement("div"), | |
prevmatches = [], | |
prevvalue = null, | |
- url = input.getAttribute("data-url") || ""; | |
+ url = input.getAttribute("data-url") || "", | |
+ urlfn = input.getAttribute("data-urlfn") || ""; | |
dropdown.className = "datalist-dropdown"; | |
+ var getvalue = function(el) { | |
+ return el.getAttribute("data-value") || | |
+ el.textContent || el.innerText; | |
+ }; | |
+ | |
var createitem = function(s) { | |
- var div = document.createElement("div"); | |
- div.innerHTML = s; | |
+ var label, value, div = document.createElement("div"); | |
+ if (typeof(s) === "string") { | |
+ label = value = s; | |
+ } else { | |
+ label = s.label; | |
+ value = s.value; | |
+ } | |
+ | |
+ div.innerHTML = label; | |
+ div.setAttribute("data-value", value); | |
div.addEventListener("mousedown", function() { | |
- input.value = this.textContent || this.innerText; | |
+ input.value = getvalue(this); | |
datalist_show(false); | |
}, false); | |
div.addEventListener("mousemove", function() { | |
if (mouse) | |
datalist_setsel(this); | |
}, false); | |
- return { el: div, search: ((div.textContent || div.innerText).… | |
+ return { el: div, label: label, value: value }; | |
}; | |
- if (url.length) { | |
+ if (url.length || urlfn.length) { | |
+ urlfn = urlfn.length ? window[urlfn] : function(s) { | |
+ return url + encodeURIComponent(s); | |
+ }; | |
+ | |
// "throttled" JSON XMLHttpRequest. | |
- var timer = null; | |
- datalist_match = function(s, fn) { | |
+ var timer = null, prevurl = ""; | |
+ datalist_match = function(s, fn, ev) { | |
clearTimeout(timer); | |
+ | |
+ url = urlfn(s); | |
+ if (url === prevurl) { | |
+ fn(prevmatches); | |
+ return; | |
+ } | |
+ | |
timer = setTimeout(function() { | |
- s = s.toLowerCase(); | |
- if (s === prevvalue) { | |
- fn(prevmatches); | |
- return; | |
- } | |
var x = new(XMLHttpRequest); | |
x.onreadystatechange = function() { | |
if (x.readyState != 4 || [ 0, 200 ].in… | |
@@ -47,21 +67,26 @@ function datalist_init(input) { | |
for (var i = 0; i < o.length; i++) | |
prevmatches.push(createitem(o[… | |
- prevvalue = s; | |
+ prevurl = url; | |
fn(prevmatches); | |
}; | |
- x.open("GET", url + encodeURIComponent(s) + "&… | |
+ | |
+ x.open("GET", url + "&t=" + String(new Date().… | |
x.setRequestHeader("X-Requested-With", "XMLHtt… | |
x.timeout = 10000; | |
x.send(); | |
- }, 150); // delay in ms. | |
+ // delay in ms: throttle request on change, bu… | |
+ }, ev == "onchange" ? 150 : 1); | |
}; | |
} else { | |
// use inline <datalist>. | |
if (attrlist === null || ellist === undefined) | |
return; | |
- for (var i = 0, ec = ellist.children; i < ec.length; i++) | |
- items.push(createitem(ec[i].innerHTML)); | |
+ for (var i = 0, ec = ellist.children, o; i < ec.length; i++) { | |
+ var o = createitem(getvalue(ec[i])); | |
+ o.search = o.label.toLowerCase().split(" "); | |
+ items.push(o); | |
+ } | |
var datalist_filter = function(data, s) { | |
var matches = [], tok = s.toLowerCase().split(" "); | |
@@ -89,6 +114,7 @@ function datalist_init(input) { | |
fn(prevmatches); | |
return; | |
} | |
+ | |
// if token string is different or string not in previ… | |
// else filter on existing data and no need to sort. | |
if (prevvalue === null || (prevvalue.split(" ").length… | |
@@ -131,7 +157,7 @@ function datalist_init(input) { | |
switch (e.which) { | |
case 13: // return | |
if (cursel) | |
- input.value = cursel.textContent || cursel.inn… | |
+ input.value = getvalue(cursel); | |
if (!datalist_visible) | |
return; | |
datalist_show(false); | |
@@ -195,7 +221,7 @@ function datalist_init(input) { | |
datalist_setsel(m[0].el); | |
datalist_render(m); | |
datalist_show(!!m.length); | |
- }); | |
+ }, "onchange"); | |
}; | |
input.addEventListener("input", onchange); | |
input.addEventListener("keyup", function(e) { | |
diff --git a/datalist/example.html b/datalist/example.html | |
@@ -32,8 +32,18 @@ | |
<label for="remote">OS: </label> | |
<input type="text" placeholder="Select OS..." value="" data-url="example-data.… | |
+<p>Using XMLHttpRequest + custom url function + JSON:</p> | |
+ | |
+<label for="remotecustom">OS: </label> | |
+<input type="text" placeholder="Select OS..." value="" data-urlfn="custom_urlf… | |
+ | |
</form> | |
+<script type="text/javascript"> | |
+function custom_urlfn(s) { | |
+ return "example-data.json?q=" + encodeURIComponent(s); | |
+}; | |
+</script> | |
<script type="text/javascript" src="datalist.js"></script> | |
</body> |