'use strict'; // // Order card initialization functions // // Functions to initialize a product card const orderCardInitializers = {}; // Product card callback weak map (because we cannot store function references on HTMLElements) const orderCardCallbacks = new WeakMap(); function initializeOrderCard(card) { const initializer = orderCardInitializers[card.dataset.initializer]; if(initializer) { const cardCallbacks = {}; orderCardCallbacks.set(card, cardCallbacks); initializer(card, cardCallbacks); } else { console.error("Order card", card, "states unknown initializer name", card.dataset.initializer, ". Card not initialized."); } } function getOrderCardCallbacks(card) { return orderCardCallbacks.get(card); } // Register initializer for the 'no product card' card orderCardInitializers['no-product-card'] = function(card, callbacks) { // noop callbacks.getOrderData = function() {}; } function validateNumberChoice(self) { /*const value = parseInt(self.value) const error_div = self.closest(".question").querySelector(".error"); var error_message = "" if(isNaN(value)) { switch(document.body.dataset.language) { case "nl": error_message = "Ongeldige waarde"; break; case "de": error_message = "Ungültiger Wert" break; case "en": default: error_message = "Invalid value"; break; } } else { const minimum = self.min; if(minimum && value < minimum) { switch(document.body.dataset.language) { // XXX: Not generic case "nl": error_message= "Bovenstaande afmeting is minimaal " + minimum + " mm"; break; case "de": error_message= "Das obige Maß beträgt mindestens " + minimum + " mm"; break; case "en": default: error_message= "The above dimension is at least " + minimum + " mm"; break; } } let maximum = self.max; if(maximum && value > maximum) { switch(document.body.dataset.language) { // XXX: Not generic case "de": error_message = "Das obige Maß beträgt maximal " + maximum + " mm"; break; case "nl": error_message = "Bovenstaande afmeting is maximaal " + maximum + " mm"; break; case "en": default: error_message = "The above dimension is at most " + maximum + " mm"; break; } } } error_div.innerHTML = error_message; const showingSnapNotice = error_div.classList.contains("snap-notice"); if (!showingSnapNotice) { if(!error_message) { error_div.classList.add("hidden"); } else { error_div.classList.remove("hidden"); } }*/ } // // General Order Card utility functions // function chooseOneProcessing(root, choices, selectedClass='choose-one-selected') { /* This function is used to process nodes in the given root element. It does so by updating all elements to select the first candidate that has a data-when attribute matching the given choices. It expects a HTML fragment shape like: ... ... Where the elements can be of any type. */ // Find each node in the tree we are updating for(const chooseOneElement of root.querySelectorAll('choose-one')) { // Remove the class indicating the element is selected Array.from(chooseOneElement.children).forEach(c => c.classList.remove(selectedClass)); // Go through the candidates top to bottom for(const candidate of chooseOneElement.children) { // Parse data-when attribute of the candidate const when = JSON.parse(candidate.dataset.when); // match candidate's "when" against the choices if(Object.keys(when).every(k => when[k] == choices[k])) { // We have found the first match candidate.classList.add(selectedClass); // Break out of the candidate matching loop break; } } } } const choiceTypeParsers = { 'string': v => v, 'integer': v => parseInt(v), }; function getChoiceValue(choiceElement) { const parser = choiceTypeParsers[choiceElement.dataset.type]; return parser(choiceElement.value); } // Encode string as UTF-8 bytes function utf8Base64UrlSafe(str) { const bytes = new TextEncoder().encode(str); let binary = ''; const chunkSize = 8192; for (let i = 0; i < bytes.length; i += chunkSize) { binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunkSize)); } return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_'); } // Opens a new tab that displays only the given order card function openOrderCardTab(card) { const orderData = getOrderCardCallbacks(card).getOrderData(); const orderDataText = JSON.stringify(orderData); const orderInfo = utf8Base64UrlSafe(orderDataText); const mountpoint = $('meta[name="mountpoint"]').attr('content'); const url = mountpoint + '/product-card/' + orderInfo + '?lang=' + document.body.dataset.language; window.open(url, '_blank'); }