1

I am using Laravel with alpinejs version 3.2.4. I would like to show/hide some input elements and show them based on what the user selects. This is my code:

<form x-data="{payFor: ''}">

  <select x-model="payFor" name="payFor">
    <option value="service">Service</option>
    <option value="product">Product</option>
  </select>

  <div x-show="payFor == 'service'">
    <select name="serviceId">
      @foreach($services as $service)
      <option value="{{ $service->id }}">{{ $service->service_name }}</option>
      @endforeach
    </select>
  </div>

  <div x-show="payFor == 'product'">
    <select name="productId">
      @foreach($products as $product)
      <option value="{{ $product->id }}">{{ $product->product_name }}</option>
      @endforeach
    </select>
  </div>
 
</form>

This doesn't seem to be working on my forms and I cannot figure out why. When the form loads, all the controls are shown and on selection, none hides. Even when I try to set default x-data="{payFor: 'service'}" it still doesn't work either. Any solution to this?

Steven
  • 51
  • 1
  • 7
  • Does the rest of Alpine function properly? E.g. if you were to add a span with `x-text="payFor"`, does it add the text? If not, what version are you using? If version 3, did you properly initialize it as per the [the docs](https://alpinejs.dev/essentials/installation)? – Yinci Aug 24 '21 at 09:35
  • Yes, all the rest of AlpineJS works just fine. Fortunately, on my edit forms (done in Livewire), Alpine and Livewire work perfectly when I use the `@entangle()` method for the same functionality. I think there's something missing for this to work since I have `@livewireScripts` in my app.blade.php file. This mainly fails on my create forms. – Steven Aug 24 '21 at 11:37

2 Answers2

0

Not sure if this has any relations so laravel, but this is how you do it in plain html (this would also work in your context):

document.getElementById('payFor').addEventListener("change", function (e) {
    if (e.target.value === 'product') {
        document.getElementById('services').style.display = 'none';
        document.getElementById('products').style.display = 'block';
    } else {
        document.getElementById('products').style.display = 'none';
        document.getElementById('services').style.display = 'block'
    }
});
<!DOCTYPE html>
<html>
   <body>
      <form>
         <label for="payFor">Select what to pay for:&nbsp;</label>
         <select name="payFor" id="payFor">
            <option disabled selected value>-</option>
            <option value="service">Service</option>
            <option value="product">Product</option>
         </select>
         <div style="display: none;" id="services">
            <select name="serviceId">
               <option disabled selected value>-</option>
               <option value="service1">service 1</option>
               <option value="service2">service 2</option>
            </select>
         </div>
         <div style="display: none;" id="products">
            <select name="productId">
               <option disabled selected value>-</option>
               <option value="product1">product 1</option>
               <option value="product2">product 2</option>
            </select>
         </div>
      </form>
   </body>
</html>

Just add the selectors to your div, and add this script to get the job done.

Lakshaya U.
  • 1,089
  • 1
  • 5
  • 21
  • This still doesn't work. I think there's something missing for it to work since I have `@livewireScripts` in my app.blade.php file. I think I have to use `@entangle()` though I still haven't figured it out yet. – Steven Aug 24 '21 at 11:46
  • @Steven php got nothing to do with this. This is all handled by the UI. – Lakshaya U. Aug 24 '21 at 12:11
0

I figured another way out. Since I am using livewire, I had to use @if... @else...@endif statement in the HTML class attribute to toggle the divs using show or hide tailwind classes.

Steven
  • 51
  • 1
  • 7