Search code examples
javascriptjqueryhtmlmeteormaterialize

Materialize material_select() not working before refresh in Meteor app


I'm using following select in a template in my Meteor project

    <div class="input-field">
        <select name="color" id="color">
            <option value="%23B1365F">Pink</option>
            <option value="%232952A3">Blue</option>
            <option value="%23711616">Red</option>
            <option value="%2328754E">Green</option>
            <option value="%23BE6D00">Orange</option>
            <option value="%23113F47">Sea Blue</option>
            <option value="%235229A3">Purple</option>
            <option value="%23528800">Olive</option>
            <option value="%2388880E">Gold</option>
            <option value="%23333333">Black</option>
        </select>
        <label for="color">Colour: </label>
    </div>

With the following in my js-file to initialize the Materialize select dropdown

    if (Meteor.isClient) {
      Template.layout_settings.onRendered(function () {
        $('select').material_select();
      });
    }

However, the select dialog only works/shows after a refresh, before a refresh I get following error in console:

    TypeError: $(...).material_select is not a function
      at null.<anonymous> (settings.js:48)
      at template.js:116
      at Function.Template._withTemplateInstanceFunc (template.js:457)
      at fireCallbacks (template.js:112)
      at null.<anonymous> (template.js:205)
      at view.js:107
      at Object.Blaze._withCurrentView (view.js:538)
      at view.js:106
      at Object.Tracker._runFlush (tracker.js:497)
      at onGlobalMessage (setimmediate.js:102)

After a refresh it works perfectly fine, does anyone has any idea why this happens? Couldn't find anything on google.

Before refresh

After refresh

Thanks in advance!


Solution

  • This isn't the prettiest of workarounds, but it fixed the problem.

    Materialze doesn't seem to add its jQuery functions in time to use them in the onRendered function of a Blaze template.

    It does however add the function to the Package.jquery.$.fn.material_select object.

    I just created my own jQuery function which referenced the function body of that object:

        (function($){
            $.fn.material_select_fix = Package.jquery.$.fn.material_select;
        })(jQuery)
        $("select").material_select_fix();
    

    I hope this works for other cases too...