Guide on implementing a date selector for each button/option clicked using Vue.js

My experience with Vuejs is still fresh, and I've incorporated 3 buttons named chart1, chart2, and chart3. Whenever any of these buttons are clicked, I want a Date selection to appear in a radio type format. You can see an example below:

https://i.sstatic.net/HUq8V.png

The goal here is to display the charts corresponding to the clicked button along with the Date selection options.

This is my attempt so far:

<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>

You'll notice that clicking a button triggers the display of the corresponding chart.

I've also implemented an interval feature in the function to define the Date range for each request.

My question revolves around displaying the Date range selection for every button option and how to integrate interval settings within the radio button selections.

For instance, by calling chartapi(chart1, 3mon), it would reveal the previous 3 months' data specific to chart1. However, my preference is to exhibit full chart data upon button click, enabling users to dictate intervals using the Date range selection via radio buttons. Can someone guide me on integrating the interval functionality into the radio buttons?

Answer №1

To clarify, the task at hand involves retrieving all data when a button is clicked, selecting radio buttons accordingly, and updating the data based on the selected radio button. To achieve this, you can modify the code as shown below:

<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 function updates the chart type and resets the value to 'all' */
          this.type = chart;
          this.val1 = 'all';
          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: {
      /* Watcher for tracking changes in the radio buttons */
      val1:(prevValue, newValue) => {
          /* This function triggers whenever the value of val1 changes */
          this.chartapi(this.type, newValue);
      }
  }
}
</script>

The modifications I made include:

  1. Introducing a separate variable to determine the chart type
  2. Creating a method to handle button clicks that update the 'type' variable and reset 'val1' to 'all'
  3. Implementing a watcher to react to changes in 'val1' and reload the chart accordingly

Update

If there's uncertainty about watchers in Vue, they are special functions that trigger upon changes to specified data fields.

Firstly, ensure the radio buttons are bound to the 'val1' field:

<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>

By binding all radio buttons with 'val1,' the value changes based on selection (all, 6mon, 3mon, 1mon).

Next, implement a watcher for 'val1' as depicted below:

watch: {
      /* Watcher for tracking changes in the radio buttons */
      val1: (prevValue, newValue) => {
          /* This function triggers whenever the value of val1 changes */
          this.chartapi(this.type, newValue);
      }
  }

By creating a watcher with matching name to the data field, it responds to 'val1' changes (i.e., changing radio buttons). Then inside the watcher, calling 'chartapi' with the updated 'val1' prompts the chart to refresh according to the chosen month.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to link my "dynamic sub-component" with AngularJS?

While I have a solid grasp on the fundamentals of AngularJS and can create basic CRUD applications, when it comes to applying this knowledge to real-world scenarios, I find myself struggling with how to integrate the concepts effectively. One specific cha ...

Conceal the loading image once the AJAX function has been successfully

I've been trying to figure out a way to load heavy images after an ajax call using animated GIF as a pre-loader, but haven't found a satisfactory solution yet. Here's the code snippet I'm currently using: function loadProducts(url) { ...

Using jQuery to reset the position of animated divs

I am currently working on a code that expands and centers a div when hovered upon using the following script: $(document).ready(function(){ //animation on hover $('#sliding_grid li').hover(function() { ...

Icon button not found

I have created a reusable hook component for input fields. The TextField renders perfectly, but the IconButton is not showing up. const InputHookComponent = (props) =>{ const [val, setval]=useState(""); const cmp = <TextField type={ ...

What are some tips for creating an improved React list container component?

I have a small application that fetches movie data. The component hierarchy is not very complex. The state is stored in App.js and then passed down to the Movies.js component, which simply displays a list of movies in a ul element. Data passing from App.j ...

What is the best way to utilize a JavaScript variable as a background within an inline style sheet?

I have a fun project for this evening - I am trying to make my website load a different background image every time the page is refreshed. Earlier on in this project, I managed to make the background interact with window size and screen resolution similar ...

when the submit button is clicked, verify whether the input field is empty

I have exhausted all my options and nothing seems to work. All I want is for the following functionality to be implemented: When a submit button is clicked -> check if a text field is empty -> if it is, display an error alert and prevent advancing t ...

Despite a successful request, the React Redux action was not dispatched

I'm currently working on adding authentication to my project. While the user registration part seems to be working, the actions are not being dispatched. Strangely, a similar action for fetching data is working fine and dispatching the actions. Here&a ...

What are the best methods for preventing scss styles from leaking between pages?

I'm currently working on a project that includes the following files: /* styles/1.scss */ body { /* Some other styles not related to background-color */ } /* styles/2.scss */ body { background-color: blue; } // pages/one.js import "../styles/ ...

The $scope.$watch function does not activate with each individual change

Yesterday, I realized that in my angularJS 1.4.8 application, the $scope.$watch doesn't trigger on every change causing a bug to occur. Is there a way to make it work on every change immediately? For example, in this code snippet, I want the function ...

Creating a fresh CSS class and utilizing its properties in JavaScript is the task at hand

Whenever I define a css class and attempt to access its member from JavaScript, the result always ends up being undefined. Where could my mistake possibly lie? function myFunction() { var x = document.getElementById("myId").style.myMember; document. ...

A guide on creating a clickable polygon in Vue.js using Konva

Is there a way to create an interactive polygon in Vue Konva where I can set each corner with a click? I haven't been able to find any resources other than the v-polygon which only creates predefined polygons. ...

File input onChange event not triggering after pressing SPACE or ENTER key

My React component features an img tag that allows users to select an image from their computer to display in it. While this component functions correctly on most browsers, I encountered an issue specifically with Chromium based browsers (tested on Chrome, ...

Setting up dynamic routes in a Vue.js Express application

I am currently working on a project that involves creating a basic Vue.js Express profile interface. This interface is responsible for retrieving profile information of a specific user based on a unique ID assigned to each user. The .get() request in Vue.j ...

Is there a way for me to obtain the present value of the chosen button in the list below?

I am working with a group of three buttons labeled English, Hindi, and Urdu. How can I retrieve the value of the selected button in a JavaScript function? <div class="btn-group" data-toggle="buttons"> <label class="btn btn-primary active"> ...

What could be causing the function to not work properly within the React component?

Having trouble with a React component utilizing speech recognition for converting speech to text. Initialized the recognition functions within the component but encountering errors. Need assistance in troubleshooting this issue. const speechRecognition = w ...

Rules for validating string and numeric combinations in Vuetify are essential for ensuring accurate

Looking for guidance on implementing Vuetify validation to enforce rules (using :rules tag on a v-text-field) in the format of AB-12345678 (starting with two letters followed by a hyphen and then an 8-digit number). I'm having difficulty achieving thi ...

Utilizing JQUERY and AJAX for conditional statements

I am currently in the process of creating a basic chat bot. At this point, the bot replies when the user inputs a pre-defined question. However, I am trying to figure out how to program the chatbot to respond with a "sorry, I don't understand" message ...

Unique alphanumeric code following the inclusion of a JavaScript file

I'm encountering an issue with a webpage that incorporates two JavaScript files. When inspecting it using firebug, I noticed that every time the page loads, these two files are included with the prefix ?_=someRandomNumber I'm unsure about the or ...

Tips for displaying just the image name without the entire image file path

When I try to upload an image, the path displayed is "C:\fakepath\promotion1.JPG". This fake path is causing the image not to upload to my project media folder. How can I solve this issue? Instead of the complete path, I only want to capture the ...