Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tower of Hanoi with Phoenix LiveView

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Wu Qing Wu Qing
November 06, 2019

Tower of Hanoi with Phoenix LiveView

Creating a Tower of Hanoi game with Phoenix LiveView. Drag-and-drop implemented with LiveView hooks
Presented at November 2019 meetup of Elixir Sydney
https://www.meetup.com/elixir-sydney/events/bckwkryzpbjb/

Avatar for Wu Qing

Wu Qing

November 06, 2019
Tweet

More Decks by Wu Qing

Other Decks in Programming

Transcript

  1. PHOENIX LIVEVIEW HOOKS const Hooks = { Disk: { mounted()

    { ... } }, DropContainer: { mounted() { ... } } } let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks}) liveSocket.connect()
  2. LIVEVIEW TEMPLATES WITH HOOKS <div class="subcontainer" phx-hook="DropContainer" phx-value-rodno="<%= @val %>">

    <div class="rod"> <div class="disk-container"> <%= for {n, index} <- Enum.with_index(@rod) do %> <%= if index === 0 do %> <div class="<%= "disk disk#{n}" %>" phx-hook="Disk" draggable="true"></div> <% else %> <div class="<%= "disk disk#{n}" %>"></div> <% end %> <% end %> </div> </div> </div>
  3. JAVASCRIPT DRAG AND DROP I const getRodNo = event =>

    event.target.closest(".subcontainer").getAttribute("phx-value-rodno") Disk: { mounted() { this.el.addEventListener("dragstart", event => { event.target.style.opacity = .7 const rod_no = getRodNo(event) event.dataTransfer.setData("text/plain", rod_no) }, false) this.el.addEventListener("dragend", event => { event.target.style.opacity = "" }, false) } }
  4. JAVASCRIPT DRAG AND DROP II DropContainer: { mounted() { this.el.addEventListener("dragover",

    event => { event.preventDefault() }, false) this.el.addEventListener("dragenter", event => { event.target.style.background = "lightgrey" }, false) this.el.addEventListener("dragleave", event => { event.target.style.background = "" }, false) ... } }
  5. JAVASCRIPT DRAG AND DROP III DropContainer: { mounted() { ...

    this.el.addEventListener("drop", event => { event.preventDefault() event.target.style.background = "" const from_rod_no = event.dataTransfer.getData("text/plain") const to_rod_no = getRodNo(event) this.pushEvent("move-disk", {from: from_rod_no, to: to_rod_no}) }, false) } }
  6. REFERENCES > 3blue1brown hanoi videw 1 > LiveView Documentation >

    HTML Drag and Drop API > Source for Tower of Hanoi with LiveView