Initial commit
This commit is contained in:
parent
20dce6b87a
commit
4118252037
37
SearchableInput.css
Normal file
37
SearchableInput.css
Normal file
@ -0,0 +1,37 @@
|
||||
div.searchable-input input
|
||||
{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.searchable-input div.items
|
||||
{
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
border: 1px solid #aaa;
|
||||
/*border-top: 0;*/
|
||||
max-width: 100%;
|
||||
max-height: 10em;
|
||||
overflow-x: scroll;
|
||||
overflow-y: scroll;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.searchable-input div.item
|
||||
{
|
||||
white-space: normal;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
div.searchable-input div.item:hover
|
||||
{
|
||||
/*background: #0af;
|
||||
color: #fff;*/
|
||||
background: highlight;
|
||||
color: highlighttext;
|
||||
cursor: pointer;
|
||||
}
|
206
SearchableInput.js
Normal file
206
SearchableInput.js
Normal file
@ -0,0 +1,206 @@
|
||||
$(function() {
|
||||
SearchableInput = {};
|
||||
|
||||
SearchableInput.initItems = function()
|
||||
{
|
||||
var items = $("div.searchable-input div.item");
|
||||
|
||||
items.each(function(i, x) {
|
||||
x = $(x);
|
||||
|
||||
var parent = x.parents("div.searchable-input").first();
|
||||
var input = parent.find("input").first();
|
||||
var item = x;
|
||||
var itemContainer = parent.find("div.items").first();
|
||||
|
||||
if (item.is("[onclick]"))
|
||||
return;
|
||||
|
||||
if (!item.is("[data-value]"))
|
||||
return;
|
||||
|
||||
item.unbind("mousedown");
|
||||
item.bind("mousedown", function() {
|
||||
input.attr("data-value", item.attr("data-value"));
|
||||
input.val(item.text().trim());
|
||||
itemContainer.hide();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SearchableInput.init = function()
|
||||
{
|
||||
$("div.searchable-input input").each(function(i, x) {
|
||||
x = $(x);
|
||||
|
||||
var parent = x.parents("div.searchable-input").first();
|
||||
var backgroundColor = null;
|
||||
var selectColor = null;
|
||||
var input = x;
|
||||
var itemContainer = parent.find("div.items").first();
|
||||
var items = itemContainer.find("div.item");
|
||||
var strictSearch = parent.attr("strict-search");
|
||||
|
||||
// Get first opaque body color:
|
||||
parent.parents("*").each(function(i, x) {
|
||||
if (backgroundColor !== null)
|
||||
return;
|
||||
|
||||
x = $(x);
|
||||
var color = x.css("backgroundColor");
|
||||
|
||||
if (/^rgba/.test(color))
|
||||
{
|
||||
var alphaPart = parseFloat(color.split(",")[3]);
|
||||
|
||||
if (isNaN(alphaPart))
|
||||
return;
|
||||
|
||||
if (alphaPart > 0.9)
|
||||
backgroundColor = color;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (/^rgb/.test(color))
|
||||
backgroundColor = color;
|
||||
});
|
||||
|
||||
itemContainer.hide();
|
||||
|
||||
x.unbind("blur");
|
||||
x.bind("blur", function() {
|
||||
setTimeout(function() {
|
||||
itemContainer.hide();
|
||||
|
||||
if (input.val().trim().length < 1)
|
||||
input.attr("data-value", null);
|
||||
}, 10);
|
||||
});
|
||||
|
||||
x.unbind("input");
|
||||
x.bind("input", function() {
|
||||
|
||||
var fnOnInputCooldown = function(itemContainer)
|
||||
{
|
||||
var parent = itemContainer.parents("div.searchable-input").first();
|
||||
var input = parent.find("input").first();
|
||||
var items = itemContainer.find("div.item");
|
||||
var searchTermsString = input.val().toLowerCase().trim();
|
||||
var searchTerms = searchTermsString.split(" ");
|
||||
|
||||
items.hide();
|
||||
|
||||
items.each(function(i, x) {
|
||||
x = $(x);
|
||||
|
||||
var item = x;
|
||||
var pass = 1;
|
||||
var itemText = item.text().toLowerCase().trim();
|
||||
|
||||
if (strictSearch)
|
||||
{
|
||||
if (itemText.includes(searchTermsString))
|
||||
item.show();
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < searchTerms.length; i++)
|
||||
{
|
||||
var searchTerm = searchTerms[i];
|
||||
if (searchTerm.length < 1)
|
||||
continue;
|
||||
if (!itemText.includes(searchTerm))
|
||||
pass = 0;
|
||||
}
|
||||
|
||||
//item.hide();
|
||||
|
||||
if (pass == 1)
|
||||
item.show();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var dataSourceApi = itemContainer.attr("data-source-api");
|
||||
|
||||
if (dataSourceApi)
|
||||
{
|
||||
if (typeof(SearchableInput.timeout) !== "undefined")
|
||||
clearTimeout(SearchableInput.timeout);
|
||||
|
||||
SearchableInput.timeout = setTimeout(function() {
|
||||
var searchTermsString = input.val().toLowerCase().trim();
|
||||
|
||||
console.log(dataSourceApi);
|
||||
|
||||
$.get({
|
||||
url: `${dataSourceApi}?q=${searchTermsString}`,
|
||||
//url: `${dataSourceApi}`,
|
||||
method: "get",
|
||||
success: function(data)
|
||||
{
|
||||
console.log(data);
|
||||
itemContainer.html("");
|
||||
|
||||
for (var i = 0; i < data.length; i++)
|
||||
{
|
||||
var item = data[i];
|
||||
var itemElement = $("<div></div>");
|
||||
|
||||
itemElement.addClass("item");
|
||||
itemElement.attr("data-value", item.value);
|
||||
itemElement.html(item.name);
|
||||
|
||||
itemContainer.append(itemElement);
|
||||
}
|
||||
|
||||
SearchableInput.initItems();
|
||||
|
||||
fnOnInputCooldown(itemContainer);
|
||||
},
|
||||
error: function(xhr, e, m)
|
||||
{
|
||||
console.log(e);
|
||||
console.log(m);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
fnOnInputCooldown(itemContainer);
|
||||
});
|
||||
|
||||
x.unbind("focus");
|
||||
x.bind("focus", function() {
|
||||
//x.trigger("input");
|
||||
|
||||
itemContainer.css("width", parent.width() + "px");
|
||||
itemContainer.css("background", backgroundColor);
|
||||
|
||||
// If data-source is a valid jQuery selector, use that container's innerHTML:
|
||||
var dataSource = itemContainer.attr("data-source");
|
||||
|
||||
if (dataSource)
|
||||
{
|
||||
var dataSourceObject = $(dataSource);
|
||||
if (dataSourceObject.length > 0)
|
||||
{
|
||||
itemContainer.html(dataSourceObject.first().html());
|
||||
//SearchableInput.init();
|
||||
SearchableInput.initItems();
|
||||
}
|
||||
}
|
||||
|
||||
itemContainer.show();
|
||||
items.show();
|
||||
input.select();
|
||||
|
||||
});
|
||||
|
||||
SearchableInput.initItems();
|
||||
});
|
||||
};
|
||||
|
||||
SearchableInput.init();
|
||||
});
|
8
data.json
Normal file
8
data.json
Normal file
@ -0,0 +1,8 @@
|
||||
[
|
||||
{"name": "Item 1", "value": 0},
|
||||
{"name": "Item 2", "value": 1},
|
||||
{"name": "Item 3", "value": 2},
|
||||
{"name": "Item 4", "value": 3},
|
||||
{"name": "Item 5", "value": 4},
|
||||
{"name": "Item 6", "value": 5}
|
||||
]
|
140
index.html
Normal file
140
index.html
Normal file
@ -0,0 +1,140 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<!-- Page styles unrelated to SearchableInput -->
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #aaa;
|
||||
}
|
||||
|
||||
.document {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 1024px;
|
||||
background: #fff;
|
||||
padding: 0.25in;
|
||||
}
|
||||
|
||||
.w-25 { width: 25%; }
|
||||
</style>
|
||||
|
||||
<!-- jQuery is required! -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||
|
||||
<!-- Importing the CSS and JS -->
|
||||
<link rel="stylesheet" href="SearchableInput.css" />
|
||||
<script src="SearchableInput.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="data-source" style="display: none;">
|
||||
<!-- Examples:
|
||||
<div class="item" data-value="0">Item 1</div>
|
||||
<div class="item" data-value="1">Item 1</div>
|
||||
<div class="item" data-value="2">Item 1</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<table class="w-100">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Selection 1</td>
|
||||
<td>
|
||||
<div class="searchable-input" strict-search="1">
|
||||
<input type="text" />
|
||||
<div class="items" data-source="#data-source"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Selection 2</td>
|
||||
<td>
|
||||
<div class="searchable-input" strict-search="1">
|
||||
<input type="text" />
|
||||
<div class="items" data-source="#data-source"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Selection 3</td>
|
||||
<td>
|
||||
<div class="searchable-input" strict-search="1">
|
||||
<input type="text" />
|
||||
<div class="items" data-source="#data-source"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Selection 4</td>
|
||||
<td>
|
||||
<div class="searchable-input" strict-search="1">
|
||||
<input type="text" />
|
||||
<div class="items" data-source="#data-source"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Selection 5</td>
|
||||
<td>
|
||||
<div class="searchable-input">
|
||||
<input type="text" />
|
||||
<div class="items" data-source-api="data.json"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
|
||||
fnChooseRandom = function(arr)
|
||||
{
|
||||
var min = 0;
|
||||
var max = arr.length;
|
||||
var i = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
return arr[i];
|
||||
};
|
||||
|
||||
var nouns = ["dog", "cat", "parrot", "fish"];
|
||||
var colors = ["red", "yellow", "green", "blue"];
|
||||
var id = 0;
|
||||
|
||||
nouns.forEach(function(n1) {
|
||||
colors.forEach(function(c1) {
|
||||
|
||||
var elem = $("<div></div>");
|
||||
|
||||
elem.addClass("item");
|
||||
elem.attr("data-value", id);
|
||||
elem.html(`The quick ${c1} fox jumped over the lazy ${n1}`);
|
||||
|
||||
$("#data-source").first().append(elem);
|
||||
|
||||
id++;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user