diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.css b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.css
new file mode 100644
index 000000000000..95736308e283
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.css
@@ -0,0 +1,55 @@
+.hidden-days-demo {
+ display: flex;
+ gap: 20px;
+}
+
+.scheduler-container {
+ flex: 1;
+ min-width: 0;
+}
+
+.options {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 220px;
+ box-sizing: border-box;
+ padding: 20px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 12px;
+}
+
+.caption {
+ font-weight: 500;
+ font-size: 18px;
+}
+
+.option {
+ display: flex;
+ flex-direction: column;
+}
+
+.validation-message {
+ display: none;
+ margin-top: 8px;
+ padding: 10px 12px;
+ background: #fdf3f4;
+ border-left: 3px solid #c50f1f;
+ border-radius: 4px;
+ color: #c50f1f;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+::ng-deep .hidden-days-demo.is-invalid .validation-message {
+ display: block;
+}
+
+::ng-deep .hidden-days-demo.is-invalid .option .dx-checkbox-icon {
+ border-color: #c50f1f;
+}
+
+::ng-deep .hidden-days-demo.is-invalid .dx-scheduler-work-space {
+ opacity: 0.4;
+ pointer-events: none;
+}
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.html b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.html
new file mode 100644
index 000000000000..248cda44647b
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
Visible Week Days
+ @for (day of dayLabels; track day.index) {
+
+
+
+
+ }
+
+ {{ validationMessage }}
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.ts b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.ts
new file mode 100644
index 000000000000..41b1ae46ae97
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.component.ts
@@ -0,0 +1,80 @@
+import { bootstrapApplication } from '@angular/platform-browser';
+import { Component, enableProdMode, provideZoneChangeDetection } from '@angular/core';
+import { DxSchedulerModule, DxSchedulerTypes } from 'devextreme-angular/ui/scheduler';
+import { DxCheckBoxModule, DxCheckBoxTypes } from 'devextreme-angular/ui/check-box';
+import { ArrayStore } from 'devextreme-angular/common/data';
+import { DataService } from './app.service';
+
+if (!/localhost/.test(document.location.host)) {
+ enableProdMode();
+}
+
+let modulePrefix = '';
+// @ts-ignore
+if (window && window.config?.packageConfigPaths) {
+ modulePrefix = '/app';
+}
+
+interface DayLabel {
+ index: DxSchedulerTypes.DayOfWeek;
+ label: string;
+ visible: boolean;
+}
+
+@Component({
+ selector: 'demo-app',
+ templateUrl: `.${modulePrefix}/app.component.html`,
+ styleUrls: [`.${modulePrefix}/app.component.css`],
+ providers: [DataService],
+ imports: [
+ DxSchedulerModule,
+ DxCheckBoxModule,
+ ],
+})
+export class AppComponent {
+ dataSource: ArrayStore;
+
+ currentDate = new Date(2021, 3, 26);
+
+ validationMessage = 'The hiddenWeekDays option cannot hide all days of the week. At least one day must remain visible.';
+
+ dayLabels: DayLabel[] = [
+ { index: 0, label: 'Sunday', visible: true },
+ { index: 1, label: 'Monday', visible: true },
+ { index: 2, label: 'Tuesday', visible: true },
+ { index: 3, label: 'Wednesday', visible: false },
+ { index: 4, label: 'Thursday', visible: true },
+ { index: 5, label: 'Friday', visible: false },
+ { index: 6, label: 'Saturday', visible: true },
+ ];
+
+ hiddenWeekDays: DxSchedulerTypes.DayOfWeek[] = [];
+
+ isInvalid = false;
+
+ constructor(dataService: DataService) {
+ this.dataSource = new ArrayStore({
+ key: 'id',
+ data: dataService.getAppointments(),
+ });
+ this.hiddenWeekDays = this.computeHiddenWeekDays();
+ }
+
+ onDayToggled(e: DxCheckBoxTypes.ValueChangedEvent, dayIndex: number): void {
+ this.dayLabels[dayIndex].visible = e.value;
+ this.isInvalid = this.dayLabels.every((d) => !d.visible);
+ this.hiddenWeekDays = this.computeHiddenWeekDays();
+ }
+
+ private computeHiddenWeekDays(): DxSchedulerTypes.DayOfWeek[] {
+ return this.dayLabels
+ .filter((d) => !d.visible)
+ .map((d) => d.index);
+ }
+}
+
+bootstrapApplication(AppComponent, {
+ providers: [
+ provideZoneChangeDetection({ eventCoalescing: true, runCoalescing: true }),
+ ],
+});
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.service.ts b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.service.ts
new file mode 100644
index 000000000000..b1f6e319614e
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Angular/app/app.service.ts
@@ -0,0 +1,121 @@
+import { Injectable } from '@angular/core';
+
+export class Appointment {
+ id: number;
+
+ text: string;
+
+ startDate: Date;
+
+ endDate: Date;
+
+ allDay?: boolean;
+}
+
+const appointments: Appointment[] = [
+ {
+ id: 1,
+ text: 'Website Re-Design Plan',
+ startDate: new Date('2021-04-26T16:30:00.000Z'),
+ endDate: new Date('2021-04-26T18:30:00.000Z'),
+ },
+ {
+ id: 2,
+ text: 'Book Flights to San Fran for Sales Trip',
+ startDate: new Date('2021-04-26T19:00:00.000Z'),
+ endDate: new Date('2021-04-26T20:00:00.000Z'),
+ allDay: true,
+ },
+ {
+ id: 3,
+ text: 'Install New Router in Dev Room',
+ startDate: new Date('2021-04-26T21:30:00.000Z'),
+ endDate: new Date('2021-04-26T22:30:00.000Z'),
+ },
+ {
+ id: 4,
+ text: 'Approve Personal Computer Upgrade Plan',
+ startDate: new Date('2021-04-27T17:00:00.000Z'),
+ endDate: new Date('2021-04-27T18:00:00.000Z'),
+ },
+ {
+ id: 5,
+ text: 'Final Budget Review',
+ startDate: new Date('2021-04-27T19:00:00.000Z'),
+ endDate: new Date('2021-04-27T20:35:00.000Z'),
+ },
+ {
+ id: 6,
+ text: 'New Brochures',
+ startDate: new Date('2021-04-27T21:30:00.000Z'),
+ endDate: new Date('2021-04-27T22:45:00.000Z'),
+ },
+ {
+ id: 7,
+ text: 'Install New Database',
+ startDate: new Date('2021-04-28T16:45:00.000Z'),
+ endDate: new Date('2021-04-28T18:15:00.000Z'),
+ },
+ {
+ id: 8,
+ text: 'Approve New Online Marketing Strategy',
+ startDate: new Date('2021-04-28T19:00:00.000Z'),
+ endDate: new Date('2021-04-28T21:00:00.000Z'),
+ },
+ {
+ id: 9,
+ text: 'Upgrade Personal Computers',
+ startDate: new Date('2021-04-28T22:15:00.000Z'),
+ endDate: new Date('2021-04-28T23:30:00.000Z'),
+ },
+ {
+ id: 10,
+ text: 'Customer Workshop',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T19:00:00.000Z'),
+ allDay: true,
+ },
+ {
+ id: 11,
+ text: 'Prepare 2021 Marketing Plan',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T20:30:00.000Z'),
+ },
+ {
+ id: 12,
+ text: 'Brochure Design Review',
+ startDate: new Date('2021-04-29T21:00:00.000Z'),
+ endDate: new Date('2021-04-29T22:30:00.000Z'),
+ },
+ {
+ id: 13,
+ text: 'Create Icons for Website',
+ startDate: new Date('2021-04-30T17:00:00.000Z'),
+ endDate: new Date('2021-04-30T18:30:00.000Z'),
+ },
+ {
+ id: 14,
+ text: 'Upgrade Server Hardware',
+ startDate: new Date('2021-04-30T21:30:00.000Z'),
+ endDate: new Date('2021-04-30T23:00:00.000Z'),
+ },
+ {
+ id: 15,
+ text: 'Submit New Website Design',
+ startDate: new Date('2021-04-30T23:30:00.000Z'),
+ endDate: new Date('2021-05-01T01:00:00.000Z'),
+ },
+ {
+ id: 16,
+ text: 'Launch New Website',
+ startDate: new Date('2021-04-30T19:20:00.000Z'),
+ endDate: new Date('2021-04-30T21:00:00.000Z'),
+ },
+];
+
+@Injectable()
+export class DataService {
+ getAppointments(): Appointment[] {
+ return appointments;
+ }
+}
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Angular/index.html b/apps/demos/Demos/Scheduler/HiddenDays/Angular/index.html
new file mode 100644
index 000000000000..1ab1fb54a1df
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Angular/index.html
@@ -0,0 +1,26 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading...
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/React/App.tsx b/apps/demos/Demos/Scheduler/HiddenDays/React/App.tsx
new file mode 100644
index 000000000000..5ecbbeba4e84
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/React/App.tsx
@@ -0,0 +1,69 @@
+import React, { useCallback, useMemo, useState } from 'react';
+
+import Scheduler, { type SchedulerTypes } from 'devextreme-react/scheduler';
+import CheckBox, { type CheckBoxTypes } from 'devextreme-react/check-box';
+import { ArrayStore } from 'devextreme-react/common/data';
+import { data } from './data.ts';
+
+const dataSource = new ArrayStore({
+ key: 'id',
+ data,
+});
+
+const allDays: SchedulerTypes.DayOfWeek[] = [0, 1, 2, 3, 4, 5, 6];
+const dayLabels = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+const defaultVisible: SchedulerTypes.DayOfWeek[] = [0, 1, 2, 4, 6];
+const views: SchedulerTypes.Properties['views'] = ['week', 'workWeek', 'month', 'timelineWeek', 'agenda'];
+const currentDate = new Date(2021, 3, 26);
+const VALIDATION_MESSAGE = 'The hiddenWeekDays option cannot hide all days of the week. At least one day must remain visible.';
+
+const App = () => {
+ const [visibleDays, setVisibleDays] = useState(defaultVisible);
+
+ const isInvalid = visibleDays.length === 0;
+
+ const hiddenWeekDays = useMemo(
+ () => allDays.filter((d) => !visibleDays.includes(d)),
+ [visibleDays],
+ );
+
+ const onDayToggle = useCallback((dayIndex: SchedulerTypes.DayOfWeek, e: CheckBoxTypes.ValueChangedEvent) => {
+ setVisibleDays((prev) => (e.value
+ ? [...prev, dayIndex]
+ : prev.filter((d) => d !== dayIndex)));
+ }, []);
+
+ return (
+
+
+
+
+
+
Visible Week Days
+ {dayLabels.map((label, idx) => (
+
+ onDayToggle(idx as SchedulerTypes.DayOfWeek, e)}
+ />
+
+ ))}
+
+ {VALIDATION_MESSAGE}
+
+
+
+ );
+};
+
+export default App;
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/React/data.ts b/apps/demos/Demos/Scheduler/HiddenDays/React/data.ts
new file mode 100644
index 000000000000..89072595cc2d
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/React/data.ts
@@ -0,0 +1,87 @@
+import type { SchedulerTypes } from 'devextreme-react/scheduler';
+
+export const data: SchedulerTypes.Appointment[] = [
+ {
+ id: 1,
+ text: 'Website Re-Design Plan',
+ startDate: new Date('2021-04-26T16:30:00.000Z'),
+ endDate: new Date('2021-04-26T18:30:00.000Z'),
+ }, {
+ id: 2,
+ text: 'Book Flights to San Fran for Sales Trip',
+ startDate: new Date('2021-04-26T19:00:00.000Z'),
+ endDate: new Date('2021-04-26T20:00:00.000Z'),
+ allDay: true,
+ }, {
+ id: 3,
+ text: 'Install New Router in Dev Room',
+ startDate: new Date('2021-04-26T21:30:00.000Z'),
+ endDate: new Date('2021-04-26T22:30:00.000Z'),
+ }, {
+ id: 4,
+ text: 'Approve Personal Computer Upgrade Plan',
+ startDate: new Date('2021-04-27T17:00:00.000Z'),
+ endDate: new Date('2021-04-27T18:00:00.000Z'),
+ }, {
+ id: 5,
+ text: 'Final Budget Review',
+ startDate: new Date('2021-04-27T19:00:00.000Z'),
+ endDate: new Date('2021-04-27T20:35:00.000Z'),
+ }, {
+ id: 6,
+ text: 'New Brochures',
+ startDate: new Date('2021-04-27T21:30:00.000Z'),
+ endDate: new Date('2021-04-27T22:45:00.000Z'),
+ }, {
+ id: 7,
+ text: 'Install New Database',
+ startDate: new Date('2021-04-28T16:45:00.000Z'),
+ endDate: new Date('2021-04-28T18:15:00.000Z'),
+ }, {
+ id: 8,
+ text: 'Approve New Online Marketing Strategy',
+ startDate: new Date('2021-04-28T19:00:00.000Z'),
+ endDate: new Date('2021-04-28T21:00:00.000Z'),
+ }, {
+ id: 9,
+ text: 'Upgrade Personal Computers',
+ startDate: new Date('2021-04-28T22:15:00.000Z'),
+ endDate: new Date('2021-04-28T23:30:00.000Z'),
+ }, {
+ id: 10,
+ text: 'Customer Workshop',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T19:00:00.000Z'),
+ allDay: true,
+ }, {
+ id: 11,
+ text: 'Prepare 2021 Marketing Plan',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T20:30:00.000Z'),
+ }, {
+ id: 12,
+ text: 'Brochure Design Review',
+ startDate: new Date('2021-04-29T21:00:00.000Z'),
+ endDate: new Date('2021-04-29T22:30:00.000Z'),
+ }, {
+ id: 13,
+ text: 'Create Icons for Website',
+ startDate: new Date('2021-04-30T17:00:00.000Z'),
+ endDate: new Date('2021-04-30T18:30:00.000Z'),
+ }, {
+ id: 14,
+ text: 'Upgrade Server Hardware',
+ startDate: new Date('2021-04-30T21:30:00.000Z'),
+ endDate: new Date('2021-04-30T23:00:00.000Z'),
+ }, {
+ id: 15,
+ text: 'Submit New Website Design',
+ startDate: new Date('2021-04-30T23:30:00.000Z'),
+ endDate: new Date('2021-05-01T01:00:00.000Z'),
+ }, {
+ id: 16,
+ text: 'Launch New Website',
+ startDate: new Date('2021-04-30T19:20:00.000Z'),
+ endDate: new Date('2021-04-30T21:00:00.000Z'),
+ },
+];
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/React/index.html b/apps/demos/Demos/Scheduler/HiddenDays/React/index.html
new file mode 100644
index 000000000000..ee451f8288ff
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/React/index.html
@@ -0,0 +1,24 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/React/index.tsx b/apps/demos/Demos/Scheduler/HiddenDays/React/index.tsx
new file mode 100644
index 000000000000..8acbec4b6179
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/React/index.tsx
@@ -0,0 +1,9 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+import App from './App.tsx';
+
+ReactDOM.render(
+ ,
+ document.getElementById('app'),
+);
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/React/styles.css b/apps/demos/Demos/Scheduler/HiddenDays/React/styles.css
new file mode 100644
index 000000000000..82a48bdf0b98
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/React/styles.css
@@ -0,0 +1,55 @@
+.hidden-days-demo {
+ display: flex;
+ gap: 20px;
+}
+
+.scheduler-container {
+ flex: 1;
+ min-width: 0;
+}
+
+.options {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 220px;
+ box-sizing: border-box;
+ padding: 20px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 12px;
+}
+
+.caption {
+ font-weight: 500;
+ font-size: 18px;
+}
+
+.option {
+ display: flex;
+ flex-direction: column;
+}
+
+.validation-message {
+ display: none;
+ margin-top: 8px;
+ padding: 10px 12px;
+ background: #fdf3f4;
+ border-left: 3px solid #c50f1f;
+ border-radius: 4px;
+ color: #c50f1f;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.hidden-days-demo.is-invalid .validation-message {
+ display: block;
+}
+
+.hidden-days-demo.is-invalid .option .dx-checkbox-icon {
+ border-color: #c50f1f;
+}
+
+.hidden-days-demo.is-invalid .dx-scheduler-work-space {
+ opacity: 0.4;
+ pointer-events: none;
+}
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/App.js b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/App.js
new file mode 100644
index 000000000000..f6447c013062
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/App.js
@@ -0,0 +1,61 @@
+import React, { useCallback, useMemo, useState } from 'react';
+import Scheduler from 'devextreme-react/scheduler';
+import CheckBox from 'devextreme-react/check-box';
+import { ArrayStore } from 'devextreme-react/common/data';
+import { data } from './data.js';
+
+const dataSource = new ArrayStore({
+ key: 'id',
+ data,
+});
+const allDays = [0, 1, 2, 3, 4, 5, 6];
+const dayLabels = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+const defaultVisible = [0, 1, 2, 4, 6];
+const views = ['week', 'workWeek', 'month', 'timelineWeek', 'agenda'];
+const currentDate = new Date(2021, 3, 26);
+const VALIDATION_MESSAGE =
+ 'The hiddenWeekDays option cannot hide all days of the week. At least one day must remain visible.';
+const App = () => {
+ const [visibleDays, setVisibleDays] = useState(defaultVisible);
+ const isInvalid = visibleDays.length === 0;
+ const hiddenWeekDays = useMemo(
+ () => allDays.filter((d) => !visibleDays.includes(d)),
+ [visibleDays],
+ );
+ const onDayToggle = useCallback((dayIndex, e) => {
+ setVisibleDays((prev) => (e.value ? [...prev, dayIndex] : prev.filter((d) => d !== dayIndex)));
+ }, []);
+ return (
+
+
+
+
+
+
Visible Week Days
+ {dayLabels.map((label, idx) => (
+
+ onDayToggle(idx, e)}
+ />
+
+ ))}
+
{VALIDATION_MESSAGE}
+
+
+ );
+};
+export default App;
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/data.js b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/data.js
new file mode 100644
index 000000000000..55832c8e21a3
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/data.js
@@ -0,0 +1,100 @@
+export const data = [
+ {
+ id: 1,
+ text: 'Website Re-Design Plan',
+ startDate: new Date('2021-04-26T16:30:00.000Z'),
+ endDate: new Date('2021-04-26T18:30:00.000Z'),
+ },
+ {
+ id: 2,
+ text: 'Book Flights to San Fran for Sales Trip',
+ startDate: new Date('2021-04-26T19:00:00.000Z'),
+ endDate: new Date('2021-04-26T20:00:00.000Z'),
+ allDay: true,
+ },
+ {
+ id: 3,
+ text: 'Install New Router in Dev Room',
+ startDate: new Date('2021-04-26T21:30:00.000Z'),
+ endDate: new Date('2021-04-26T22:30:00.000Z'),
+ },
+ {
+ id: 4,
+ text: 'Approve Personal Computer Upgrade Plan',
+ startDate: new Date('2021-04-27T17:00:00.000Z'),
+ endDate: new Date('2021-04-27T18:00:00.000Z'),
+ },
+ {
+ id: 5,
+ text: 'Final Budget Review',
+ startDate: new Date('2021-04-27T19:00:00.000Z'),
+ endDate: new Date('2021-04-27T20:35:00.000Z'),
+ },
+ {
+ id: 6,
+ text: 'New Brochures',
+ startDate: new Date('2021-04-27T21:30:00.000Z'),
+ endDate: new Date('2021-04-27T22:45:00.000Z'),
+ },
+ {
+ id: 7,
+ text: 'Install New Database',
+ startDate: new Date('2021-04-28T16:45:00.000Z'),
+ endDate: new Date('2021-04-28T18:15:00.000Z'),
+ },
+ {
+ id: 8,
+ text: 'Approve New Online Marketing Strategy',
+ startDate: new Date('2021-04-28T19:00:00.000Z'),
+ endDate: new Date('2021-04-28T21:00:00.000Z'),
+ },
+ {
+ id: 9,
+ text: 'Upgrade Personal Computers',
+ startDate: new Date('2021-04-28T22:15:00.000Z'),
+ endDate: new Date('2021-04-28T23:30:00.000Z'),
+ },
+ {
+ id: 10,
+ text: 'Customer Workshop',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T19:00:00.000Z'),
+ allDay: true,
+ },
+ {
+ id: 11,
+ text: 'Prepare 2021 Marketing Plan',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T20:30:00.000Z'),
+ },
+ {
+ id: 12,
+ text: 'Brochure Design Review',
+ startDate: new Date('2021-04-29T21:00:00.000Z'),
+ endDate: new Date('2021-04-29T22:30:00.000Z'),
+ },
+ {
+ id: 13,
+ text: 'Create Icons for Website',
+ startDate: new Date('2021-04-30T17:00:00.000Z'),
+ endDate: new Date('2021-04-30T18:30:00.000Z'),
+ },
+ {
+ id: 14,
+ text: 'Upgrade Server Hardware',
+ startDate: new Date('2021-04-30T21:30:00.000Z'),
+ endDate: new Date('2021-04-30T23:00:00.000Z'),
+ },
+ {
+ id: 15,
+ text: 'Submit New Website Design',
+ startDate: new Date('2021-04-30T23:30:00.000Z'),
+ endDate: new Date('2021-05-01T01:00:00.000Z'),
+ },
+ {
+ id: 16,
+ text: 'Launch New Website',
+ startDate: new Date('2021-04-30T19:20:00.000Z'),
+ endDate: new Date('2021-04-30T21:00:00.000Z'),
+ },
+];
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/index.html b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/index.html
new file mode 100644
index 000000000000..db31b0fd60c6
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/index.html
@@ -0,0 +1,44 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/index.js b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/index.js
new file mode 100644
index 000000000000..b853e0be8242
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/index.js
@@ -0,0 +1,5 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App.js';
+
+ReactDOM.render(, document.getElementById('app'));
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/styles.css b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/styles.css
new file mode 100644
index 000000000000..82a48bdf0b98
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/ReactJs/styles.css
@@ -0,0 +1,55 @@
+.hidden-days-demo {
+ display: flex;
+ gap: 20px;
+}
+
+.scheduler-container {
+ flex: 1;
+ min-width: 0;
+}
+
+.options {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 220px;
+ box-sizing: border-box;
+ padding: 20px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 12px;
+}
+
+.caption {
+ font-weight: 500;
+ font-size: 18px;
+}
+
+.option {
+ display: flex;
+ flex-direction: column;
+}
+
+.validation-message {
+ display: none;
+ margin-top: 8px;
+ padding: 10px 12px;
+ background: #fdf3f4;
+ border-left: 3px solid #c50f1f;
+ border-radius: 4px;
+ color: #c50f1f;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.hidden-days-demo.is-invalid .validation-message {
+ display: block;
+}
+
+.hidden-days-demo.is-invalid .option .dx-checkbox-icon {
+ border-color: #c50f1f;
+}
+
+.hidden-days-demo.is-invalid .dx-scheduler-work-space {
+ opacity: 0.4;
+ pointer-events: none;
+}
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Vue/App.vue b/apps/demos/Demos/Scheduler/HiddenDays/Vue/App.vue
new file mode 100644
index 000000000000..d336bb3a406f
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Vue/App.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+ Visible Week Days
+
+
+ onDayToggled(idx, e.value)"
+ />
+
+
+ {{ validationMessage }}
+
+
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Vue/data.ts b/apps/demos/Demos/Scheduler/HiddenDays/Vue/data.ts
new file mode 100644
index 000000000000..cc369e2b2d66
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Vue/data.ts
@@ -0,0 +1,85 @@
+export const data = [
+ {
+ id: 1,
+ text: 'Website Re-Design Plan',
+ startDate: new Date('2021-04-26T16:30:00.000Z'),
+ endDate: new Date('2021-04-26T18:30:00.000Z'),
+ }, {
+ id: 2,
+ text: 'Book Flights to San Fran for Sales Trip',
+ startDate: new Date('2021-04-26T19:00:00.000Z'),
+ endDate: new Date('2021-04-26T20:00:00.000Z'),
+ allDay: true,
+ }, {
+ id: 3,
+ text: 'Install New Router in Dev Room',
+ startDate: new Date('2021-04-26T21:30:00.000Z'),
+ endDate: new Date('2021-04-26T22:30:00.000Z'),
+ }, {
+ id: 4,
+ text: 'Approve Personal Computer Upgrade Plan',
+ startDate: new Date('2021-04-27T17:00:00.000Z'),
+ endDate: new Date('2021-04-27T18:00:00.000Z'),
+ }, {
+ id: 5,
+ text: 'Final Budget Review',
+ startDate: new Date('2021-04-27T19:00:00.000Z'),
+ endDate: new Date('2021-04-27T20:35:00.000Z'),
+ }, {
+ id: 6,
+ text: 'New Brochures',
+ startDate: new Date('2021-04-27T21:30:00.000Z'),
+ endDate: new Date('2021-04-27T22:45:00.000Z'),
+ }, {
+ id: 7,
+ text: 'Install New Database',
+ startDate: new Date('2021-04-28T16:45:00.000Z'),
+ endDate: new Date('2021-04-28T18:15:00.000Z'),
+ }, {
+ id: 8,
+ text: 'Approve New Online Marketing Strategy',
+ startDate: new Date('2021-04-28T19:00:00.000Z'),
+ endDate: new Date('2021-04-28T21:00:00.000Z'),
+ }, {
+ id: 9,
+ text: 'Upgrade Personal Computers',
+ startDate: new Date('2021-04-28T22:15:00.000Z'),
+ endDate: new Date('2021-04-28T23:30:00.000Z'),
+ }, {
+ id: 10,
+ text: 'Customer Workshop',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T19:00:00.000Z'),
+ allDay: true,
+ }, {
+ id: 11,
+ text: 'Prepare 2021 Marketing Plan',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T20:30:00.000Z'),
+ }, {
+ id: 12,
+ text: 'Brochure Design Review',
+ startDate: new Date('2021-04-29T21:00:00.000Z'),
+ endDate: new Date('2021-04-29T22:30:00.000Z'),
+ }, {
+ id: 13,
+ text: 'Create Icons for Website',
+ startDate: new Date('2021-04-30T17:00:00.000Z'),
+ endDate: new Date('2021-04-30T18:30:00.000Z'),
+ }, {
+ id: 14,
+ text: 'Upgrade Server Hardware',
+ startDate: new Date('2021-04-30T21:30:00.000Z'),
+ endDate: new Date('2021-04-30T23:00:00.000Z'),
+ }, {
+ id: 15,
+ text: 'Submit New Website Design',
+ startDate: new Date('2021-04-30T23:30:00.000Z'),
+ endDate: new Date('2021-05-01T01:00:00.000Z'),
+ }, {
+ id: 16,
+ text: 'Launch New Website',
+ startDate: new Date('2021-04-30T19:20:00.000Z'),
+ endDate: new Date('2021-04-30T21:00:00.000Z'),
+ },
+];
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Vue/index.html b/apps/demos/Demos/Scheduler/HiddenDays/Vue/index.html
new file mode 100644
index 000000000000..7b884ccdeda8
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Vue/index.html
@@ -0,0 +1,30 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Vue/index.ts b/apps/demos/Demos/Scheduler/HiddenDays/Vue/index.ts
new file mode 100644
index 000000000000..684d04215d72
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Vue/index.ts
@@ -0,0 +1,4 @@
+import { createApp } from 'vue';
+import App from './App.vue';
+
+createApp(App).mount('#app');
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/Vue/styles.css b/apps/demos/Demos/Scheduler/HiddenDays/Vue/styles.css
new file mode 100644
index 000000000000..82a48bdf0b98
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/Vue/styles.css
@@ -0,0 +1,55 @@
+.hidden-days-demo {
+ display: flex;
+ gap: 20px;
+}
+
+.scheduler-container {
+ flex: 1;
+ min-width: 0;
+}
+
+.options {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 220px;
+ box-sizing: border-box;
+ padding: 20px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 12px;
+}
+
+.caption {
+ font-weight: 500;
+ font-size: 18px;
+}
+
+.option {
+ display: flex;
+ flex-direction: column;
+}
+
+.validation-message {
+ display: none;
+ margin-top: 8px;
+ padding: 10px 12px;
+ background: #fdf3f4;
+ border-left: 3px solid #c50f1f;
+ border-radius: 4px;
+ color: #c50f1f;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.hidden-days-demo.is-invalid .validation-message {
+ display: block;
+}
+
+.hidden-days-demo.is-invalid .option .dx-checkbox-icon {
+ border-color: #c50f1f;
+}
+
+.hidden-days-demo.is-invalid .dx-scheduler-work-space {
+ opacity: 0.4;
+ pointer-events: none;
+}
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/jQuery/data.js b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/data.js
new file mode 100644
index 000000000000..cabf71cfd630
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/data.js
@@ -0,0 +1,85 @@
+const data = [
+ {
+ id: 1,
+ text: 'Website Re-Design Plan',
+ startDate: new Date('2021-04-26T16:30:00.000Z'),
+ endDate: new Date('2021-04-26T18:30:00.000Z'),
+ }, {
+ id: 2,
+ text: 'Book Flights to San Fran for Sales Trip',
+ startDate: new Date('2021-04-26T19:00:00.000Z'),
+ endDate: new Date('2021-04-26T20:00:00.000Z'),
+ allDay: true,
+ }, {
+ id: 3,
+ text: 'Install New Router in Dev Room',
+ startDate: new Date('2021-04-26T21:30:00.000Z'),
+ endDate: new Date('2021-04-26T22:30:00.000Z'),
+ }, {
+ id: 4,
+ text: 'Approve Personal Computer Upgrade Plan',
+ startDate: new Date('2021-04-27T17:00:00.000Z'),
+ endDate: new Date('2021-04-27T18:00:00.000Z'),
+ }, {
+ id: 5,
+ text: 'Final Budget Review',
+ startDate: new Date('2021-04-27T19:00:00.000Z'),
+ endDate: new Date('2021-04-27T20:35:00.000Z'),
+ }, {
+ id: 6,
+ text: 'New Brochures',
+ startDate: new Date('2021-04-27T21:30:00.000Z'),
+ endDate: new Date('2021-04-27T22:45:00.000Z'),
+ }, {
+ id: 7,
+ text: 'Install New Database',
+ startDate: new Date('2021-04-28T16:45:00.000Z'),
+ endDate: new Date('2021-04-28T18:15:00.000Z'),
+ }, {
+ id: 8,
+ text: 'Approve New Online Marketing Strategy',
+ startDate: new Date('2021-04-28T19:00:00.000Z'),
+ endDate: new Date('2021-04-28T21:00:00.000Z'),
+ }, {
+ id: 9,
+ text: 'Upgrade Personal Computers',
+ startDate: new Date('2021-04-28T22:15:00.000Z'),
+ endDate: new Date('2021-04-28T23:30:00.000Z'),
+ }, {
+ id: 10,
+ text: 'Customer Workshop',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T19:00:00.000Z'),
+ allDay: true,
+ }, {
+ id: 11,
+ text: 'Prepare 2021 Marketing Plan',
+ startDate: new Date('2021-04-29T18:00:00.000Z'),
+ endDate: new Date('2021-04-29T20:30:00.000Z'),
+ }, {
+ id: 12,
+ text: 'Brochure Design Review',
+ startDate: new Date('2021-04-29T21:00:00.000Z'),
+ endDate: new Date('2021-04-29T22:30:00.000Z'),
+ }, {
+ id: 13,
+ text: 'Create Icons for Website',
+ startDate: new Date('2021-04-30T17:00:00.000Z'),
+ endDate: new Date('2021-04-30T18:30:00.000Z'),
+ }, {
+ id: 14,
+ text: 'Upgrade Server Hardware',
+ startDate: new Date('2021-04-30T21:30:00.000Z'),
+ endDate: new Date('2021-04-30T23:00:00.000Z'),
+ }, {
+ id: 15,
+ text: 'Submit New Website Design',
+ startDate: new Date('2021-04-30T23:30:00.000Z'),
+ endDate: new Date('2021-05-01T01:00:00.000Z'),
+ }, {
+ id: 16,
+ text: 'Launch New Website',
+ startDate: new Date('2021-04-30T19:20:00.000Z'),
+ endDate: new Date('2021-04-30T21:00:00.000Z'),
+ },
+];
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/jQuery/index.html b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/index.html
new file mode 100644
index 000000000000..6c8d0efe8ebf
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/index.html
@@ -0,0 +1,28 @@
+
+
+
+ DevExtreme Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/jQuery/index.js b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/index.js
new file mode 100644
index 000000000000..64f1be225395
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/index.js
@@ -0,0 +1,48 @@
+$(() => {
+ const dayLabels = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+ let visibleDays = [0, 1, 2, 4, 6];
+ const VALIDATION_MESSAGE = 'The hiddenWeekDays option cannot hide all days of the week. At least one day must remain visible.';
+
+ function computeHiddenWeekDays() {
+ return [0, 1, 2, 3, 4, 5, 6].filter((d) => !visibleDays.includes(d));
+ }
+
+ function refreshValidity() {
+ $('.hidden-days-demo').toggleClass('is-invalid', visibleDays.length === 0);
+ }
+
+ const scheduler = $('#scheduler').dxScheduler({
+ timeZone: 'America/Los_Angeles',
+ dataSource: new DevExpress.data.ArrayStore({
+ key: 'id',
+ data,
+ }),
+ views: ['week', 'workWeek', 'month', 'timelineWeek', 'agenda'],
+ hiddenWeekDays: computeHiddenWeekDays(),
+ currentView: 'week',
+ currentDate: new Date(2021, 3, 26),
+ startDayHour: 9,
+ height: 730,
+ }).dxScheduler('instance');
+
+ const $optionsPanel = $('.options');
+ dayLabels.forEach((label, idx) => {
+ const $cb = $('').appendTo($optionsPanel);
+ $cb.dxCheckBox({
+ text: label,
+ value: visibleDays.includes(idx),
+ onValueChanged(e) {
+ if (e.value) {
+ visibleDays = [...visibleDays, idx];
+ } else {
+ visibleDays = visibleDays.filter((d) => d !== idx);
+ }
+ refreshValidity();
+ scheduler.option('hiddenWeekDays', computeHiddenWeekDays());
+ },
+ });
+ });
+
+ $('').text(VALIDATION_MESSAGE).appendTo($optionsPanel);
+ refreshValidity();
+});
diff --git a/apps/demos/Demos/Scheduler/HiddenDays/jQuery/styles.css b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/styles.css
new file mode 100644
index 000000000000..82a48bdf0b98
--- /dev/null
+++ b/apps/demos/Demos/Scheduler/HiddenDays/jQuery/styles.css
@@ -0,0 +1,55 @@
+.hidden-days-demo {
+ display: flex;
+ gap: 20px;
+}
+
+.scheduler-container {
+ flex: 1;
+ min-width: 0;
+}
+
+.options {
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ width: 220px;
+ box-sizing: border-box;
+ padding: 20px;
+ background-color: rgba(191, 191, 191, 0.15);
+ gap: 12px;
+}
+
+.caption {
+ font-weight: 500;
+ font-size: 18px;
+}
+
+.option {
+ display: flex;
+ flex-direction: column;
+}
+
+.validation-message {
+ display: none;
+ margin-top: 8px;
+ padding: 10px 12px;
+ background: #fdf3f4;
+ border-left: 3px solid #c50f1f;
+ border-radius: 4px;
+ color: #c50f1f;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.hidden-days-demo.is-invalid .validation-message {
+ display: block;
+}
+
+.hidden-days-demo.is-invalid .option .dx-checkbox-icon {
+ border-color: #c50f1f;
+}
+
+.hidden-days-demo.is-invalid .dx-scheduler-work-space {
+ opacity: 0.4;
+ pointer-events: none;
+}
diff --git a/apps/demos/menuMeta.json b/apps/demos/menuMeta.json
index 1f6ce3a3bc46..c4677e60cb4f 100644
--- a/apps/demos/menuMeta.json
+++ b/apps/demos/menuMeta.json
@@ -3704,6 +3704,13 @@
"/Models/SampleData/AppointmentsWorkHours.cs"
],
"DemoType": "Web"
+ },
+ {
+ "Title": "Hidden Week Days",
+ "Name": "HiddenDays",
+ "Widget": "Scheduler",
+ "Equivalents": "",
+ "DemoType": "Web"
}
]
},
diff --git a/apps/demos/testing/etalons/Scheduler-HiddenDays (fluent.blue.light).png b/apps/demos/testing/etalons/Scheduler-HiddenDays (fluent.blue.light).png
new file mode 100644
index 000000000000..b4e879eeeae5
Binary files /dev/null and b/apps/demos/testing/etalons/Scheduler-HiddenDays (fluent.blue.light).png differ
diff --git a/apps/demos/testing/etalons/Scheduler-HiddenDays (material.blue.light).png b/apps/demos/testing/etalons/Scheduler-HiddenDays (material.blue.light).png
new file mode 100644
index 000000000000..b042cae98854
Binary files /dev/null and b/apps/demos/testing/etalons/Scheduler-HiddenDays (material.blue.light).png differ