import { updateCart, updateCartIcon, updateTable, updateProductURL, displayProductSelectable } from './cart.js'; async function processForm(form) { // handle form by preventing default behaviour // and instead manipulate data appropriately: // - send form to backend via POST // - receive response and update DOM w/o hard-refresh form.addEventListener('submit', async(e) => { e.preventDefault(); // -- update form data const data = await updateCart(form); // -- update cart icon updateCartIcon(data); // -- display product availability const btnSubmit = document.querySelector('.btn-submit'); const isProductSelectable = data.is_product_selectable; const isProductAvailable = data.is_product_available; displayProductSelectable(btnSubmit, isProductSelectable, isProductAvailable); // -- update URL updateProductURL(data.product_selected); }); }; async function checkProductAvailability(product_path, searchParams){ const res = await fetch(`/${product_path}?js=true&${searchParams.toString()}`); if (res.ok) { return res.json(); } else { return {status: res.status, error: res.statusText}; } }; async function changeProductURLOnInputRadio(form) { // add on-change listener to all .input-listen input fields // and update URL accordingly const inputs = Array.from(form.querySelectorAll('.input-listen')); await Promise.all(inputs.map(async(input) => { input.addEventListener('change', async(e) => { let key = e.target.name; let value = e.target.value; if ('URLSearchParams' in window) { // send request to `/products/?` // to get back an instant result for this and update UI const product_path = form.querySelector('#product_path').value; const searchParams = new URLSearchParams(window.location.search); searchParams.set(key, value); // update URL only if a key combination of size and style are selected, // else do nothing — otherwise the item would be seen as sold out. let size = searchParams.get('size'); let style = searchParams.get('style'); if (size || style) { const data = await checkProductAvailability(product_path, searchParams); // -- update product availability const btnSubmit = document.querySelector('.btn-submit'); const isProductSelectable = data.is_product_selectable; const isProductAvailable = data.is_product_available; displayProductSelectable(btnSubmit, isProductSelectable, isProductAvailable); } history.pushState(null, '', `?${searchParams.toString()}`); }; }); })); } window.addEventListener('load', () => { ;(async() => { const forms = Array.from(document.querySelectorAll('.product-item')); await Promise.all(forms.map(async(form) => { processForm(form); changeProductURLOnInputRadio(form); })); })(); });