Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintenance/remove legacy string refs #43

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,23 @@ export class FormView extends React.Component {
style={{ paddingLeft: 10, paddingRight: 10, height: 200 }}
>
<Form
ref="registrationForm"
ref={this.formRef}
onFocus={this.handleFormFocus.bind(this)}
onChange={this.handleFormChange.bind(this)}
label="Personal Information"
>
<Separator />
<InputField
ref="first_name"
ref={this.firstNameRef}
fieldKey={"first_name"}
label="First Name"
placeholder="First Name"
helpText={(self => {
if (Object.keys(self.refs).length !== 0) {
if (!self.refs.registrationForm.refs.first_name.valid) {
return self.refs.registrationForm.refs.first_name.validationErrors.join(
if (self.firstNameRef.current && !self.firstNameRef.current.valid) {
return self.firstNameRef.current.validationErrors.join(
"\n"
);
}
}
// if(!!(self.refs && self.refs.first_name.valid)){
// }
})(this)}
validationFunction={[
value => {
Expand Down Expand Up @@ -162,22 +159,29 @@ export class FormView extends React.Component {
}
]}
/>
<InputField ref="last_name" placeholder="Last Name" />
<InputField
fieldKey={"last_name"}
ref={this.lastNameRef}
placeholder="Last Name"
/>
<InputField
multiline={true}
ref="other_input"
fieldKey={"other_input"}
ref={this.otherInputRef}
placeholder="Other Input"
helpText="this is an helpful text it can be also very very long and it will wrap"
/>
<Separator />
<LinkField label="test test test" onPress={() => {}} />
<SwitchField
fieldKey={"has_accepted_conditions"}
label="I accept Terms & Conditions"
ref="has_accepted_conditions"
ref={this.hasAcceptedRef}
helpText="Please read carefully the terms & conditions"
/>
<PickerField
ref="gender"
fieldKey={"gender"}
ref={this.genderRef}
label="Gender"
options={{
"": "",
Expand All @@ -186,14 +190,20 @@ export class FormView extends React.Component {
}}
/>
<DatePickerField
ref="birthday"
fieldKey={"birthday"}
ref={this.birthdayRef}
minimumDate={new Date("1/1/1900")}
maximumDate={new Date()}
placeholder="Birthday"
/>
<TimePickerField ref="alarm_time" placeholder="Set Alarm" />
<TimePickerField
fieldKey={"alarm"}
ref={this.alarmTimeRef}
placeholder="Set Alarm"
/>
<DatePickerField
ref="meeting"
fieldKey={"meeting"}
ref={this.meetingRef}
minimumDate={new Date("1/1/1900")}
maximumDate={new Date()}
mode="datetime"
Expand Down Expand Up @@ -239,7 +249,7 @@ It's just a wrapper that allows you to attach onFocus (used to track focus event

Input fields can be used to receive text, you can add icons (a react component) to the left and the right side of the field.

InputField can validate values based on keyboardType property, validation is not "aggressive", just changes a value inside the class, you can access the value using the ref (ex. this.ref.example*input_field.valid).
InputField can validate values based on keyboardType property, validation is not "aggressive", just changes a value inside the class, you can access the value using the ref (ex. this.refName.current.valid).
InputField automatically provides the attibutes \_valid* and _validationErrors_ to guarantee full control to the developer.

you can customize your validation function by adding a _validationFunction_ prop to the component. _validationFunction_ supports also an array of validators.
Expand Down Expand Up @@ -271,7 +281,8 @@ look at the example here.
```javascript
<InputField
label="Example" // if label is present the field is rendered with the value on the left (see First Name example in the gif), otherwise its rendered with textinput at full width (second name in the gif).
ref="example_input_field" // used in onChange event to collect the value
ref={this.exampleRef}
fieldKey="example_input_field" // used in onChange event to collect the value
value="default_value" // used as initial value
keyboardType="" // undefined, 'email-address',
validationFunction={value => {
Expand All @@ -285,8 +296,8 @@ look at the example here.
{ marginTop: 7, color: "#61d062" },
(self => {
//i can change the style of the component related to the attibute of example_input_field
if (!!(self.refs && self.refs.example_input_field)) {
if (!self.refs.example_input_field.valid)
if (!!self.exampleRef.current) {
if (!self.exampleRef.current.valid)
return { color: "#d52222" };
}
})(this)
Expand Down
68 changes: 44 additions & 24 deletions examples/FormView.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ import {
} from "react-native-form-generator";

class CustomModal extends React.Component {
constructor(props) {
super(props);
this.formRef = React.createRef();
this.firstNameRef = React.createRef();
this.lastNameRef = React.createRef();
this.otherInputRef = React.createRef();
this.emailRef = React.createRef();
this.hasAcceptedRef = React.createRef();
this.genderRef = React.createRef();
this.birthdayRef = React.createRef();
this.alarmTimeRef = React.createRef();
this.countdownRef = React.createRef();
this.meetingRef = React.createRef();
}
handleClose() {
this.props.onHidePicker && this.props.onHidePicker();
}
Expand Down Expand Up @@ -116,36 +130,33 @@ export class FormView extends React.Component {
}
openTermsAndConditionsURL() {}
resetForm() {
this.refs.registrationForm.refs.first_name.setValue("");
this.refs.registrationForm.refs.last_name.setValue("");
this.refs.registrationForm.refs.other_input.setValue("");
this.refs.registrationForm.refs.meeting.setDate(new Date());
this.refs.registrationForm.refs.has_accepted_conditions.setValue(false);
this.firstNameRef.current && this.firstNameRef.current.setValue("");
this.lastNameRef.current && this.lastNameRef.current.setValue("");
this.otherInputRef.current && this.otherInputRef.current.setValue("");
this.meetingRef.current && this.meetingRef.current.setDate(new Date());
this.hasAcceptedRef.current && this.hasAcceptedRef.current.setValue(false);
}
render() {
return (
<ScrollView keyboardShouldPersistTaps={true} style={{ height: 200 }}>
<Form
ref="registrationForm"
ref={this.formRef}
onFocus={this.handleFormFocus.bind(this)}
onChange={this.handleFormChange.bind(this)}
label="Personal Information"
>
<Separator />
<InputField
ref="first_name"
ref={this.firstNameRef}
fieldKey={"first_name"}
label="First Name"
placeholder="First Name"
helpText={(self => {
if (Object.keys(self.refs).length !== 0) {
if (!self.refs.registrationForm.refs.first_name.valid) {
return self.refs.registrationForm.refs.first_name.validationErrors.join(
"\n"
);
if (self.firstNameRef.current) {
if (!self.firstNameRef.current.valid) {
return self.firstNameRef.current.validationErrors.join("\n");
}
}
// if(!!(self.refs && self.refs.first_name.valid)){
// }
})(this)}
validationFunction={[
value => {
Expand Down Expand Up @@ -173,6 +184,7 @@ export class FormView extends React.Component {
]}
/>
<InputField
fieldKey={"last_name"}
iconLeft={
<WrappedIcon
style={{
Expand All @@ -184,18 +196,20 @@ export class FormView extends React.Component {
size={30}
/>
}
ref="last_name"
ref={this.lastNameRef}
value="Default Value"
placeholder="Last Name"
/>
<InputField
fieldKey={"other_input"}
multiline={true}
ref="other_input"
ref={this.otherInputRef}
placeholder="Other Input"
helpText="this is an helpful text it can be also very very long and it will wrap"
/>
<InputField
ref="email"
fieldKey={"email"}
ref={this.emailRef}
value="[email protected]"
keyboardType="email-address"
placeholder="Email fields"
Expand Down Expand Up @@ -229,12 +243,14 @@ export class FormView extends React.Component {
}
/>
<SwitchField
fieldKey={"has_accepted_conditions"}
label="I accept Terms & Conditions"
ref="has_accepted_conditions"
ref={this.hasAcceptedRef}
helpText="Please read carefully the terms & conditions"
/>
<PickerField
ref="gender"
fieldKey={"gender"}
ref={this.genderRef}
label="Gender"
value="female"
options={[
Expand All @@ -244,7 +260,8 @@ export class FormView extends React.Component {
]}
/>
<DatePickerField
ref="birthday"
fieldKey={"birthday"}
ref={this.birthdayRef}
minimumDate={new Date("1/1/1900")}
maximumDate={new Date()}
iconRight={[
Expand All @@ -262,7 +279,8 @@ export class FormView extends React.Component {
placeholder="Birthday"
/>
<TimePickerField
ref="alarm_time"
fieldKey={"alarm"}
ref={this.alarmTimeRef}
placeholder="Set Alarm"
iconLeft={
<Icon
Expand All @@ -275,12 +293,14 @@ export class FormView extends React.Component {
pickerWrapper={<CustomModal />}
/>
<CountDownField
ref="countdown"
fieldKey={"countdown"}
ref={this.countdownRef}
label="CountDown"
placeholder="11:00"
/>
<DatePickerField
ref="meeting"
fieldKey={"meeting"}
ref={this.meetingRef}
iconLeft={[
<Icon
style={{ alignSelf: "center", marginLeft: 10 }}
Expand Down Expand Up @@ -317,7 +337,7 @@ export class FormView extends React.Component {
</TouchableHighlight>
<TouchableHighlight
disabled={!this.state.formData.has_accepted_conditions}
onPress={() => this.refs.registrationForm.refs.other_input.focus()}
onPress={() => this.otherInputRef.current.focus()}
underlayColor="#78ac05"
>
<View
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"test:watch": "jest --watchAll",
"format": "prettier --write --loglevel=silent"
},
"version": "0.10.0",
"version": "0.10.1",
"devDependencies": {
"@tsconfig/react-native": "^1.0.4",
"@types/react": "^17.0.39",
Expand Down
22 changes: 15 additions & 7 deletions src/Form.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from "react";
import { Text, View } from "react-native";
import { View } from "react-native";

export class Form extends Component {
constructor(props) {
Expand All @@ -12,10 +12,14 @@ export class Form extends Component {
this.props.onFocus?.(event, inputHandle);
}

handleFieldChange(field_ref, value) {
const name = typeof field_ref === "function" ? field_ref() : field_ref;
this.values[name] = value;
this.props.onChange?.({...this.values}, {[name]: value});
handleFieldChange(fieldKey, value) {
if (!fieldKey) {
console.warn('Field key is undefined. Cannot update value.');
return;
}

this.values[fieldKey] = value;
this.props.onChange?.({ ...this.values }, { [fieldKey]: value });
}

getValues() {
Expand Down Expand Up @@ -48,20 +52,24 @@ export class Form extends Component {
this.addProps(fieldElement, isTestable, key)
)
);

return isTestable
? React.cloneElement(sectionElement, { children: connectedTarget })
: connectedTarget;
}

addProps(element, isTestable, key) {
const target = isTestable ? element.props.children : element;
const fieldKey = target.props.fieldKey || target.key;

const targetWithProps = React.cloneElement(target, {
key,
fieldRef: target.ref,
fieldKey,
ref: target.ref,
onFocus: this.handleFieldFocused.bind(this),
onChange: this.handleFieldChange.bind(this, target.ref)
onChange: this.handleFieldChange.bind(this, fieldKey)
});

return isTestable
? React.cloneElement(element, { children: targetWithProps })
: targetWithProps;
Expand Down
23 changes: 13 additions & 10 deletions src/KeyboardAwareScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class KeyboardAwareScrollView extends React.Component {
this.state = {
keyboardSpace: 0
};

this.keyboardAwareScrollviewRef = React.createRef();
this.updateKeyboardSpace = this.updateKeyboardSpace.bind(this);
this.resetKeyboardSpace = this.resetKeyboardSpace.bind(this);
}
Expand Down Expand Up @@ -54,21 +54,24 @@ export class KeyboardAwareScrollView extends React.Component {
* @param extraHeight: takes an extra height in consideration.
*/
scrollToFocusedInput(event, reactNode, extraHeight = 69) {
const scrollView = this.refs.keyboardScrollView.getScrollResponder();
setTimeout(() => {
scrollView.scrollResponderScrollNativeHandleToKeyboard(
reactNode,
extraHeight,
true
);
}, 220);
if (this.keyboardAwareScrollviewRef.current) {
const scrollView =
this.keyboardAwareScrollviewRef.current.getScrollResponder();
setTimeout(() => {
scrollView.scrollResponderScrollNativeHandleToKeyboard(
reactNode,
extraHeight,
true
);
}, 220);
}
}

render() {
return (
<ScrollView
keyboardShouldPersistTaps={false}
ref="keyboardScrollView"
ref={this.keyboardAwareScrollviewRef}
keyboardDismissMode="interactive"
contentInset={{ bottom: this.state.keyboardSpace }}
showsVerticalScrollIndicator={true}
Expand Down
Loading