Search code examples
twitter-bootstrapmeteorbootstrap-select

Meteor: How to make Bootstrap Select reactive?


When using Bootstrap multiselect, I find that the multiselect jquery always fires a little bit too early - before the template has finished pulling data from the helpers, and as a result the select boxes are often empty (I'd say about 60% of the time).

Clearly Template.usersLayout.rendered() is not the right place to call functions that rely on data to have been rendered. What is a better way to do this?

Alternatively, I guess making the bootstrap-select javascript 'reactive would be 1st prize. How can I do this?

code is below

==========

I'm using a helper (#each) to create a select box where each option is it's own data context.

<template name="usersLayout">
    <form>
        <!-- Multiselect for instruments -->
        <div class="form-group">
            <label for="playerInstruments">Player instruments</label>
            <div class="controls text-left">
                <select id="playerInstruments" multiple="multiple" class="selectFilter" name="playerInstruments">
                    {{#each instruments}}
                    <option value="{{name}}">{{name}}</option>
                    {{/each}}
                </select>
            </div>
        </div>
    </form>
</template>

The helper is defined as follows:

Template.usersLayout.helpers({

    /* Database retrievals */

    // Returns all Instruments from Mongo
    instruments: function() {
        return Instruments.find();
    }

})

The twitter bootstrap code is all something like the following:

Template.usersLayout.rendered = function () {

    $('#playerInstruments').multiselect({
        disableIfEmpty: true,
        onChange: function(option, checked) {
            // Set the session as the checked valuess
            var tempSessionArr = $("#playerInstruments").val();
            // Add or delete from Session
            Session.set('playerInstruments', tempSessionArr);
        },
    });
}

Solution

  • The problem is your template does not wait for the data before it start to render, Since data only appears on page after template already rendered, select box is empty. I know that this is your first app and you did not remove the autopublish package, but it is a best practice to follow the full tutorial from Flow Router

    First of all, read this. Then, change your router to have the subcriptions options. After that, check if the subscriptions are ready through this (the subsReady() should be inside the rendered function) and then, in the callback of the subsReady(), init the selectbox