From 5834e3671bcc6b3ee1684f5c0ffc347798ba39d6 Mon Sep 17 00:00:00 2001 From: pharret31 Date: Tue, 14 Apr 2026 19:30:43 +0200 Subject: [PATCH 1/6] Fix --- .../scss/widgets/base/_form.scss | 1 + .../form.markup.tests.js | 85 ++++++++++++++----- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/packages/devextreme-scss/scss/widgets/base/_form.scss b/packages/devextreme-scss/scss/widgets/base/_form.scss index c1061dcc1a5f..8a419a9cfcc0 100644 --- a/packages/devextreme-scss/scss/widgets/base/_form.scss +++ b/packages/devextreme-scss/scss/widgets/base/_form.scss @@ -79,6 +79,7 @@ .dx-field-item-content { vertical-align: top; + min-width: 0; // TODO: form layout manager should not contains settings with checkbox/switch classes .dx-checkbox, diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js index a72e160ba554..174b9d866112 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js @@ -5,10 +5,12 @@ import responsiveBoxScreenMock from '../../helpers/responsiveBoxScreenMock.js'; import { isRenderer } from 'core/utils/type'; import config from 'core/config'; import 'ui/form'; -import { FIELD_ITEM_CLASS, +import { FORM_CLASS, FORM_FIELD_ITEM_COL_CLASS, FORM_GROUP_CLASS, + FIELD_ITEM_CLASS, + FIELD_ITEM_LABEL_CLASS, FIELD_ITEM_CONTENT_CLASS, FIELD_ITEM_LABEL_CONTENT_CLASS, FORM_GROUP_CAPTION_CLASS, @@ -24,6 +26,7 @@ import ValidationEngine from 'ui/validation_engine'; import 'ui/text_area'; import 'ui/radio_group'; import 'ui/switch'; +import 'ui/tag_box'; const FORM_GROUP_CONTENT_CLASS = 'dx-form-group-content'; const FORM_GROUP_CUSTOM_CAPTION_CLASS = 'dx-form-group-custom-caption'; @@ -34,6 +37,8 @@ const VALIDATOR_CLASS = 'dx-validator'; const READONLY_STATE_CLASS = 'dx-state-readonly'; const TEXTEDITOR_CLASS = 'dx-texteditor'; +import 'fluent_blue_light.css!'; + const { test } = QUnit; const formatTestValue = value => Array.isArray(value) ? '[]' : value; @@ -142,7 +147,7 @@ QUnit.module('Form', () => { assert.equal(rootLayoutManager.option('width'), 100, 'Correct width'); }); - test('Form isn\'t refresh on dimension changed if colCount is auto', function(assert) { + test('Form should not refresh on dimension changed if colCount is auto', function(assert) { const $formContainer = $('#form').dxForm({ colCount: 'auto', items: [ @@ -157,10 +162,10 @@ QUnit.module('Form', () => { resizeCallbacks.fire(); - assert.equal(refreshStub.callCount, 0, 'don\'t refresh on resize if colCount is auto'); + assert.equal(refreshStub.callCount, 0, 'did not refresh on resize if colCount is auto'); }); - test('Form doesn\'t refresh on dimension changed if colCount is not auto', function(assert) { + test('Form should not refresh on dimension changed if colCount is not auto', function(assert) { const $formContainer = $('#form').dxForm({ items: [ { @@ -175,7 +180,7 @@ QUnit.module('Form', () => { resizeCallbacks.fire(); - assert.equal(refreshStub.callCount, 0, 'do not refresh on resize if colCount isn\'t auto'); + assert.equal(refreshStub.callCount, 0, 'did not refresh on resize if colCount is not auto'); }); test('Render read only form', function(assert) { @@ -217,7 +222,7 @@ QUnit.module('Form', () => { assert.equal($fieldItems.length, 5, '4 simple items + 1 group item'); }); - test('\'readOnly\' is changed in inner components on optionChanged', function(assert) { + test('readOnly option is changed in inner components on optionChanged', function(assert) { const $formContainer = $('#form').dxForm({ items: [ { @@ -227,7 +232,7 @@ QUnit.module('Form', () => { ] }); - assert.notOk($formContainer.find(`.${FIELD_ITEM_CLASS} .${TEXTEDITOR_CLASS}`).hasClass(READONLY_STATE_CLASS), 'editor isn\'t read only'); + assert.notOk($formContainer.find(`.${FIELD_ITEM_CLASS} .${TEXTEDITOR_CLASS}`).hasClass(READONLY_STATE_CLASS), 'editor is not read only'); $formContainer.dxForm('instance').option('readOnly', true); @@ -250,7 +255,7 @@ QUnit.module('Form', () => { assert.ok($testContainer.find(`.${FIELD_ITEM_CLASS} .${TEXTEDITOR_CLASS}`).hasClass(READONLY_STATE_CLASS), 'editor is read only'); }); - test('\'disable\' is changed in inner components on optionChanged', function(assert) { + test('disable option is changed in inner components on optionChanged', function(assert) { const $formContainer = $('#form').dxForm({ items: [ { @@ -265,7 +270,7 @@ QUnit.module('Form', () => { $formContainer.dxForm('instance').option('disabled', false); - assert.notOk($formContainer.find(`.${FIELD_ITEM_CLASS} .${TEXTEDITOR_CLASS}`).hasClass('dx-state-disabled'), 'editor isn\'t disabled'); + assert.notOk($formContainer.find(`.${FIELD_ITEM_CLASS} .${TEXTEDITOR_CLASS}`).hasClass('dx-state-disabled'), 'editor is not disabled'); }); test('Customize item event', function(assert) { @@ -335,7 +340,7 @@ QUnit.module('Form', () => { assert.deepEqual($testContainer.find('.dx-layout-manager').dxLayoutManager('instance').option('layoutData'), { FamousPirate: 'John Morgan' }, 'Correct formData'); }); - test('Check data at render with items and change widget\'s value', function(assert) { + test('Check data at render with items and change widget value', function(assert) { const $testContainer = $('#form'); $testContainer.dxForm({ @@ -348,7 +353,7 @@ QUnit.module('Form', () => { assert.deepEqual($testContainer.dxForm('instance').option('formData'), { FamousPirate: 'John Morgan', FamousDetective: 'Sherlock Holmes' }, 'Correct formData'); }); - test('Change of editor\'s value changing \'formData\' option', function(assert) { + test('Change of editor value changing formData option', function(assert) { const $testContainer = $('#form'); $testContainer.dxForm({ @@ -360,7 +365,7 @@ QUnit.module('Form', () => { assert.deepEqual($testContainer.dxForm('instance').option('formData'), { FamousPirate: 'Cpt. Jack Sparrow' }, 'Correct formData'); }); - test('Update of editor\'s value when formOption is changed and items is defined', function(assert) { + test('Update of editor value when formOption is changed and items is defined', function(assert) { const $testContainer = $('#form'); const textBoxes = []; @@ -710,7 +715,7 @@ QUnit.module('Form', () => { assert.equal($editors.eq(1).dxTextBox('option', 'validationBoundary'), undefined); }); - test('button item should have a Form\'s validation group by default', function(assert) { + test('button item should have a Form validation group by default', function(assert) { const $testContainer = $('#form'); const form = $testContainer.dxForm({ items: [{ @@ -791,6 +796,44 @@ QUnit.module('Form', () => { assert.equal(templateStub.getCall(0).args[0].name, undefined, 'name argument'); }); + + test('TagBox should not exceed group column width when many items are selected', function(assert) { + const $form = $('#form').width(600); + + $form.dxForm({ + labelLocation: 'left', + formData: { + tags: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }, + items: [ + { + itemType: 'group', + items: [{ + dataField: 'tags', + editorType: 'dxTagBox', + editorOptions: { + items: Array.from({ length: 10 }, (_, i) => ({ + id: i + 1, + name: `Long item name ${i + 1}`, + })), + displayExpr: 'name', + valueExpr: 'id', + multiline: false, + }, + }], + }, + ], + }); + + const $group = $form.find(`.${FORM_GROUP_CLASS}`).first(); + const $label = $group.find(`.${FIELD_ITEM_LABEL_CLASS}`).first(); + const $content = $group.find(`.${FIELD_ITEM_CONTENT_CLASS}`).first(); + + const groupWidth = $group.outerWidth(); + const totalItemWidth = $label.outerWidth() + $content.outerWidth(); + + assert.strictEqual(totalItemWidth <= groupWidth, true, `field item content width (${totalItemWidth}) should not exceed group width (${groupWidth})`); + }); }); QUnit.module(`"${TOGGLE_CONTROLS_PADDING_CLASS}" class`, ()=>{ @@ -990,7 +1033,7 @@ QUnit.module('Validation group', () => { assert.equal($validator.length, 1, 'validators count'); assert.equal(validator.option('validationGroup'), form, 'validation group of the validator'); - assert.ok(ValidationEngine.getGroupConfig(form), 'form\'s validation group in the validation engine'); + assert.ok(ValidationEngine.getGroupConfig(form), 'form validation group in the validation engine'); }); test('Set { items: [{dataField: name, isRequired: true}], showValidationSummary: true }', function(assert) { @@ -1016,7 +1059,7 @@ QUnit.module('Validation group', () => { assert.equal($validator.length, 1, 'validators count'); assert.equal(validator.option('validationGroup'), 'Test', 'validation group of the validator'); - assert.ok(ValidationEngine.getGroupConfig('Test'), 'form\'s validation group in the validation engine'); + assert.ok(ValidationEngine.getGroupConfig('Test'), 'form validation group in the validation engine'); }); test('Set { items: [{dataField: name, isRequired: true}], validationGroup: Test, showValidationSummary: true }', function(assert) { @@ -1040,7 +1083,7 @@ QUnit.module('Validation group', () => { const $validator = $formContainer.find(`.${VALIDATOR_CLASS}`); assert.equal($validator.length, 0, 'validators count'); - assert.ok(ValidationEngine.getGroupConfig(form), 'form\'s validation group in the validation engine'); + assert.ok(ValidationEngine.getGroupConfig(form), 'form validation group in the validation engine'); }); test('Set { items: [{dataField: name}], showValidationSummary: true }', function(assert) { @@ -1064,7 +1107,7 @@ QUnit.module('Validation group', () => { const $validator = $formContainer.find(`.${VALIDATOR_CLASS}`); assert.equal($validator.length, 0, 'validators count'); - assert.ok(ValidationEngine.getGroupConfig('Test'), 'form\'s validation group in the validation engine'); + assert.ok(ValidationEngine.getGroupConfig('Test'), 'form validation group in the validation engine'); }); test('Set { items: [{dataField: name}], validationGroup: Test, showValidationSummary: true }', function(assert) { @@ -1270,7 +1313,7 @@ QUnit.module('Grouping', () => { assert.equal($captions.eq(0).text(), 'Personal'); }); - test('helpText element didn\'t render for group item', function(assert) { + test('helpText element should not be rendered for group item', function(assert) { const $formContainer = $('#form').dxForm({ formData: { firstName: 'John' @@ -1328,7 +1371,7 @@ QUnit.module('Grouping', () => { assert.equal($groups.length, 2, '2 groups rendered'); assert.equal($groups.eq(1).find('.template-biography').length, 1, 'We have template content'); - assert.equal($groups.eq(1).find('.template-biography').text(), 'bla-bla-bla', 'Template\'s content has correct data'); + assert.equal($groups.eq(1).find('.template-biography').text(), 'bla-bla-bla', 'Template content has correct data'); }); test('Simple Item labelTemplate', function(assert) { @@ -1363,7 +1406,7 @@ QUnit.module('Grouping', () => { assert.strictEqual($groups.length, 2, '2 groups rendered'); assert.strictEqual($groups.eq(0).find(`.${labelClass}`).length, 1, 'label template content'); - assert.strictEqual($groups.eq(0).find(`.${labelClass}`).text(), 'First Name: ?', 'Labels\'s content has correct data'); + assert.strictEqual($groups.eq(0).find(`.${labelClass}`).text(), 'First Name: ?', 'Labels content has correct data'); }); QUnit.module('Caption template', () => { @@ -1497,7 +1540,7 @@ QUnit.module('Grouping', () => { ] }); - assert.equal(templateOwnerComponent, 'dxForm', 'Template\'s data.component is \'dxForm\''); + assert.equal(templateOwnerComponent, 'dxForm', 'Template data.component is dxForm'); }); test('Recursive grouping', function(assert) { From 30bb0cfb9ea1699211e7d60525e6ef9607485902 Mon Sep 17 00:00:00 2001 From: pharret31 Date: Tue, 14 Apr 2026 19:34:18 +0200 Subject: [PATCH 2/6] Add ticket number --- .../tests/DevExpress.ui.widgets.form/form.markup.tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js index 174b9d866112..4943f884b845 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js @@ -797,7 +797,7 @@ QUnit.module('Form', () => { assert.equal(templateStub.getCall(0).args[0].name, undefined, 'name argument'); }); - test('TagBox should not exceed group column width when many items are selected', function(assert) { + test('TagBox should not exceed group column width when many items are selected (T1326645)', function(assert) { const $form = $('#form').width(600); $form.dxForm({ From 1b46044c0dd0d72b7abc6dfbf00369b2990f37f2 Mon Sep 17 00:00:00 2001 From: pharret31 Date: Tue, 14 Apr 2026 20:01:40 +0200 Subject: [PATCH 3/6] Fix --- .../tests/DevExpress.ui.widgets.form/form.markup.tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js index 4943f884b845..72ab8c55d490 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js @@ -28,6 +28,8 @@ import 'ui/radio_group'; import 'ui/switch'; import 'ui/tag_box'; +import 'fluent_blue_light.css!'; + const FORM_GROUP_CONTENT_CLASS = 'dx-form-group-content'; const FORM_GROUP_CUSTOM_CAPTION_CLASS = 'dx-form-group-custom-caption'; const MULTIVIEW_ITEM_CONTENT_CLASS = 'dx-multiview-item-content'; @@ -37,8 +39,6 @@ const VALIDATOR_CLASS = 'dx-validator'; const READONLY_STATE_CLASS = 'dx-state-readonly'; const TEXTEDITOR_CLASS = 'dx-texteditor'; -import 'fluent_blue_light.css!'; - const { test } = QUnit; const formatTestValue = value => Array.isArray(value) ? '[]' : value; From 63f8567528cc7c2a7fdb8d3fd339056dca7bff2b Mon Sep 17 00:00:00 2001 From: pharret31 Date: Wed, 15 Apr 2026 11:11:40 +0200 Subject: [PATCH 4/6] Fix --- packages/devextreme-scss/scss/widgets/base/_form.scss | 2 +- .../tests/DevExpress.ui.widgets.form/form.markup.tests.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/devextreme-scss/scss/widgets/base/_form.scss b/packages/devextreme-scss/scss/widgets/base/_form.scss index 8a419a9cfcc0..a7bb77218173 100644 --- a/packages/devextreme-scss/scss/widgets/base/_form.scss +++ b/packages/devextreme-scss/scss/widgets/base/_form.scss @@ -81,7 +81,7 @@ vertical-align: top; min-width: 0; - // TODO: form layout manager should not contains settings with checkbox/switch classes + // TODO: form layout manager should not contain settings with checkbox/switch classes .dx-checkbox, .dx-switch { margin-top: 7px; diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js index 72ab8c55d490..cb3118c2784a 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js @@ -832,7 +832,7 @@ QUnit.module('Form', () => { const groupWidth = $group.outerWidth(); const totalItemWidth = $label.outerWidth() + $content.outerWidth(); - assert.strictEqual(totalItemWidth <= groupWidth, true, `field item content width (${totalItemWidth}) should not exceed group width (${groupWidth})`); + assert.strictEqual(totalItemWidth === groupWidth, true, `field item content width (${totalItemWidth}) should not exceed group width (${groupWidth})`); }); }); @@ -1406,7 +1406,7 @@ QUnit.module('Grouping', () => { assert.strictEqual($groups.length, 2, '2 groups rendered'); assert.strictEqual($groups.eq(0).find(`.${labelClass}`).length, 1, 'label template content'); - assert.strictEqual($groups.eq(0).find(`.${labelClass}`).text(), 'First Name: ?', 'Labels content has correct data'); + assert.strictEqual($groups.eq(0).find(`.${labelClass}`).text(), 'First Name: ?', 'Label content has correct data'); }); QUnit.module('Caption template', () => { From 249fb0fb656d816e368dc14c237e5a737af9b418 Mon Sep 17 00:00:00 2001 From: pharret31 Date: Wed, 15 Apr 2026 11:17:45 +0200 Subject: [PATCH 5/6] Fix --- packages/devextreme-scss/scss/widgets/base/_form.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme-scss/scss/widgets/base/_form.scss b/packages/devextreme-scss/scss/widgets/base/_form.scss index a7bb77218173..0177d17b74f9 100644 --- a/packages/devextreme-scss/scss/widgets/base/_form.scss +++ b/packages/devextreme-scss/scss/widgets/base/_form.scss @@ -79,7 +79,6 @@ .dx-field-item-content { vertical-align: top; - min-width: 0; // TODO: form layout manager should not contain settings with checkbox/switch classes .dx-checkbox, @@ -92,6 +91,7 @@ .dx-field-item-content, .dx-field-item-content-wrapper { width: 100%; + min-width: 0; } } From 92b37da1b15701b1d82c2904cf492bb1c796fac7 Mon Sep 17 00:00:00 2001 From: pharret31 Date: Wed, 15 Apr 2026 11:31:00 +0200 Subject: [PATCH 6/6] Fix --- .../tests/DevExpress.ui.widgets.form/form.markup.tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js index cb3118c2784a..a969f8ab8acb 100644 --- a/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js +++ b/packages/devextreme/testing/tests/DevExpress.ui.widgets.form/form.markup.tests.js @@ -832,7 +832,7 @@ QUnit.module('Form', () => { const groupWidth = $group.outerWidth(); const totalItemWidth = $label.outerWidth() + $content.outerWidth(); - assert.strictEqual(totalItemWidth === groupWidth, true, `field item content width (${totalItemWidth}) should not exceed group width (${groupWidth})`); + assert.roughEqual(totalItemWidth, groupWidth, 0.1, `field item content width (${totalItemWidth}) should not exceed group width (${groupWidth})`); }); });