coder805
coder805

Reputation: 21

Alpine.js Form has Multiple Selects, How to get Option values?

Using Alpine.js how do you get the value of select1 or select2 in the main form() function?

I can do it if I don't use x-data on the Selects, but then you have to do funky things with the open variable so it is unique for each Select (if you don't, then all the Selects open at once).

Notes:

<div x-data="form()">

  <!-- snip other fields like regular inputs -->

  <label for="select-1">Select 1</label>
  <div x-data="{ select1: '', open: false }">
    <div>Selected: <span x-text="select1"></span></div>
    <button @click="open=true">Select ...</button>
    <ul x-show="open" @click.away="open=false" x-model="select1" style="display: none;">
      <li @click="$dispatch('input', 'option1Key')"><i class="icon"></i> Option1</li>
      <li @click="$dispatch('input', 'option2Key')"><i class="icon"></i> Option2</li>
    </ul>
  </div>

  <label for="select-2">Select 2</label>
  <div x-data="{ select2: '', open: false }">
    <div>Selected: <span x-text="select2"></span></div>
    <button @click="open=true">Select ...</button>
    <ul x-show="open" @click.away="open=false" x-model="select2" style="display: none;">
      <li @click="$dispatch('input', 'option1Key')"><i class="icon"></i> Option1</li>
      <li @click="$dispatch('input', 'option2Key')"><i class="icon"></i> Option2</li>
    </ul>
  </div>

  <button class="search" type="submit" :disabled="loading" @click="search()">Search</button>

</div>
<script>
function form() {
  return {
    select1: '',
    select2: '',
    search() {
      console.log(select1); // undefined
      console.log(select2); // undefined
    },
  };
};

Upvotes: 2

Views: 6847

Answers (1)

Hugo
Hugo

Reputation: 3888

For posterity, we discussed this through another channel but the way to fix this issue is to have a single Alpine component (x-data)

<div x-data="f()">

  <!-- snip other fields like regular inputs -->

  <div class="select">
    <label for="select-1">Select 1 Label</label>
    <div>
      <div class="output">x-text "select1": <span x-text="select1"></span></div>
      <button @click="open='select1'">Click to Select1 ...</button>
      <ul x-show="open === 'select1'" @click.away="open=null" x-model="select1">
        <li @click="$dispatch('input', 'option1Key')"><i class="icon"></i> Option1</li>
        <li @click="$dispatch('input', 'option2Key')"><i class="icon"></i> Option2</li>
      </ul>
    </div>
  </div>

  <div class="select">
    <label for="select-2">Select 2 Label</label>
    <div>
      <div class="output">x-text "select2": <span x-text="select2"></span></div>
      <button @click="open='select2'">Click to Select2 ...</button>
      <ul x-show="open === 'select2'" @click.away="open=null" x-model="select2">
        <li @click="$dispatch('input', 'option1Key')"><i class="icon"></i> Option1</li>
        <li @click="$dispatch('input', 'option2Key')"><i class="icon"></i> Option2</li>
      </ul>
    </div>
  </div>

  <button class="search" type="submit" :disabled="loading" @click="search()">Search</button>

</div>

Script

function f() {
  return {
    open: null,
    loading: false,
    select1: '',
    select2: '',
    search() {
      console.log('select1 value: ' + "'" + this.select1 + "'"); // ''
      console.log('select2 value: ' + "'" + this.select2 + "'"); // ''
    },
  };
}

The fills working fiddle is at https://jsfiddle.net/w7hg341m/9/

Upvotes: 1

Related Questions