mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-15 02:33:22 +00:00
Create base class for ajax-select
This commit is contained in:
parent
b9cbba2309
commit
56cc4776a6
@ -1,41 +1,89 @@
|
|||||||
import "tom-select/dist/css/tom-select.css";
|
import "tom-select/dist/css/tom-select.css";
|
||||||
import { inheritHtmlElement, registerComponent } from "#core:utils/web-components";
|
import { inheritHtmlElement, registerComponent } from "#core:utils/web-components";
|
||||||
import TomSelect from "tom-select";
|
import TomSelect from "tom-select";
|
||||||
import type { TomItem, TomLoadCallback, TomOption } from "tom-select/dist/types/types";
|
import type {
|
||||||
|
RecursivePartial,
|
||||||
|
TomItem,
|
||||||
|
TomLoadCallback,
|
||||||
|
TomOption,
|
||||||
|
TomSettings,
|
||||||
|
} from "tom-select/dist/types/types";
|
||||||
import type { escape_html } from "tom-select/dist/types/utils";
|
import type { escape_html } from "tom-select/dist/types/utils";
|
||||||
import { type UserProfileSchema, userSearchUsers } from "#openapi";
|
import { type UserProfileSchema, userSearchUsers } from "#openapi";
|
||||||
|
|
||||||
@registerComponent("ajax-select")
|
abstract class AjaxSelectBase extends inheritHtmlElement("select") {
|
||||||
export class AjaxSelect extends inheritHtmlElement("select") {
|
static observedAttributes = ["delay", "placeholder", "max"];
|
||||||
public widget: TomSelect;
|
public widget: TomSelect;
|
||||||
public filter?: <T>(items: T[]) => T[];
|
|
||||||
|
private delay: number | null = null;
|
||||||
|
private placeholder = "";
|
||||||
|
private max: number | null = null;
|
||||||
|
|
||||||
|
attributeChangedCallback(name: string, _oldValue?: string, newValue?: string) {
|
||||||
|
switch (name) {
|
||||||
|
case "delay": {
|
||||||
|
this.delay = Number.parseInt(newValue) ?? null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "placeholder": {
|
||||||
|
this.placeholder = newValue ?? "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "max": {
|
||||||
|
this.max = Number.parseInt(newValue) ?? null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", () => {
|
window.addEventListener("DOMContentLoaded", () => {
|
||||||
this.loadTomSelect();
|
this.configureTomSelect(this.defaultTomSelectSettings());
|
||||||
|
this.setDefaultTomSelectBehaviors();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTomSelect() {
|
private defaultTomSelectSettings(): RecursivePartial<TomSettings> {
|
||||||
|
return {
|
||||||
|
maxItems: this.max,
|
||||||
|
loadThrottle: this.delay,
|
||||||
|
placeholder: this.placeholder,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private setDefaultTomSelectBehaviors() {
|
||||||
|
// Allow removing selected items by clicking on them
|
||||||
|
this.widget.on("item_select", (item: TomItem) => {
|
||||||
|
this.widget.removeItem(item);
|
||||||
|
});
|
||||||
|
// Remove typed text once an item has been selected
|
||||||
|
this.widget.on("item_add", () => {
|
||||||
|
this.widget.setTextboxValue("");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract configureTomSelect(defaultSettings: RecursivePartial<TomSettings>): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
@registerComponent("user-ajax-select")
|
||||||
|
export class UserAjaxSelect extends AjaxSelectBase {
|
||||||
|
public filter?: <T>(items: T[]) => T[];
|
||||||
|
|
||||||
|
configureTomSelect(defaultSettings: RecursivePartial<TomSettings>) {
|
||||||
const minCharNumberForSearch = 2;
|
const minCharNumberForSearch = 2;
|
||||||
let maxItems = 1;
|
|
||||||
|
|
||||||
if (this.node.multiple) {
|
|
||||||
maxItems = Number.parseInt(this.node.dataset.max) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.widget = new TomSelect(this.node, {
|
this.widget = new TomSelect(this.node, {
|
||||||
|
...defaultSettings,
|
||||||
hideSelected: true,
|
hideSelected: true,
|
||||||
diacritics: true,
|
diacritics: true,
|
||||||
duplicates: false,
|
duplicates: false,
|
||||||
maxItems: maxItems,
|
|
||||||
loadThrottle: Number.parseInt(this.node.dataset.delay) ?? null,
|
|
||||||
valueField: "id",
|
valueField: "id",
|
||||||
labelField: "display_name",
|
labelField: "display_name",
|
||||||
searchField: ["display_name", "nick_name", "first_name", "last_name"],
|
searchField: [], // Disable local search filter and rely on tested backend
|
||||||
placeholder: this.node.dataset.placeholder ?? "",
|
|
||||||
shouldLoad: (query: string) => {
|
shouldLoad: (query: string) => {
|
||||||
return query.length >= minCharNumberForSearch; // Avoid launching search with less than 2 characters
|
return query.length >= minCharNumberForSearch; // Avoid launching search with less than 2 characters
|
||||||
},
|
},
|
||||||
@ -80,14 +128,5 @@ export class AjaxSelect extends inheritHtmlElement("select") {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow removing selected items by clicking on them
|
|
||||||
this.widget.on("item_select", (item: TomItem) => {
|
|
||||||
this.widget.removeItem(item);
|
|
||||||
});
|
|
||||||
// Remove typed text once an item has been selected
|
|
||||||
this.widget.on("item_add", () => {
|
|
||||||
this.widget.setTextboxValue("");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,12 +157,12 @@
|
|||||||
<h5>{% trans %}People{% endtrans %}</h5>
|
<h5>{% trans %}People{% endtrans %}</h5>
|
||||||
{% if user.was_subscribed %}
|
{% if user.was_subscribed %}
|
||||||
<form @submit.prevent="submitIdentification" x-show="!!selector">
|
<form @submit.prevent="submitIdentification" x-show="!!selector">
|
||||||
<ajax-select
|
<user-ajax-select
|
||||||
x-ref="search"
|
x-ref="search"
|
||||||
multiple
|
multiple
|
||||||
data-delay="300"
|
delay="300"
|
||||||
data-placeholder="{%- trans -%}Identify users on pictures{%- endtrans -%}"
|
placeholder="{%- trans -%}Identify users on pictures{%- endtrans -%}"
|
||||||
></ajax-select>
|
></user-ajax-select>
|
||||||
<input type="submit" value="{% trans %}Go{% endtrans %}"/>
|
<input type="submit" value="{% trans %}Go{% endtrans %}"/>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
Loading…
Reference in New Issue
Block a user