SearchableInput/SearchableInput.js
2025-02-27 10:21:01 -07:00

207 lines
6.9 KiB
JavaScript

$(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();
});