@@ -2,22 +2,25 @@ import React, { useCallback } from 'react';
2
2
import PropTypes from 'prop-types' ;
3
3
import { normalizeOptions } from './helpers/form-helpers' ;
4
4
import { useFormControl } from './helpers/useFormControl' ;
5
+ import { getValueByPath } from '../utils/getters-setters' ;
5
6
6
- export function FormSelect ( { id, name, options, required, placeholder } ) {
7
+ export function FormSelect ( { id, name, options, required, placeholder, trackBy } ) {
7
8
const { getFormData, getValue, handleOnChange, register } = useFormControl ( name ) ;
8
9
const registerRef = useCallback ( register , [ ] ) ;
10
+ const value = getValue ( ) ;
11
+ const normalizedOptions = normalizeOptions ( options , getFormData ( ) ) ;
9
12
10
13
return (
11
14
< select
12
15
{ ...{ required, name, id } }
13
16
className = "custom-select"
14
17
onChange = { handleOnChange }
15
- value = { getValue ( ) }
18
+ value = { getSelectedOption ( value , normalizedOptions , trackBy ) }
16
19
ref = { registerRef }
17
20
>
18
21
< option value = "" > { placeholder } </ option >
19
22
20
- { renderOptions ( options , getFormData ( ) ) }
23
+ { renderOptions ( normalizedOptions , trackBy ) }
21
24
</ select >
22
25
) ;
23
26
}
@@ -31,12 +34,37 @@ FormSelect.propTypes = {
31
34
] ) ,
32
35
placeholder : PropTypes . string ,
33
36
required : PropTypes . any ,
37
+ trackBy : PropTypes . string ,
34
38
} ;
35
39
36
- function renderOptions ( options , formData ) {
37
- return normalizeOptions ( options , formData ) . map ( ( { value, label } , index ) => (
38
- < option key = { index } value = { value } >
40
+ function renderOptions ( options , trackBy ) {
41
+ return options . map ( ( { value, label } , index ) => (
42
+ < option key = { index } name = { trackBy } value = { serializeValue ( value ) } >
39
43
{ label }
40
44
</ option >
41
45
) ) ;
42
46
}
47
+
48
+ function getSelectedOption ( value , options , trackBy ) {
49
+ let selectedValue = value ;
50
+
51
+ if ( trackBy ) {
52
+ const selectedOption = options . find (
53
+ ( option ) => getValueByPath ( option . value , trackBy ) === getValueByPath ( value , trackBy )
54
+ ) ;
55
+
56
+ if ( selectedOption ) {
57
+ selectedValue = selectedOption . value ;
58
+ }
59
+ }
60
+
61
+ return serializeValue ( selectedValue ) ;
62
+ }
63
+
64
+ function serializeValue ( value ) {
65
+ if ( typeof value !== 'object' ) {
66
+ return value ;
67
+ }
68
+
69
+ return JSON . stringify ( value ) ;
70
+ }
0 commit comments