Encountering a problem with integrating Vue js and making a jquery

Hello there! I'm currently working on fetching data through ajax and utilizing a vue wrapper component. Here's the code snippet I'm using:

  <html>
    <head>
        <title>title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            html, body {
                font: 13px/18px sans-serif;
            }
            select {
                min-width: 300px;
            }
        </style>
    </head>
    <body>
        <div id="el"></div>

        <!-- using string template here to work around HTML <option> placement restriction -->
        <script type="text/x-template" id="demo-template">
            <div>
            <p>Selected: {{ input.selected }}</p>
            <select2 :options="options" v-model="input.selected">
            <option disabled value="0">Select one</option>
            </select2>
            </div>
        </script>

        <script type="text/x-template" id="select2-template">
            <select>
            <slot></slot>
            </select>
        </script>
        <script src="http://themestarz.net/html/craigs/assets/js/jquery-3.3.1.min.js"></script>
        <script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c3b5b6a683f1edf6edf2f4">[email protected]</a>/dist/vue.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script>
            Vue.component('select2', {
                props: ['options', 'value'],
                template: '#select2-template',
                mounted: function () {
                    var vm = this;
                    $(this.$el)
                            // init select2
                            .select2({data: this.options})
                            .val(this.value)
                            .trigger('change')
                            // emit event on change.
                            .on('change', function () {
                                vm.$emit('input', this.value)
                            });
                },
                watch: {
                    value: function (value) {
                        // update value
                        $(this.$el)
                                .val(value)
                                .trigger('change')



                    },
                    options: function (options) {
                        // update options
                        $(this.$el).empty().select2({data: options})
                    }
                },
                destroyed: function () {
                    $(this.$el).off().select2('destroy')
                }
            })

            var vm = new Vue({
                el: '#el',
                template: '#demo-template',
                data: {
                    input: {
                        selected: "all"
                    },
                    options: []
                },
                created: function () {
                    this.mymethod();
                },
                methods: {
                    mymethod: function () {
                        var vm = this;


                        $.get("https://api.coindesk.com/v1/bpi/currentprice.json", function (data) {
                            vm.options = [
                                {id: 'all', text: 'All'},
                                {id: 1, text: 'Hello'},
                                {id: 2, text: 'World'},
                                {id: 3, text: 'Bye'}
                            ];

                            vm.input.selected = 2;
                        });
                    }
                }
            });
        </script>
    </body>
</html>

Once the items are loaded into the drop-down, I need to modify the selected item like this:

vm.input.selected = 2;

However, this change is not taking place after the ajax request. If I include the array before the ajax call, it works as expected. But I specifically require the data from an ajax request. To simplify things for better understanding, I have reduced the complexity of the code.

You can also check out the jsfiddle link for this issue. It appears that the problem lies within the vue component implementation.

Answer №1

After conducting a few tests, it appears that the issue arises from changing the select2's value prior to updating its options. Consequently, when attempting to change to option 2, which doesn't exist, the modification fails to take effect.

As mentioned in my earlier comment, rearranging the order of options and value within the component's watch resolves this issue. This is likely because by adjusting the sequence, the options are updated right before the new value is assigned.

To illustrate, refer to the following functional example:

Vue.component('select2', {
  props: ['options', 'value'],
  template: '#select2-template',
  mounted: function() {
    var vm = this;
    $(this.$el)
      // initialize select2
      .select2({
        data: this.options
      })
      .val(this.value)
      .trigger('change')
      // emit event upon change.
      .on('change', function() {
        vm.$emit('input', this.value)
      });
  },
  watch: {
    options: function(options) {
      // update options
      $(this.$el).empty().select2({
        data: options
      })
    },
    value: function(value) {
      // update value
      $(this.$el)
        .val(value)
        .trigger('change')
    }
  },
  destroyed: function() {
    $(this.$el).off().select2('destroy')
  }
})

var vm = new Vue({
  el: '#el',
  template: '#demo-template',
  data: {
    input: {
      selected: "all"
    },
    options: []
  },
  created: function() {
    this.mymethod();
  },
  methods: {
    mymethod: function() {
      var vm = this;
      $.get("https://api.coindesk.com/v1/bpi/currentprice.json", function(data) {
        vm.options = [{
            id: 'all',
            text: 'All'
          },
          {
            id: 1,
            text: 'Hello'
          },
          {
            id: 2,
            text: 'World'
          },
          {
            id: 3,
            text: 'Bye'
          }
        ];
        vm.input.selected = 2;
        //      setTimeout(() =>  { vm.input.selected = 2; }, 0);
      });
    }
  }
});
html,
body {
  font: 13px/18px sans-serif;
}

select {
  min-width: 300px;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dbadaebe9be9f5eef5eaec">[email protected]</a>/dist/vue.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/axios/dist/axios.min.js"></script>

<div id="el"></div>

<!-- using string template here to work around HTML <option> placement restriction -->
<script type="text/x-template" id="demo-template">
  <div>
    <p>Selected: {{ input.selected }}</p>
    <select2 :options="options" v-model="input.selected">
      <option disabled value="0">Select one</option>
    </select2>
  </div>
</script>

<script type="text/x-template" id="select2-template">
  <select>
    <slot></slot>
  </select>
</script>

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

Redirect link depending on JSON callback information

I experimented with utilizing JavaScript to automatically redirect website visitors based on their country. The code snippet below demonstrates how the visitor's IP is checked to determine their country, such as CN for China, and then redirects them ...

Potential bug may arise with the hashchange event

Recently, I stumbled upon a rather unique bug in my Javascript code that has left me puzzled. Here's the scenario: within a parent div with relative positioning, there are three child divs positioned absolutely side by side. Each child div is 1200px ...

Is there a way to use JavaScript/jQuery to randomly resize images every time the page loads

Instead of generating thumbnails for my images, I am interested in displaying the original images on my page. However, I still need to resize these images for optimal viewing. Instead of applying a fixed width of 200px, I would like each image to be displa ...

Vue.js - Maintaining input value when model declines updates

I am working on a text input that allows users to enter numbers with a maximum of three digits after the decimal point: <v-text-field type="text" :value="num" @change="changeNum($event)" /> <p>{{ num }}</p> ... export default { data: ...

Enhancing the Efficiency of JavaScript's indexOf Method

I am currently developing a basic search algorithm in JavaScript. var title = "Discovering the Best Book of All Time"; var search1 = "of DiscoverinG boOk Best"; var search2 = "Of TIme best all" var search3 = "Book discovering time" When using indexOf(), ...

What is the best method to retrieve the current time in minutes using the Timer component?

I have integrated the react-timer-hook library into my Next.js application to display a timer. The timer is functioning correctly, but I am encountering an issue where I cannot retrieve the current elapsed time in minutes during the handle form event. My g ...

Exclusive Nuxt component designed for clientside use only

I have created a universal component to display thumbnail collections, utilizing the Glightbox library for image viewing. However, I am facing an issue with server-side rendering as Glightbox relies on browser detection. I am looking for a way to disable o ...

Show various attachment file names using jQuery

Utilizing jQuery, I've implemented a script to extract the filename from a hidden field and then append it to the filename class in my HTML. filenameCache = $('#example-marketing-material-file-cache').val().replace(/^.*[\\\/ ...

Steps for inserting an item into a div container

I've been attempting to create a website that randomly selects elements from input fields. Since I don't have a set number of inputs, I wanted to include a button that could generate inputs automatically. However, I am encountering an issue where ...

Express Form Validation: Ensuring Data Accuracy

I have recently learned that client-side form validations may not be sufficient to prevent malicious actions from users. It is recommended to also validate the form on the server-side. Since I am new to using express, can someone provide guidance on what s ...

What could be the reason for the bottom edge of my central diagonal image having a darker border?

I can't figure out why the border on the bottom edge of my image is darker. You can check out the demo here. To get a closer look at the issue, you can open a software like GIMP and zoom in on the following image to see the difference in values: http ...

Creating a personalized aggregation function in a MySQL query

Presenting the data in tabular format: id | module_id | rating 1 | 421 | 3 2 | 421 | 5 3. | 5321 | 4 4 | 5321 | 5 5 | 5321 | 4 6 | 641 | 2 7 | ...

Learning how to interpret data within configuration files (.properties) using JavaScript

I'm trying to retrieve data from a configuration file (.properties) in my code. The structure of my configuration file is as follows: maxTime = 60 upVotePostMaxTime=60 However, I am unsure of how to read this configuration file using JavaScript. Is ...

Attempting to organize date and time down to the second

I'm currently working on sorting time with seconds included. While I am able to sort the minutes successfully, I'm facing difficulty in sorting the seconds. Despite trying various approaches and using dynamic data that needs to be sorted in desce ...

Adjust the alignment and floating of text within an iframe on the same domain

Is it possible to align text on the right side of an iframe that contains a width and text inside? The iframe's src is from the same domain. If so, how can this be achieved through JavaScript? ...

Ways to incorporate an item into previous and future weekdays

I would like to customize the colors for previous weekdays by displaying them in gray and upcoming days in blue. Here is the code I am using: $week .= str_repeat('<td></td>', $str); for ( $day = 1; $day <= $day_count; $day++, $st ...

Navigating routes for a module sourced from NPM: Best practices

Looking for guidance on loading Angular routes from an NPM module? Take a look at this snippet from my app.module.ts file: import { HelloWorldModule } from 'hello-world-app-npm/hello-world-app.umd.js'; // Loading module from NPM const routes = ...

Reading a Json file with keys in puppeteer BDD: A Guide

Greetings, I am new to the world of puppeteer. I have successfully created my basic framework and now I am trying to figure out how to read data from .json files. I attempted to use the readFile method in my helper class, but unfortunately, it resulted in ...

Organizing data in a Vue 3 table using the Composition API and v-for loop

I managed to display a table of my object array with this code snippet: <div class="table-responsive"> <table ref="tbl" border="1" class="table"> <thead ...

Dependencies for Grunt tasks

I am facing some issues with a grunt task named taskA that was installed via npm. The task has a dependency on grunt-contrib-stylus, which is specified in the package.json file of taskA and installed successfully. However, when I run grunt default from the ...