mirror of
https://github.com/esiur/iui.git
synced 2025-12-13 18:20:23 +00:00
i-search
This commit is contained in:
@@ -1935,7 +1935,7 @@ _:-moz-tree-row(hover), html[dir='rtl'] .autocomplete-menu, html[dir='rtl'] .sel
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input > input {
|
.input > input {
|
||||||
width: 100%;
|
width: calc(100% - 10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.input > input, .input > textarea, .select, .textbox {
|
.input > input, .input > textarea, .select, .textbox {
|
||||||
|
|||||||
@@ -115,6 +115,11 @@ export default IUI.module(
|
|||||||
|
|
||||||
async navigate(url, data, target, state, dataToQuery = true) {
|
async navigate(url, data, target, state, dataToQuery = true) {
|
||||||
|
|
||||||
|
if (this.isLoading || target?.isLoading){
|
||||||
|
console.warn("Router in loading mode.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (url == null)
|
if (url == null)
|
||||||
throw new Error("URL not specified.");
|
throw new Error("URL not specified.");
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export default IUI.module(class Target extends IUIElement {
|
|||||||
|
|
||||||
$messageElement;
|
$messageElement;
|
||||||
$progressElement;
|
$progressElement;
|
||||||
|
$loadingMode = false;
|
||||||
|
|
||||||
constructor(properties) {
|
constructor(properties) {
|
||||||
super(IUI.extend(properties, { cssClass: 'target' }));
|
super(IUI.extend(properties, { cssClass: 'target' }));
|
||||||
@@ -16,12 +17,18 @@ export default IUI.module(class Target extends IUIElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLoading(value) {
|
setLoading(value) {
|
||||||
|
this.$loadingMode = value;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
this.$loadingElement.classList.add(this.cssClass + "-loading-visible");
|
this.$loadingElement.classList.add(this.cssClass + "-loading-visible");
|
||||||
else
|
else
|
||||||
this.$loadingElement.classList.remove(this.cssClass + "-loading-visible");
|
this.$loadingElement.classList.remove(this.cssClass + "-loading-visible");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isLoading()
|
||||||
|
{
|
||||||
|
return this.$loadingMode;
|
||||||
|
}
|
||||||
|
|
||||||
async setMessage(message) {
|
async setMessage(message) {
|
||||||
await this.$messageElement.setData({ message });
|
await this.$messageElement.setData({ message });
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
this._register("select");
|
this._register("select");
|
||||||
this._register("input");
|
this._register("input");
|
||||||
this._register("add");
|
this._register("add");
|
||||||
|
|
||||||
|
//this.selected = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkValidity() {
|
_checkValidity() {
|
||||||
@@ -51,6 +53,46 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
return this.hasAttribute("add");
|
return this.hasAttribute("add");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_selectIndex(index){
|
||||||
|
let found = null;
|
||||||
|
|
||||||
|
for(let i = 0; i < this.repeat.children.length; i++)
|
||||||
|
{
|
||||||
|
let el = this.repeat.children[i];
|
||||||
|
|
||||||
|
if (i == index)
|
||||||
|
{
|
||||||
|
found = el.data;
|
||||||
|
el.classList.add(this.cssClass + "-selected");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el.classList.remove(this.cssClass + "-selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
_select(value){
|
||||||
|
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
for(let i = 0; i < this.repeat.children.length; i++)
|
||||||
|
{
|
||||||
|
let el = this.repeat.children[i];
|
||||||
|
|
||||||
|
if (el.data == value)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
el.classList.add(this.cssClass + "-selected");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el.classList.remove(this.cssClass + "-selected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async create() {
|
async create() {
|
||||||
|
|
||||||
this.isAuto = this.hasAttribute("auto");
|
this.isAuto = this.hasAttribute("auto");
|
||||||
@@ -68,10 +110,16 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
|
|
||||||
this.repeat = new Repeat();
|
this.repeat = new Repeat();
|
||||||
this.repeat.cssClass = this.cssClass + "-repeat";
|
this.repeat.cssClass = this.cssClass + "-repeat";
|
||||||
|
if (this.hasAttribute("menu")) {
|
||||||
|
let menuData = this.getAttribute("menu");
|
||||||
|
this.repeat.setAttribute(":data", menuData);// "d[1]");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.repeat.setAttribute("i-skip-data", "skip");
|
||||||
|
|
||||||
this.repeat.on("click", async (e) => {
|
this.repeat.on("click", async (e) => {
|
||||||
|
|
||||||
if (e.target !== self.repeat)
|
if (e.target == self.repeat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(let i = 0; i < self.repeat.children.length; i++)
|
for(let i = 0; i < self.repeat.children.length; i++)
|
||||||
@@ -80,10 +128,21 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
|
|
||||||
if (el.contains(e.target))
|
if (el.contains(e.target))
|
||||||
{
|
{
|
||||||
|
|
||||||
el.classList.add(self.cssClass + "-selected");
|
el.classList.add(self.cssClass + "-selected");
|
||||||
await self.setData(el.data);
|
|
||||||
self._emit("input", { value: el.data });
|
try {
|
||||||
|
self._emit("input", { value: el.data });
|
||||||
|
//self._emit("select", { value: el.data });
|
||||||
|
self._skipQuery = true;
|
||||||
|
await self.setData(el.data);
|
||||||
|
self._skipQuery = false;
|
||||||
|
|
||||||
|
//self.selected = el.data;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
el.classList.remove(self.cssClass + "-selected");
|
el.classList.remove(self.cssClass + "-selected");
|
||||||
@@ -91,8 +150,11 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let html = this.innerHTML;
|
||||||
|
|
||||||
// get repeated item
|
// get repeated item
|
||||||
this.repeat.innerHTML = this.innerHTML;
|
this.repeat.innerHTML = html;
|
||||||
|
this.innerHTML = "";
|
||||||
|
|
||||||
this.appendChild(this.repeat);
|
this.appendChild(this.repeat);
|
||||||
|
|
||||||
@@ -119,7 +181,6 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
await IUI.created(this.repeat);
|
await IUI.created(this.repeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._query();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get disabled() {
|
get disabled() {
|
||||||
@@ -153,32 +214,32 @@ export default IUI.module(class Radio extends IUIElement {
|
|||||||
if (res instanceof Promise)
|
if (res instanceof Promise)
|
||||||
res = await res;
|
res = await res;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.repeat.setData(res);
|
await this.repeat.setData(res);
|
||||||
|
|
||||||
if (this.repeat.data.length == 0)
|
//if (this.repeat.data.length == 0)
|
||||||
await self.setData(null);
|
// await self.setData(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async setData(value, radix) {
|
async setData(value, radix) {
|
||||||
|
|
||||||
// this.label.innerHTML = "";
|
|
||||||
|
|
||||||
await super.setData(value, radix);
|
await super.setData(value, radix);
|
||||||
|
|
||||||
try {
|
if (!this._skipQuery) {
|
||||||
//let text = this.formatter(value);
|
await this._query();
|
||||||
// this.label.innerHTML = text == null ? "" : text;
|
|
||||||
|
if (!this._select(value))
|
||||||
|
super.setData(this._selectIndex(0), radix);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
this._emit("select", { value });
|
this._emit("select", { value });
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
//console.log(ex);
|
|
||||||
this._emit("select", { value });
|
|
||||||
}
|
|
||||||
|
|
||||||
//this._checkValidity();
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this._checkValidity() && this.isAuto)
|
if (this._checkValidity() && this.isAuto)
|
||||||
|
|||||||
353
src/UI/Search.js
Normal file
353
src/UI/Search.js
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
import { IUI, iui } from '../Core/IUI.js';
|
||||||
|
import IUIElement from '../Core/IUIElement.js';
|
||||||
|
import Menu from '../UI/Menu.js';
|
||||||
|
import Layout from '../Data/Layout.js';
|
||||||
|
import Repeat from '../Data/Repeat.js';
|
||||||
|
|
||||||
|
export default IUI.module(class Select extends IUIElement {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
visible: false,
|
||||||
|
searchlist: false,
|
||||||
|
query: (x) => null,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._register("select");
|
||||||
|
this._register("input");
|
||||||
|
this._register("add");
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
//console.log("Select removed", this);
|
||||||
|
if (!this.searchlist && this.menu)
|
||||||
|
app.removeChild(this.menu);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback(){
|
||||||
|
super.connectedCallback();
|
||||||
|
if (!this.searchlist && this.menu)
|
||||||
|
app.appendChild(this.menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_checkValidity() {
|
||||||
|
|
||||||
|
if (this.validate != null) {
|
||||||
|
try {
|
||||||
|
let valid = this.validate.apply(this);
|
||||||
|
if (!valid) {
|
||||||
|
this.setAttribute("invalid", "");
|
||||||
|
this.classList.add(this.cssClass + "-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.removeAttribute("invalid");
|
||||||
|
this.classList.remove(this.cssClass + "-invalid");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
console.log("Validation Error", ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async create() {
|
||||||
|
|
||||||
|
this.isAuto = this.hasAttribute("auto");
|
||||||
|
this.field = this.getAttribute("field");
|
||||||
|
|
||||||
|
|
||||||
|
if (this.field != null)
|
||||||
|
{
|
||||||
|
this.setAttribute(":data", `d['${this.field}']`)
|
||||||
|
this.setAttribute(":revert", `d['${this.field}'] = this.data`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
|
||||||
|
this.repeat = new Repeat();
|
||||||
|
this.repeat.cssClass = this.cssClass + "-menu-repeat";
|
||||||
|
|
||||||
|
|
||||||
|
if (this.hasAttribute("menu")) {
|
||||||
|
let menuData = this.getAttribute("menu");
|
||||||
|
this.repeat.setAttribute(":data", menuData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.hasAttribute("footer")) {
|
||||||
|
let footer = this.getAttribute("footer");
|
||||||
|
this.footer = document.createElement("div");
|
||||||
|
this.footer.className = this.cssClass + "-footer";
|
||||||
|
this.footer.innerHTML = footer;// "${d[0]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.menu = new Menu({ cssClass: this.cssClass + "-menu", "target-class": "" });
|
||||||
|
|
||||||
|
this.menu.on("click", async (e) => {
|
||||||
|
|
||||||
|
if (e.target != self.textbox && e.target != self.footer && e.target !== self.menu && e.target != self.repeat) {
|
||||||
|
await self.setData(e.target.data);
|
||||||
|
|
||||||
|
self._emit("input", { value: e.target.data });
|
||||||
|
|
||||||
|
self.hide();
|
||||||
|
}
|
||||||
|
}).on("visible", x=> { if (!x.visible) self.hide()});
|
||||||
|
|
||||||
|
|
||||||
|
this.textbox = document.createElement("input");
|
||||||
|
this.textbox.type = "search";
|
||||||
|
this.textbox.className = this.cssClass + "-textbox";
|
||||||
|
|
||||||
|
if (this.placeholder)
|
||||||
|
this.textbox.placeholder = this.placeholder;
|
||||||
|
|
||||||
|
this.textbox.addEventListener("keyup", function (e) {
|
||||||
|
if (e.keyCode != 13) {
|
||||||
|
self._query(0, self.textbox.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.textbox.addEventListener("search", function (e) {
|
||||||
|
// console.log(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.appendChild(this.textbox);
|
||||||
|
|
||||||
|
|
||||||
|
// get collection
|
||||||
|
let layout = Layout.get(this, "div", true, true);
|
||||||
|
|
||||||
|
|
||||||
|
if (layout != null && layout.label != undefined && layout.menu != undefined) {
|
||||||
|
this.label = layout.label.node;
|
||||||
|
this.repeat.appendChild(layout.menu.node);
|
||||||
|
}
|
||||||
|
else if (layout != null && layout.null != null)
|
||||||
|
{
|
||||||
|
this.label = layout.null.node;
|
||||||
|
this.repeat.appendChild(layout.null.node.cloneNode(true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.label = document.createElement("div");
|
||||||
|
this.label.innerHTML = this.innerHTML;
|
||||||
|
this.repeat.innerHTML = this.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear everything else
|
||||||
|
//this.innerHTML = "";
|
||||||
|
|
||||||
|
this.label.className = this.cssClass + "-label";
|
||||||
|
|
||||||
|
this.appendChild(this.label);
|
||||||
|
|
||||||
|
this.label.addEventListener("click", function (e) {
|
||||||
|
self.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.menu.appendChild(this.repeat);
|
||||||
|
if (this.footer != null)
|
||||||
|
this.menu.appendChild(this.footer);
|
||||||
|
|
||||||
|
|
||||||
|
if (this.searchlist)
|
||||||
|
this.appendChild(this.menu);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
app.appendChild(this.menu);
|
||||||
|
if (app.loaded)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
await IUI.create(this.menu);
|
||||||
|
|
||||||
|
IUI.bind(this.menu, false, "menu", this.__i_bindings?.scope, false);
|
||||||
|
// update referencing
|
||||||
|
this.__i_bindings?.scope?.refs?._build();
|
||||||
|
|
||||||
|
await IUI.created(this.menu);
|
||||||
|
|
||||||
|
/////console.log("Append", this.menu);
|
||||||
|
//await this.menu.create();
|
||||||
|
|
||||||
|
//IUI.bind(this.menu, false, "menu");
|
||||||
|
//await IUI.create(this.menu);
|
||||||
|
|
||||||
|
//await await IUI.create(e);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addEventListener("click", function (e) {
|
||||||
|
if (e.target == self.textbox)
|
||||||
|
self.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get disabled() {
|
||||||
|
return this.hasAttribute("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
set disabled(value) {
|
||||||
|
if (this._autocomplete) {
|
||||||
|
this.textbox.disabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
this.setAttribute("disabled", value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
set(item) {
|
||||||
|
|
||||||
|
if (this.autocomplete != undefined) {
|
||||||
|
if (item != null)
|
||||||
|
this.textbox.value = this.layout.text.formatter ? this.layout.text.formatter(item[this.layout.text.field], item) : item[this.layout.text.field];
|
||||||
|
else
|
||||||
|
this.textbox.value = "";
|
||||||
|
} else {
|
||||||
|
if (item != null)
|
||||||
|
this.label.innerHTML = this.layout.text.formatter ? this.layout.text.formatter(item[this.layout.text.field], item) : item[this.layout.text.field];
|
||||||
|
else
|
||||||
|
this.label.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selected = item;
|
||||||
|
this._emit("select", item);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this.setVisible(true);
|
||||||
|
//this.textbox.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.setVisible(false);
|
||||||
|
//this.textbox.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
if (this.autocomplete !== undefined)
|
||||||
|
this.textbox.value = "";
|
||||||
|
//else
|
||||||
|
// this.label.innerHTML = "";
|
||||||
|
|
||||||
|
//this.menu.clear();
|
||||||
|
this.response.start = 0;
|
||||||
|
this.selected = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _query() {
|
||||||
|
|
||||||
|
|
||||||
|
if (this._autocomplete)
|
||||||
|
if (this.disabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
let text = this._autocomplete ? this.textbox.value : null;
|
||||||
|
let res;
|
||||||
|
|
||||||
|
if (this.query instanceof Array) {
|
||||||
|
res = this.query;
|
||||||
|
}
|
||||||
|
else if (this.query instanceof Function) {
|
||||||
|
res = this.query(0, text)
|
||||||
|
if (res instanceof Promise)
|
||||||
|
res = await res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//if (res[1].length == 0)
|
||||||
|
// await self.setData(null);
|
||||||
|
|
||||||
|
await this.menu.setData(res);
|
||||||
|
|
||||||
|
if (this.repeat.data.length == 0)
|
||||||
|
await self.setData(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async setData(value, radix) {
|
||||||
|
|
||||||
|
// this.label.innerHTML = "";
|
||||||
|
|
||||||
|
await super.setData(value, radix);
|
||||||
|
|
||||||
|
try {
|
||||||
|
//let text = this.formatter(value);
|
||||||
|
// this.label.innerHTML = text == null ? "" : text;
|
||||||
|
|
||||||
|
this._emit("select", { value });
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
//console.log(ex);
|
||||||
|
this._emit("select", { value });
|
||||||
|
}
|
||||||
|
|
||||||
|
//this._checkValidity();
|
||||||
|
|
||||||
|
|
||||||
|
if (this._checkValidity() && this.isAuto)
|
||||||
|
this.revert();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setVisible(visible) {
|
||||||
|
|
||||||
|
if (visible == this.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//console.log("SLCT: SetVisible", visible);
|
||||||
|
|
||||||
|
if (visible) {
|
||||||
|
this._query(0);
|
||||||
|
|
||||||
|
// show menu
|
||||||
|
var rect = this.getBoundingClientRect();
|
||||||
|
this.menu.style.width = (this.clientWidth - this._computeMenuOuterWidth()) + "px";
|
||||||
|
this.menu.style.paddingTop = rect.height + "px";
|
||||||
|
this.menu.setVisible(true, rect.left, rect.top);//, this.menu);
|
||||||
|
this.visible = true;
|
||||||
|
|
||||||
|
this.classList.add(this.cssClass + "-visible");
|
||||||
|
|
||||||
|
if (this._autocomplete)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.textbox.focus();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.visible = false;
|
||||||
|
this.classList.remove(this.cssClass + "-visible");
|
||||||
|
|
||||||
|
this.menu.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.textbox.focus();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeMenuOuterWidth() {
|
||||||
|
return this.menu.offsetWidth - this.menu.clientWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user