For a Django project I am trying to build a toggle component to switch from list to grid view without reloading the page. I am using a Flowbite toggle component. Using Alpine's x-if
I am able to dynamically change the HTML for the list view and the grid view which are contained in two template tags within the same alpine component. Here is a simplified version of the component:
<div x-data="{ value: false }">
<!-- Toggle component from Flowbite -->
<label class="relative inline-flex items-center cursor-pointer">
<input x-model="value" type="checkbox" value="" class="sr-only peer">
<div class="w-11 h-6 bg-slate-300 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-yellow-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-yellow-500"></div>
<span class="ml-2 font-medium text-slate-600 mdi mdi-view-grid"></span>
</label>
<!-- Template tags with the HTML code -->
<template x-if="value===true">
<div>
<a href="{% url 'inventory:inventory' %}">HREF</a>
</div>
</template>
<template x-if="value===false">
<div>
<a hx-get="{% url 'inventory:inventory %}">HX-GET</a>
</div>
</template>
</div>
The toggle works just fine. However, while the toggled code with the href url works just fine, the code with the hx-get attribute (HTMX) does not work. Clicking on the link does not do anything. I suppose this has to do with inserting HTMX properties after the page is already loaded, thus HTMX does not 'see' the code toggled via alpine js.
I tried to apply hx-on (with htmx:load to the main div but I could not make it work. What can be done to make the hx-get attribute work after being added to the page via alpine?
HTMX mentions this phenomena in the documentation, you have to call htmx.process()
on the DOM elements that were not present/visible on page load. You can call this method from e.g. a $watch
:
<div id="mycomponent"
x-data="{ value: false }"
x-init="$watch('value', new_value => {htmx.process(htmx.find('#mycomponent'))})">