1

im working on making months to change accordingly depending on what i select with vue, as seen on the code on the link below.

<div id="app">

  <span class="selectboxWrap">
    <select v-on:change="changeSearchMonths" ref="comCd" v-model="searchParams.searchTaxTerm">
      <option value="1">1</option>
      <option value="2">2</option>
    </select>
  </span>
  <span class="selectboxWrap">
    <select v-on:change="changeSearchMonths" ref="comCd" v-model="searchParams.planConfirmFlag">
      <option value="P">P</option>
      <option value="F">F</option>
    </select>
  </span>
  <br>
  <div class="boxHorizental">
    <span class="dateRange full">
      <div class="selectboxWrap">
        <select v-model="searchParams.searchFromInvoiceDate">
          <option v-for="opt in monthOptions" v-bind:key="opt.val" v-bind:value="opt.val">
            {{ opt.text }}
          </option>
        </select>
      </div>
      <em class="dash">~</em>
      <div class="selectboxWrap">
        <select v-model="searchParams.searchToInvoiceDate">
          <option v-for="opt in monthOptions" v-bind:key="opt.val" v-bind:value="opt.val">
            {{ opt.text }}
          </option>
        </select>
      </div>
    </span>
  </div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    searchParams: {},
    monthOptions: [{
        text: 1,
        val: '01'
      },
      {
        text: 2,
        val: '02'
      },
      {
        text: 3,
        val: '03'
      },
      {
        text: 4,
        val: '04'
      },
      {
        text: 5,
        val: '05'
      },
      {
        text: 6,
        val: '06'
      },
      {
        text: 7,
        val: '07'
      },
      {
        text: 8,
        val: '08'
      },
      {
        text: 9,
        val: '09'
      },
      {
        text: 10,
        val: '10'
      },
      {
        text: 11,
        val: '11'
      },
      {
        text: 12,
        val: '12'
      }
    ]
  },
  methods: {

    changeSearchMonths: function() {
      if (this.searchParams.searchTaxTerm === '1' && this.searchParams.planConfirmFlag === 'P') {

        this.searchParams.searchFromInvoiceDate = '01'
        this.searchParams.searchToInvoiceDate = '03'
      } else if (this.searchParams.searchTaxTerm === '1' && this.searchParams.planConfirmFlag === 'F') {
        this.searchParams.searchFromInvoiceDate = '04'
        this.searchParams.searchToInvoiceDate = '06'
      } else if (this.searchParams.searchTaxTerm === '2' && this.searchParams.planConfirmFlag === 'P') {
        this.searchParams.searchFromInvoiceDate = '07'
        this.searchParams.searchToInvoiceDate = '09'
      } else if (this.searchParams.searchTaxTerm === '2' && this.searchParams.planConfirmFlag === 'F') {
        this.searchParams.searchFromInvoiceDate = '10'
        this.searchParams.searchToInvoiceDate = '12'
      }
    }
  },
  created() {

      this.searchParams.searchTaxTerm = '1'
      this.searchParams.planConfirmFlag = 'P'
      this.searchParams.searchFromInvoiceDate = '01'
      this.searchParams.searchToInvoiceDate = '06'
  }
})

</script>

https://jsfiddle.net/L90ur587/5/

i can see my values change on dev. tools, but the selected box does not change accordingly, is there a way i can get the page to switch accordingly?

e.g. if I change value of either of the two select box on top, other select boxes below should change accordingly. right now the values change, but not the select box on the front view

2 Answers 2

2

Don't assign default values in created!
That's what data is for. Declaring each sub-property inside data (with any value, other than undefined) will allow Vue to wrap setters and getters around them, making them reactive.

Run changeSearchMonths once inside mounted so your custom logic is applied to the default values. I took the liberty to rewrite bits of your code to make it slightly more readable.

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  data: () => ({
    searchParams: {
      searchToInvoiceDate: '06',
      searchFromInvoiceDate: '01',
      planConfirmFlag: 'P',
      searchTaxTerm: '1'
    }
  }),
  methods: {
    pad(n) {
      return `${n}`.padStart(2, '0')
    },
    changeSearchMonths() {
      const p = this.searchParams;
      switch (true) {
        case p.searchTaxTerm === '1' && p.planConfirmFlag === 'P':
          p.searchFromInvoiceDate = '01';
          p.searchToInvoiceDate = '03';
          break;
        case p.searchTaxTerm === '1' && p.planConfirmFlag === 'F':
          p.searchFromInvoiceDate = '04';
          p.searchToInvoiceDate = '06';
          break;
        case p.searchTaxTerm === '2' && p.planConfirmFlag === 'P':
          p.searchFromInvoiceDate = '07';
          p.searchToInvoiceDate = '09';
          break;
        case p.searchTaxTerm === '2' && p.planConfirmFlag === 'F':
          p.searchFromInvoiceDate = '10';
          p.searchToInvoiceDate = '12';
          break;
        default:
      }
    }
  },
  mounted() {
    this.changeSearchMonths()
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">

  <span class="selectboxWrap">
    <select @change="changeSearchMonths" ref="comCd"
            v-model="searchParams.searchTaxTerm">
      <option value="1">1</option>
      <option value="2">2</option>
    </select>
  </span>
  <span class="selectboxWrap">
    <select @change="changeSearchMonths" ref="comCd"
            v-model="searchParams.planConfirmFlag">
      <option value="P">P</option>
      <option value="F">F</option>
    </select>
  </span>
  <br>
  <div class="boxHorizental">
    <span class="dateRange full">
      <div class="selectboxWrap">
        <select v-model="searchParams.searchFromInvoiceDate">
          <option v-for="n in 12" :key="n" :value="pad(n)" v-text="n" />
        </select>
      </div>
      <em class="dash">~</em>
      <div class="selectboxWrap">
        <select v-model="searchParams.searchToInvoiceDate">
          <option v-for="n in 12" :key="n" :value="pad(n)" v-text="n" />
        </select>
      </div>
    </span>
  </div>
</div>

Side note: you have two refs under the same key (comCd). While it's not invalid or illegal (the latter in template simply overrides the first), it's been known to cause adverse reactions, such as developer hair loss.

Also, very important: data Must Be a Function!
This allows Vue to add its reactivity to all properties declared in the object returned by that function.

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

2 Comments

oh yes, it's a function in the original code, missed it when writing to the snippet. thank you for the advice. will gonna look more into it!
@MrSolid, all you need to do is move the defaults from created into data and run changeSearchMonths in mounted(). The other changes I made are not necessary, but I thought you might find them useful. In general, I advise against using $forceUpdate. It makes your app slower and masks underlying problems with your data flow. Another problem is it makes debugging more difficult and slower as you'll now have longer trace threads.
1

Your dom doesn't update after the value being changed. You need to update dom forcely.Add this.$forceUpdate() at the end of the function changeSearchMonths.

The working snippet below:

new Vue({
  el: '#app',
  data: {
    searchParams: {},
    monthOptions: [{
        text: 1,
        val: '01'
      },
      {
        text: 2,
        val: '02'
      },
      {
        text: 3,
        val: '03'
      },
      {
        text: 4,
        val: '04'
      },
      {
        text: 5,
        val: '05'
      },
      {
        text: 6,
        val: '06'
      },
      {
        text: 7,
        val: '07'
      },
      {
        text: 8,
        val: '08'
      },
      {
        text: 9,
        val: '09'
      },
      {
        text: 10,
        val: '10'
      },
      {
        text: 11,
        val: '11'
      },
      {
        text: 12,
        val: '12'
      }
    ]
  },
  methods: {

    changeSearchMonths: function() {
      if (this.searchParams.searchTaxTerm === '1' && this.searchParams.planConfirmFlag === 'P') {
        this.searchParams.searchFromInvoiceDate = '01'
        this.searchParams.searchToInvoiceDate = '03'
      } else if (this.searchParams.searchTaxTerm === '1' && this.searchParams.planConfirmFlag === 'F') {
        this.searchParams.searchFromInvoiceDate = '04'
        this.searchParams.searchToInvoiceDate = '06'
      } else if (this.searchParams.searchTaxTerm === '2' && this.searchParams.planConfirmFlag === 'P') {
        this.searchParams.searchFromInvoiceDate = '07'
        this.searchParams.searchToInvoiceDate = '09'
      } else if (this.searchParams.searchTaxTerm === '2' && this.searchParams.planConfirmFlag === 'F') {
        this.searchParams.searchFromInvoiceDate = '10'
        this.searchParams.searchToInvoiceDate = '12'
      }
      this.$forceUpdate();
    }
  },
  created() {

    this.searchParams.searchTaxTerm = '1'
    this.searchParams.planConfirmFlag = 'P'
    this.searchParams.searchFromInvoiceDate = '01'
    this.searchParams.searchToInvoiceDate = '06'
  }
})
<!doctype html>
<html lang="en">

<head>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">

    <span class="selectboxWrap">
          <select v-on:change="changeSearchMonths" ref="comCd" v-model="searchParams.searchTaxTerm">
            <option value="1">1</option>
            <option value="2">2</option>
          </select>
        </span>
    <span class="selectboxWrap">
          <select v-on:change="changeSearchMonths" ref="comCd" v-model="searchParams.planConfirmFlag">
            <option value="P">P</option>
            <option value="F">F</option>
          </select>
        </span>
    <br>
    <div class="boxHorizental">
      <span class="dateRange full">
            <div class="selectboxWrap">
              <select v-model="searchParams.searchFromInvoiceDate">
                <option v-for="opt in monthOptions" v-bind:key="opt.val" v-bind:value="opt.val">
                  {{ opt.text }}
                </option>
              </select>
            </div>
            <em class="dash">~</em>
            <div class="selectboxWrap">
              <select v-model="searchParams.searchToInvoiceDate">
                <option v-for="opt in monthOptions" v-bind:key="opt.val" v-bind:value="opt.val">
                  {{ opt.text }}
                </option>
              </select>
            </div>
          </span>
    </div>
  </div>


</body>

</html>

2 Comments

so it wasn't being updated after my method ran. TIL. thanks!
The cause was not declaring the sub-props in data, even as nulls. Changes to them were therefore not reactive. So, to update searchFromInvoiceDate reactively with what you had you could have used Vue.set(this.searchParams, 'searchFromInvoiceDate', '04') or this.searchParams = { ...this.searchParams, searchFromInvoiceDate: '04'}, as parent object was tracked.

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.