0

I have a 'Add' button which adds a select box and when I select a value in the select box I want to display an input field so every time I click 'Add' it should show a select box and when I select a value in it I would like to display an input field.

I know I could use a flag 'selected' but when I already add one select box this would change the flag to true and show the input field immediately after I click 'Add' but I want the input field to show only when a value is selected.

<template>
    <button @click="onBtnClick">Add<button>
    <select>...</select> # This gets added when 'Add' button is clicked
    <input v-if="selected" type="text" /> # This should show when a value is selected.
<select>
</template>

data(){
    return {
       selected: false
  }
},
methods: {
  onValueSelected(){
    this.selected = true
  }
}

Do you have any ideas how I could accomplish this?

4
  • how do you calling onValueSelected method? Commented Jan 12, 2019 at 10:18
  • Right now I am not calling it at all because it won't do what I need. Normally, I would call it with @change="onValueSelected" Commented Jan 12, 2019 at 10:22
  • @jedi Do you need the input field to be dynamically added also? Commented Jan 12, 2019 at 10:54
  • Yes, this is what I want. I need the input text field to be dynamic as well. Commented Jan 12, 2019 at 11:05

2 Answers 2

1

Use v-for and push new fields onto the collection at will.

new Vue({
  el: '#app',

  data() {
    return {
      goods: []
    }
  },

  methods: {
    addSelect() {
      let item = {
        id: this.goods.length,
        menus: [
          { value: '', text: '- select -' },
          { value: 1, text: 'Item 1' },
          { value: 2, text: 'Item 2' },
          { value: 3, text: 'Item 3' }
        ],
        input: {
          show: false
        }
      };

      this.goods.push(item);
    },
    
    showInput(item, e) {
      item.input.show = e.currentTarget.selectedIndex > 0;
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button @click="addSelect">Add to cart</button>

  <div v-for="item in goods" :key="item.id" class="goods">
    <select @change="showInput(item, $event)">
      <option 
        v-for="opt in item.menus" 
        :key="opt.key"
        value="opt.value">
        {{opt.text}}
      </option>
    </select>
    
    <input v-if="item.input.show" type="text" value="0" />
  </div>

</div>

Sign up to request clarification or add additional context in comments.

2 Comments

I would recommend against using the change event, and instead use a v-model instead. Then simply check in the v-if if the modelled value is not a falsy value. (Something similar to codesandbox.io/s/y26k62r62v ) Using the change event opens up questions like "But what if I changed the value of the dropdown myself", while using a v-model and a v-if that uses that model will work correctly regardless of how the modelled data changes.
@Sumurai8 Thanks, I'll keep that in mind. I am using v-model myself in different places, but it's good to note that v-model actually does the same thing as binding the value attribute and @change or @input.
0

I figured out that I can render a new component and pass it props. Everytime a new component is rendered it gets selected flag as false by default and I can change it then by selecting a value in the select box.

<b-form-group 
    v-if="element.elementName === 'Some value'"
    label="Select field *:"
    label-for="benefitSelectField">
    <SalaryField :element="element" />
</b-form-group>

SalaryField component

<template>
  <div>
    <select @change="onValueSelected" ></select>
    <input v-if="selected" type="text" />       
  </div>
</template>
<script>
  export default {
    props: {
      element: Object
    },
    data(){
      return {
        selected: false,
      }
    },
    methods: {
      onValueSelected() {
        this.selected = true
      }
    }
  }
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.