83 lines
2.7 KiB
JavaScript
83 lines
2.7 KiB
JavaScript
|
class SmartInput extends HTMLElement {
|
||
|
|
||
|
#data = null;
|
||
|
#rootdoc = null;
|
||
|
#delay = 300;
|
||
|
#value = null;
|
||
|
#timeoutid = null;
|
||
|
#input = null;
|
||
|
#list = null;
|
||
|
#label = null;
|
||
|
|
||
|
constructor(){
|
||
|
super()
|
||
|
this.#rootdoc = this.attachShadow({ "mode" : "open"})
|
||
|
this.render()
|
||
|
}
|
||
|
|
||
|
connectedCallback(){}
|
||
|
|
||
|
set data(data){ this.#data = data; this.render() }
|
||
|
|
||
|
render(){
|
||
|
this.#rootdoc.innerHTML = `
|
||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||
|
<div>
|
||
|
<div class="d-flex align-items-center" style="gap:5px">
|
||
|
<input class="form-control"/>
|
||
|
<small id="restriction-enzyme-feedback" class="form-text text-muted"></small>
|
||
|
</div>
|
||
|
<div>
|
||
|
<ul class="d-none list-group" style="position:absolute;z-index:1000"></ul>
|
||
|
</div>
|
||
|
<div>
|
||
|
`
|
||
|
this.#list = this.#rootdoc.querySelector("ul")
|
||
|
this.#input = this.#rootdoc.querySelector("input")
|
||
|
this.#label = this.#rootdoc.querySelector("small#restriction-enzyme-feedback")
|
||
|
this.#rootdoc.addEventListener("keydown", ev=>{
|
||
|
if(ev.code === "Escape"){
|
||
|
this.#list.classList.add("d-none")
|
||
|
}
|
||
|
})
|
||
|
this.#input.addEventListener("input", ev=>{
|
||
|
this.#value = ev.target.value
|
||
|
this.#label.textContent = ""
|
||
|
if(this.#timeoutid != null) window.clearTimeout(this.#timeoutid)
|
||
|
this.#timeoutid = window.setTimeout(()=>{
|
||
|
this.renderOptions()
|
||
|
}, this.#delay)
|
||
|
})
|
||
|
this.#input.addEventListener("keypress", ev=>{
|
||
|
if(ev.code === "Enter"){
|
||
|
this.#list.classList.add("d-none")
|
||
|
document.querySelector("igene-data-display").updateEnzyme(this.#input.value)
|
||
|
}
|
||
|
})
|
||
|
this.#list.addEventListener("click", ev=>{
|
||
|
if(ev.target.classList.contains("list-group-item")){
|
||
|
this.#input.value = ev.target.getAttribute("data-sequence")
|
||
|
this.#label.textContent = ev.target.getAttribute("data-enzyme")
|
||
|
this.#list.classList.add("d-none")
|
||
|
document.querySelector("igene-data-display").updateEnzyme(this.#input.value)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
renderOptions(){
|
||
|
if(this.#value == null || this.#value === ""){
|
||
|
this.#list.classList.add("d-none")
|
||
|
return
|
||
|
}
|
||
|
const options = this.#data.filter(d=>{
|
||
|
return d.name.startsWith(this.#value) || d.sequence.startsWith(this.#value)
|
||
|
}).map(o=>{
|
||
|
return `
|
||
|
<li class="list-group-item d-flex" style="gap:5px; cursor: pointer;" data-sequence="${o.sequence}" data-enzyme="${o.name}"><span style="pointer-events: none;">${o.name}</span><span style="pointer-events: none;" class="badge bg-primary">${o.sequence}</span></li>
|
||
|
`
|
||
|
}).join("")
|
||
|
this.#list.innerHTML = options
|
||
|
this.#list.classList.remove("d-none")
|
||
|
}
|
||
|
}
|
||
|
window.customElements.define('nw-smart-input', SmartInput);
|