1+ /*
2+ * ping-sample-web-react-davinci
3+ *
4+ * object-value.js
5+ *
6+ * Copyright (c) 2025 - 2026 Ping Identity Corporation. All rights reserved.
7+ * This software may be modified and distributed under the terms
8+ * of the MIT license. See the LICENSE file for details.
9+ */
10+
111import React , { useEffect , useContext , useState } from 'react' ;
212import { ThemeContext } from '../../context/theme.context.js' ;
313
4- export default function ObjectValueComponent ( { collector, updater } ) {
5- const [ selected , setSelected ] = useState ( collector . output . options [ 0 ] . value ) ;
14+ export default function ObjectValueComponent ( { collector, updater, inputName } ) {
15+ const [ selectedDevice , setSelectedDevice ] = useState (
16+ collector . output . options ?. [ 0 ] ?. value ?? null ,
17+ ) ;
18+ const [ phoneValue , setPhoneValue ] = useState ( {
19+ phoneNumber : collector . input . value ?. phoneNumber ?? '' ,
20+ extension : collector . input . value ?. extension ?? '' ,
21+ } ) ;
622 const theme = useContext ( ThemeContext ) ;
723
824 useEffect ( ( ) => {
9- updater ( selected ) ;
10- } , [ selected ] ) ;
25+ if (
26+ collector . type === 'DeviceAuthenticationCollector' ||
27+ collector . type === 'DeviceRegistrationCollector'
28+ ) {
29+ updater ( selectedDevice ) ;
30+ }
31+ } , [ selectedDevice , updater , collector . type ] ) ;
1132
12- const handleChange = ( event ) => {
33+ const handleChangeDevice = ( event ) => {
1334 event . preventDefault ( ) ;
14- setSelected ( event . target . value ) ;
35+ setSelectedDevice ( event . target . value ) ;
1536 } ;
1637 if (
1738 collector . type === 'DeviceAuthenticationCollector' ||
@@ -28,8 +49,8 @@ export default function ObjectValueComponent({ collector, updater }) {
2849 < select
2950 id = "device-select"
3051 className = "form-select form-select-lg w-100"
31- value = { selected }
32- onChange = { handleChange }
52+ value = { selectedDevice }
53+ onChange = { handleChangeDevice }
3354 >
3455 { collector . output . options . map ( ( option ) => (
3556 < option key = { option . value + option . label } value = { option . value } >
@@ -41,25 +62,86 @@ export default function ObjectValueComponent({ collector, updater }) {
4162 </ div >
4263 ) ;
4364 } else if ( collector . type === 'PhoneNumberCollector' ) {
65+ const phoneInputId = `${ inputName } -phone-number` ;
66+ const required = collector . input . validation ?. some (
67+ ( validation ) => validation . type === 'required' && validation . rule === true ,
68+ ) ;
69+
4470 return (
4571 < >
46- < label htmlFor = { 'form-label phone-number-input' } className = { 'mb-2 mt-2' } >
72+ < label htmlFor = { phoneInputId } className = { 'form-label mb-2 mt-2' } >
4773 { collector . output . label || 'Phone Number' }
4874 </ label >
4975 < input
5076 type = "text"
5177 className = { 'mb-2 mt-2' }
52- id = "phone-number-input"
53- name = "phone-number-input"
78+ id = { phoneInputId }
79+ name = { phoneInputId }
80+ placeholder = "Enter phone number"
81+ value = { phoneValue . phoneNumber }
82+ onChange = { ( event ) => {
83+ const updatedPhone = event . target . value ;
84+ setPhoneValue ( ( prev ) => ( { ...prev , phoneNumber : updatedPhone } ) ) ;
85+ updater ( {
86+ phoneNumber : updatedPhone ,
87+ countryCode : collector . input . value ?. countryCode ,
88+ } ) ;
89+ } }
90+ required = { required }
91+ />
92+ </ >
93+ ) ;
94+ } else if ( collector . type === 'PhoneNumberExtensionCollector' ) {
95+ const phoneInputId = `${ inputName } -phone-number` ;
96+ const extensionInputId = `${ inputName } -extension` ;
97+ const required = collector . input . validation ?. some (
98+ ( validation ) => validation . type === 'required' && validation . rule === true ,
99+ ) ;
100+ return (
101+ < >
102+ < label htmlFor = { phoneInputId } className = { 'form-label mb-2 mt-2' } >
103+ { collector . output . label || 'Phone Number' }
104+ </ label >
105+ < input
106+ type = "text"
107+ className = { 'mb-2' }
108+ id = { phoneInputId }
109+ name = { phoneInputId }
54110 placeholder = "Enter phone number"
111+ value = { phoneValue . phoneNumber }
112+ onChange = { ( event ) => {
113+ const updatedPhoneNumber = event . target . value ;
114+ const updatedPhoneValue = { ...phoneValue , phoneNumber : updatedPhoneNumber } ;
115+ setPhoneValue ( updatedPhoneValue ) ;
116+ updater ( {
117+ phoneNumber : updatedPhoneValue . phoneNumber ,
118+ countryCode : collector . input . value ?. countryCode ,
119+ extension : updatedPhoneValue . extension ,
120+ } ) ;
121+ } }
122+ required = { required }
123+ />
124+ < label htmlFor = { extensionInputId } className = { 'form-label mb-2 mt-2' } >
125+ { collector . output . extensionLabel || 'Extension' }
126+ </ label >
127+ < input
128+ type = "text"
129+ className = { 'mb-2' }
130+ id = { extensionInputId }
131+ name = { extensionInputId }
132+ placeholder = "Enter extension"
133+ value = { phoneValue . extension }
55134 onChange = { ( event ) => {
56- const selectedValue = event . target . value ;
57- if ( ! selectedValue ) {
58- console . error ( 'No value found for the selected option' ) ;
59- return ;
60- }
61- updater ( { phoneNumber : selectedValue , countryCode : collector . input . value . countryCode } ) ;
135+ const updatedExtension = event . target . value ;
136+ const updatedPhoneValue = { ...phoneValue , extension : updatedExtension } ;
137+ setPhoneValue ( updatedPhoneValue ) ;
138+ updater ( {
139+ phoneNumber : updatedPhoneValue . phoneNumber ,
140+ countryCode : collector . input . value ?. countryCode ,
141+ extension : updatedPhoneValue . extension ,
142+ } ) ;
62143 } }
144+ required = { required }
63145 />
64146 </ >
65147 ) ;
0 commit comments