0

What is the best way to watch the property and get an index of nested object. Look at my code already solve it manually by passing method in select field @change="operatorChanged(key)"

But in my real project, I'm using https://vue-multiselect.js.org/ instead of normal select tag. In multiselect component I didn't get way to pass key in method. They only provide @select="method" but not allow parameter.

JSFiddle link

Here is my template HTML.

<div class="flexi-area">
<div class="flexi-number-list">
    <div class="flexi-numbers" v-for="(flex, key) in mt.flexi">  

        <input type="number" placeholder="Number" autocomplete="off" id="number" v-model="flex.number" v-on:keyup="numberChange(key)" required>

        <!-- this is created by me-->
        <select v-model="flex.operator_id" @change="operatorChanged(key)">
            <option value="">Operator</option>
            <option v-for="operator in operatorList" :value="operator"> 
                {{ operator.name }}
            </option> 
        </select>

        <!-- this is multiselect field -->
        <multiselect :allow-empty="false" deselect-label="" select-label="" v-model="flex.operator_id" :options="operatorList" :preserve-search="true" placeholder="Operator" label="name" track-by="name" :preselect-first="false" @onChange="operatorChanged(key)">
            <template slot="tag" slot-scope="props">
                <span>{{ props.option.name }}</span>
                <span @click="props.remove(props.option)">x</span> 
            </template>
        </multiselect>  

        <select v-model="flex.type"> 
            <option v-if="!flex.operator_id" value="">Type</option>

            <template v-if="flex.operator_id">  
                <template v-if="flex.operator_id.type == 'flexiload'">  
                    <option value="prepaid">Prepaid</option>
                    <option value="postpaid">Postpaid</option> 
                </template>

                <template v-else-if="flex.operator_id.type == 'mobile-banking'"> 
                    <option value="personal">Personal</option>
                    <option value="agent">Agent</option>
                </template> 
            </template>   
        </select>

        <input type="number" autocomplete="off"  placeholder="Amount" v-on:keyup="amountChange(key)" id="amount" v-model="flex.amount" required > 
    </div><!--  /.flexi-numbers -->
</div> <!-- /.flexi-number-list --> 
<input type="password" placeholder="Pin" id="pin" v-model="mt.pin" required></div>

and here is my vue js code.

export default {  
data: function () {
    return {
        mt: {  
            flexi: [ 
                { number: '', operator_id: '', type: '', amount: '' }, 
                { number: '', operator_id: '', type: '', amount: '' }, 
            ],
            pin: '',
        }, 
        operatorList: [
            { id: 1, name: 'Grameenphone', type: 'flexiload' },
            { id: 2, name: 'Banglalink', type: 'flexiload' },
            { id: 3, name: 'Bkash', type: 'mobile-banking' },
            { id: 4, name: 'Rocket', type: 'mobile-banking' },
        ],
    }
},
watch: {  
    // is any way to watch operator_id value or object index like follwing?
    /*
    'mt.flexi.operator_id': function (index, value) {

    }
    */
}, 
methods: {  
    numberChange(key) { 
      /* Here I can get the number */
      //this.mt.flexi[key].number;          
    },
    amountChange(key) { 
        alert(key);
      /* Here I can get the amount */
      //this.mt.flexi[key].amount;          
    },
    operatorChanged( key ) {
        alert(key);
      if ( this.mt.flexi[key].operator_id ) {
        if ( this.mt.flexi[key].operator_id.type == 'flexiload' ) {
          this.mt.flexi[key].type = 'prepaid'; 
        } else if ( this.mt.flexi[key].operator_id.type == 'mobile-banking' ) {
          this.mt.flexi[key].type = 'personal';
        }  
      }   
      //this.amountChange(key);
    },
} //methods } //export default
1
  • What do you want to achieve? You can surely pass an inline handler to @select, for example @select="operatorChanged(key)" Commented Feb 26, 2019 at 5:30

1 Answer 1

2

I think what you want is @input handler instead of @onChange.

<div class="flexi-numbers" v-for="(flex, key) in mt.flexi">

  <multiselect 
    :allow-empty="false" 
    deselect-label="" 
    select-label="" 
    v-model="flex.operator_id" 
    :options="operatorList" 
    :preserve-search="true" 
    placeholder="Operator" 
    label="name" 
    track-by="name" 
    :preselect-first="false" 

    @input="operatorChanged(key)">

    <template slot="tag" slot-scope="props">
      <span>{{ props.option.name }}</span>
      <span @click="props.remove(props.option)">x</span> 
    </template>

  </multiselect>

<!-- other stuff -->

Is the any way to watch operator_id value or object index?

operatorChanged(key) {
  // "key" here should be the index being selected,
  // and of course to get the "operator_id"

  this.mt.flexi[key].operator_id
},
Sign up to request clarification or add additional context in comments.

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.