checkout.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { updateCart, updateCartIcon, updateTable, displayProductSelectable, updateBreakdown } from './cart.js';
  2. async function processForm(form) {
  3. // handle form by preventing default behaviour
  4. // and instead manipulate data appropriately:
  5. // - send form to backend via POST
  6. // - receive response and update DOM w/o hard-refresh
  7. form.addEventListener('submit', async(e) => {
  8. e.preventDefault();
  9. // -- update form data
  10. const data = await updateCart(form);
  11. // -- update cart icon
  12. updateCartIcon(data);
  13. // -- checkout: update item row
  14. const cart_items = data.cart_items;
  15. const cart_breakdown = data.cart_breakdown;
  16. const cart_item_rows = Array.from(document.querySelectorAll(".cart-table-row"));
  17. updateTable(cart_items, cart_item_rows, cart_breakdown);
  18. // -- product: display product availability
  19. if ('is_product_available' in data) {
  20. const isProductSelectable = data.is_product_selectable;
  21. const isProductAvailable = data.is_product_available;
  22. // -- product: display product availability
  23. const btnSubmit = document.querySelector('.btn-submit');
  24. displayProductSelectable(btnSubmit, isProductSelectable, isProductAvailable);
  25. };
  26. });
  27. };
  28. async function updateShippingCost(country, weight, csrftoken) {
  29. const formData = new FormData();
  30. formData.append("country", country);
  31. formData.append("weight", weight);
  32. formData.append("csrftoken", csrftoken);
  33. const res = await fetch("/checkout/shipping?js=true", {
  34. method: "POST",
  35. body: formData
  36. });
  37. if (res.ok) {
  38. return res.json();
  39. } else {
  40. return {status: res.status, error: res.statusText};
  41. }
  42. }
  43. function prepareShippingCost(selectCountry) {
  44. let weight = document.querySelector('.checkout-shipping-info > input[name="weight"]');
  45. if (weight !== undefined) {
  46. weight = Number(weight.value);
  47. }
  48. let csrftoken = '';
  49. const token = document.querySelector('.checkout-shipping-info > input[name="csrftoken"]');
  50. if (token !== undefined) {
  51. csrftoken = token.value;
  52. }
  53. let country = '';
  54. if (selectCountry.value !== '') {
  55. country = selectCountry.value;
  56. }
  57. if (!isNaN(weight) && csrftoken !== '' && country !== '') {
  58. return {
  59. weight: weight,
  60. csrftoken: csrftoken,
  61. country: country,
  62. };
  63. }
  64. }
  65. async function setShippingCost() {
  66. // on page-load and
  67. // on select-country change,
  68. // get selected item and make a POST request
  69. // to calculate the shipping price + return it
  70. const selectCountry = document.querySelector('select#country');
  71. if (selectCountry !== undefined && selectCountry !== null) {
  72. // update shipping costs on page load
  73. const data = prepareShippingCost(selectCountry);
  74. if (data !== undefined) {
  75. const cart_breakdown = await updateShippingCost(data.country, data.weight, data.csrftoken);
  76. updateBreakdown(cart_breakdown);
  77. };
  78. // update shipping cost on select change
  79. selectCountry.addEventListener('change', async(e) => {
  80. const data = prepareShippingCost(selectCountry);
  81. if (data !== undefined) {
  82. const cart_breakdown = await updateShippingCost(data.country, data.weight, data.csrftoken);
  83. updateBreakdown(cart_breakdown);
  84. };
  85. });
  86. };
  87. }
  88. window.addEventListener('load', () => {
  89. ;(async() => {
  90. const forms = Array.from(document.querySelectorAll('.checkout-item'));
  91. await Promise.all(forms.map(async(form) => processForm(form)));
  92. await setShippingCost();
  93. })();
  94. });