Skip to content

Commit 15e22fe

Browse files
authored
CardView - Header Filter: Fix item's selection state when headerFilter.dataSource is specified (DevExpress#29926)
Co-authored-by: Alyar <>
1 parent 3df9972 commit 15e22fe

File tree

4 files changed

+108
-58
lines changed

4 files changed

+108
-58
lines changed

e2e/testcafe-devextreme/tests/cardView/headerFilter/common.functional.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,50 @@ test('Filter values should be filtered by SearchPanel', async (t) => {
258258
},
259259
});
260260
});
261+
262+
test('The item\'s selection state should be correct if a custom data source is specified', async (t) => {
263+
// arrange
264+
const cardView = new CardView('#container');
265+
266+
await t
267+
.click(cardView.getHeaderPanel().getHeaderItem(0).getFilterIcon());
268+
269+
const firstHeaderFilterItem = cardView.getHeaderFilterList().getItem(0);
270+
271+
// assert
272+
await t
273+
.expect(cardView.getHeaderFilterList().getItems().count)
274+
.eql(2)
275+
.expect(firstHeaderFilterItem.text)
276+
.eql('Test1')
277+
.expect(firstHeaderFilterItem.isSelected)
278+
.ok();
279+
}).before(async () => {
280+
await createWidget('dxCardView', {
281+
...baseConfig,
282+
columns: [
283+
{
284+
dataField: 'id',
285+
filterValues: [1],
286+
headerFilter: {
287+
dataSource: [{
288+
text: 'Test1',
289+
value: 1,
290+
}, {
291+
text: 'Test2',
292+
value: 2,
293+
}],
294+
},
295+
},
296+
{
297+
dataField: 'title',
298+
},
299+
{
300+
dataField: 'name',
301+
},
302+
{
303+
dataField: 'lastName',
304+
},
305+
],
306+
});
307+
});

packages/devextreme/js/__internal/grids/new/grid_core/filtering/header_filter/__snapshots__/options.integration.test.ts.snap

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -458,20 +458,20 @@ exports[`Options Column.HeaderFilter dataSource: custom dataSource with exclude
458458
tabindex="0"
459459
>
460460
<div
461-
aria-label="Select All, Not checked"
461+
aria-label="Select All, Checked"
462462
class="dx-list-select-all"
463463
>
464464
<div
465-
aria-checked="false"
465+
aria-checked="true"
466466
aria-invalid="false"
467467
aria-label="Select All"
468468
aria-readonly="false"
469-
class="dx-widget dx-checkbox dx-list-select-all-checkbox"
469+
class="dx-widget dx-checkbox dx-checkbox-checked dx-list-select-all-checkbox"
470470
role="checkbox"
471471
>
472472
<input
473473
type="hidden"
474-
value="false"
474+
value="true"
475475
/>
476476
<div
477477
class="dx-checkbox-container"
@@ -495,24 +495,24 @@ exports[`Options Column.HeaderFilter dataSource: custom dataSource with exclude
495495
>
496496
<div
497497
aria-label="A"
498-
aria-selected="false"
499-
class="dx-item dx-list-item"
498+
aria-selected="true"
499+
class="dx-item dx-list-item dx-list-item-selected"
500500
role="option"
501501
>
502502
<div
503503
class="dx-list-item-before-bag dx-list-select-checkbox-container"
504504
>
505505
<div
506-
aria-checked="false"
506+
aria-checked="true"
507507
aria-invalid="false"
508508
aria-label="Check state"
509509
aria-readonly="false"
510-
class="dx-widget dx-checkbox dx-list-select-checkbox"
510+
class="dx-widget dx-checkbox dx-checkbox-checked dx-list-select-checkbox"
511511
role="checkbox"
512512
>
513513
<input
514514
type="hidden"
515-
value="false"
515+
value="true"
516516
/>
517517
<div
518518
class="dx-checkbox-container"
@@ -532,24 +532,24 @@ exports[`Options Column.HeaderFilter dataSource: custom dataSource with exclude
532532
</div>
533533
<div
534534
aria-label="B"
535-
aria-selected="false"
536-
class="dx-item dx-list-item"
535+
aria-selected="true"
536+
class="dx-item dx-list-item dx-list-item-selected"
537537
role="option"
538538
>
539539
<div
540540
class="dx-list-item-before-bag dx-list-select-checkbox-container"
541541
>
542542
<div
543-
aria-checked="false"
543+
aria-checked="true"
544544
aria-invalid="false"
545545
aria-label="Check state"
546546
aria-readonly="false"
547-
class="dx-widget dx-checkbox dx-list-select-checkbox"
547+
class="dx-widget dx-checkbox dx-checkbox-checked dx-list-select-checkbox"
548548
role="checkbox"
549549
>
550550
<input
551551
type="hidden"
552-
value="false"
552+
value="true"
553553
/>
554554
<div
555555
class="dx-checkbox-container"
@@ -862,24 +862,24 @@ exports[`Options Column.HeaderFilter dataSource: custom dataSource with exclude
862862
>
863863
<div
864864
aria-label="A"
865-
aria-selected="false"
866-
class="dx-item dx-list-item"
865+
aria-selected="true"
866+
class="dx-item dx-list-item dx-list-item-selected"
867867
role="option"
868868
>
869869
<div
870870
class="dx-list-item-before-bag dx-list-select-checkbox-container"
871871
>
872872
<div
873-
aria-checked="false"
873+
aria-checked="true"
874874
aria-invalid="false"
875875
aria-label="Check state"
876876
aria-readonly="false"
877-
class="dx-widget dx-checkbox dx-list-select-checkbox"
877+
class="dx-widget dx-checkbox dx-checkbox-checked dx-list-select-checkbox"
878878
role="checkbox"
879879
>
880880
<input
881881
type="hidden"
882-
value="false"
882+
value="true"
883883
/>
884884
<div
885885
class="dx-checkbox-container"
@@ -1266,24 +1266,24 @@ exports[`Options Column.HeaderFilter dataSource: custom dataSource with filter v
12661266
</div>
12671267
<div
12681268
aria-label="B"
1269-
aria-selected="false"
1270-
class="dx-item dx-list-item"
1269+
aria-selected="true"
1270+
class="dx-item dx-list-item dx-list-item-selected"
12711271
role="option"
12721272
>
12731273
<div
12741274
class="dx-list-item-before-bag dx-list-select-checkbox-container"
12751275
>
12761276
<div
1277-
aria-checked="false"
1277+
aria-checked="true"
12781278
aria-invalid="false"
12791279
aria-label="Check state"
12801280
aria-readonly="false"
1281-
class="dx-widget dx-checkbox dx-list-select-checkbox"
1281+
class="dx-widget dx-checkbox dx-checkbox-checked dx-list-select-checkbox"
12821282
role="checkbox"
12831283
>
12841284
<input
12851285
type="hidden"
1286-
value="false"
1286+
value="true"
12871287
/>
12881288
<div
12891289
class="dx-checkbox-container"

packages/devextreme/js/__internal/grids/new/grid_core/filtering/header_filter/legacy_header_filter.ts

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -154,42 +154,41 @@ export const getDataSourceOptions = (
154154
if (isDefined(headerFilterDataSource) && !isFunction(headerFilterDataSource)) {
155155
// @ts-expect-error
156156
options.dataSource = oldNormalizeDataSourceOptions(headerFilterDataSource);
157-
return options.dataSource;
157+
} else {
158+
const cutoffLevel = Array.isArray(group) ? group.length - 1 : 0;
159+
160+
options.dataSource = {
161+
filter,
162+
group,
163+
useDefaultSearch: true,
164+
load: (loadOptions) => {
165+
// @ts-expect-error Deferred ctor.
166+
const d = new Deferred();
167+
// NOTE: this marked as deprecated in original code
168+
loadOptions.dataField = column.dataField || column.name;
169+
storeLoadAdapter.load(loadOptions).done((data) => {
170+
const convertUTCDates = remoteGrouping
171+
&& isUTCFormat(column.serializationFormat)
172+
&& cutoffLevel > 3;
173+
174+
if (convertUTCDates) {
175+
data = convertDataFromUTCToLocal(data, column);
176+
}
177+
178+
_processGroupItems(data, null, null, {
179+
level: cutoffLevel,
180+
column,
181+
headerFilterOptions,
182+
});
183+
184+
d.resolve(data);
185+
}).fail(d.reject);
186+
187+
return d;
188+
},
189+
};
158190
}
159191

160-
const cutoffLevel = Array.isArray(group) ? group.length - 1 : 0;
161-
162-
options.dataSource = {
163-
filter,
164-
group,
165-
useDefaultSearch: true,
166-
load: (loadOptions) => {
167-
// @ts-expect-error Deferred ctor.
168-
const d = new Deferred();
169-
// NOTE: this marked as deprecated in original code
170-
loadOptions.dataField = column.dataField || column.name;
171-
storeLoadAdapter.load(loadOptions).done((data) => {
172-
const convertUTCDates = remoteGrouping
173-
&& isUTCFormat(column.serializationFormat)
174-
&& cutoffLevel > 3;
175-
176-
if (convertUTCDates) {
177-
data = convertDataFromUTCToLocal(data, column);
178-
}
179-
180-
_processGroupItems(data, null, null, {
181-
level: cutoffLevel,
182-
column,
183-
headerFilterOptions,
184-
});
185-
186-
d.resolve(data);
187-
}).fail(d.reject);
188-
189-
return d;
190-
},
191-
};
192-
193192
if (isFunction(headerFilterDataSource)) {
194193
headerFilterDataSource.call(column, options);
195194
}

packages/testcafe-models/list/item.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const CLASS = {
55
disabled: 'dx-state-disabled',
66
focused: 'dx-state-focused',
77
hovered: 'dx-state-hover',
8+
selected: 'dx-list-item-selected',
89
reorderHandle: 'dx-list-reorder-handle',
910
};
1011

@@ -19,6 +20,8 @@ export default class ListItem {
1920

2021
isHovered: Promise<boolean>;
2122

23+
isSelected: Promise<boolean>;
24+
2225
radioButton: RadioButton;
2326

2427
reorderHandle: Selector;
@@ -31,6 +34,7 @@ export default class ListItem {
3134
this.isDisabled = element.hasClass(CLASS.disabled);
3235
this.isFocused = element.hasClass(CLASS.focused);
3336
this.isHovered = element.hasClass(CLASS.hovered);
37+
this.isSelected = element.hasClass(CLASS.selected);
3438
this.radioButton = new RadioButton(element);
3539
this.reorderHandle = element.find(`.${CLASS.reorderHandle}`);
3640
this.text = element.textContent;

0 commit comments

Comments
 (0)