Django & JavaScript – Part 3 JavaScript & jQuery
This is the third post in a multipart series that explores web front-end technologies and how they can be used with Django. You can find the previous post here: Django & JavaScript – Part 2 HTMX.
Requirements
- Single process to host the UI & API
- Django + Django REST framework
- Overarching web framework from day 1
- Intuitive UI/UX that can be dynamically updated without loading a new page
DRF API Class
This API class will be used for all examples using the API, in which DRF handles all PUT/PATCH/POST/GET/DELETE operations.
class UserViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
filterset_class = UserFilterSet
Raw JavaScript + jQuery
By building the site based on raw JavaScript enriched by jQuery I am able to provide a tremendous amount of flexibility due to being beholden to fewer opinionated constraints. This simplistic solution pushed the the data processing and rendering to the client side, which is common practice in rich modern webpages. Where issues start to become apparent is as a project scales out. The continual need to add large amounts of JavaScript that is not constrained by an opinionated framework can lead to inconsistencies and tech debt to manage long-term.
Have you ever taken a look at a webpage’s JavaScript and seen $
used preceding a function call or a tuple with a string? There is a high likelihood that this was jQuery and the $
is the jQuery object. An example of invoking a function on the jQuery object would be $.ajax({....})
. Whereas using jQuery to access and interact with an HTML element would be using $(<selector>, <content>...)
syntax. If I wanted to select all <p>
HTML elements and hide them via jQuery, I would use $("p").hide()
. For the scope of this blog post we will be taking a simplified approach and focusing on jQuery selectors and the function calls that can be performed on the returned element(s). I will be using a mixture of JavaScript and jQuery in my blog post examples.
jQuery Selectors
jQuery selectors are very much as the name suggests—a method of selecting HTML element(s) via some type of descriptor. Keep in mind ANY function performed against a selector will apply to ALL items selected. This makes for quick updates to large amounts of elements, but you must be sure you are not changing elements that are not meant to be changed.
ID Selector
In HTML it is best practice for ID attributes of HTML elements be globally unique for everything in the DOM and to be able to select just the one element by the ID attribute it would be represented by with #<id attribute value>
as the selector. In the example of <p id="jquery">My fun paragraph</p>
I can access this element via $("#jquery")
.
Comparison
// jQuery
$("#jquery")
// JavaScript
document.getElementByID("jquery");
Element Selector
To select ALL
HTML elements of an element type, you pass in a string representation of the element type. For instance, if I wanted to select all paragraph elements which are represented by <p>
the jQuery selector would be $("p")
. And if I wanted to select just the first appearance of a <p>
element, I would use the same selector but add :first
to the element type $("p:first")
.
Comparison
// jQuery
$("p")
// JavaScript
document.getElementsByTag("p");
Class Selector
Similar to element selectors, class selectors are meant to return all HTML elements, but in this scenario it is any element with a specific class attribute. To represent the class selector, use a .
followed by the class name, as such $(.table)
.
Comparison
// jQuery
$(".table")
// JavaScript
document.getElementsByClassName("table");
Create Selector
Create selectors are done as the HTML element type in <>
symbols and will create a single instance of an HTML element in memory that is not directly applied to the DOM. This can be done via selecting another element and manipulating the HTML from that element.
Comparison
// jQuery
$("tr:last").append( // Selects the last table row
$("<td>").html("Table Data innerHTML") // Adds a table data to the table row with innerHTML
)
// JavaScript
let tr = document.getElementsByTagName("tr"); // Selects all table rows
tr[-1].innerHTML = document.createElement("td").innerHTML = "Table Data innerHTML"; // Creates and applies table data with innerHTML to the last index of table rows selected
jQuery Events
Applying a jQuery event to a jQuery selector will make it so on the event trigger. For that element the browser will execute JavaScript defined inside the event. Common event types are click
, keyup
, submit
, ready
, and change
, however there are several more.
Paragraph Highlight Example
In this example, every time the mouse cursor enters a <p>
HTML element it will change the background of that element to a light gray; and upon leaving, the background color will become unset for that element.
$(document).ready(function(){
$("p").on({
mouseenter: function(){
$(this).css("background-color", "lightgray");
},
mouseleave: function(){
$(this).css("background-color", "unset");
},
});
});
Example 1 – Build DOM from Button Click
Initial Page Without Profile Data
Page with Profile Data
Initial HTML
<div class="container">
<div class="col" id="dom-container">
<h1 id="container-heading">Waiting to load user profile.</h1>
<button
class="btn btn-primary mt-2"
onclick="load_user_profile(this, '{{ request.user.id }}')">
Load User Profile
</button>
</div>
</div>