Current section

45 Versions

Jump to

Compare versions

5 files changed
+20 additions
-15 deletions
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/maxmarcon/live_select">>}]}.
2 2 {<<"name">>,<<"live_select">>}.
3 - {<<"version">>,<<"1.7.3">>}.
3 + {<<"version">>,<<"1.7.4">>}.
4 4 {<<"description">>,<<"Dynamic (multi)selection field for LiveView">>}.
5 5 {<<"elixir">>,<<"~> 1.14">>}.
6 6 {<<"app">>,<<"live_select">>}.
  @@ -131,7 +131,6 @@ defmodule LiveSelect.Component do
131 131 socket =
132 132 socket
133 133 |> assign(assigns)
134 - |> assign(:active_option, -1)
135 134 |> update(:awaiting_update, fn
136 135 _, %{options: _} -> false
137 136 awaiting_update, _ -> awaiting_update
  @@ -272,7 +271,7 @@ defmodule LiveSelect.Component do
272 271 active_option: active_option,
273 272 hide_dropdown: false
274 273 )
275 - |> push_event("active", %{id: socket.assigns.id, idx: active_option})
274 + |> scroll_to_active_option()
276 275
277 276 {:noreply, socket}
278 277 end
  @@ -286,7 +285,7 @@ defmodule LiveSelect.Component do
286 285 active_option: active_option,
287 286 hide_dropdown: false
288 287 )
289 - |> push_event("active", %{id: socket.assigns.id, idx: active_option})
288 + |> scroll_to_active_option()
290 289
291 290 {:noreply, socket}
292 291 end
  @@ -507,17 +506,21 @@ defmodule LiveSelect.Component do
507 506 extra_params
508 507 )
509 508 )
509 + |> scroll_to_active_option()
510 510 end
511 511
512 512 defp unselect(socket, pos) do
513 - socket =
514 - if pos == :all do
515 - assign(socket, :selection, [])
516 - else
517 - update(socket, :selection, &List.delete_at(&1, pos))
518 - end
513 + socket
514 + |> update(:selection, &List.delete_at(&1, pos))
515 + |> client_select(%{input_event: true})
516 + |> scroll_to_active_option()
517 + end
519 518
520 - client_select(socket, %{input_event: true})
519 + defp scroll_to_active_option(socket) do
520 + push_event(socket, "scroll_to_option", %{
521 + id: socket.assigns.id,
522 + idx: socket.assigns.active_option
523 + })
521 524 end
522 525
523 526 defp clear(socket, params) do
  @@ -526,7 +529,9 @@ defmodule LiveSelect.Component do
526 529 |> client_select(params)
527 530 end
528 531
529 - defp clear_options(socket), do: assign(socket, current_text: "", options: [], active_option: -1)
532 + defp clear_options(socket) do
533 + assign(socket, current_text: "", options: [], active_option: -1)
534 + end
530 535
531 536 defp client_select(socket, extra_params) do
532 537 socket
  @@ -4,7 +4,7 @@ defmodule LiveSelect.MixProject do
4 4 def project do
5 5 [
6 6 app: app(),
7 - version: "1.7.3",
7 + version: "1.7.4",
8 8 elixir: "~> 1.14",
9 9 description: "Dynamic (multi)selection field for LiveView",
10 10 elixirc_paths: elixirc_paths(Mix.env()),
  @@ -1,6 +1,6 @@
1 1 {
2 2 "name": "live_select",
3 - "version": "1.7.3",
3 + "version": "1.7.4",
4 4 "description": "JS hooks for LiveSelect",
5 5 "main": "priv/static/live_select.min.js",
6 6 "repository": "git@github.com:maxmarcon/live_select.git",
  @@ -1 +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)},maybeStyleClearButtons(){const e=this.el.querySelector("button.ls-clear-button");e&&(this.textInput().parentElement.style.position="relative",this.textInput().parentElement.style.display="flex",this.textInput().parentElement.style.alignItems="center",e.style.minHeight="20px",e.style.minWidth="20px",e.style.position="absolute",e.style.right="5px",e.style.display="block"),this.el.querySelectorAll("button.ls-clear-tag-button").forEach(t=>{t.style.minHeight="20px",t.style.minWidth="20px"})},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.maybeStyleClearButtons(),this.handleEvent("select",({id:e,selection:t,mode:i,current_text:s,input_event:l,parent_event:n})=>{this.el.id===e&&(this.selection=t,s!==null&&this.setInputValue(s),l&&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.maybeStyleClearButtons(),this.attachDomEventHandlers()},reconnected(){this.selection&&this.selection.length>0&&this.pushEventTo(this.el,"selection_recovery",this.selection)}}};
1 + function o(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)},maybeStyleClearButtons(){const e=this.el.querySelector("button.ls-clear-button");e&&(this.textInput().parentElement.style.position="relative",this.textInput().parentElement.style.display="flex",this.textInput().parentElement.style.alignItems="center",e.style.minHeight="20px",e.style.minWidth="20px",e.style.position="absolute",e.style.right="5px",e.style.display="block"),this.el.querySelectorAll("button.ls-clear-tag-button").forEach(t=>{t.style.minHeight="20px",t.style.minWidth="20px"})},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=o((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.maybeStyleClearButtons(),this.handleEvent("select",({id:e,selection:t,mode:i,current_text:s,input_event:l,parent_event:n})=>{this.el.id===e&&(this.selection=t,s!=null&&this.setInputValue(s),l&&this.inputEvent(t,i),n&&this.pushEventToParent(n,{id:e}))}),this.handleEvent("scroll_to_option",({id:e,idx:t})=>{if(this.el.id===e){const i=this.el.querySelector(`div[data-idx="${t}"]`);i&&i.scrollIntoView({block:"nearest",behavior:"instant",container:"nearest"})}}),this.attachDomEventHandlers()},updated(){this.maybeStyleClearButtons(),this.attachDomEventHandlers()},reconnected(){this.selection&&this.selection.length>0&&this.pushEventTo(this.el,"selection_recovery",this.selection)}}};