diff --git a/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js b/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js index adc61f6..5e99e66 100644 --- a/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js +++ b/django_forms_workflows/static/django_forms_workflows/js/form-builder-property-editor.js @@ -409,7 +409,10 @@ export const propertyEditorMethods = { // Add event listener for add button const btnAdd = document.getElementById('btnAddCondition'); if (btnAdd) { - btnAdd.addEventListener('click', () => this.addConditionRow({}, conditions.length)); + btnAdd.addEventListener('click', () => { + const nextIndex = container.querySelectorAll('.card').length; + this.addConditionRow({}, nextIndex); + }); } }, @@ -472,7 +475,11 @@ export const propertyEditorMethods = { // Add event listener for add button const btnAdd = document.getElementById('btnAddValidation'); if (btnAdd) { - btnAdd.addEventListener('click', () => this.addValidationRuleRow({}, rules.length)); + btnAdd.addEventListener('click', () => { + const container = document.getElementById('validationRulesList'); + const nextIndex = container ? container.querySelectorAll('.card').length : rules.length; + this.addValidationRuleRow({}, nextIndex); + }); } }, @@ -528,7 +535,11 @@ export const propertyEditorMethods = { // Add event listener for add button const btnAdd = document.getElementById('btnAddDependency'); if (btnAdd) { - btnAdd.addEventListener('click', () => this.addDependencyRow({}, dependencies.length)); + btnAdd.addEventListener('click', () => { + const container = document.getElementById('dependenciesList'); + const nextIndex = container ? container.querySelectorAll('.card').length : dependencies.length; + this.addDependencyRow({}, nextIndex); + }); } }, @@ -630,7 +641,8 @@ export const propertyEditorMethods = { const enableConditional = document.getElementById('propEnableConditional'); if (enableConditional && enableConditional.checked) { const conditions = []; - document.querySelectorAll('.condition-field').forEach((el, index) => { + document.querySelectorAll('.condition-field').forEach((el) => { + const index = el.dataset.index; const fieldName = el.value; const operator = document.querySelector(`.condition-operator[data-index="${index}"]`).value; const value = document.querySelector(`.condition-value[data-index="${index}"]`).value; @@ -665,7 +677,8 @@ export const propertyEditorMethods = { // Save validation rules const validationRules = []; - document.querySelectorAll('.validation-type').forEach((el, index) => { + document.querySelectorAll('.validation-type').forEach((el) => { + const index = el.dataset.index; const type = el.value; const value = document.querySelector(`.validation-value[data-index="${index}"]`)?.value; const message = document.querySelector(`.validation-message[data-index="${index}"]`)?.value; @@ -691,7 +704,8 @@ export const propertyEditorMethods = { // Save field dependencies const dependencies = []; - document.querySelectorAll('.dependency-source').forEach((el, index) => { + document.querySelectorAll('.dependency-source').forEach((el) => { + const index = el.dataset.index; const sourceField = el.value; const endpoint = document.querySelector(`.dependency-endpoint[data-index="${index}"]`)?.value; diff --git a/tests_js/form-builder/initializePropertyFormTabs.test.js b/tests_js/form-builder/initializePropertyFormTabs.test.js new file mode 100644 index 0000000..a9b44ab --- /dev/null +++ b/tests_js/form-builder/initializePropertyFormTabs.test.js @@ -0,0 +1,63 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { FormBuilder } from '../../django_forms_workflows/static/django_forms_workflows/js/form-builder.js'; + +function createInstance(FormBuilder) { + const instance = Object.create(FormBuilder.prototype); + instance.initializeConditionsList = vi.fn(); + instance.initializeValidationRulesList = vi.fn(); + instance.initializeDependenciesList = vi.fn(); + return instance; +} + +describe('FormBuilder#initializePropertyFormTabs', () => { + beforeEach(() => { + document.body.innerHTML = ` + +
+ `; + }); + + it('wires the conditional-logic toggle to show/hide its section', () => { + const instance = createInstance(FormBuilder); + const field = { conditional_rules: null, validation_rules: [], field_dependencies: [] }; + + instance.initializePropertyFormTabs(field); + + const checkbox = document.getElementById('propEnableConditional'); + const container = document.getElementById('conditionalRulesContainer'); + + checkbox.checked = true; + checkbox.dispatchEvent(new Event('change')); + expect(container.style.display).toBe('block'); + + checkbox.checked = false; + checkbox.dispatchEvent(new Event('change')); + expect(container.style.display).toBe('none'); + }); + + it("initializes all three tabs' lists with the field's current data", () => { + const instance = createInstance(FormBuilder); + const field = { + conditional_rules: { conditions: [{ field: 'x', operator: 'equals', value: '1' }] }, + validation_rules: [{ type: 'required' }], + field_dependencies: [{ source: 'a', target: 'b' }], + }; + + instance.initializePropertyFormTabs(field); + + expect(instance.initializeConditionsList).toHaveBeenCalledWith(field.conditional_rules.conditions); + expect(instance.initializeValidationRulesList).toHaveBeenCalledWith(field.validation_rules); + expect(instance.initializeDependenciesList).toHaveBeenCalledWith(field.field_dependencies); + }); + + it('defaults to empty lists when the field has no rules/dependencies yet', () => { + const instance = createInstance(FormBuilder); + const field = {}; + + instance.initializePropertyFormTabs(field); + + expect(instance.initializeConditionsList).toHaveBeenCalledWith([]); + expect(instance.initializeValidationRulesList).toHaveBeenCalledWith([]); + expect(instance.initializeDependenciesList).toHaveBeenCalledWith([]); + }); +});