Skip to content
Advertisement

How to have Date selector for every button/option clicked in Vuejs

I am new to Vuejs, I have used 3 buttons which are chart1, chart2 and chart3 respectively. So whenever I click any of the button I want the Date selection to be displayed which is in a radio type. Shown Below:

enter image description here

What I am trying to do is, I am trying to display the charts, whenever the button is clicked, whichever the button clicked I want to display Date selection.

Here how I tried:

<template>
  <div class="Different charts">
    <div class="buttons" >
      <vs-button color="warning" size="small" @click="chartapi(chart1, all)">Chart1</vs-button>
      <vs-button color="warning" size="small" @click="chartapi(chart2, all)" >Chart2</vs-button>
      <vs-button color="warning" size="small" @click="chartapi(chart3, all)">Chart3</vs-button>
    </div>
      <ul class="demo-alignment ">
        <li>
          <vs-radio id="all" color="warning" vs-name="options" vs-value="all" v-model="radios2" >All</vs-radio>
        </li>

        <li>
          <vs-radio id="6mon" color="warning"  vs-name="options" vs-value="6mon" v-model="val1">6mon</vs-radio>
        </li>
        <li>
          <vs-radio id="3mon" color="warning"  vs-name="options" vs-value="3mon" v-model="val1">3mon</vs-radio>
        </li>
        <li>
          <vs-radio id="1mon" color="warning"  vs-name="options" vs-value="1mon" v-model="val1">1mon</vs-radio>
        </li>
      </ul>
  <div class="chart-container"> 
  <canvas id="chart"></canvas>
  </div>
  </div>
</template>

<script>
import Chart from 'chart.js'
export default {
  data () {
    return {
      date: [],
      challenge: [],
      data: [],
      val1: 'all'
    }
  },
  mounted () {
    this.chartapi()
  },
  methods: {
    chartapi (type_name, interval) {
      this.$http.get(`/different/chart/${ type_name  }?interval=${  interval}`)
        .then((r) => {
          this.date = r.data.date
          this.challenge = r.data.challenge
          this.data = this.date.map((date, index) => ({
            x: new Date(date * 1000),
            y: this.challenge[index]
          }))

          const ctx = this.$refs.chart.getContext('2d')
          new Chart(ctx, {
            type: 'line',
            data: {
              datasets: [
                {
                  label: 'Challenge',
                  data: this.data,
                  borderColor: 'black',
                }
              ]
            },
            options: {
              scales: {
                yAxes: [
                  {
                    ticks: {
                      callback (value) {
                        return `${value}%`
                      }
                    }
                  }
                ],
                xAxes: [
                  {
                    type: 'time',
                    time: {
                      unit: 'month'
                    }
                  }
                ]
              }
            }
          })
        })
    }
  }
}
</script>

As you can see my code you can understand that whenever the button is clicked, the respective chart is displayed

And I have used the interval in the method which is used to specify the value of the Date range selection.

My question is how to show the Date range selection for all the options (buttons) and how the interval can be specified in the radio buttons.

For example, if chartapi(chart1, 3mon) then it displays the previous 3 months chart1 data. But what I want is when the button is clicked it should show whole chart data, if the user wants to view any interval he can use the radio buttons which is the Date range selection. So I want to know how to integrate the interval to the radio buttons. Please do help me.

Advertisement

Answer

As I understand you need to fetch all data when the button clicks and after you will select the radio buttons accordingly and you want to change the data when you change the radio button. so you can change tho code as following,

<template>
  <div class="Different charts">
    <div class="buttons" >
      <vs-button color="warning" size="small" @click="handleBtnClick(chart1)">Chart1</vs-button>
      <vs-button color="warning" size="small" @click="handleBtnClick(chart2)" >Chart2</vs-button>
      <vs-button color="warning" size="small" @click="handleBtnClick(chart3)">Chart3</vs-button>
    </div>
      <ul class="demo-alignment ">
        <li>
          <vs-radio id="all" color="warning" vs-name="options" vs-value="all" v-model="val1" >All</vs-radio>
        </li>

        <li>
          <vs-radio id="6mon" color="warning"  vs-name="options" vs-value="6mon" v-model="val1">6mon</vs-radio>
        </li>
        <li>
          <vs-radio id="3mon" color="warning"  vs-name="options" vs-value="3mon" v-model="val1">3mon</vs-radio>
        </li>
        <li>
          <vs-radio id="1mon" color="warning"  vs-name="options" vs-value="1mon" v-model="val1">1mon</vs-radio>
        </li>
      </ul>
  <div class="chart-container"> 
  <canvas id="chart"></canvas>
  </div>
  </div>
</template>

<script>
import Chart from 'chart.js'
export default {
  data () {
    return {
      date: [],
      challenge: [],
      data: [],
      val1: 'all',
      type: 'chart1'
    }
  },
  mounted () {
    this.chartapi(type, val1);
  },
  methods: {
      handleBtnClick: (chart) => {
          /* This is a method to use in button click */
          this.type = chart;
          this.val1 = 'all' // Assigning 'all' as initial value for each chart
          this.chartapi(this.type, this.val1);
      },
    chartapi (type_name, interval) {
      this.$http.get(`/different/chart/${ type_name  }?interval=${  interval}`)
        .then((r) => {
          this.date = r.data.date
          this.challenge = r.data.challenge
          this.data = this.date.map((date, index) => ({
            x: new Date(date * 1000),
            y: this.challenge[index]
          }))

          const ctx = this.$refs.chart.getContext('2d')
          new Chart(ctx, {
            type: 'line',
            data: {
              datasets: [
                {
                  label: 'Challenge',
                  data: this.data,
                  borderColor: 'black',
                }
              ]
            },
            options: {
              scales: {
                yAxes: [
                  {
                    ticks: {
                      callback (value) {
                        return `${value}%`
                      }
                    }
                  }
                ],
                xAxes: [
                  {
                    type: 'time',
                    time: {
                      unit: 'month'
                    }
                  }
                ]
              }
            }
          })
        })
    }
  },
  watch: {
      /* You can write a watcher for listen the changes of the radio button */
      val1:(prevValue, newValue) => {
          /* This method triggers everytime you change the value of val1 */
          this.chartapi(this.type, newValue);
      }
  }
}
</script>

The changes I do was,

  1. Add separate data filed/variable to assign the type of the chart
  2. create a separate method to trigger the buttons that change the type variable accordingly and change the val1 back to all.
  3. Create watcher to watch the val1 and if val1 changes loading the chart respectively.

Update

Since you are unclear about how watcher works, we can create watchers in vue as a special kind of function which will trigger when the relevant data field is updated.

first, we bind our radio buttons to the val1 data field as follows.

<ul class="demo-alignment ">
        <li>
          <vs-radio id="all" color="warning" vs-name="options" vs-value="all" v-model="val1" >All</vs-radio>
        </li>

        <li>
          <vs-radio id="6mon" color="warning"  vs-name="options" vs-value="6mon" v-model="val1">6mon</vs-radio>
        </li>
        <li>
          <vs-radio id="3mon" color="warning"  vs-name="options" vs-value="3mon" v-model="val1">3mon</vs-radio>
        </li>
        <li>
          <vs-radio id="1mon" color="warning"  vs-name="options" vs-value="1mon" v-model="val1">1mon</vs-radio>
        </li>
      </ul>

as you can see all the radio buttons are v-bind with val1 so the value of val1 changes according to the selected radio button. (all, 6mon, 3mon, 1mon).

next, we create weather to the val1 as the following code.

watch: {
      /* You can write a watcher for listen the changes of the radio button */
      val1: (prevValue, newValue) => {
          /* This method triggers everytime you change the value of val1 */
          this.chartapi(this.type, newValue);
      }
  }

we create watcher with the same name as the data field and it triggers each time the val1 changes, (that mean it triggers when you change the radio button). then inside that watcher when the value changes we call chartapi with the new value of val1 as a second parameter. which makes the chart to load again according to the selected month.

Advertisement