| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- 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/<product-id>?<params>`
- // 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);
- }));
- })();
- });
|