This code is created for a specific example use case. Feel free to modify the code using ChatGPT to suit your needs.
document.addEventListener("DOMContentLoaded", function () {
const config = {
formSelector: '[fs-configurator-element="form"]',
inputSelector: "[fs-configurator-input]",
inputAttribute: "fs-configurator-input", // Use this for direct attribute references
imageSelector: "[fs-configurator-finalimage]",
imageAttribute: "fs-configurator-finalimage", // Use this for direct attribute references
sourceSelector: "[fs-configurator-imagesource]",
sourceAttribute: "fs-configurator-imagesource", // Use this for direct attribute references
storagePrefix: "user_", // Prefix for local storage keys
};
// Updates images based on current selections
function updateImages() {
const selections = getSelections();
const selectionKeys = Object.keys(selections)
.sort()
.map((key) => selections[key])
.join("-")
.toLowerCase();
document.querySelectorAll(config.imageSelector).forEach((image) => {
const imageId = image.getAttribute(config.imageAttribute); // Use attribute from config
const sourceKey = `${selectionKeys}-${imageId}`; // Dynamically constructs the key to match source
const matchedSource = findMatchingSource(sourceKey);
if (matchedSource) {
image.src = matchedSource;
console.log(`Image ${imageId} source updated to ${matchedSource}`);
} else {
console.log(
`No matching source found for ${sourceKey}. Image ${imageId} not updated.`,
);
}
});
}
// Gathers current selections from form inputs
function getSelections() {
const selections = {};
document.querySelectorAll(config.inputSelector).forEach((input) => {
if (
input.checked ||
input.type === "text" ||
input.tagName.toLowerCase() === "select"
) {
const attributeValue = input.getAttribute(config.inputAttribute); // Use attribute from config
selections[attributeValue] = input.value;
}
});
return selections;
}
// Finds a matching source based on the constructed key
function findMatchingSource(sourceKey) {
const sourceElement = document.querySelector(
`${config.sourceSelector}[${config.sourceAttribute}="${sourceKey.toLowerCase()}"]`, // Use attribute from config
);
return sourceElement ? sourceElement.textContent.trim() : null;
}
// Saves the current selections to local storage
function saveSelections() {
Object.entries(getSelections()).forEach(([key, value]) => {
const storageKey = `${config.storagePrefix}${key}`;
localStorage.setItem(storageKey, value);
console.log(`Selection saved: ${storageKey} = ${value}`);
});
}
// Loads selections from local storage upon initialization
function loadSelections() {
document.querySelectorAll(config.inputSelector).forEach((input) => {
const key = input.getAttribute(config.inputAttribute); // Use attribute from config
const storageKey = `${config.storagePrefix}${key}`;
const value = localStorage.getItem(storageKey);
if (value !== null) {
if (input.type === "checkbox" || input.type === "radio") {
input.checked = input.value === value;
} else {
input.value = value;
}
console.log(`Loaded selection: ${storageKey} = ${value}`);
}
});
}
// Attaches change event listeners to form inputs to trigger updates
document
.querySelector(config.formSelector)
.addEventListener("change", function (e) {
if (e.target.matches(config.inputSelector)) {
updateImages();
saveSelections();
}
});
// Initial actions: load selections and update images accordingly
loadSelections();
updateImages();
});