0

I'm getting the following JavaScript error in the console on a form page:

Uncaught TypeError: $(...).tooltip is not a function

If I reload the page, then it works fine. If I navigate to the page from elsewhere, then it gives the error. The CoffeeScript which initializes the tooltips is

$(document).on 'turbolinks:load', ->
  # copy all placeholders to title
  $('[data-toggle="tooltip"]').each ->
    $(this).attr 'title', $(this).attr('placeholder')
  $('[data-toggle="tooltip"]').tooltip()

I don't include JQuery twice.

    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
    %script{:crossorigin => "anonymous", :src => "https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js", :integrity => "sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb"}
    %script{:crossorigin => "anonymous", :src => "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js", :integrity => "sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"}
    / UIkit JS
    %script{:src => "https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.30/js/uikit.min.js"}
    %script{:src => "https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.30/js/uikit-icons.min.js"}    
    ...
  %body
    ...
    = yield
    = render 'layouts/footer'
    -# PureChat
    <script type='text/javascript' data-cfasync='false'>window.purechatApi = { l: [], t: [], on: function () { this.l.push(arguments); } }; (function () { var done = false; var script = document.createElement('script'); script.async = true; script.type = 'text/javascript'; script.src = 'https://app.purechat.com/VisitorWidget/WidgetScript'; document.getElementsByTagName('HEAD').item(0).appendChild(script); script.onreadystatechange = script.onload = function (e) { if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) { var w = new PCWidget({c: 'fffff-ffff-ffff-fffffffff', f: true }); done = true; } }; })();</script>

The Bootstrap docs are here. The Turbolinks docs are here.

I believe the problem may be with Turbolinks or PureChat. For some reason, the .tooltip() function is not available, even though the call to it is wrapped in the event turbolinks:load. Also, I cannot reproduce the problem if I exclude PureChat from the bottom of the body. When I do include PureChat, the first error in the console is a .tooltip() error, but only sometimes, and only when I navigate from one page to another. Sometimes it works. It still always works if I reload the page with the tooltips.

None of the similar questions (link, link, link) mention Turbolinks. I am not using JQueryUI. I am not including JQuery twice.

How do I fix this error?

Rails 5.0.6.

Chloe
  • 25,162
  • 40
  • 190
  • 357
  • I added `script = document.createElement('script'); script.dataset.turbolinksTrack = 'reload';` to the PureChat script loader and it seemed to prevent the problem, but it also seemed to disable Turbolinks for every page and just make everything slower. I did see in the Elements inspector that it does insert and load another JQuery 2.1.4 at the bottom of the `body`, which might be the problem. The `data-turbolinks-track` will temporarily fix it until PureChat fixes the root cause. – Chloe Oct 16 '17 at 19:15
  • Adding `data-turbolinks-track` to the PureChat script causes page navigation to jump around to random spots in the page. I had to just disable PureChat. I will look for an alternative unless they fix it soon. – Chloe Oct 16 '17 at 19:30

1 Answers1

0

use this if jquery does not work this line will fix

$(document).on("turbolinks:load", function () {
    console.log('into setInterval');
    if(window.jQuery){
        console.log('Get From first');
        return init();
    }else{
        console.log('into setInterval else');
        var fixloop = setInterval(() => {
            console.log('into setInterval');

            if(!window.jQuery){

                console.log('into setInterval inner if');
                var script = document.createElement('script');
                script.src = 'https://code.jquery.com/jquery-3.3.1.min.js';
                return init();
            }else{

                console.log('into setInterval inner else');
                clearInterval(fixloop);
                return init();

            }
        }, 50);
    }
});

link like this

<script src="https://code.jquery.com/jquery-3.3.1.min.js" ></script>
<script src="{{ asset('plugins/popper.js/dist/umd/popper.min.js') }}" data-turbolinks-eval='false'></script>
<script src="{{ asset('plugins/bootstrap/dist/js/bootstrap.min.js') }}" ></script>
<script src="{{ asset('dist/js/theme.js') }}" data-turbolinks-eval='true' > </script>