Home > Blockchain >  Binding input to select options dropdown Vuejs
Binding input to select options dropdown Vuejs

Time:10-26

I am trying build a basic currency converter and having issues binding the selected option and displaying its value in the input

<template>
      <div >

        <h1 >
            Currency Converter
        </h1>
        
        <div >
            <input v-model="currencyValue"  type="number">
            <select>
                <option v-for="Currency in currencyName" :key="Currency">
                    {{ Currency }}
                </option>
            </select>
        </div>

        =

        <div >
            <input v-model="currencyValue"  type="number">
            <select>
                <option v-for="Currency in currencyName" :key="Currency">
                    {{ Currency }}
                </option>
            </select>
        </div>

    </div>
</template>
<script>
  export default {
    data() {
      return {
        listItems: [],
        currencyName: [],
        currencyValue: []
      }
    },
    methods: {
      async getData() {
        const res = await fetch("https://api.exchangerate.host/latest");
        const finalRes = await res.json();
        this.listItems = finalRes.rates;
        this.currencyName = Object.keys(this.listItems)
        this.currencyValue = Object.values(this.listItems)
        console.log(this.currencyName);
        console.log(this.currencyValue);
        console.log(this.listItems);
      }
    },
    mounted() {
      this.getData()
    }
  }
</script>

I tried using a v-model on the input however I still seem to be needing more to loop through the values in the object from the API

CodePudding user response:

Why bind the entire array of exchange rate values to an input (to both inputs actually)? Assuming the first input is for a user to input an amount that you will then convert, the v-model should be a unique variable initialized as null or 0, not with your API data. Also, each input/select that the user can interact with should have it's own unique v-model to provide 2-way binding. Any inputs sharing the same v-model are always going to share and display the exact same value. Any "output" field where you only want to display a result (not have the user change/interact with it) should use just 1-way binding with the :value= property.

Not to write the entire component for you, I've made this codesandbox that should help you get the right idea

CodePudding user response:

As per my understanding, You want to fill the input fields based on the currency name selected in the select. If Yes, Here are few observations as per your code :

  • You are passing whole array of currency values in a v-model of input, It should be a single value based on the currency name selection. Hence, you have to add the @change event on dropdown and based on the value update the input field v-model.
  • I did not see any v-model to the select. It should be there to capture the selected currency name.
  • Input fields should be read only as you are not doing any calculations on currency. I think user input is not required.
  • listItems is an object, hence it should be initialized as {} not [].

Live Demo :

new Vue({
  el: '#app',
  data() {
    return {
        listItems: {},
      currencyName: [],
      currencyValue1: '',
      currencyValue2: '',
      selectedCurrency1: '',
      selectedCurrency2: ''
    }
  },
  methods: {
    async getData() {
      const res = await fetch("https://api.exchangerate.host/latest");
      const finalRes = await res.json();
      this.listItems = finalRes.rates;
      this.currencyName = Object.keys(this.listItems)
      this.currencyValue = Object.values(this.listItems)
    },
    getCurrValue1() {
        this.currencyValue1 = this.listItems[this.selectedCurrency1];
    },
    getCurrValue2() {
        this.currencyValue2 = this.listItems[this.selectedCurrency2];
    }
  },
  mounted() {
    this.getData()
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <h1 >
    Currency Converter
  </h1>

  <div >
    <input v-model="currencyValue1"  type="number" disabled>
    <select v-model="selectedCurrency1" @change="getCurrValue1">
      <option disabled value="">Select Currency</option>
      <option v-for="Currency in currencyName" :value="Currency" :key="Currency">
        {{ Currency }}
      </option>
    </select>
  </div>

  =

  <div >
    <input v-model="currencyValue2"  type="number" disabled>
    <select v-model="selectedCurrency2" @change="getCurrValue2">
      <option disabled value="">Select Currency</option>
      <option v-for="Currency in currencyName" :value="Currency" :key="Currency">
        {{ Currency }}
      </option>
    </select>
  </div>
</div>

  • Related