fceruti

fceruti

In a nutshell the issue I’m facing is that every time I register alpine’s @ or x-on event handler, two are registered and called when the action is performed.

The issue is solved if I comment liveSocket.connect(), which leads me to believe the problem is in the interoperation of liveSocket and Alpine.

I’ve circled the internet without success. Has anyone had this issue and solved it?

Packages:
Phoenix: 1.6.2
Phoenix Live View: 0.16.4
Surface: 0.6.1
Alpinejs: 3.3.5 & 3.4.2

Surface component:

defmodule TimetaskApp.WeekCalendar do
  use Surface.LiveComponent

  prop hours, :list, required: true

  prop dates, :list, required: true

  @impl true
  def render(assigns) do
    ~F"""
    <div class="w-full h-full flex flex-col" style="height: calc(100vh - 100px)" id="week-calendar">  {!-- Calendar --}
      <div class="h-full flex-1 flex flex-row relative">
        <div
          class="flex-1 flex"
          id="week-calendar-columns"
          :hook="WeekCalendar"
          x-init="fromHour = +$el.dataset.fromHour; toHour = +$el.dataset.toHour;"
          x-data="week_calendar_data"
          data-from-hour={List.first(@hours)}
          data-to-hour={List.last(@hours)}
        >
          <div
            class="flex-1 flex"
            id="week-calendar-days-container"
            x-ref="days_container"
          >
            {#for date <- @dates}
              <div
                id={"day_col_#{format_date(date)}"}
                data-date={format_date(date)}
                class="flex-1 border-r border-tt-border-calendar relative"
                @mousedown.stop="startNewTimebox($event, $el.dataset.date)"
              >
              </div>
            {/for}
          </div>
        </div>
      </div>
    </div>
    """
  end
end

app.js:

import { Socket } from "phoenix"
import { LiveSocket } from "phoenix_live_view"
import topbar from "topbar"
import Alpine from "alpinejs"
import Hooks from "./_hooks"

import "./app/week_calendar.js"

window.Alpine = Alpine
Alpine.start()

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {
  params: { _csrf_token: csrfToken },
  hooks: Hooks,
  dom: {
    onBeforeElUpdated(from, to) {
      if (from._x_dataStack) {
        window.Alpine.clone(from, to)
      }
    },
  },
});

topbar.config({ barColors: { 0: "#03ad8c" }, shadowColor: "rgba(0, 0, 0, .3)" })
window.addEventListener("phx:page-loading-start", info => topbar.show())
window.addEventListener("phx:page-loading-stop", info => topbar.hide())

liveSocket.connect()
window.liveSocket = liveSocket

./app/week_calendar.js

document.addEventListener("alpine:init", () => {
  Alpine.data("week_calendar_data", () => ({
    fromHour: 0,
    toHour: 0,
    newTimebox: null,
    startNewTimebox(event, date) {
      const fromTime = this.getTimeFromEvent(event)
      this.newTimebox = {
        date: date,
        fromTime: fromTime,
        toTime: null
      }
      console.log(`Start new timebox ${date} ${fromTime.hour}:${fromTime.minute}`)
    },
  }))
});

Chrome dev tools:

Chrome console:
Screen Shot 2021-11-04 at 03.59.51

Showing Posts 1 to 10

seanc

seanc

Does it work if you get rid of Alpine.start()? Importing might automatically start it.

fceruti

fceruti OP

Nothing happens, the event handlers are not present. Alpine is not started in the import.

cmo

cmo

You got an x-data on that div, or its parent?

fceruti

fceruti OP

Yes there is, I updated my original post to show more context.

cmo

cmo

what’s the rendered html look like for the bit inside {#for date <- @dates}?

fceruti

fceruti OP

This is the page full html (ps: I made a few updates to the original post)

view-source:127.0.0.1:4000/app/calendar

<div data-phx-main="true" data-phx-session="SFMyNTY.g2gDaAJhBXQAAAAIZAACaWRtAAAAFHBoeC1GclJGMEZlRS1DVVB2UktCZAAMbGl2ZV9zZXNzaW9uaAJkAAdkZWZhdWx0bggAUIScpgUdtBZkAApwYXJlbnRfcGlkZAADbmlsZAAIcm9vdF9waWRkAANuaWxkAAlyb290X3ZpZXdkAB9FbGl4aXIuVGltZXRhc2tBcHAuTGl2ZUNhbGVuZGFyZAAGcm91dGVyZAAZRWxpeGlyLlRpbWV0YXNrV2ViLlJvdXRlcmQAB3Nlc3Npb250AAAAAGQABHZpZXdkAB9FbGl4aXIuVGltZXRhc2tBcHAuTGl2ZUNhbGVuZGFybgYAzjTB6XwBYgABUYA.gQQA8Bf1ScKf-xpokXsCPC48M9lqLWwb6Won9BzCkpA" data-phx-static="SFMyNTY.g2gDaAJhBXQAAAADZAAKYXNzaWduX25ld2wAAAACZAALX19jb250ZXh0X19kAAtfX3N1cmZhY2VfX2pkAAVmbGFzaHQAAAAAZAACaWRtAAAAFHBoeC1GclJGMEZlRS1DVVB2UktCbgYAzjTB6XwBYgABUYA.GBBwOY7Xtgbxw51hEzU0mvpHuSMM9realSNQyzeoL8A" id="phx-FrRF0FeE-CUPvRKB"><!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="NWVsPwERIkA3IUFBJwc_FVxgFUh7ZGFPw2YeXgo-AY3vO3kRo1w1LU9w" name="csrf-token">
<title>Calendar</title>
    <link phx-track-static rel="stylesheet" href="/assets/app.css">
    <script defer phx-track-static type="text/javascript" src="/assets/app.js"></script>
  </head>
  <body>
    <div class="flex flex-col min-h-screen max-h-screen select-none overflow-hidden bg-gray-0">
    <nav>
  <div class="px-4">
    <div class="grid grid-cols-6 h-16 items-center">
      <div class="col-span-2">
        <div class="flex items-center">
          <a class="block h-6 w-auto mr-8 ml-2" href="/app/calendar">
            <svg width="100%" height="100%" viewBox="0 0 606 123" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule: evenodd; clip-rule: evenodd; stroke-linejoin: round; stroke-miterlimit: 2; max-height: 100px">
    <g transform="matrix(1,0,0,1,-196,-237)">
        <g id="Layer-1" serif:id="Layer 1">
            <g transform="matrix(1,0,0,1,219.121,343.75)">
                <path d="M0,-37.498L0,-51.124L-19.121,-51.124L-19.121,-36.216C-19.121,-8.689 3.195,13.626 30.722,13.626L33.105,13.626L33.105,-5.22L30.722,-5.22C13.755,-5.22 0,-20.531 0,-37.498" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,0,31.156)">
                <rect x="269.411" y="242.624" width="18.583" height="83.596" style="fill: rgb(65,65,91)"></rect>
            </g>
            <g transform="matrix(1,0,0,1,270.098,244.227)">
                <path d="M0,5.141C2.361,7.504 5.335,8.752 8.604,8.752C12.004,8.752 15.139,7.415 17.433,4.988C19.645,2.645 20.814,-0.329 20.814,-3.611L-3.605,-3.611C-3.605,-0.242 -2.356,2.786 0,5.141" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,530.42,332.174)">
                <path d="M0,-58.394L-0.012,-83.574L-14.114,-83.574L-14.114,-13.575C-14.114,7.833 3.256,25.18 24.664,25.152L24.664,10.962C11.097,10.962 0.094,-0.026 0.076,-13.594L0.042,-35.514L0.013,-35.514L0.008,-44.286L24.664,-44.303L24.664,-58.394L0,-58.394Z" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,621.528,294.74)">
                <path d="M0,41.689C-5.881,47.527 -12.813,50.366 -21.195,50.366C-29.487,50.366 -36.398,47.523 -42.329,41.677C-48.26,35.832 -51.144,28.969 -51.144,20.701C-51.144,12.53 -48.26,5.716 -42.329,-0.131C-36.396,-5.977 -29.484,-8.82 -21.195,-8.82C-12.815,-8.82 -5.883,-5.981 0,-0.143C5.89,5.705 8.753,12.524 8.753,20.701C8.753,28.977 5.89,35.843 0,41.689M8.753,-10.612C6.857,-12.442 4.771,-14.12 2.496,-15.639C-4.651,-20.406 -12.718,-22.822 -21.487,-22.822C-33.529,-22.822 -43.964,-18.528 -52.498,-10.061C-61.023,-1.603 -65.347,8.746 -65.347,20.701C-65.347,32.748 -61.027,43.166 -52.51,51.668C-43.975,60.19 -33.538,64.511 -21.487,64.511C-12.712,64.511 -4.644,62.093 2.496,57.328C4.771,55.809 6.857,54.128 8.753,52.289L8.753,62.636L22.958,62.636L22.958,-20.96L8.753,-20.96L8.753,-10.612Z" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,698.696,318.45)">
                <path d="M0,-5.731L-9.553,-8.785L-23.552,-13.258C-30.075,-15.25 -30.955,-18.171 -30.955,-20.765C-30.955,-23.668 -29.424,-26.28 -26.271,-28.751C-22.831,-31.45 -18.06,-32.819 -12.089,-32.819C-5.425,-32.819 0.452,-30.794 5.877,-26.626L7.401,-25.455L17.594,-35.476L14.274,-37.826C6.11,-43.602 -3.154,-46.532 -13.265,-46.532C-22.449,-46.532 -30.188,-43.959 -36.268,-38.888C-42.581,-33.616 -45.783,-27.42 -45.783,-20.476C-45.783,-15.769 -44.191,-11.5 -41.052,-7.789C-38.021,-4.198 -33.571,-1.561 -27.972,0.008L-20.786,2.26L-4.478,7.372C5.015,10.342 5.015,14.275 5.015,15.755C5.015,16.681 5.015,19.494 0.148,22.954C-3.625,25.638 -8.299,26.943 -14.145,26.943C-29.364,26.943 -38.443,15.016 -38.443,15.016L-48.347,24.754C-48.347,24.754 -41.905,33.542 -31.205,37.707C-25.399,39.967 -19.088,40.801 -12.677,40.801C-3.822,40.801 3.74,38.35 9.802,33.512C16.171,28.433 19.4,22.312 19.4,15.323C19.4,8.351 16.018,-0.964 0,-5.731" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,393.782,354.677)">
                <path d="M0,-80.06C-3.938,-81.834 -8.218,-82.759 -12.833,-82.759L-17.232,-82.759C-24.307,-82.759 -30.728,-80.586 -36.318,-76.298C-37.382,-75.483 -38.359,-74.607 -39.287,-73.698C-40.215,-74.607 -41.192,-75.483 -42.257,-76.298C-47.847,-80.586 -54.268,-82.759 -61.342,-82.759L-65.741,-82.759C-70.356,-82.759 -74.637,-81.834 -78.574,-80.06C-81.942,-78.542 -85.061,-76.411 -87.888,-73.613C-94.04,-67.523 -97.157,-60.079 -97.157,-51.486L-97.157,2.699L-78.577,2.699L-78.577,-50.763C-78.511,-54.483 -77.208,-57.53 -74.475,-60.23C-71.75,-62.923 -68.743,-64.178 -65.014,-64.178L-62.065,-64.178C-58.338,-64.178 -55.333,-62.923 -52.606,-60.228C-49.874,-57.53 -48.57,-54.483 -48.505,-50.763L-48.505,2.699L-30.07,2.699L-30.07,-50.763C-30.004,-54.483 -28.701,-57.53 -25.969,-60.228C-23.241,-62.923 -20.237,-64.178 -16.509,-64.178L-13.56,-64.178C-9.832,-64.178 -6.825,-62.923 -4.1,-60.23C-1.368,-57.53 -0.063,-54.483 0.003,-50.763L0.003,2.699L18.582,2.699L18.582,-51.486C18.582,-60.079 15.465,-67.523 9.313,-73.613C6.487,-76.411 3.367,-78.542 0,-80.06" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,237.775,273.779)">
                <path d="M0,18.846L22.94,18.846L22.94,0L-18.655,0C-18.655,10.408 -10.409,18.846 0,18.846" style="fill: rgb(0,225,171); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(0,1,1,0,226.143,247.637)">
                <path d="M-7.021,-26.143L7.309,-26.143C17.717,-26.143 26.143,-17.431 26.143,-7.023L-7.021,-7.021L-7.021,-26.143Z" style="fill: rgb(0,173,140); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,759.544,273.773)">
                <path d="M0,34.359L34.099,0L-0.083,34.258L0,34.359Z" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,759.461,297.945)">
                <path d="M0,10.086L34.182,-24.173L14.216,-24.173L-20.299,10.46L-20.299,-49.345L-34.54,-49.345L-34.54,59.431L-20.299,59.431L-20.299,30.725L0.083,10.187L0,10.086Z" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,749.022,318.737)">
                <path d="M0,0.169L0.163,0.001L0.162,0L0,0.169Z" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,800,318.5)">
                <path d="M0,38.876L-31.938,0L-50.581,0L-50.814,0.238L-18.875,38.876L0,38.876Z" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
            <g transform="matrix(1,0,0,1,438.97,324.014)">
                <path d="M0,-16.859L0.038,-16.974C1.391,-21.066 3.689,-24.625 7.065,-27.852C12.295,-32.85 18.392,-35.278 25.7,-35.278C33.114,-35.278 39.285,-32.844 44.563,-27.837C47.959,-24.613 50.253,-21.06 51.577,-16.974L51.614,-16.859L0,-16.859ZM57.09,-39.418C48.954,-47.919 38.395,-52.229 25.704,-52.229C13.472,-52.229 2.975,-47.912 -5.496,-39.4C-13.938,-30.912 -18.22,-20.514 -18.22,-8.498C-18.22,3.593 -13.66,14.057 -4.668,22.604C4.24,31.075 15.157,35.37 27.778,35.37C35.241,35.37 42.318,33.75 48.813,30.556C52.824,28.581 56.545,26.044 59.871,23.014L59.974,22.92L47.704,10.65L47.614,10.561L47.521,10.646C45.533,12.457 43.338,13.931 40.811,15.151C36.772,17.1 32.509,18.047 27.778,18.047C20.221,18.047 13.875,15.63 8.379,10.66C4.913,7.526 2.554,4.108 1.168,0.213L0.795,-0.886L67.731,-0.886L67.755,-0.988C69.816,-9.405 69.249,-17.856 66.117,-25.427C63.912,-30.757 60.875,-35.465 57.09,-39.418" style="fill: rgb(65,65,91); fill-rule: nonzero"></path>
            </g>
        </g>
    </g>
</svg>


          </a>

          <nav class="flex gap-2">
            <a tabindex="-1" href="/app/calendar">
    <button class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 hover:text-brand-dark font-normal text-brand-regular fill-current" tabindex="-1" type="button">
    
    
              <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="fill-current" viewBox="0 0 24 24"><path d="M3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-2V2h-2v2H9V2H7v2H5a2 2 0 0 0-2 2zm16 14H5V8h14z"/></svg>
            
  
  </button>

</a>


            <a tabindex="-1" href="/app/projects">
    <button class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 hover:text-brand-dark font-normal text-tt-text fill-current" tabindex="-1" type="button">
    
    
              <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="fill-current" viewBox="0 0 24 24"><path d="M18.5 2h-12C4.57 2 3 3.57 3 5.5V22l7-3.5 7 3.5v-9h5V5.5C22 3.57 20.43 2 18.5 2zM15 18.764l-5-2.5-5 2.5V5.5C5 4.673 5.673 4 6.5 4h8.852A3.451 3.451 0 0 0 15 5.5v13.264zM20 11h-3V5.5c0-.827.673-1.5 1.5-1.5s1.5.673 1.5 1.5V11z"/></svg>
            
  
  </button>

</a>


            <a tabindex="-1" href="/app/reports">
    <button class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 hover:text-brand-dark font-normal text-tt-text fill-current" tabindex="-1" type="button">
    
    
              <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="fill-current" viewBox="0 0 24 24"><path d="M9 6h2v14H9zm4 2h2v12h-2zm4-4h2v16h-2zM5 12h2v8H5z"/></svg>
            
  
  </button>

</a>


          </nav>
        </div>
      </div>
      <div class="col-span-2 flex justify-center">
        
            <a data-phx-link="patch" data-phx-link-state="push" href="/app/calendar?date=today">
      <button class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 text-tt-text bg-transparent font-medium hover:bg-gray-50 hover:text-tt-text-dark active:text-brand-regular active:bg-transparent fill-current" tabindex="-1" type="button">
    
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="fill-current" viewBox="0 0 24 24"><path d="M13.293 6.293 7.586 12l5.707 5.707 1.414-1.414L10.414 12l4.293-4.293z"/></svg>
    
  </button>

  </a>

  <a data-phx-link="patch" data-phx-link-state="push" href="/app/calendar?date=today">
      <button class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 text-tt-text bg-transparent font-medium hover:bg-gray-50 hover:text-tt-text-dark active:text-brand-regular active:bg-transparent font-semibold w-52 justify-center" tabindex="-1" type="button">
    
      8 - 14 November
    
  </button>

  </a>

  <a data-phx-link="patch" data-phx-link-state="push" href="/app/calendar?date=2021-11-18">
      <button class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 text-tt-text bg-transparent font-medium hover:bg-gray-50 hover:text-tt-text-dark active:text-brand-regular active:bg-transparent fill-current" tabindex="-1" type="button">
    
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="fill-current" viewBox="0 0 24 24"><path d="M10.707 17.707 16.414 12l-5.707-5.707-1.414 1.414L13.586 12l-4.293 4.293z"/></svg>
    
  </button>

  </a>


        
      </div>
      <div class="col-span-2 flex justify-end">
        <div phx-hook="TimetaskApp.Components.Dropdown#Dropdown" class="relative inline-block text-left z-20" id="nav-dropdown">
    <button phx-click="toggle_dropdown" phx-target="4" class="inline-flex items-center rounded-md focus:outline-none transition duration-75 whitespace-nowrap disabled:cursor-not-allowed py-2 px-3 text-base gap-2 text-tt-text bg-transparent font-medium hover:bg-gray-50 hover:text-tt-text-dark active:text-brand-regular active:bg-transparent fill-current" tabindex="-1" type="button">
    
    
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="fill-current" viewBox="0 0 24 24"><path d="M12 16c2.206 0 4-1.794 4-4s-1.794-4-4-4-4 1.794-4 4 1.794 4 4 4zm0-6c1.084 0 2 .916 2 2s-.916 2-2 2-2-.916-2-2 .916-2 2-2z"/><path d="m2.845 16.136 1 1.73c.531.917 1.809 1.261 2.73.73l.529-.306A8.1 8.1 0 0 0 9 19.402V20c0 1.103.897 2 2 2h2c1.103 0 2-.897 2-2v-.598a8.132 8.132 0 0 0 1.896-1.111l.529.306c.923.53 2.198.188 2.731-.731l.999-1.729a2.001 2.001 0 0 0-.731-2.732l-.505-.292a7.718 7.718 0 0 0 0-2.224l.505-.292a2.002 2.002 0 0 0 .731-2.732l-.999-1.729c-.531-.92-1.808-1.265-2.731-.732l-.529.306A8.1 8.1 0 0 0 15 4.598V4c0-1.103-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.598a8.132 8.132 0 0 0-1.896 1.111l-.529-.306c-.924-.531-2.2-.187-2.731.732l-.999 1.729a2.001 2.001 0 0 0 .731 2.732l.505.292a7.683 7.683 0 0 0 0 2.223l-.505.292a2.003 2.003 0 0 0-.731 2.733zm3.326-2.758A5.703 5.703 0 0 1 6 12c0-.462.058-.926.17-1.378a.999.999 0 0 0-.47-1.108l-1.123-.65.998-1.729 1.145.662a.997.997 0 0 0 1.188-.142 6.071 6.071 0 0 1 2.384-1.399A1 1 0 0 0 11 5.3V4h2v1.3a1 1 0 0 0 .708.956 6.083 6.083 0 0 1 2.384 1.399.999.999 0 0 0 1.188.142l1.144-.661 1 1.729-1.124.649a1 1 0 0 0-.47 1.108c.112.452.17.916.17 1.378 0 .461-.058.925-.171 1.378a1 1 0 0 0 .471 1.108l1.123.649-.998 1.729-1.145-.661a.996.996 0 0 0-1.188.142 6.071 6.071 0 0 1-2.384 1.399A1 1 0 0 0 13 18.7l.002 1.3H11v-1.3a1 1 0 0 0-.708-.956 6.083 6.083 0 0 1-2.384-1.399.992.992 0 0 0-1.188-.141l-1.144.662-1-1.729 1.124-.651a1 1 0 0 0 .471-1.108z"/></svg>
          
  
  </button>


  
</div>

      </div>
    </div>
  </div>
</nav>



  <div class="full-width-container">
    <div class="w-full h-full flex flex-col" style="height: calc(100vh - 100px)" id="week-calendar">  
  <div class="flex h-10 w-full">  
    <div class="h-10 calendar-head" style="width: 40px"></div>
    <div class="h-10 flex-1 flex">
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Monday 8
</button>

        </div>
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Tuesday 9
</button>

        </div>
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Wednesday 10
</button>

        </div>
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Thursday 11
</button>

        </div>
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Friday 12
</button>

        </div>
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Saturday 13
</button>

        </div>
      
        <div class="flex-1 flex justify-center items-end pb-2 calendar-head">
          <button class="text-tt-text inline-flex items-center py-2 px-4 rounded-md hover:bg-gray-50 hover:font-semibold focus:outline-none" tabindex="-1">
  Sunday 14
</button>

        </div>
      
    </div>
  </div>

  <div class="h-full flex-1 flex flex-row relative">  
    <div class="flex flex-col border-r border-tt-border-calendar" style="width: 40px">  
      
        <div id="hour_line_7" class="relative h0">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">7</span>
        </div>
      
        <div id="hour_line_8" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">8</span>
        </div>
      
        <div id="hour_line_9" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">9</span>
        </div>
      
        <div id="hour_line_10" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">10</span>
        </div>
      
        <div id="hour_line_11" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">11</span>
        </div>
      
        <div id="hour_line_12" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">12</span>
        </div>
      
        <div id="hour_line_13" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">13</span>
        </div>
      
        <div id="hour_line_14" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">14</span>
        </div>
      
        <div id="hour_line_15" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">15</span>
        </div>
      
        <div id="hour_line_16" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">16</span>
        </div>
      
        <div id="hour_line_17" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">17</span>
        </div>
      
        <div id="hour_line_18" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">18</span>
        </div>
      
        <div id="hour_line_19" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">19</span>
        </div>
      
        <div id="hour_line_20" class="relative flex-1">
          <span class="absolute right-6 -bottom-2 text-xs text-tt-text-dimmed">20</span>
        </div>
      
    </div>
    <div phx-hook="TimetaskApp.WeekCalendar#WeekCalendar" class="flex-1 flex" id="week-calendar-columns" x-init="fromHour = +$el.dataset.fromHour; toHour = +$el.dataset.toHour;" x-data="week_calendar_data" data-from-hour="7" data-to-hour="20">  
      <div class="w-0 h-full flex flex-col"> 
        
          <div id="hour_7" class="calendar-line flex-1"></div>
        
          <div id="hour_8" class="calendar-line flex-1"></div>
        
          <div id="hour_9" class="calendar-line flex-1"></div>
        
          <div id="hour_10" class="calendar-line flex-1"></div>
        
          <div id="hour_11" class="calendar-line flex-1"></div>
        
          <div id="hour_12" class="calendar-line flex-1"></div>
        
          <div id="hour_13" class="calendar-line flex-1"></div>
        
          <div id="hour_14" class="calendar-line flex-1"></div>
        
          <div id="hour_15" class="calendar-line flex-1"></div>
        
          <div id="hour_16" class="calendar-line flex-1"></div>
        
          <div id="hour_17" class="calendar-line flex-1"></div>
        
          <div id="hour_18" class="calendar-line flex-1"></div>
        
          <div id="hour_19" class="calendar-line flex-1"></div>
        
          <div id="hour_20" class="calendar-line"></div>
        
      </div>
      <div class="flex-1 flex" id="week-calendar-days-container" x-ref="days_container" @mousemove.outside="updateNewTimeboxOutside($event)" @mouseup.stop.outside="stopNewTimebox()" @keydown.escape.window="newTimebox = null"> 
        
          <div id="day_col_2021-11-08" data-date="2021-11-08" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-08&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-08&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
          <div id="day_col_2021-11-09" data-date="2021-11-09" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-09&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-09&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
          <div id="day_col_2021-11-10" data-date="2021-11-10" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-10&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-10&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
          <div id="day_col_2021-11-11" data-date="2021-11-11" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-11&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-11&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
          <div id="day_col_2021-11-12" data-date="2021-11-12" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-12&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-12&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
          <div id="day_col_2021-11-13" data-date="2021-11-13" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-13&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-13&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
          <div id="day_col_2021-11-14" data-date="2021-11-14" class="flex-1 border-r border-tt-border-calendar relative" @mousedown.stop="startNewTimebox($event, $el.dataset.date)" @mousemove.stop="onColumnMouseMouse($event, $el.dataset.date)" " @mouseup.stop="onColumnMouseUp()">
            <div :style="`
                display: ${showNewTimebox(&#39;2021-11-14&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${newTimeboxGeometry().height}px;
                top: ${newTimeboxGeometry().top}px;
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-50"></div> 

            <div :style="`
                display: ${showMovingTimebox(&#39;2021-11-14&#39;) ? &#39;block&#39;: &#39;none&#39;};
                height: ${movingTimeboxGeometry().height}px;
                top: ${movingTimeboxGeometry().top}px;
                ${movingTimeboxColors()};
              `" class="absolute left-3 right-0 rounded-md bg-gray-100 opacity-100 z-20"></div> 
            

          </div>
        
      </div>
    </div>
  </div>
</div>

  </div>

  


  


    <div x-data>
  
    
  
    
  
</div>



    </div>
  <iframe hidden height="0" width="0" src="/phoenix/live_reload/frame"></iframe></body>
</html>
</div>

What you are asking is inside the element with id week-calendar-days-container

cmo

cmo

Probably doesn’t matter but you have a random " in the divs with the IDs <div id="day_col_2021-11-09"?

I’ve had to use alpines template tag (wrapped in a Raw tag - I use surface) for somewhere where I generated a list of things which had myriad alpine bindings. Unfortunately, I’ve stepped away from the computer for the day so I can’t show you an example.

fceruti

fceruti OP

By any chance are you back yet? I’m stilll having this issue

cmo

cmo

Here is a cut down version. Note that I’m using Surface, hence the <#Raw> tags (I assume there is a parallel in plain old liveview) and different syntax. The hook reads attributes from the hidden spans and sends them to Apline. Alpine creates the html for the options. I had a bit of trouble getting this to work and when it worked I stopped touching it and moved on. I hope to revist if/when I get some time :wink:

    <div
      id={"column-filter-#{@field}"}
      :hook="ColumnOptionsFilter"
      x-data="{
        ...
        options: [],
        ...
      }"
      @options-loaded="options = $event.detail.options"
    ...
    >
      <div id={"column-filter-#{@field}-data"} hidden>
        {#for option <- @all_options}
          <span data-option={option} />
        {/for}
      </div>

    ...

        <div id={"column-filter-options-#{@field}"} phx-update="ignore">
          <#Raw>
          <template x-for="(option, index) in options" :key="index">
          </#Raw>
            <div class="flex items-center py-1">
              <input
                x-model="selected"
                :value="option"
                :id="option"
                :name="option"
                type="checkbox"
                :class="{ 'opacity-50': !available[index]}"
                class="h-4 w-4 text-blue-900 focus:ring-blue-900 border-gray-300"
              />
              <label
                :for="option"
                x-text="option"
                :class="{ 'text-gray-400': !available[index], 'text-gray-900': available[index] }"
                class="ml-2 block text-sm"
              />
            </div>
          <#Raw>
          </template>
          </#Raw>
        </div>
     ...
     </div>

Hook:

const ColumnOptionsFilter = {
  mounted() {
    const options = Array.from(
      document.getElementById(this.el.id + "-data").children || []
    ).map(({ dataset: { option, available, selected } }) => {
      return option === undefined ? "[Blanks]" : option;
    });

   ...

    setTimeout(() => {
      if (options.length > 0) {
        var event = new CustomEvent("options-loaded", {
          detail: { options: options, available: available },
        });
        this.el.dispatchEvent(event);
        this.optionsLoaded = true;
      }
    }, 0);
  },
fceruti

fceruti OP

:raised_hands: thanks!

Me too!

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews