HTML not executing code from external JavaScript file

I wrote ajax for django to add products to cart, I use internal js which runs but when I put that code in external js file it doesn't work, Although I received the ID and csrf_token.

  • html

     <main data-item-id="{{ product.id }}" data-csrf-token="{{ csrf_token }}">
    

javascript

$(document).ready(function(){
var btn = document.querySelector(".add-to-cart");
var productId = document.querySelector('main').getAttribute('data-item-id');
var csrfToken = document.querySelector('main').getAttribute('data-csrf-token');
btn.addEventListener("click", function(){
    $.ajax({
        type: 'POST',
        url: '{% url "cart:add_to_cart"%}',
        data: {'productId': productId},
        headers: {'X-CSRFToken': csrfToken},
        success: function(data){
            $("#total-items").text(data.total_items);
        }
    })
})

})

also the script and jquery are defined.

You have a Django template tag inside the JS file: url: '{% url "cart:add_to_cart" %}' Django only processes template tags in HTML templates (or any file passed through the template engine).

You can put the URL into a data-attribute in your HTML and read it in JS:

<main
  data-item-id="{{ product.id }}"
  data-csrf-token="{{ csrf_token }}"
  data-add-to-cart-url="{% url 'cart:add_to_cart' %}"
>

External JS

$(function () {
  const btn = document.querySelector(".add-to-cart");
  const mainEl = document.querySelector("main");

  const productId = mainEl.getAttribute("data-item-id");
  const csrfToken  = mainEl.getAttribute("data-csrf-token");
  const addToCartUrl = mainEl.getAttribute("data-add-to-cart-url");

  if (!btn) return;

  btn.addEventListener("click", function () {
    $.ajax({
      type: "POST",
      url: addToCartUrl,
      data: { productId },
      headers: { "X-CSRFToken": csrfToken },
      success: function (data) {
        $("#total-items").text(data.total_items);
      },
      error: function (xhr) {
        console.error("Add to cart failed:", xhr.status, xhr.responseText);
      }
    });
  });
});

Or you can expose the URL directly as a global variable and then have in cart.js const addToCartUrl = window.ADD_TO_CART_URL;

<script>
  window.ADD_TO_CART_URL = "{% url 'cart:add_to_cart' %}";
</script>
<script src="{% static 'js/cart.js' %}"></script>

Kindly include the JQuery before your external JS:

<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/cart.js' %}"></script>

Ensure the file path is correct and being served via {% static %}. If the .add-to-cart button is rendered later (via another script), use event delegation.

$(document).on("click", ".add-to-cart", function () {
  const mainEl = document.querySelector("main");
  const productId = mainEl.getAttribute("data-item-id");
  const csrfToken = mainEl.getAttribute("data-csrf-token");
  $.ajax({
    type: "POST",
    url: addToCartUrl,
    data: { productId },
    headers: { "X-CSRFToken": csrfToken },
    success: function (data) {
      $("#total-items").text(data.total_items);
    }
  });
});

This should help you.

Вернуться на верх