Search code examples
javascriptselectonchangealpine.js

Alpine.js - show/hide div based from select input values


I'm trying to show and hide div's based from a select box selected value. I have my select boxes working so that it changes the value like so:

// x-data="{ week: false, day: false }

            <select @change="week = $event.target.value">
                <option x-bind:value="Week 1">Week 1</option>
                <option x-bind:value="Week 2">Week 2</option>
                <option x-bind:value="Week 3">Week 3</option>
            </select>
            <select @change="day = $event.target.value">
                <option x-bind:value="1">Monday</option>
                <option x-bind:value="2">Tuesday</option>
                <option x-bind:value="3">Wednesday</option>
                <option x-bind:value="4">Thursday</option>
                <option x-bind:value="5">Friday</option>
            </select>
            <span x-text="'option '+ week"></span>
            <span x-text="'option '+ day"></span>

I am then trying to show and hide divs based on the selections like so, but having no luck.

<div :class="week !== {{ $week['name'] }} ? 'hidden' : 'block'">
     <p>{{ $week['name'] }}</p>
</div>

How can I correctly set the class? or can I do this using x-show?


Solution

  • When you insert strings from the backend template system, you have to make sure that you place it in a correct environment. Blade does not know that you actually want to generate JS code, it just parses Blade-specific part of the template. In the :class attribute you are missing quotations marks around {{ $week['name'] }}. Blade just inserts the string e.g. Week 1 but you have to add the quotations marks around it to create valid JS code. And yes, you can use the x-show directive to hide/show content. Furthermore instead of @change for input element you can use x-model directive.

    <!-- Assuming you have 'week' and 'day' in x-data -->
    <select x-model="week">
        <option x-bind:value="Week 1">Week 1</option>
        <option x-bind:value="Week 2">Week 2</option>
        <option x-bind:value="Week 3">Week 3</option>
    </select>
    <select x-model="day">
        <option x-bind:value="1">Monday</option>
        <option x-bind:value="2">Tuesday</option>
        <option x-bind:value="3">Wednesday</option>
        <option x-bind:value="4">Thursday</option>
        <option x-bind:value="5">Friday</option>
    </select>    
    
    <div x-show="week === '{{ $week['name'] }}'">
        <p>{{ $week['name'] }}</p>
    </div>