Javascript in Laravel (just jQuery)

The jQuery way

Pim Hooghiemstra
May 2, 2018 · 5 min read

Update May 2021

Please note that this post is currently 3 years old. As you know, things move fast in our tech world and event though the principles described in this post are still valid, there might be better ways to achieve the same result; You are free to continue reading, but I recently wrote a post about our current approach.

Additionally, Laravel 8 brings a new starter kit to quickly scaffold the frontend of your next project. It’s called Laravel Jetstream and is definitely worth taking a look. I’ll choose Laravel Jetstream with Inertia scaffolding for my next project.

Therefore, I am removing the code repository that originally came with this post.

Original post

This post is the first part of a greater series on adding Javascript in a Laravel project. If you haven’t, I strongly encourage you to start with the overview post where the sample project and the goal of the series is described.

So far we created a registration form in a blade view and the next step is to add the desired behaviour to the form:

  • Choosing a gender should add a text field to the form to enter your name. The label of the text field should become either Mr. or Ms. depending on the chosen gender.
  • Validatie the email address is valid when the email field looses focus and if it is valid, check whether the email is still available (via AJAX request to the server). Show a message reflecting this.
  • Check the combination of zipcode and country when choosing one or the other. Show a message if the zipcode does not comply with the rules for the specific country.

In this post I’ll describe the easiest way to achieve this: by adding a script tag directly below the form inside the blade view and writing all Javascript logic using jQuery.

Including <script> tags in head and view

The initial approach described here uses jQuery. It is the oldest (and quickest and easiest) way I know and in some of my legacy projects it is still used. Either because this code is still working properly or due to limited time or budget to update the code.

Back in the day I used jQuery to add any special behaviour. Hence, jQuery is loaded from a CDN in the <head> section of the document (in app.blade.php). Since our sample project has a Bootstrap menu, the Popper.js and Bootstrap.js scripts must be included to make it work. Note that the order of these scripts is important!

Hence, app.blade.php looks like this:

The sample app only has a single page at the moment. The contents of the page are inserted at the @yield('content') you see in line 34 of app.blade.php.

In this view we include the form, a blade partial (see line 17)

Since we have jQuery available via the include in the head section, let’s add the following script tag inside the page:

The script starts with the traditional jQuery ready line to make sure that jQuery is fully loaded and initialised to do its magic. Then we wrap the whole code inside an immediately invoked function expression (IIFE) to be able to use the $ instead of jQuery. The latter shouldn’t be necessary for this post on its own, but in upcoming posts we’ll show why this is needed.

Inside the IIFE we add Laravel’s CSRF token to the AJAX headers. This way we won’t get any errors when doing a POST request.

Then we come to the event listeners attached to the DOM elements. The code is rather self explanatory so I won’t discuss it in detail. One thing to point out though: this approach requires us to add and remove DOM nodes to react to user input.

For example, the error messages from previous events need to be removed before the event listener’s callback continues (line 41). In addition, a text field is inserted after the user chooses its gender (line 35), a message is displayed after entering the email address (line 48 and 80) and so on.

This is typically the way jQuery works. It is an imperative language that works directly on the DOM by adding, removing, updating, hiding and showing DOM nodes.

Pros and cons of this approach

Throughout the years and before we embraced Javascript frameworks (Vue, React, Angular to name a few), jQuery was the de facto way of handling user interactions because

  • it is easy to learn for newcomers to Javascript
  • it just makes your code work across browsers
    Back in the day this was a huge win, today most browsers are converting to very similar behaviour.
  • it has (should I say had?) a vibrant community creating huge amounts of plugins
  • it comes with $.ajax as a wrapper for the native Javascript XMLHttpRequest
  • it lets you write code without bothering about bundling and stuff a like.

However, as time went by and webapplications were growing and became more complex, the downsides using jQuery became clear:

  • script tags need to be inserted in the correct order
  • difficult to reason about the flow of the code
  • callback hell awaits you
  • difficult (or even impossible) to test the code
  • jQuery is defined as a global variable which comes with its problems as described in great detail in this post:

This makes maintaining code tricky. It makes removing old code or script tags a game of roulette. You don’t know what might break. The dependencies between these different parts of your code are implicit. Any function can grab anything on the global, so you don’t know which functions depend on which scripts.

A second problem is that because these variables are on the global scope, every part of the code that’s inside of that global scope can change the variable. Malicious code can change that variable on purpose to make your code do something you didn’t mean for it to, or non-malicious code could just accidentally clobber your variable.

Concluding remarks

All in all I have been very happy with jQuery in the past. But as the apps I was working on became larger and more complex, it was time for a better approach. For example using a bundler to bundle, minimize and uglify the code and being able to import npm modules and our own helper functions. This will be the subject of the next post of this series on using Javascript in Laravel, where we use webpack to do exactly this!

PLint-sites

Dutch based webdevelopment company, focussing on modern…

PLint-sites

Dutch based webdevelopment company, focussing on modern webapplications using Laravel and Vue. Mainly writes about stuff to achieve cool things!

Pim Hooghiemstra

Written by

Love to build Laravel + Vue applications! Founder of PLint-sites. https://plint-sites.nl

PLint-sites

Dutch based webdevelopment company, focussing on modern webapplications using Laravel and Vue. Mainly writes about stuff to achieve cool things!