WallyJ's avatar

JQuery not working in Blade template

I am trying to use Typeahead to create an autocomplete search box in a view.

If I copy the full code from the tutorial into a blade file WITHOUT any @extends or @section areas, it works fine.

If I try to add the links and scripts to app.blade.php,

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.1/bootstrap3-typeahead.min.js"></script>

It seems to load in the browser fine, per the Chrome Inspection tool, but the functionality doesn't work.

The links in the head are there. The scripts at the bottom are there. I don't know why it isn't firing properly. When the code is on one page it works fine. When it comes from separate sections through Blade, it doesn't work. Anyone else seen this issue?

0 likes
6 replies
Dalma's avatar

Are you loading the default bootstrap js as well somewhere, is it required by your library?

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js">

Using the same Chrome inspection tool do you see any output in the Console section as it will show JS errors there?

WallyJ's avatar

I thought that it was using the typehead version of that file through this link:

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.1/bootstrap3-typeahead.min.js"></script>

I did see one error:

Uncaught TypeError: Cannot read property 'fn' of undefined
    at bootstrap3-typeahead.min.js:1
    at bootstrap3-typeahead.min.js:1
    at bootstrap3-typeahead.min.js:1
(anonymous) @ bootstrap3-typeahead.min.js:1
(anonymous) @ bootstrap3-typeahead.min.js:1
(anonymous) @ bootstrap3-typeahead.min.js:1
Snapey's avatar

what scripts do you have in your layout master

WallyJ's avatar

This is the "head" section of my app.blade.php (No scripts at the bottom of the page)

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'DocuClub') }}</title>

    <!-- Scripts -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.1/bootstrap3-typeahead.min.js"></script>
    
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">

This is the actual script on the index.blade.php page for Typeahead JS:

<script type="text/javascript">
    var path = "{{ route('autocomplete') }}";
    $('input.typeahead').typeahead({
        source:  function (query, process) {
        return $.get(path, { query: query }, function (data) {
                return process(data);
            });
        }
    });
</script>
Snapey's avatar
Snapey
Best Answer
Level 122

this

<script src="{{ asset('js/app.js') }}" defer></script>

loads app.js

If it is the out of the box app.js, then it already includes jquery, bootstrap.js and vue. You should not load any of these again.

It also contains the word 'defer'

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.

Scripts with the defer attribute will prevent the DOMContentLoaded event from firing until the script has loaded and finished evaluating.

The problem with this is that your script will try and use jquery before it has been initialised.

If you don't need vue, and want to load jquery yourself then take this line out of your layout.

If you need to keep this, don't load jquery. You will need to alse defer your other scripts, and put them after app.js

1 like
WallyJ's avatar

@SNAPEY - I wasn't sure what that file was for. It was there by default so I just ignored it. I don't currently us Vue at all, so I commented it out and... Voila!! It works now!

Thanks!

Now I just have to figure out how to add links into the results so they're clickable. I put another post into the Javascript forum about that. :)

Please or to participate in this conversation.