Troubleshooting issue with refreshing selectpicker in Bootstrap-select and Vue.js

Incorporating the bootstrap-select plugin (found at ) into a ruby on rails app with Vue.js as the javascript framework has been my latest project.

The goal is to have two select options where one selects a category and the other displays all available teachers for that selected category. I am utilizing axios and vue to make a request to my API and populate the second select field. While this works perfectly fine with a simple select field, I want to use bootstrap-select for a better user interface experience. The issue arises when trying to refresh the options using the "selectpicker('refresh')" function of the plugin. Although it works when manually executed in the browser console, calling it on my vue instance triggers a 'selectpicker is not a function' error in the console.

Here is a snippet of my code:

Javascript:

Vue.use(VueAxios, axios)
    document.addEventListener('DOMContentLoaded', () => {
      if(document.getElementById('enrollment_form')) {
      var app = new Vue({
        el: '#enrollment_form',
        data: {
          CategoryValue: null,
          TeacherValue: null,
          teachers: null,
        },
        methods: {
          fetchTeachers() {
            this.axios.get('/api/teachers/' + this.licenceTypeValue).then(response => (this.teachers = response.data))
              $('.selectpicker').selectpicker('refresh');
          }
        }, 
      })
    }})

View:

       <div class="row">
          <div class="col-lg-5">
            <div class="form-group">
              <%= f.label :category %>*<br />
              <%= f.collection_select(
                  :category,
                  Category.all,
                  :id,
                  :catgegory_name,
                  {include_blank: true},
                  {
                    class: 'form-control selectpicker',
                    "v-model" => "CategoryValue",
                    "v-on:change" => "fetchTeachers"

                  }
              )%>
            </div>
          </div>  
        </div>

        <div class="row">
          <div class="col-lg-5">
            <div class="form-group">
              <label for="teacher_id">Teacher</label>
              <div>
                <select id="teachers-list" class='form-control selectpicker' v-model="TeacherValue" data-fieldname = "TeacherValue">
                  <option label="" ></option>
                  <option v-for="teacher in teachers" :value="teacher.id"> {{teacher.name}}  </option>
                </select>
              </div>
            </div>
          </div>  
        </div>

        <div>
          <%= f.hidden_field :teacher_id, {"v-model" => "TeacherValue"} %>
        </div>

Lastly, my application.js file includes:

//= require rails-ujs
//= require activestorage
//= require jquery
//= require jquery_ujs
//= require popper
//= require bootstrap
//= require bootstrap-select

If anyone could provide assistance, I would greatly appreciate it as I am currently stuck and unable to find a solution.

Answer №1

If you encounter a similar issue, consider making the following changes:

let vm = new Vue({
    el: '#enrollment_form',
    data: {
        CategoryValue: null,
        TeacherValue: null,
        teachers: null,
    },
    methods: {
        retrieveTeachers() {
            // Store the Vue object in a variable to retain context for subsequent use within the 'then' block 
            // as 'this' will be redefined.
            let vueInstance = this;

            this.axios
                .get('/api/teachers/' + this.licenceTypeValue)
                .then(response => {
                    vueInstance.teachers = response.data;
                    // Utilize Vue's $nextTick function to guarantee that bootstrap-select is refreshed after the update has completed.
                    vueInstance.$nextTick(function(){ $('#teachers-list').selectpicker('refresh'); });
                });
        }
    }, 
})

I faced a similar challenge while working on a project and documented my findings in an informative article, which includes both faulty and functional demos. Although my examples focus on altering options through JavaScript sans AJAX, the fundamental principle remains unchanged.

In the provided code snippet, the 'refresh' method of bootstrap-select is triggered using Vue's $nextTick function, ensuring its execution post-update completion by the Vue object. (refer to Vue documentation on $nextTick)

Note: A broader approach can also incorporate a generic update in the Vue 'update' event handler:

updated: function(){
  this.$nextTick(function(){ $('.selectpicker').selectpicker('refresh'); });
}

It is important to note that this tactic would universally refresh all selectpickers sharing the 'selectpicker' class. This repeated update may affect performance and result in inefficiency, especially if it occurs with unrelated vue data updates.

Optimally, selectively refreshing only the affected <select> at the precise moment necessitating the refresh (i.e., upon the return of the AJAX call and successful update of the 'teachers' property) is advisable.

Answer №2

Running this code within a timeout function will trigger a refresh.

 setTimeout(function () {
            $(".selectpicker").selectpicker("refresh");
        }, 1000);

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

Developing uniform resource locators with jQuery

As I work on developing my webapp, I have made use of the tag in my JSPs to ensure that all links within the application - whether they lead to pages or resources like images and CSS - always stem from the root directory rather than being relative to the ...

Which specific HTML element triggers the initiation of ajax in Jquery?

I have a situation where various HTML elements trigger ajax requests when clicked. My goal is to determine which specific element was clicked inside the ajaxComplete event. Although I attempted to use event.target, it only returns the entire document inst ...

Easily linking a React app to MongoDB

I recently developed a basic react app using 'create-react-app'. The app includes a form, validation, and Bootstrap components. It may not be extravagant, but it functions flawlessly. Furthermore, I registered with MongoDB to obtain a compliment ...

Vue transition unexpectedly ending in the wrong position due to nested transitions

I've encountered an issue while trying to implement a transition on a child div within a 'parent' div that already has its own transition. It seems like the child transition is conflicting with the parent transition, causing it to end up in ...

What advantages does using `prestart` offer compared to `&&` in a command within `package.json`?

I believe the title speaks for itself, but let's dive in: What advantages does using the pre-script of npm package.json, like prestart, have over simply combining commands with && in the start script? { prestart: "parcel build", start "n ...

Ways to update the cart page automatically after quantity changes in Shopify

I have made some updates to the Approach and now I am using JavaScript. I've also updated the script and its logic, which is pasted below. Please take a look and see if you can assist me. I am trying to display information on the top of the cart page ...

Inadequate speed and efficiency in Javascript and JQuery operations

I'm facing severe lag problems in my JavaScript code, particularly with the parallax effects being very slow. I suspect this is due to multiple executions of functions. Below is the code snippet: function tada() { $(".arrow").addClass("tada"); s ...

When iterating through a table, an error occurs stating that the property "rows" is not available on type HTMLElement (

Issue Error TS2339 - Property 'rows' does not exist on type HTMLElement when looping through table in Angular 7 Encountering error when trying to loop through HTML table in Angular 7 Currently working with Angular 7 and facing an error while ...

Second attempt at initiating Ajax request fails

My ajax/php structure works perfectly when selecting one image. However, if I click on "selecteer" to perform the same code for the second time, no images are displayed. The "ajax" page loads correctly each time. Here's the setup: Article page: Disp ...

Include the component with the function getStaticProps loaded

I am currently working on a project using NextJs and I have created a component to load dynamic data. The component works fine when accessed via localhost:3000/faq, but I encounter an error when trying to import the same component into index.js. It seems l ...

The v-for directive does not automatically update components in real time

I created a main component called Data, which retrieves state from Vuex. I then use this state to create multiple child components called Table. These child components receive some of the Vuex data as props, all within a v-for loop. <template> < ...

Using async and await inside a setTimeout function within a forEach loop

Currently, I am facing a challenge with scheduling background jobs in Node.js. I need each job to run only after the previous one has finished. Below is the code snippet inside a function: jobArray.forEach((item, i) => { setTimeout(async () => { ...

Simulating server-side interactions in Node.js with TestCafe

I am currently working on a project where I need to figure out how to mock server-side requests. While I have successfully managed to mock client-side requests using request hooks, I am facing challenges when it comes to intercepting server-side requests ...

The Owl carousel's autoplay feature seems to be set at a fixed speed of 5

I've been attempting to adjust the autoplay speed on an owl carousel (specifically using owl carousel 1), but no matter what integer I add after autoplay:, it remains stuck at 5 seconds. The website, which is currently broken, suggests that adding a n ...

Concatenating strings with JavaScript

I am currently working on building a web page using a combination of html and javascript. I have a json file that provides inputs for some specific content I need to display. My main goal is to set up an address variable in order to show the Google Maps AP ...

Guide to retrieving a byte array from a server using JavaScript and converting it into a downloadable PDF

I am attempting to convert a byte array received from the server and download it as a pdf. The download functionality is working, but unfortunately, the file appears to be corrupt. My approach involves using JavaScript and vue.js. Function responsible fo ...

Upon refreshing the page, next.js 13's useSession() function fails to fetch session information

Currently, I am working on replicating an ecommerce site using nextjs 13. On the order page, I am utilizing useSession from next-auth/react to check if a user is signed in or not. Everything works fine when I navigate to the page through a link, but if I r ...

What is the best way to incorporate a JavaScript library into a Vue3 project?

Trying to incorporate Leaflet into a Vue 3 project has presented some challenges for me. I require assistance in integrating a pure JS library with a Vue project, and I am uncertain if it is feasible without using a dedicated NPM package. After following t ...

When using ReactJS, hovering over a row in a table should trigger a change in the background color of the corresponding row in another table with the same index

I need to create a feature where hovering over a row in the first table will highlight a corresponding row in the second table. The highlighting should be based on the index of the hovered row. Here is an example: <div> <table> < ...

How can I make the columns in Next.js / Tailwind expand horizontally first instead of vertically?

Recently, I decided to customize the Next.js Image Gallery starter for some hands-on experience in full stack development with Next.js. My goal was to create a chronological photo gallery of a recent trip, but encountered an issue where the responsive colu ...