snapshot: preserve configurable onboarding conditional logic

This commit is contained in:
Md Bayazid Bostame
2026-03-27 12:54:47 +01:00
parent eb0fb811e4
commit 2e5e941d41
9 changed files with 431 additions and 41 deletions

View File

@@ -6,6 +6,8 @@
const btnSubmit = document.getElementById('btn-submit');
const form = document.getElementById('onboarding-form');
const emailDomain = ((form && form.dataset.emailDomain) || 'workdock.de').replace(/^@+/, '').trim();
const conditionalRulesNode = document.getElementById('onboarding-conditional-rules');
const conditionalRules = conditionalRulesNode ? JSON.parse(conditionalRulesNode.textContent || '{}') : {};
let current = 0;
form.setAttribute('novalidate', 'novalidate');
@@ -14,34 +16,39 @@
const el = document.getElementById(id);
if (!el) return;
el.classList.toggle('hidden', !state);
el.setAttribute('aria-hidden', state ? 'false' : 'true');
}
function fieldState(name) {
const field = byName(name);
if (!field) return { exists: false, value: '', checked: false };
return {
exists: true,
value: (field.value || '').trim(),
checked: !!field.checked,
};
}
function evaluateClause(clause) {
const state = fieldState(clause.field);
if (!state.exists) return false;
if (clause.operator === 'checked') return state.checked === !!clause.value;
if (clause.operator === 'equals') return state.value === String(clause.value);
if (clause.operator === 'not_equals') return state.value !== String(clause.value);
return false;
}
function evaluateRule(rule) {
const all = Array.isArray(rule.all) ? rule.all : [];
return all.every(evaluateClause);
}
function syncConditionals() {
const orderCards = byName('order_business_cards');
toggle('business-card-box', orderCards && orderCards.checked);
const employmentType = byName('employment_type');
toggle('employment-end-box', employmentType && employmentType.value === 'befristet');
const groupMailbox = byName('group_mailboxes_required_choice');
toggle('group-mailboxes-box', groupMailbox && groupMailbox.value === 'ja');
const extraHardware = byName('additional_hardware_needed_choice');
toggle('extra-hardware-box', extraHardware && extraHardware.value === 'ja');
const extraSoftware = byName('additional_software_needed_choice');
toggle('extra-software-box', extraSoftware && extraSoftware.value === 'ja');
const extraAccess = byName('additional_access_needed_choice');
toggle('extra-access-box', extraAccess && extraAccess.value === 'ja');
const successor = byName('successor_required_choice');
const showSuccessor = successor && successor.value === 'ja';
toggle('successor-box', showSuccessor);
const inheritPhone = byName('inherit_phone_number_choice');
const hidePhone = showSuccessor && inheritPhone && inheritPhone.value === 'ja';
toggle('phone-box', !hidePhone);
Object.entries(conditionalRules).forEach(function (entry) {
const targetId = entry[0];
const rule = entry[1] || {};
toggle(targetId, evaluateRule(rule));
});
// Hidden conditional groups must not block submit with invisible required fields.
document.querySelectorAll('.field-group').forEach(function (group) {
@@ -60,6 +67,22 @@
});
}
function setupConditionalBindings() {
const watched = new Set();
Object.values(conditionalRules).forEach(function (rule) {
const all = Array.isArray(rule.all) ? rule.all : [];
all.forEach(function (clause) {
if (clause.field) watched.add(clause.field);
});
});
watched.forEach(function (name) {
const field = byName(name);
if (!field) return;
field.addEventListener('change', syncConditionals);
field.addEventListener('input', syncConditionals);
});
}
function slugifyForEmail(value) {
const map = { 'ä': 'ae', 'ö': 'oe', 'ü': 'ue', 'ß': 'ss' };
const lower = (value || '').toLowerCase();
@@ -224,7 +247,6 @@
current = Math.max(0, step);
}
document.addEventListener('change', syncConditionals);
navItems.forEach((n, idx) => {
n.addEventListener('click', function () { current = idx; updateStep(); });
n.addEventListener('keydown', function (e) {
@@ -245,6 +267,7 @@
});
syncConditionals();
setupConditionalBindings();
setupWorkEmailAutofill();
setupBusinessCardAutofill();
setupChecklistToggles();