From 1ec72110c2f0a832db7400d09b9d2805d79da28c Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 15:37:16 +0100 Subject: [PATCH 01/12] Scroll to the right position when clicking error --- src/components/Form.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/Form.js b/src/components/Form.js index 74f3bbf12fed..f0c6b190e9f7 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -79,6 +79,7 @@ class Form extends React.Component { this.inputRefs = {}; this.touchedInputs = {}; + this.inputPositions = {}; this.setTouchedInput = this.setTouchedInput.bind(this); this.validate = this.validate.bind(this); @@ -217,6 +218,9 @@ class Form extends React.Component { this.setTouchedInput(inputID); this.validate(this.state.inputValues); }, + onLayout: (event) => { + this.inputPositions[inputID] = event.nativeEvent.layout.y; + }, onInputChange: (value, key) => { const inputKey = key || inputID; this.setState(prevState => ({ @@ -245,6 +249,7 @@ class Form extends React.Component { style={[styles.w100, styles.flex1]} contentContainerStyle={styles.flexGrow1} keyboardShouldPersistTaps="handled" + ref={el => this.form = el} > {this.childrenWrapperWithProps(this.props.children)} @@ -259,6 +264,7 @@ class Form extends React.Component { const errors = !_.isEmpty(this.state.errors) ? this.state.errors : this.props.formState.errorFields; const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); this.inputRefs[focusKey].focus(); + this.form.scrollTo({y: this.inputPositions[focusKey], animated: true}); }} containerStyles={[styles.mh0, styles.mt5]} enabledWhenOffline={this.props.enabledWhenOffline} From 51f22107bba60816974261e5f4e9a5c51eb024a5 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 15:38:16 +0100 Subject: [PATCH 02/12] use measure instead --- src/components/Form.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index f0c6b190e9f7..41bb9fe7d889 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -79,7 +79,7 @@ class Form extends React.Component { this.inputRefs = {}; this.touchedInputs = {}; - this.inputPositions = {}; + this.inputPosition = 0; this.setTouchedInput = this.setTouchedInput.bind(this); this.validate = this.validate.bind(this); @@ -218,9 +218,6 @@ class Form extends React.Component { this.setTouchedInput(inputID); this.validate(this.state.inputValues); }, - onLayout: (event) => { - this.inputPositions[inputID] = event.nativeEvent.layout.y; - }, onInputChange: (value, key) => { const inputKey = key || inputID; this.setState(prevState => ({ @@ -264,7 +261,9 @@ class Form extends React.Component { const errors = !_.isEmpty(this.state.errors) ? this.state.errors : this.props.formState.errorFields; const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); this.inputRefs[focusKey].focus(); - this.form.scrollTo({y: this.inputPositions[focusKey], animated: true}); + this.inputRefs[focusKey].measure((fx, fy, width, height, px, py) => { + this.form.scrollTo({y: py, animated: false}); + }) }} containerStyles={[styles.mh0, styles.mt5]} enabledWhenOffline={this.props.enabledWhenOffline} From d3802f6c62669fa78281957935aaa9de1b334a71 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 15:39:02 +0100 Subject: [PATCH 03/12] Use relative position --- src/components/Form.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/Form.js b/src/components/Form.js index 41bb9fe7d889..a7320e96580b 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -247,6 +247,9 @@ class Form extends React.Component { contentContainerStyle={styles.flexGrow1} keyboardShouldPersistTaps="handled" ref={el => this.form = el} + onLayout={(event) => { + this.inputPosition = event.nativeEvent.layout.y + 1; + }} > {this.childrenWrapperWithProps(this.props.children)} @@ -262,7 +265,7 @@ class Form extends React.Component { const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); this.inputRefs[focusKey].focus(); this.inputRefs[focusKey].measure((fx, fy, width, height, px, py) => { - this.form.scrollTo({y: py, animated: false}); + this.form.scrollTo({y: py-this.inputPosition, animated: false}); }) }} containerStyles={[styles.mh0, styles.mt5]} From 3aa99f8935fa4152c2a011e7975e2a44b3007f9b Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 15:57:26 +0100 Subject: [PATCH 04/12] style --- src/components/Form.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index a7320e96580b..c59e03aed58b 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -265,8 +265,8 @@ class Form extends React.Component { const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); this.inputRefs[focusKey].focus(); this.inputRefs[focusKey].measure((fx, fy, width, height, px, py) => { - this.form.scrollTo({y: py-this.inputPosition, animated: false}); - }) + this.form.scrollTo({y: py - this.inputPosition, animated: false}); + }); }} containerStyles={[styles.mh0, styles.mt5]} enabledWhenOffline={this.props.enabledWhenOffline} From 90104a5b2a335ad53e28a68a7ea8627f48434b22 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 16:53:45 +0100 Subject: [PATCH 05/12] add comment --- src/components/Form.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/Form.js b/src/components/Form.js index c59e03aed58b..a65f37756196 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -248,6 +248,8 @@ class Form extends React.Component { keyboardShouldPersistTaps="handled" ref={el => this.form = el} onLayout={(event) => { + // Store the parent component position to be used for scrolling. The +1 is to avoid covering + // the upper border of the element we scroll to this.inputPosition = event.nativeEvent.layout.y + 1; }} > From b7344e53d5a7b78eed3271f31b8af1219a03bb8f Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 16:56:47 +0100 Subject: [PATCH 06/12] rename variable --- src/components/Form.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index a65f37756196..f376fdfccffc 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -79,7 +79,7 @@ class Form extends React.Component { this.inputRefs = {}; this.touchedInputs = {}; - this.inputPosition = 0; + this.viewPosition = 0; this.setTouchedInput = this.setTouchedInput.bind(this); this.validate = this.validate.bind(this); @@ -250,7 +250,7 @@ class Form extends React.Component { onLayout={(event) => { // Store the parent component position to be used for scrolling. The +1 is to avoid covering // the upper border of the element we scroll to - this.inputPosition = event.nativeEvent.layout.y + 1; + this.viewPosition = event.nativeEvent.layout.y + 1; }} > From b10456170c9d13da4104a09e69d0fb3fa3b42fbf Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 23 Nov 2022 16:57:10 +0100 Subject: [PATCH 07/12] typo --- src/components/Form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form.js b/src/components/Form.js index f376fdfccffc..e02fa9460cef 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -267,7 +267,7 @@ class Form extends React.Component { const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); this.inputRefs[focusKey].focus(); this.inputRefs[focusKey].measure((fx, fy, width, height, px, py) => { - this.form.scrollTo({y: py - this.inputPosition, animated: false}); + this.form.scrollTo({y: py - this.viewPosition, animated: false}); }); }} containerStyles={[styles.mh0, styles.mt5]} From 66a4d627f40bd006e77000b52a8d03d6660be73e Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 24 Nov 2022 09:47:18 +0100 Subject: [PATCH 08/12] Fix keyboard behavior --- src/components/Form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form.js b/src/components/Form.js index e02fa9460cef..e2818ad86154 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -265,9 +265,9 @@ class Form extends React.Component { onFixTheErrorsLinkPressed={() => { const errors = !_.isEmpty(this.state.errors) ? this.state.errors : this.props.formState.errorFields; const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); - this.inputRefs[focusKey].focus(); this.inputRefs[focusKey].measure((fx, fy, width, height, px, py) => { this.form.scrollTo({y: py - this.viewPosition, animated: false}); + this.inputRefs[focusKey].focus(); }); }} containerStyles={[styles.mh0, styles.mt5]} From bf348307de43de19a205b1d7bc76f43665eb774f Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 25 Nov 2022 12:31:13 +0100 Subject: [PATCH 09/12] new approach --- src/components/Form.js | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index e2818ad86154..658fb3c9cea8 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -79,7 +79,7 @@ class Form extends React.Component { this.inputRefs = {}; this.touchedInputs = {}; - this.viewPosition = 0; + this.childPosition = {}; this.setTouchedInput = this.setTouchedInput.bind(this); this.validate = this.validate.bind(this); @@ -239,7 +239,18 @@ class Form extends React.Component { }); } + setPosition(element, position) { + if (!element.props.inputID && element.props.children) { + _.forEach(element.props.children, (child) => { + this.setPosition(child, position); + }); + } else { + this.childPosition[element.props.inputID] = position; + } + } + render() { + const children = this.childrenWrapperWithProps(this.props.children); return ( <> - {this.childrenWrapperWithProps(this.props.children)} + {_.map(children, child => ( + { + this.setPosition(child, event.nativeEvent.layout.y); + }} + > + {child} + + ))} {this.props.isSubmitButtonVisible && ( { const errors = !_.isEmpty(this.state.errors) ? this.state.errors : this.props.formState.errorFields; const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); - this.inputRefs[focusKey].measure((fx, fy, width, height, px, py) => { - this.form.scrollTo({y: py - this.viewPosition, animated: false}); - this.inputRefs[focusKey].focus(); - }); + this.form.scrollTo({y: this.childPosition[focusKey], animated: false}); + this.inputRefs[focusKey].focus(); }} containerStyles={[styles.mh0, styles.mt5]} enabledWhenOffline={this.props.enabledWhenOffline} From 443d6868d949fcf684bccbc12829b07ac3f8b7a0 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 25 Nov 2022 12:31:43 +0100 Subject: [PATCH 10/12] cleanUp --- src/components/Form.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index 658fb3c9cea8..580cd99d0d37 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -258,11 +258,6 @@ class Form extends React.Component { contentContainerStyle={styles.flexGrow1} keyboardShouldPersistTaps="handled" ref={el => this.form = el} - onLayout={(event) => { - // Store the parent component position to be used for scrolling. The +1 is to avoid covering - // the upper border of the element we scroll to - this.viewPosition = event.nativeEvent.layout.y + 1; - }} > {_.map(children, child => ( From bf7d9b40c6ec5bf848eecfcd164f4627c94abbc2 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 25 Nov 2022 12:33:20 +0100 Subject: [PATCH 11/12] remove extra const --- src/components/Form.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index 580cd99d0d37..77e32939f466 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -250,7 +250,6 @@ class Form extends React.Component { } render() { - const children = this.childrenWrapperWithProps(this.props.children); return ( <> this.form = el} > - {_.map(children, child => ( + {_.map(this.childrenWrapperWithProps(this.props.children), child => ( { this.setPosition(child, event.nativeEvent.layout.y); From 868bfe83475b6296a52ceed0567ad668689af39f Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 25 Nov 2022 12:47:20 +0100 Subject: [PATCH 12/12] style --- src/components/Form.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index 77e32939f466..4cdeaac1f5db 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -109,6 +109,16 @@ class Form extends React.Component { return _.first(_.keys(hasStateErrors ? this.state.erorrs : this.props.formState.errorFields)); } + setPosition(element, position) { + if (!element.props.inputID && element.props.children) { + _.forEach(element.props.children, (child) => { + this.setPosition(child, position); + }); + } else { + this.childPosition[element.props.inputID] = position; + } + } + submit() { // Return early if the form is already submitting to avoid duplicate submission if (this.props.formState.isLoading) { @@ -239,16 +249,6 @@ class Form extends React.Component { }); } - setPosition(element, position) { - if (!element.props.inputID && element.props.children) { - _.forEach(element.props.children, (child) => { - this.setPosition(child, position); - }); - } else { - this.childPosition[element.props.inputID] = position; - } - } - render() { return ( <>