Search code examples
laravellaravel-livewirealpine.js

Using Alpine JS, enable dropdown when one or more checkboxes are checked


I have a need to use some Alpine in an existing Livewire view.

We have rows of data, each with wire:model:defer assigned, each with a checkbox and I would like to use Alpine to enable a dropdown when one of these checkboxes are checked.

Currently I when I click one checkbox, all checkboxes are checked!

Below is a very dumbed down version of my view. I have an outer DIV 'x-data="{enableBulk: false}"' and my dropdown is in one child DIV and the rows, each with a checkbox are in another child DIV!

When I have the 'x-data="{enableBulk: false}"' on the parent DIV it works but ALL checkboxes are checked when I check just one!

<script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.8.0/alpine.js"></script>
<div x-data="{ enableBulk: false }">

    <div class="">
        <div class="card-block mb-5">

            <div class="">
     
                <Select name="bulkAction" x-bind:disabled="!enableBulk"
                    wire:model="bulkAction" class="">
                    <option value=""> Bulk actions </option>
                    <option value="bulk_delete">Delete task(s) </option>
                </select>
            </div>
            <button wire:click='confirmBulkAction' class=" ">
                Apply
            </button>


        </div>
    </div>

    <div>


      <div class="table-bordered-row  group task-list " wire:key="row-11">
        <input type="checkbox" wire:model:defer="checked" name="checked[]" x-model="enableBulk"
               id="task-checkbox-11" value="11" class="" />
        <div class="cursor-pointer unifirm-custom-row items-center">
          <a title="Row #1" class="" href="/xyz">
            Row #1
          </a>
        </div>
      </div>
      
      <div class="table-bordered-row  group task-list " wire:key="row-22">
        <input type="checkbox" wire:model:defer="checked" name="checked[]" x-model="enableBulk"
               id="task-checkbox-22" value="22" class="" />
        <div class="cursor-pointer unifirm-custom-row items-center">
          <a title="Row #2" class="" href="/xyz">
            Row #2
          </a>
        </div>
      </div>


    </div>


</div>

How can I ensure that the dropdown is enabled after just one of the checkboxes are checked, and without all checkboxes being checked when I check one of them?

Any help much appreciated; I know this is a little brief but it is last thing Friday :D


Solution

  • Use an array for the checkboxes so each of them has a unique state and check the length of this array to enable/disable the dropdown element.

    <script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.8.0/alpine.js"></script>
    <div x-data="{ enableBulk: [] }">
      <div class="">
        <div class="card-block mb-5">
            <div class="">     
                <select name="bulkAction" x-bind:disabled="enableBulk.length == 0"
                    wire:model="bulkAction" class="">
                    <option value=""> Bulk actions </option>
                    <option value="bulk_delete">Delete task(s) </option>
                </select>
            </div>
            <button wire:click='confirmBulkAction' class=" ">
                Apply
            </button>
        </div>
      </div>
    
      <div>
      <div class="table-bordered-row  group task-list " wire:key="row-11">
        <input type="checkbox" wire:model.defer="checked" name="checked[]" x-model="enableBulk"
               id="task-checkbox-11" value="11" class="" />
        <div class="cursor-pointer unifirm-custom-row items-center">
          <a title="Row #1" class="" href="/xyz">
            Row #1
          </a>
        </div>
      </div>
    
      <div class="table-bordered-row  group task-list " wire:key="row-22">
        <input type="checkbox" wire:model.defer="checked" name="checked[]" x-model="enableBulk"
               id="task-checkbox-22" value="22" class="" />
        <div class="cursor-pointer unifirm-custom-row items-center">
          <a title="Row #2" class="" href="/xyz">
            Row #2
          </a>
        </div>
      </div>
      </div>
    </div>