Skip to content

Instantly share code, notes, and snippets.

@signalwerk
Last active May 21, 2023 22:47
Show Gist options
  • Save signalwerk/9802b92b6606d4ec2aca58d8f0def4be to your computer and use it in GitHub Desktop.
Save signalwerk/9802b92b6606d4ec2aca58d8f0def4be to your computer and use it in GitHub Desktop.
Conditional form handling based on JSON-Definiton
// Latest Vesrsion
// curl https://gist.githubusercontent.com/signalwerk/9802b92b6606d4ec2aca58d8f0def4be/raw/form.js > form.js
//
// Example:
//
// document.addEventListener("DOMContentLoaded", (event) => {
// const formCondition = document.querySelector("input[id$=condition]");
// if (formCondition) {
// form(JSON.parse(formCondition.value));
// }
// });
//
// const formSchema = {
// elements: [
// {
// id: "field2",
// selector: "#field2",
// dependency: {
// dependsOn: ["field1"],
// condition: "not_empty",
// action: "show",
// elseAction: "hide",
// },
// },
// {
// id: "field3",
// selector: "#field3",
// dependency: {
// dependsOn: ["field2"],
// condition: "greater_than",
// value: 50,
// action: "hide",
// elseAction: "show",
// },
// },
// {
// id: "field4",
// selector: "#field4",
// dependency: {
// dependsOn: ["field3"],
// condition: "checked",
// action: "show",
// elseAction: "hide",
// },
// },
// {
// id: "field5",
// selector: "#field5",
// dependency: {
// dependsOn: ["field3", "field4"],
// condition: "not_empty",
// action: "show",
// elseAction: "hide",
// },
// },
// ],
// };
const form = (formSchema) => {
const getValue = (element) => {
switch (element.type) {
case "checkbox":
return element.checked;
default:
return element.value;
}
};
const checkCondition = (field, dependsOnField) => {
const dependsOnElement = document.querySelector(dependsOnField.selector);
const value = getValue(dependsOnElement);
switch (field.dependency.condition) {
// case "not_empty":
// return value !== "";
// case "greater_than":
// return Number(value) > field.dependency.value;
case "checked":
return value;
default:
console.error("Unsupported condition: ", field.dependency.condition);
return false;
}
};
const applyAction = (field, action) => {
const targetElement = document.querySelector(field.selector);
switch (action) {
case "show":
targetElement.style.display = "";
break;
case "hide":
targetElement.style.display = "none";
break;
default:
console.error("Unsupported action: ", action);
}
};
const applyDependency = (field) => {
if (field.dependency) {
const allConditionsMet = field.dependency.dependsOn.every(
(dependsOnId) => {
const dependsOnField = formSchema.elements.find(
(e) => e.id === dependsOnId
);
return checkCondition(field, dependsOnField);
}
);
if (allConditionsMet) {
applyAction(field, field.dependency.action);
} else {
applyAction(field, field.dependency.elseAction);
}
}
};
formSchema.elements.forEach((field) => {
applyDependency(field);
if (field.dependency) {
field.dependency.dependsOn.forEach((dependsOnId) => {
const dependsOnField = formSchema.elements.find(
(e) => e.id === dependsOnId
);
document
.querySelector(dependsOnField.selector)
.addEventListener("change", () => {
applyDependency(field);
});
});
}
});
};
export default form;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment