Cleaned up chip list code further and simplified a few things.
This commit is contained in:
119
chip-list.js
119
chip-list.js
@@ -52,11 +52,10 @@ class ChipList extends IgniteElement {
|
|||||||
input: null,
|
input: null,
|
||||||
search: true,
|
search: true,
|
||||||
searching: false,
|
searching: false,
|
||||||
showSearchResults: true,
|
|
||||||
searchLoading: false,
|
searchLoading: false,
|
||||||
searchResults: null,
|
searchResults: null,
|
||||||
searchResultConverter: (result) => new text(result),
|
searchResultConverter: (result) => new text(result),
|
||||||
searchDelay: 200,
|
searchDelay: 300,
|
||||||
searchCallback: null,
|
searchCallback: null,
|
||||||
searchFunction: null,
|
searchFunction: null,
|
||||||
documentListener: null,
|
documentListener: null,
|
||||||
@@ -101,46 +100,6 @@ class ChipList extends IgniteElement {
|
|||||||
.class("input")
|
.class("input")
|
||||||
.attribute("contenteditable", "true")
|
.attribute("contenteditable", "true")
|
||||||
.ref(this.input)
|
.ref(this.input)
|
||||||
.onEnter((e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
//If we are read only don't do anything.
|
|
||||||
if (this.readOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If this chip allows free form input then add a new item.
|
|
||||||
if (this.freeForm && this.input.textContent.trim().length >= 1) {
|
|
||||||
if (this.items == null) {
|
|
||||||
this.items = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add a new item to the chip list.
|
|
||||||
this.items.push({ content: this.input.textContent.trim() });
|
|
||||||
this.input.innerHTML = "";
|
|
||||||
this.input.focus(); //Refocus to ensure we still have it.
|
|
||||||
this.searching = false; //Reset searching since we just added a item.
|
|
||||||
this.changed = true; //Make sure changed flag was set.
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.onBackspace((e) => {
|
|
||||||
//If we are read only don't do anything.
|
|
||||||
if (this.readOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//If the backspace key is pressed and there is no content, try to remove the last item from the list.
|
|
||||||
if (this.input.textContent.length == 0 || (this.input.textContent.length == 1 && this.input.textContent[0] == " ")) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (this.items) {
|
|
||||||
this.items.pop();
|
|
||||||
this.changed = true; //Make sure changed flag was set.
|
|
||||||
}
|
|
||||||
|
|
||||||
this.searching = false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.on("keydown", (e) => {
|
.on("keydown", (e) => {
|
||||||
//If we are read only don't do anything.
|
//If we are read only don't do anything.
|
||||||
if (this.readOnly) {
|
if (this.readOnly) {
|
||||||
@@ -149,16 +108,39 @@ class ChipList extends IgniteElement {
|
|||||||
|
|
||||||
//If the escape key is pressed stop searching until something else happens.
|
//If the escape key is pressed stop searching until something else happens.
|
||||||
if (e.key == "Escape") {
|
if (e.key == "Escape") {
|
||||||
this.searching = false;
|
this.stopSearching();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//If the enter key is pressed add a new item if free form allows.
|
||||||
|
else if (e.key == "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (this.freeForm && this.input.textContent.trim().length >= 1) {
|
||||||
|
this.stopSearching();
|
||||||
|
|
||||||
|
//Add a new item to the chip list.
|
||||||
|
if (this.items) {
|
||||||
|
this.items.push(this.input.textContent.trim());
|
||||||
|
} else {
|
||||||
|
this.items = [this.input.textContent.trim()];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.input.innerHTML = "";
|
||||||
|
this.input.focus(); //Refocus to ensure we still have it.
|
||||||
|
this.changed = true; //Make sure changed flag was set.
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (!this.searching) {
|
||||||
|
this.searching = true;
|
||||||
|
this.searchLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
//Reset the searching and input if we get a tab, since the browser
|
//Reset the searching and input if we get a tab, since the browser
|
||||||
//will focus the next avaiable element.
|
//will focus the next avaiable element.
|
||||||
if (e.key == "Tab") {
|
else if (e.key == "Tab") {
|
||||||
this.searching = false;
|
|
||||||
this.editing = false;
|
this.editing = false;
|
||||||
|
|
||||||
//Fire a change event if there was a change.
|
//Fire a change event if there was a change.
|
||||||
@@ -167,32 +149,44 @@ class ChipList extends IgniteElement {
|
|||||||
this.dispatchEvent(new Event("change"));
|
this.dispatchEvent(new Event("change"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.stopSearching();
|
||||||
|
|
||||||
this.input.innerHTML = "";
|
this.input.innerHTML = "";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If we are not searching and a key was pressed, open the search box.
|
//If we are not searching and a key was pressed, open the search box.
|
||||||
if (!this.searching && this.search && (e.key !== "Backspace" || (e.key == "Backspace" && e.target.textContent.length > 1)) && (this.items == null || this.items.length < this.itemsMax)) {
|
else if (!this.searching && this.search && (e.key !== "Backspace" || (e.key == "Backspace" && e.target.textContent.length > 1)) && (this.items == null || this.items.length < this.itemsMax)) {
|
||||||
this.searching = true;
|
this.searching = true;
|
||||||
this.showSearchResults = true;
|
this.searchLoading = false;
|
||||||
} else if (this.items != null && this.items.length >= this.itemsMax && e.key !== "Backspace") {
|
}
|
||||||
//Don't allow input if we reached the max number of items.
|
//Don't allow input if we reached the max number of items.
|
||||||
|
else if (this.items != null && this.items.length >= this.itemsMax && e.key !== "Backspace") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
//Remove the last item and stop searching if the backspace was pressed and there is no search text
|
||||||
|
else if (e.key == "Backspace" && (this.input.textContent.length == 0 || (this.input.textContent.length == 1 && this.input.textContent[0] == " "))) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
//If we are searching and we have a on search function invoke it.
|
if (this.items) {
|
||||||
|
this.items.pop();
|
||||||
|
this.changed = true; //Make sure changed flag was set.
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stopSearching();
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we are searching and we have a search function invoke it.
|
||||||
if (this.searching && this.searchFunction) {
|
if (this.searching && this.searchFunction) {
|
||||||
//Clear a pending search
|
//Clear a pending search if there is one
|
||||||
if (this.searchCallback) {
|
if (this.searchCallback) {
|
||||||
clearTimeout(this.searchCallback);
|
clearTimeout(this.searchCallback);
|
||||||
|
this.searchCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Schedule a new search
|
//Schedule a new search
|
||||||
this.searchCallback = setTimeout(async () => {
|
this.searchCallback = setTimeout(async () => {
|
||||||
this.searchLoading = true;
|
this.searchLoading = true;
|
||||||
|
|
||||||
this.searchResults = await this.searchFunction(this.input.textContent.trim());
|
this.searchResults = await this.searchFunction(this.input.textContent.trim());
|
||||||
|
|
||||||
this.searchLoading = false;
|
this.searchLoading = false;
|
||||||
}, this.searchDelay);
|
}, this.searchDelay);
|
||||||
}
|
}
|
||||||
@@ -203,16 +197,18 @@ class ChipList extends IgniteElement {
|
|||||||
//Clear button
|
//Clear button
|
||||||
new button()
|
new button()
|
||||||
.class("btn btn-link text-muted fs-4")
|
.class("btn btn-link text-muted fs-4")
|
||||||
|
.attribute("tabindex", "-1")
|
||||||
.title("Clear")
|
.title("Clear")
|
||||||
.show([this.showClearButton, this.items], (show, items) => show && items && items.length > 0)
|
.show([this.showClearButton, this.items], (show, items) => show && items && items.length > 0)
|
||||||
.child(new i().class('fa fa-times'))
|
.child(new i().class('fa fa-times'))
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.items = null;
|
this.items = null;
|
||||||
this.editing = false;
|
this.editing = false;
|
||||||
this.searching = false;
|
this.stopSearching();
|
||||||
this.changed = true;
|
|
||||||
this.input.blur();
|
this.input.blur();
|
||||||
this.input.innerHTML = "";
|
this.input.innerHTML = "";
|
||||||
|
this.changed = false;
|
||||||
|
this.dispatchEvent(new Event("change"));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
//Search results popper
|
//Search results popper
|
||||||
@@ -232,7 +228,7 @@ class ChipList extends IgniteElement {
|
|||||||
new span().class("text-muted").hide(this.searchLoading).innerText(this.searchResults, results => results && results.length > 0 ? `Showing ${results.length} ${results.length == 1 ? "result" : "results"}` : "No results"),
|
new span().class("text-muted").hide(this.searchLoading).innerText(this.searchResults, results => results && results.length > 0 ? `Showing ${results.length} ${results.length == 1 ? "result" : "results"}` : "No results"),
|
||||||
|
|
||||||
//Results
|
//Results
|
||||||
new div().class("d-flex flex-column gap-2").hide([this.showSearchResults, this.searchLoading], (showSearchResults, searchLoading) => !showSearchResults || searchLoading).child(
|
new div().class("d-flex flex-column gap-2").hide(this.searchLoading).child(
|
||||||
new list(
|
new list(
|
||||||
this.searchResults,
|
this.searchResults,
|
||||||
result => new div()
|
result => new div()
|
||||||
@@ -299,6 +295,17 @@ class ChipList extends IgniteElement {
|
|||||||
this.input.innerHTML = "";
|
this.input.innerHTML = "";
|
||||||
this.input.focus();
|
this.input.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopSearching() {
|
||||||
|
this.searching = false;
|
||||||
|
|
||||||
|
this.searchLoading = false;
|
||||||
|
|
||||||
|
if (this.searchCallback) {
|
||||||
|
clearTimeout(this.searchCallback);
|
||||||
|
this.searchCallback = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChipListTemplate extends IgniteTemplate {
|
class ChipListTemplate extends IgniteTemplate {
|
||||||
|
|||||||
Reference in New Issue
Block a user