Skip to content

Commit 69048a9

Browse files
fix React
1 parent 1cc9772 commit 69048a9

File tree

10 files changed

+5490
-5600
lines changed

10 files changed

+5490
-5600
lines changed

React/package-lock.json

Lines changed: 2567 additions & 3980 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

React/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020
"react-dom": "^18.2.0"
2121
},
2222
"devDependencies": {
23+
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
2324
"@testing-library/jest-dom": "^5.16.5",
2425
"@testing-library/react": "^14.1.2",
2526
"@testing-library/user-event": "^14.4.3",
2627
"@types/react": "^18.2.47",
2728
"@types/react-dom": "^18.2.17",
2829
"@vitejs/plugin-react": "^4.4.1",
2930
"@vitest/coverage-v8": "^1.5.0",
30-
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
3131
"eslint": "^8.35.0",
3232
"eslint-config-devextreme": "^1.1.4",
3333
"eslint-plugin-no-only-tests": "2.6.0",
@@ -39,10 +39,10 @@
3939
"npm-run-all": "^4.1.5",
4040
"stylelint": "^15.6.1",
4141
"stylelint-config-standard": "^33.0.0",
42+
"ts-node": "10.9.2",
4243
"typescript": "~5.8.2",
4344
"typescript-eslint": "^8.18.2",
4445
"vite": "^6.3.5",
45-
"ts-node": "10.9.2",
4646
"vitest": "^1.5.0"
4747
}
48-
}
48+
}

React/src/App.tsx

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,116 @@
1-
import { useCallback, useState } from 'react';
1+
import {
2+
useRef, useState, useCallback,
3+
} from 'react';
4+
import { SelectBox, type SelectBoxRef, type SelectBoxTypes } from 'devextreme-react/select-box';
5+
import Form, { SimpleItem, Label, type FormTypes } from 'devextreme-react/form';
6+
import notify from 'devextreme/ui/notify';
27
import './App.css';
3-
import 'devextreme/dist/css/dx.material.blue.light.compact.css';
4-
import Button from 'devextreme-react/button';
8+
import 'devextreme/dist/css/dx.light.css';
9+
10+
import type dxSelectBox from 'devextreme/ui/select_box';
11+
import service from './data';
12+
13+
const states = service.getStates();
14+
const cities = service.getCities();
15+
16+
const stateEditorOptions = {
17+
dataSource: states,
18+
valueExpr: 'ID',
19+
displayExpr: 'Name',
20+
};
21+
22+
const cityEditorOptions = {
23+
dataSource: cities,
24+
valueExpr: 'ID',
25+
displayExpr: 'Name',
26+
};
527

628
function App(): JSX.Element {
7-
var [count, setCount] = useState<number>(0);
8-
const clickHandler = useCallback(() => {
9-
setCount((prev) => prev + 1);
10-
}, [setCount]);
29+
const [formData, setFormData] = useState(service.getAddress);
30+
const [stateValue, setStateValue] = useState(null);
31+
const [cityValue, setCityValue] = useState(null);
32+
const citySelectBoxRef = useRef<SelectBoxRef>(null);
33+
34+
const stateValueChanged = useCallback((e: SelectBoxTypes.ValueChangedEvent): void => {
35+
if (citySelectBoxRef.current) {
36+
const cityDataSource = citySelectBoxRef.current.instance().getDataSource();
37+
cityDataSource.filter(['StateID', '=', e.value]);
38+
cityDataSource.load().then(() => {
39+
setStateValue(e.value);
40+
setCityValue(null);
41+
}).catch(() => {
42+
notify('An error occurred while loading changes.', 'error', 3000);
43+
});
44+
}
45+
}, []);
46+
const cityValueChanged = useCallback((e: SelectBoxTypes.ValueChangedEvent): void => {
47+
setCityValue(e.value);
48+
}, []);
49+
const onFieldDataChanged = useCallback((e: FormTypes.FieldDataChangedEvent) => {
50+
if (e.dataField === 'StateID') {
51+
const cityEditor = e.component.getEditor('CityID') as dxSelectBox;
52+
const dataSource = cityEditor.getDataSource();
53+
dataSource.filter(['StateID', '=', e.value]);
54+
dataSource.load().then(() => {
55+
setFormData({ ...formData, ...{ CityID: null, StateID: e.value } });
56+
}).catch(() => {
57+
notify('An error occurred while loading changes.', 'error', 3000);
58+
});
59+
}
60+
}, []);
61+
1162
return (
12-
<div className="main">
13-
<Button text={`Click count: ${count}`} onClick={clickHandler} />
63+
<div>
64+
<div className="dx-fieldset" style={{ width: '50%' }}>
65+
<div className="dx-fieldset-header">Select State, City</div>
66+
<div className="dx-field">
67+
<div className="dx-field-label">State</div>
68+
<div className="dx-field-value">
69+
<SelectBox
70+
dataSource={states}
71+
valueExpr="ID"
72+
displayExpr="Name"
73+
value={stateValue}
74+
onValueChanged={stateValueChanged}
75+
/>
76+
</div>
77+
</div>
78+
<div className="dx-field">
79+
<div className="dx-field-label">City</div>
80+
<div className="dx-field-value">
81+
<SelectBox
82+
ref={citySelectBoxRef}
83+
dataSource={cities}
84+
onValueChanged={cityValueChanged}
85+
valueExpr="ID"
86+
displayExpr="Name"
87+
value={cityValue}
88+
/>
89+
</div>
90+
</div>
91+
<div className="dx-fieldset-header">In Form</div>
92+
<div className="dx-field">
93+
<Form
94+
formData={formData}
95+
onFieldDataChanged={onFieldDataChanged}
96+
>
97+
<SimpleItem
98+
dataField="StateID"
99+
editorType="dxSelectBox"
100+
editorOptions={stateEditorOptions}
101+
>
102+
<Label text="State" />
103+
</SimpleItem>
104+
<SimpleItem
105+
dataField="CityID"
106+
editorType="dxSelectBox"
107+
editorOptions={cityEditorOptions}
108+
>
109+
<Label text="City" />
110+
</SimpleItem>
111+
</Form>
112+
</div>
113+
</div>
14114
</div>
15115
);
16116
}

React/src/data.ts

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
export interface State {
2+
ID: number;
3+
Name: string;
4+
}
5+
6+
export interface City {
7+
ID: number;
8+
Name: string;
9+
StateID: number | null;
10+
}
11+
12+
export interface Address {
13+
StateID: number | null;
14+
CityID: number | null;
15+
}
16+
17+
const address: Address = { StateID: null, CityID: null };
18+
19+
const states: State[] = [
20+
{
21+
ID: 1,
22+
Name: 'Alabama',
23+
},
24+
{
25+
ID: 2,
26+
Name: 'Alaska',
27+
},
28+
{
29+
ID: 3,
30+
Name: 'Arizona',
31+
},
32+
{
33+
ID: 4,
34+
Name: 'Arkansas',
35+
},
36+
{
37+
ID: 5,
38+
Name: 'California',
39+
},
40+
];
41+
42+
const cities: City[] = [
43+
{
44+
ID: 1,
45+
Name: 'Tuscaloosa',
46+
StateID: 1,
47+
},
48+
{
49+
ID: 2,
50+
Name: 'Hoover',
51+
StateID: 1,
52+
},
53+
{
54+
ID: 3,
55+
Name: 'Dothan',
56+
StateID: 1,
57+
},
58+
{
59+
ID: 4,
60+
Name: 'Decatur',
61+
StateID: 1,
62+
},
63+
{
64+
ID: 5,
65+
Name: 'Anchorage',
66+
StateID: 2,
67+
},
68+
{
69+
ID: 6,
70+
Name: 'Fairbanks',
71+
StateID: 2,
72+
},
73+
{
74+
ID: 7,
75+
Name: 'Juneau',
76+
StateID: 2,
77+
},
78+
{
79+
ID: 8,
80+
Name: 'Avondale',
81+
StateID: 3,
82+
},
83+
{
84+
ID: 9,
85+
Name: 'Buckeye',
86+
StateID: 3,
87+
},
88+
{
89+
ID: 10,
90+
Name: 'Carefree',
91+
StateID: 3,
92+
},
93+
{
94+
ID: 11,
95+
Name: 'Springdale',
96+
StateID: 4,
97+
},
98+
{
99+
ID: 12,
100+
Name: 'Rogers',
101+
StateID: 4,
102+
},
103+
{
104+
ID: 13,
105+
Name: 'Sherwood',
106+
StateID: 4,
107+
},
108+
{
109+
ID: 14,
110+
Name: 'Jacksonville',
111+
StateID: 4,
112+
},
113+
{
114+
ID: 15,
115+
Name: 'Cabot',
116+
StateID: 4,
117+
},
118+
{
119+
ID: 16,
120+
Name: 'Adelanto',
121+
StateID: 5,
122+
},
123+
{
124+
ID: 17,
125+
Name: 'Glendale',
126+
StateID: 5,
127+
},
128+
{
129+
ID: 18,
130+
Name: 'Moorpark',
131+
StateID: 5,
132+
},
133+
{
134+
ID: 19,
135+
Name: 'Needles',
136+
StateID: 5,
137+
},
138+
{
139+
ID: 20,
140+
Name: 'Ontario',
141+
StateID: 5,
142+
},
143+
];
144+
145+
export default {
146+
getStates(): State[] {
147+
return states;
148+
},
149+
getCities(): City[] {
150+
return cities;
151+
},
152+
getAddress(): Address {
153+
return address;
154+
},
155+
};

React/src/orig_App.css

Whitespace-only changes.

0 commit comments

Comments
 (0)