From 805b39731467bee3f03ad997b40e7874205e267f Mon Sep 17 00:00:00 2001 From: Alexander Cherry Date: Fri, 17 Jan 2025 15:45:30 -0500 Subject: [PATCH 1/3] Push selection_recovery to element id --- assets/js/live_select.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/js/live_select.js b/assets/js/live_select.js index 8545d02..92bd4ae 100644 --- a/assets/js/live_select.js +++ b/assets/js/live_select.js @@ -43,11 +43,11 @@ export default { if (event.code === "Enter") { event.preventDefault() } - this.pushEventTo(this.el, 'keydown', {key: event.code}) + this.pushEventTo(this.el, 'keydown', { key: event.code }) } this.changeEvents = debounce((id, field, text) => { - this.pushEventTo(this.el, "change", {text}) - this.pushEventToParent("live_select_change", {id: this.el.id, field, text}) + this.pushEventTo(this.el, "change", { text }) + this.pushEventToParent("live_select_change", { id: this.el.id, field, text }) }, this.debounceMsec()) this.textInput().oninput = (event) => { const text = event.target.value.trim() @@ -63,14 +63,14 @@ export default { dropdown.onmousedown = (event) => { const option = event.target.closest('div[data-idx]') if (option) { - this.pushEventTo(this.el, 'option_click', {idx: option.dataset.idx}) + this.pushEventTo(this.el, 'option_click', { idx: option.dataset.idx }) event.preventDefault() } } } this.el.querySelectorAll("button[data-idx]").forEach(button => { button.onclick = (event) => { - this.pushEventTo(this.el, 'option_remove', {idx: button.dataset.idx}) + this.pushEventTo(this.el, 'option_remove', { idx: button.dataset.idx }) } }) }, @@ -79,16 +79,16 @@ export default { }, inputEvent(selection, mode) { const selector = mode === "single" ? "input.single-mode" : (selection.length === 0 ? "input[data-live-select-empty]" : "input[type=hidden]") - this.el.querySelector(selector).dispatchEvent(new Event('input', {bubbles: true})) + this.el.querySelector(selector).dispatchEvent(new Event('input', { bubbles: true })) }, mounted() { this.maybeStyleClearButton() - this.handleEvent("parent_event", ({id, event, payload}) => { + this.handleEvent("parent_event", ({ id, event, payload }) => { if (this.el.id === id) { this.pushEventToParent(event, payload) } }) - this.handleEvent("select", ({id, selection, mode, input_event, parent_event}) => { + this.handleEvent("select", ({ id, selection, mode, input_event, parent_event }) => { if (this.el.id === id) { this.selection = selection if (mode === "single") { @@ -101,15 +101,15 @@ export default { this.inputEvent(selection, mode) } if (parent_event) { - this.pushEventToParent(parent_event, {id}) + this.pushEventToParent(parent_event, { id }) } } }) - this.handleEvent("active", ({id, idx}) => { + this.handleEvent("active", ({ id, idx }) => { if (this.el.id === id) { const option = this.el.querySelector(`div[data-idx="${idx}"]`) if (option) { - option.scrollIntoView({block: "nearest"}) + option.scrollIntoView({ block: "nearest" }) } } }) @@ -121,7 +121,7 @@ export default { }, reconnected() { if (this.selection && this.selection.length > 0) { - this.pushEventTo(this.el, "selection_recovery", this.selection) + this.pushEventTo(this.el.id, "selection_recovery", this.selection) } } } From 4c63e3cd27a700271fe22f57767205a51aac4278 Mon Sep 17 00:00:00 2001 From: Alexander Cherry Date: Fri, 17 Jan 2025 15:51:00 -0500 Subject: [PATCH 2/3] Undo accidental formatting --- assets/js/live_select.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/js/live_select.js b/assets/js/live_select.js index 92bd4ae..0a933b8 100644 --- a/assets/js/live_select.js +++ b/assets/js/live_select.js @@ -43,11 +43,11 @@ export default { if (event.code === "Enter") { event.preventDefault() } - this.pushEventTo(this.el, 'keydown', { key: event.code }) + this.pushEventTo(this.el, 'keydown', {key: event.code}) } this.changeEvents = debounce((id, field, text) => { - this.pushEventTo(this.el, "change", { text }) - this.pushEventToParent("live_select_change", { id: this.el.id, field, text }) + this.pushEventTo(this.el, "change", {text}) + this.pushEventToParent("live_select_change", {id: this.el.id, field, text}) }, this.debounceMsec()) this.textInput().oninput = (event) => { const text = event.target.value.trim() @@ -63,14 +63,14 @@ export default { dropdown.onmousedown = (event) => { const option = event.target.closest('div[data-idx]') if (option) { - this.pushEventTo(this.el, 'option_click', { idx: option.dataset.idx }) + this.pushEventTo(this.el, 'option_click', {idx: option.dataset.idx}) event.preventDefault() } } } this.el.querySelectorAll("button[data-idx]").forEach(button => { button.onclick = (event) => { - this.pushEventTo(this.el, 'option_remove', { idx: button.dataset.idx }) + this.pushEventTo(this.el, 'option_remove', {idx: button.dataset.idx}) } }) }, @@ -79,16 +79,16 @@ export default { }, inputEvent(selection, mode) { const selector = mode === "single" ? "input.single-mode" : (selection.length === 0 ? "input[data-live-select-empty]" : "input[type=hidden]") - this.el.querySelector(selector).dispatchEvent(new Event('input', { bubbles: true })) + this.el.querySelector(selector).dispatchEvent(new Event('input', {bubbles: true})) }, mounted() { this.maybeStyleClearButton() - this.handleEvent("parent_event", ({ id, event, payload }) => { + this.handleEvent("parent_event", ({id, event, payload}) => { if (this.el.id === id) { this.pushEventToParent(event, payload) } }) - this.handleEvent("select", ({ id, selection, mode, input_event, parent_event }) => { + this.handleEvent("select", ({id, selection, mode, input_event, parent_event}) => { if (this.el.id === id) { this.selection = selection if (mode === "single") { @@ -101,15 +101,15 @@ export default { this.inputEvent(selection, mode) } if (parent_event) { - this.pushEventToParent(parent_event, { id }) + this.pushEventToParent(parent_event, {id}) } } }) - this.handleEvent("active", ({ id, idx }) => { + this.handleEvent("active", ({id, idx}) => { if (this.el.id === id) { const option = this.el.querySelector(`div[data-idx="${idx}"]`) if (option) { - option.scrollIntoView({ block: "nearest" }) + option.scrollIntoView({block: "nearest"}) } } }) From a20ef98348dadd79f4d0370d69b4a97a1cfba11d Mon Sep 17 00:00:00 2001 From: Max Marcon Date: Mon, 27 Jan 2025 20:21:56 +0100 Subject: [PATCH 3/3] update js assets --- priv/static/live_select.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/priv/static/live_select.min.js b/priv/static/live_select.min.js index 702ded7..9d248a5 100644 --- a/priv/static/live_select.min.js +++ b/priv/static/live_select.min.js @@ -1 +1 @@ -function h(e,t){let i;return(...s)=>{clearTimeout(i),i=setTimeout(()=>{e.apply(this,s)},t)}}export default{LiveSelect:{textInput(){return this.el.querySelector("input[type=text]")},debounceMsec(){return parseInt(this.el.dataset.debounce)},updateMinLen(){return parseInt(this.el.dataset.updateMinLen)},maybeStyleClearButton(){const e=this.el.querySelector("button[phx-click=clear]");e&&(this.textInput().parentElement.style.position="relative",e.style.position="absolute",e.style.top="0px",e.style.bottom="0px",e.style.right="5px",e.style.display="block")},pushEventToParent(e,t){const i=this.el.dataset.phxTarget;i?this.pushEventTo(i,e,t):this.pushEvent(e,t)},attachDomEventHandlers(){this.textInput().onkeydown=t=>{t.code==="Enter"&&t.preventDefault(),this.pushEventTo(this.el,"keydown",{key:t.code})},this.changeEvents=h((t,i,s)=>{this.pushEventTo(this.el,"change",{text:s}),this.pushEventToParent("live_select_change",{id:this.el.id,field:i,text:s})},this.debounceMsec()),this.textInput().oninput=t=>{const i=t.target.value.trim(),s=this.el.dataset.field;i.length>=this.updateMinLen()?this.changeEvents(this.el.id,s,i):this.pushEventTo(this.el,"options_clear",{})};const e=this.el.querySelector("ul");e&&(e.onmousedown=t=>{const i=t.target.closest("div[data-idx]");i&&(this.pushEventTo(this.el,"option_click",{idx:i.dataset.idx}),t.preventDefault())}),this.el.querySelectorAll("button[data-idx]").forEach(t=>{t.onclick=i=>{this.pushEventTo(this.el,"option_remove",{idx:t.dataset.idx})}})},setInputValue(e){this.textInput().value=e},inputEvent(e,t){const i=t==="single"?"input.single-mode":e.length===0?"input[data-live-select-empty]":"input[type=hidden]";this.el.querySelector(i).dispatchEvent(new Event("input",{bubbles:!0}))},mounted(){this.maybeStyleClearButton(),this.handleEvent("parent_event",({id:e,event:t,payload:i})=>{this.el.id===e&&this.pushEventToParent(t,i)}),this.handleEvent("select",({id:e,selection:t,mode:i,input_event:s,parent_event:n})=>{if(this.el.id===e){if(this.selection=t,i==="single"){const l=t.length>0?t[0].label:null;this.setInputValue(l)}else this.setInputValue(null);s&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e})}}),this.handleEvent("active",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView({block:"nearest"})}}),this.attachDomEventHandlers()},updated(){this.maybeStyleClearButton(),this.attachDomEventHandlers()},reconnected(){this.selection&&this.selection.length>0&&this.pushEventTo(this.el,"selection_recovery",this.selection)}}}; +function h(e,t){let i;return(...s)=>{clearTimeout(i),i=setTimeout(()=>{e.apply(this,s)},t)}}export default{LiveSelect:{textInput(){return this.el.querySelector("input[type=text]")},debounceMsec(){return parseInt(this.el.dataset.debounce)},updateMinLen(){return parseInt(this.el.dataset.updateMinLen)},maybeStyleClearButton(){const e=this.el.querySelector("button[phx-click=clear]");e&&(this.textInput().parentElement.style.position="relative",e.style.position="absolute",e.style.top="0px",e.style.bottom="0px",e.style.right="5px",e.style.display="block")},pushEventToParent(e,t){const i=this.el.dataset.phxTarget;i?this.pushEventTo(i,e,t):this.pushEvent(e,t)},attachDomEventHandlers(){this.textInput().onkeydown=t=>{t.code==="Enter"&&t.preventDefault(),this.pushEventTo(this.el,"keydown",{key:t.code})},this.changeEvents=h((t,i,s)=>{this.pushEventTo(this.el,"change",{text:s}),this.pushEventToParent("live_select_change",{id:this.el.id,field:i,text:s})},this.debounceMsec()),this.textInput().oninput=t=>{const i=t.target.value.trim(),s=this.el.dataset.field;i.length>=this.updateMinLen()?this.changeEvents(this.el.id,s,i):this.pushEventTo(this.el,"options_clear",{})};const e=this.el.querySelector("ul");e&&(e.onmousedown=t=>{const i=t.target.closest("div[data-idx]");i&&(this.pushEventTo(this.el,"option_click",{idx:i.dataset.idx}),t.preventDefault())}),this.el.querySelectorAll("button[data-idx]").forEach(t=>{t.onclick=i=>{this.pushEventTo(this.el,"option_remove",{idx:t.dataset.idx})}})},setInputValue(e){this.textInput().value=e},inputEvent(e,t){const i=t==="single"?"input.single-mode":e.length===0?"input[data-live-select-empty]":"input[type=hidden]";this.el.querySelector(i).dispatchEvent(new Event("input",{bubbles:!0}))},mounted(){this.maybeStyleClearButton(),this.handleEvent("parent_event",({id:e,event:t,payload:i})=>{this.el.id===e&&this.pushEventToParent(t,i)}),this.handleEvent("select",({id:e,selection:t,mode:i,input_event:s,parent_event:n})=>{if(this.el.id===e){if(this.selection=t,i==="single"){const l=t.length>0?t[0].label:null;this.setInputValue(l)}else this.setInputValue(null);s&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e})}}),this.handleEvent("active",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView({block:"nearest"})}}),this.attachDomEventHandlers()},updated(){this.maybeStyleClearButton(),this.attachDomEventHandlers()},reconnected(){this.selection&&this.selection.length>0&&this.pushEventTo(this.el.id,"selection_recovery",this.selection)}}};