From e06f85d350fbd1fc0d1873551e4bf16b5d24f495 Mon Sep 17 00:00:00 2001 From: James Lucas Date: Fri, 20 Oct 2023 14:33:21 +1100 Subject: [PATCH] fix: allow Bootstrap row identifiers to be any string value after row- (eg row-myrow). This allows default fields or inputSets to be pre-configured with named rows which can then be targeted with CSS rules. --- src/js/form-builder.js | 65 ++++++++++++++++++----------------------- src/js/helpers.js | 12 ++++---- tests/bootstrap.test.js | 9 ++++-- 3 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/js/form-builder.js b/src/js/form-builder.js index 4494915bf..e6100354c 100644 --- a/src/js/form-builder.js +++ b/src/js/form-builder.js @@ -56,6 +56,7 @@ function FormBuilder(opts, element, $) { const data = new Data(formID) const d = new Dom(formID) + /** @var formRows Allocated rows IDs in the builder */ let formRows = [] formBuilder.preserveTempContainers = [] formBuilder.rowWrapperClassSelector = rowWrapperClassSelector @@ -331,10 +332,7 @@ function FormBuilder(opts, element, $) { const loadFields = function (formData) { formData = h.getData(formData) if (formData && formData.length) { - formData.forEach(field => { - CaptureRowData(field) - }) - + formData.forEach(field => CaptureRowData(field)) formData.forEach(fieldData => prepFieldVars(trimObj(fieldData))) d.stage.classList.remove('empty') } else if (opts.defaultFields && opts.defaultFields.length) { @@ -1133,7 +1131,7 @@ function FormBuilder(opts, element, $) { let rowWrapperNode if (enhancedBootstrapEnabled()) { - const targetRow = `div.row-${columnData.rowNumber}` + const targetRow = `div.row-${columnData.rowUniqueId}` //Check if an overall row already exists for the field, else create one if ($stage.children(targetRow).length) { @@ -1141,7 +1139,7 @@ function FormBuilder(opts, element, $) { } else { rowWrapperNode = m('div', null, { id: `${field.id}-row`, - className: `row row-${columnData.rowNumber} ${rowWrapperClass}`, + className: `row row-${columnData.rowUniqueId} ${rowWrapperClass}`, }) } @@ -1329,7 +1327,7 @@ function FormBuilder(opts, element, $) { const rowWrapperNode = m('div', null, { id: `${colWrapper.find('li').attr('id')}-row`, - className: `row row-${columnData.rowNumber} ${rowWrapperClass}`, + className: `row row-${columnData.rowUniqueId} ${rowWrapperClass}`, }) $(ui.item).parent().replaceWith(rowWrapperNode) @@ -1465,48 +1463,43 @@ function FormBuilder(opts, element, $) { } function prepareFieldRow(data) { - let result = {} - if (!enhancedBootstrapEnabled()) { - return result + return {} } - result = h.tryParseColumnInfo(data) - TryCreateNew() - - if (!formRows.includes(result.rowNumber)) { - formRows.push(result.rowNumber) - } - - return result - - function TryCreateNew() { - if (!result.rowNumber) { + const result = h.tryParseColumnInfo(data) + if (!result.rowUniqueId) { + //If inserting directly into column, use the correct rowUniqueId + if (insertingNewControl && insertTargetIsColumn) { + result.rowUniqueId = h.getRowValue($targetInsertWrapper.attr('class')) + } else { //Column information wasn't defined, get new default configuration for one. let nextRow if (formRows.length === 0) { nextRow = 1 } else { - nextRow = Math.max(...formRows) + 1 + const numericalRows = formRows.filter(value => !isNaN(value) && !isNaN(parseInt(value))).map(str => parseInt(str)) + nextRow = (Math.max(...numericalRows) + 1) } - result.rowNumber = nextRow + result.rowUniqueId = nextRow.toString() + } - //If inserting directly into column, use the correct rowNumber - if (insertingNewControl && insertTargetIsColumn) { - result.rowNumber = h.getRowValue($targetInsertWrapper.attr('class')) - } + result.columnSize = opts.defaultGridColumnClass - result.columnSize = opts.defaultGridColumnClass + if (!data.className) { + data.className = '' + } - if (!data.className) { - data.className = '' - } + data.className += ` row-${result.rowUniqueId} ${result.columnSize}` + result.addedDefaultColumnClass = true + } - data.className += ` row-${result.rowNumber} ${result.columnSize}` - result.addedDefaultColumnClass = true - } + if (!formRows.includes(result.rowUniqueId)) { + formRows.push(result.rowUniqueId) } + + return result } // Select field html, since there may be multiple @@ -1868,7 +1861,7 @@ function FormBuilder(opts, element, $) { const rowWrapper = m('div', null, { id: `${$clone.attr('id')}-row`, - className: `row row-${columnData.rowNumber} ${rowWrapperClass}`, + className: `row row-${columnData.rowUniqueId} ${rowWrapperClass}`, }) const colWrapper = m('div', null, { @@ -2173,7 +2166,7 @@ function FormBuilder(opts, element, $) { const rowWrapperNode = m('div', null, { id: `${h.incrementId(data.lastID)}-row`, - className: `row row-${columnData.rowNumber} ${rowWrapperClass}`, + className: `row row-${columnData.rowUniqueId} ${rowWrapperClass}`, }) $stage.append(rowWrapperNode) diff --git a/src/js/helpers.js b/src/js/helpers.js index d8253d6df..69bb0a9ed 100644 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -1334,7 +1334,7 @@ export default class Helpers { /** * @typedef BsColumnInfo - * @param {number} [rowNumber] + * @param {string} [rowUniqueId] * @param {string} [columnSize] */ @@ -1351,7 +1351,7 @@ export default class Helpers { if (classes && classes.length > 0) { classes.forEach(element => { if (element.startsWith('row-')) { - result['rowNumber'] = parseInt(element.replace('row-', '').trim()) + result['rowUniqueId'] = element.replace('row-', '').trim() } else { result['columnSize'] = element } @@ -1434,18 +1434,18 @@ export default class Helpers { } /** - * Return the row value i.e row-2 would return 2 + * Return the row value i.e row-2 would return '2' * @param {string} className - * @returns {number} Row number or 0 for invalid definitions + * @returns {string} Row value as string or '0' for invalid definitions */ getRowValue(className) { if (className) { const rowClass = this.getRowClass(className) if (rowClass) { - return parseInt(rowClass.split('-')[1]) + return rowClass.split('-')[1] } } - return 0 + return '0' } /** diff --git a/tests/bootstrap.test.js b/tests/bootstrap.test.js index 0dd7b9679..5bf2a580c 100644 --- a/tests/bootstrap.test.js +++ b/tests/bootstrap.test.js @@ -15,7 +15,8 @@ describe('Test Boostrap Helper functions', () => { }) test('tryParseColumnInfo', () => { - expect(helper.tryParseColumnInfo({className: 'col-md-5 row-1 random-class row col'})).toEqual({ 'columnSize': 'col-md-5', 'rowNumber': 1, }) + expect(helper.tryParseColumnInfo({className: 'col-md-5 row-1 random-class row col'})).toEqual({ 'columnSize': 'col-md-5', 'rowUniqueId': '1', }) + expect(helper.tryParseColumnInfo({className: 'col-md-5 row-unique random-class row col'})).toEqual({ 'columnSize': 'col-md-5', 'rowUniqueId': 'unique', }) expect(helper.tryParseColumnInfo({className: ''})).toEqual({ }) }) @@ -25,6 +26,7 @@ describe('Test Boostrap Helper functions', () => { expect(helper.getDistanceBetweenPoints(100,2,35,5)).toBe(65) }) + //Returns first matching row-* value test('getRowClass', () => { expect(helper.getRowClass('')).toBe('') expect(helper.getRowClass('row row-4 col-md-2')).toBe('row-4') @@ -32,8 +34,9 @@ describe('Test Boostrap Helper functions', () => { }) test('getRowValue', () => { - expect(helper.getRowValue('row row-4 col-md-2')).toBe(4) - expect(helper.getRowValue('row row-5 row-me col-md-2')).toBe(5) + expect(helper.getRowValue('row row-4 col-md-2')).toBe('4') + expect(helper.getRowValue('row row-5 row-me col-md-2')).toBe('5') + expect(helper.getRowValue('row row-myrow row-me col-md-2')).toBe('myrow') }) test('changeRowClass', () => {