Skip to content

Commit ba7dd99

Browse files
committed
convert react demo
1 parent bfd6a9a commit ba7dd99

File tree

2 files changed

+87
-80
lines changed

2 files changed

+87
-80
lines changed

apps/demos/Demos/Scheduler/Templates/ReactJs/App.js

Lines changed: 74 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import React, { useCallback, useRef } from 'react';
1+
import React, { useCallback, useMemo, useRef } from 'react';
22
import Scheduler, {
33
Editing,
44
Resource,
55
Form as SchedulerForm,
66
Item,
7+
Label,
78
} from 'devextreme-react/scheduler';
89
import { query } from 'devextreme-react/common/data';
910
import Appointment from './Appointment.js';
@@ -14,35 +15,15 @@ import { data, moviesData, theatreData } from './data.js';
1415
const currentDate = new Date(2025, 3, 27);
1516
const views = ['day', 'week', 'timelineDay'];
1617
const groups = ['theatreId'];
17-
const getMovieById = (id) => query(moviesData).filter(['id', id]).toArray()[0];
18+
const getMovieById = (id) => (id ? query(moviesData).filter(['id', '=', id]).toArray()[0] : null);
1819
const getEditorStylingMode = () => {
1920
const isMaterialOrFluent = document.querySelector('.dx-theme-fluent, .dx-theme-material');
2021
return isMaterialOrFluent ? 'filled' : 'outlined';
2122
};
2223
const priceDisplayExpr = (value) => `$${value}`;
23-
const updateEndDate = (form, movie) => {
24-
const formData = form.option('formData');
25-
const { startDate } = formData;
26-
if (startDate && movie?.duration) {
27-
const newEndDate = new Date(startDate.getTime() + 60 * 1000 * movie.duration);
28-
form.updateData('endDate', newEndDate);
29-
}
30-
};
24+
const colCountByScreen = { xs: 2 };
3125
const App = () => {
3226
const formInstanceRef = useRef(null);
33-
const onMovieValueChanged = useCallback((e) => {
34-
const movie = getMovieById(e.value);
35-
if (formInstanceRef.current && movie) {
36-
formInstanceRef.current.updateData('director', movie.director);
37-
updateEndDate(formInstanceRef.current, movie);
38-
}
39-
}, []);
40-
const onMovieEditorContentReady = useCallback((e) => {
41-
e.component.option('stylingMode', getEditorStylingMode());
42-
}, []);
43-
const onPriceEditorContentReady = useCallback((e) => {
44-
e.component.option('stylingMode', getEditorStylingMode());
45-
}, []);
4627
const onPopupOptionChanged = useCallback((e) => {
4728
if (e.fullName === 'toolbarItems' && e.value) {
4829
e.value.forEach((item, index) => {
@@ -52,25 +33,75 @@ const App = () => {
5233
});
5334
}
5435
}, []);
55-
const onFormInitialized = useCallback((e) => {
56-
const form = e.component;
57-
formInstanceRef.current = form;
58-
form.on('fieldDataChanged', (fieldEvent) => {
59-
if (fieldEvent.dataField === 'startDate') {
60-
const currentFormData = form.option('formData');
61-
if (currentFormData.movieId) {
36+
const popupOptions = useMemo(
37+
() => ({
38+
maxWidth: 440,
39+
onOptionChanged: onPopupOptionChanged,
40+
}),
41+
[onPopupOptionChanged],
42+
);
43+
const updateEndDate = useCallback((movie) => {
44+
const form = formInstanceRef.current;
45+
const formData = form.option('formData');
46+
const { startDate } = formData;
47+
if (startDate) {
48+
const newEndDate = new Date(startDate.getTime() + 60 * 1000 * movie.duration);
49+
form.updateData('endDate', newEndDate);
50+
}
51+
}, []);
52+
const onFormInitialized = useCallback(
53+
(e) => {
54+
const form = e.component;
55+
formInstanceRef.current = form;
56+
form.on('fieldDataChanged', (fieldEvent) => {
57+
if (fieldEvent.dataField === 'startDate') {
58+
const currentFormData = form.option('formData');
6259
const movie = getMovieById(currentFormData.movieId);
6360
if (movie) {
64-
updateEndDate(form, movie);
61+
updateEndDate(movie);
6562
}
6663
}
64+
});
65+
},
66+
[updateEndDate],
67+
);
68+
const onMovieValueChanged = useCallback(
69+
(e) => {
70+
const movie = getMovieById(e.value);
71+
if (movie) {
72+
formInstanceRef.current.updateData('director', movie.director);
73+
updateEndDate(movie);
6774
}
68-
});
69-
}, []);
75+
},
76+
[updateEndDate],
77+
);
7078
const movieInfoContainerRender = useCallback(
7179
() => <MovieInfoContainer formInstanceRef={formInstanceRef} />,
7280
[],
7381
);
82+
const onCustomEditorContentReady = useCallback((e) => {
83+
e.component.option('stylingMode', getEditorStylingMode());
84+
}, []);
85+
const movieEditorOptions = useMemo(
86+
() => ({
87+
items: moviesData,
88+
displayExpr: 'text',
89+
valueExpr: 'id',
90+
stylingMode: getEditorStylingMode(),
91+
onValueChanged: onMovieValueChanged,
92+
onContentReady: onCustomEditorContentReady,
93+
}),
94+
[onMovieValueChanged, onCustomEditorContentReady],
95+
);
96+
const priceEditorOptions = useMemo(
97+
() => ({
98+
items: [5, 10, 15, 20],
99+
displayExpr: priceDisplayExpr,
100+
stylingMode: getEditorStylingMode(),
101+
onContentReady: onCustomEditorContentReady,
102+
}),
103+
[onCustomEditorContentReady],
104+
);
74105
return (
75106
<Scheduler
76107
timeZone="America/Los_Angeles"
@@ -91,46 +122,33 @@ const App = () => {
91122
>
92123
<Editing
93124
allowAdding={false}
94-
popup={{
95-
maxWidth: 440,
96-
onOptionChanged: onPopupOptionChanged,
97-
}}
125+
popup={popupOptions}
98126
>
99127
<SchedulerForm onInitialized={onFormInitialized}>
100128
<Item render={movieInfoContainerRender} />
101129

102130
<Item
103131
itemType="group"
104132
colCount={2}
105-
colCountByScreen={{ xs: 2 }}
133+
colCountByScreen={colCountByScreen}
106134
>
107135
<Item
108136
dataField="movieId"
109137
editorType="dxSelectBox"
110-
label={{ text: 'Movie' }}
111138
colSpan={1}
112-
editorOptions={{
113-
items: moviesData,
114-
displayExpr: 'text',
115-
valueExpr: 'id',
116-
stylingMode: getEditorStylingMode(),
117-
onValueChanged: onMovieValueChanged,
118-
onContentReady: onMovieEditorContentReady,
119-
}}
120-
/>
139+
editorOptions={movieEditorOptions}
140+
>
141+
<Label>Movie</Label>
142+
</Item>
121143

122144
<Item
123145
dataField="price"
124146
editorType="dxSelectBox"
125-
label={{ text: 'Price' }}
126147
colSpan={1}
127-
editorOptions={{
128-
items: [5, 10, 15, 20],
129-
displayExpr: priceDisplayExpr,
130-
stylingMode: getEditorStylingMode(),
131-
onContentReady: onPriceEditorContentReady,
132-
}}
133-
/>
148+
editorOptions={priceEditorOptions}
149+
>
150+
<Label>Price</Label>
151+
</Item>
134152
</Item>
135153

136154
<Item

apps/demos/Demos/Scheduler/Templates/ReactJs/MovieInfoContainer.js

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,24 @@ import React, { useState, useEffect } from 'react';
22
import { query } from 'devextreme-react/common/data';
33
import { moviesData } from './data.js';
44

5-
const getMovieById = (id) => query(moviesData).filter(['id', id]).toArray()[0];
5+
const getMovieById = (id) => (id ? query(moviesData).filter(['id', id]).toArray()[0] : null);
66
const MovieInfoContainer = ({ formInstanceRef }) => {
77
const [movie, setMovie] = useState(null);
88
useEffect(() => {
99
const form = formInstanceRef.current;
10-
if (form) {
11-
const formData = form.option('formData');
12-
if (formData?.movieId) {
13-
const currentMovie = getMovieById(formData.movieId);
14-
setMovie(currentMovie);
15-
} else {
16-
setMovie(null);
10+
const formData = form.option('formData');
11+
const currentMovie = getMovieById(formData.movieId);
12+
setMovie(currentMovie);
13+
const handleFieldDataChanged = (e) => {
14+
if (e.dataField === 'movieId') {
15+
const updatedMovie = getMovieById(e.value);
16+
setMovie(updatedMovie);
1717
}
18-
const handleFieldDataChanged = (e) => {
19-
if (e.dataField === 'movieId') {
20-
if (e.value) {
21-
const updatedMovie = getMovieById(e.value);
22-
setMovie(updatedMovie);
23-
} else {
24-
setMovie(null);
25-
}
26-
}
27-
};
28-
form.on('fieldDataChanged', handleFieldDataChanged);
29-
return () => {
30-
form.off('fieldDataChanged', handleFieldDataChanged);
31-
};
32-
}
33-
return undefined;
18+
};
19+
form.on('fieldDataChanged', handleFieldDataChanged);
20+
return () => {
21+
form.off('fieldDataChanged', handleFieldDataChanged);
22+
};
3423
}, [formInstanceRef]);
3524
return (
3625
<div className="movie-info-container">

0 commit comments

Comments
 (0)