Search code examples
javascriptphplaraveleventsalpine.js

Alpinejs Event Listener On Checkbox Not Toggling Show Variable Value


I'm working with Alpinejs and Laravel and I wanted to show a hidden input field when a checkbox is checked.

So here it is:

<div x-data="{ show:false }">
    <div class="row mb-3">
        <div class="form-check">
            <input class="form-check-input" type="checkbox" id="gridCheck1" name="change_background" @click="show = event.target.value == 'on' ? true : false">
            <label class="form-check-label" for="gridCheck1">
                Change Background
            </label>
        </div>
    </div>

    <div class="row mb-3" x-show="show">
        <label for="background" class="col-sm-2 col-form-label">Background File</label>
        <div class="col-sm-10">
            <input class="form-control" type="file" name="background" id="background">
        </div>
    </div>
</div>

So if user checks the checkbox (Change Background), then the file input field would be appear.

So I tried binding the value to show variable:

@click="show = event.target.value == 'on' ? true : false">

Now the problem with this is that, when I uncheck the checkbox once again to hide the file upload field, it still appears on the page somehow.

So what's going wrong here? How can I toggle this field depending on the value of checkbox?


Solution

  • The default value of a checkbox is on. Therefore event.target.value == 'on' is always true, so show will be always true after the first click.

    The fix is very easy, just use the x-model directive to bind the boolean value of show to the checkbox:

    <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
    <div x-data="{ show:false }">
      <div class="row mb-3">
        <div class="form-check">
          <input class="form-check-input" type="checkbox" id="gridCheck1" x-model="show">
          <label class="form-check-label" for="gridCheck1">
            Change Background
          </label>
        </div>
      </div>
    
      <div class="row mb-3" x-show="show">
        <label for="background" class="col-sm-2 col-form-label">Background File</label>
        <div class="col-sm-10">
          <input class="form-control" type="file" name="background" id="background">
        </div>
      </div>
    </div>