checkout.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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. document.getElementById('loader').style.display = 'flex';
  11. const data = await updateCart(form);
  12. document.getElementById('loader').style.display = 'none';
  13. // -- update cart icon
  14. updateCartIcon(data);
  15. // -- checkout: update item row
  16. const cart_items = data.cart_items;
  17. const cart_breakdown = data.cart_breakdown;
  18. const cart_item_rows = Array.from(document.querySelectorAll(".cart-table-row"));
  19. updateTable(cart_items, cart_item_rows, cart_breakdown);
  20. // -- product: display product availability
  21. if ('is_product_available' in data) {
  22. const isProductSelectable = data.is_product_selectable;
  23. const isProductAvailable = data.is_product_available;
  24. // -- product: display product availability
  25. const btnSubmit = document.querySelector('.btn-submit');
  26. displayProductSelectable(btnSubmit, isProductSelectable, isProductAvailable);
  27. }
  28. // update shipping cost on amount change
  29. const selectCountry = document.querySelector('select#country');
  30. const shipping_data = prepareShippingCost(selectCountry);
  31. if (shipping_data !== undefined) {
  32. const cart_breakdown_shipping = await updateShippingCost(shipping_data.country, shipping_data.weight, shipping_data.csrftoken);
  33. updateBreakdown(cart_breakdown_shipping);
  34. };
  35. });
  36. };
  37. async function updateShippingCost(country, weight, csrftoken) {
  38. const formData = new FormData();
  39. formData.append("country", country);
  40. formData.append("weight", weight);
  41. formData.append("csrftoken", csrftoken);
  42. const res = await fetch("/checkout/shipping?js=true", {
  43. method: "POST",
  44. body: formData
  45. });
  46. if (res.ok) {
  47. return res.json();
  48. } else {
  49. return {status: res.status, error: res.statusText};
  50. }
  51. }
  52. function prepareShippingCost(selectCountry) {
  53. let weight = document.querySelector('.checkout-shipping-info > input[name="weight"]');
  54. if (weight !== undefined) {
  55. weight = Number(weight.value);
  56. }
  57. let csrftoken = '';
  58. const token = document.querySelector('.checkout-shipping-info > input[name="csrftoken"]');
  59. if (token !== undefined) {
  60. csrftoken = token.value;
  61. }
  62. let country = '';
  63. if (selectCountry.value !== '') {
  64. country = selectCountry.value;
  65. }
  66. if (!isNaN(weight) && csrftoken !== '' && country !== '') {
  67. return {
  68. weight: weight,
  69. csrftoken: csrftoken,
  70. country: country,
  71. };
  72. }
  73. }
  74. async function setShippingCost() {
  75. // on page-load and
  76. // on select-country change,
  77. // get selected item and make a POST request
  78. // to calculate the shipping price + return it
  79. const selectCountry = document.querySelector('select#country');
  80. if (selectCountry !== undefined && selectCountry !== null) {
  81. // update shipping costs on page load
  82. const data = prepareShippingCost(selectCountry);
  83. if (data !== undefined) {
  84. const cart_breakdown = await updateShippingCost(data.country, data.weight, data.csrftoken);
  85. updateBreakdown(cart_breakdown);
  86. };
  87. // update shipping cost on select change
  88. selectCountry.addEventListener('change', async(e) => {
  89. const data = prepareShippingCost(selectCountry);
  90. if (data !== undefined) {
  91. const cart_breakdown = await updateShippingCost(data.country, data.weight, data.csrftoken);
  92. updateBreakdown(cart_breakdown);
  93. };
  94. });
  95. };
  96. }
  97. window.addEventListener('load', () => {
  98. ;(async() => {
  99. const forms = Array.from(document.querySelectorAll('.checkout-item'));
  100. await Promise.all(forms.map(async(form) => processForm(form)));
  101. await setShippingCost();
  102. })();
  103. });