From 37245e04833c5ff1edd4aa93fea65686c1fa2cda Mon Sep 17 00:00:00 2001 From: halit-ozsoy-2016400141 Date: Sat, 3 Mar 2018 15:29:03 +0300 Subject: [PATCH 1/4] added support for any input element, no need to import text input anymore needs testing --- form.js | 72 ++++++++++++++++++++++++++++++++++++++++++++------- index.js | 2 +- package.json | 5 +++- text-input.js | 20 ++++++++++++++ 4 files changed, 88 insertions(+), 11 deletions(-) diff --git a/form.js b/form.js index 271d713..fbf7bf9 100644 --- a/form.js +++ b/form.js @@ -7,21 +7,74 @@ export default class Form extends React.Component { this.inputs = []; } + defaultProps = { + inputElements: [ + { + names: [ + 'TextInput' + ], // names: 'TextInput' or name: 'TextInput' is also okay + submitFunctionNames: [ + 'onSubmitEditing' + ] // submitFunctionNames: 'onSubmitEditing' or submitFunctionName: 'onSubmitEditing' is also okay + focus: 'focus' + } + ] + } + + checkIfInput = (element) => { + for (let i = 0; i < this.props.inputElements.length; ++i) { + let names = []; + if (this.props.names) { + names = names.concat(this.props.names) + } + if (this.props.name) { + names .push(this.props.name); + } + if (names.includes(element.type.name)) { + return i; + } + } + return false; + } + + cloneElement = (element, index, inputInfo) => { + let functionNames = []; + if (inputInfo.submitFunctionNames) { + functionNames.concat(inputInfo.submitFunctionNames); + } + if (inputInfo.submitFunctionName) { + functionNames.concat(inputInfo.submitFunctionName); + } + let oldEnter = null; + for (let i = 0; i < functionNames.length && !oldEnter; ++i) { + oldEnter = element.props[functionNames[i]]; + } + const oldRef = element.props.ref; + const handleEnter = (...arg) => + this.inputs[index + 1] ? this.inputs[index + 1][inputInfo['focus']]() : oldEnter(...arg); + const handleRef = (ref, ...rest) => { + this.inputs[index] = ref; + if (oldRef) { + oldRef(ref, ...rest); + } + } + return React.cloneElement(element, + { onEnter: handleEnter, ref: handleRef ); + } + renderChildren(children, recursiveIndex = 0) { return React.Children.map(children, (child, index) => { if (child.props.children) return React.cloneElement(child, { - ...child.props, + ...child.props, children: this.renderChildren(child.props.children, index) }); - if (child.type.name !== 'TextInput') return child; - - let realIndex = index + recursiveIndex - return React.cloneElement(child, { - onEnter: () => - this.inputs[realIndex + 1] ? this.inputs[realIndex + 1].focus() : null, - inputRef: ref => (this.inputs[realIndex] = ref), - }); + const childType = this.checkIfInput(child); + if (childType === false) return child; + + const realIndex = index + recursiveIndex; + + return this.cloneElement(child, realIndex, this.props.inputElements[childType]); }); } @@ -34,3 +87,4 @@ export default class Form extends React.Component { ); } } + diff --git a/index.js b/index.js index e4bd23d..e990a4f 100644 --- a/index.js +++ b/index.js @@ -1,2 +1,2 @@ export { default as Form } from './form'; -export { default as TextInput } from './text-input'; +//export { default as TextInput } from './text-input'; diff --git a/package.json b/package.json index 9020ddf..586e066 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,8 @@ "bugs": { "url": "https://github.com/zackify/react-native-autofocus/issues" }, - "homepage": "https://github.com/zackify/react-native-autofocus#readme" + "homepage": "https://github.com/zackify/react-native-autofocus#readme", + "devDependencies": { + "prop-types": "^15.6.1" + } } diff --git a/text-input.js b/text-input.js index 0b60e06..7a4ea0c 100644 --- a/text-input.js +++ b/text-input.js @@ -1,6 +1,25 @@ +/* import React from 'react'; import { TextInput as Input } from 'react-native'; +export const InputBuilder = (Element, submitFunctionNames) => ({ onEnter, inputRef, ...props }) => { + const enterProp = {}; + const functionNamesArray = [].concat(submitFunctionNames); + for (let functionName of functionNamesArray) { + enterProp[functionName] = onEnter; + } + return ( + inputRef(ref) } + { ...enterProp, ...props } + /> + ); +} + + +const TextInput = InputBuilder(Input); + + const TextInput = ({ onSubmitEditing, onEnter, inputRef, ...props }) => ( inputRef(ref)} @@ -13,3 +32,4 @@ const TextInput = ({ onSubmitEditing, onEnter, inputRef, ...props }) => ( ); export default TextInput; +*/ From 352476e0aae3f08ccdfaf296bd33403183983bab Mon Sep 17 00:00:00 2001 From: halit-ozsoy-2016400141 Date: Sat, 3 Mar 2018 16:07:37 +0300 Subject: [PATCH 2/4] bug fixes --- form.js | 63 ++++++++++++++++++++++++++-------------------------- package.json | 5 +++-- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/form.js b/form.js index fbf7bf9..17dc345 100644 --- a/form.js +++ b/form.js @@ -2,40 +2,34 @@ import React from 'react'; import { View } from 'react-native'; export default class Form extends React.Component { - constructor() { - super(); + constructor(props) { + super(props); this.inputs = []; } - defaultProps = { - inputElements: [ + checkIfInput = element => { + const inputElements = this.props.inputElements || + [ { - names: [ - 'TextInput' - ], // names: 'TextInput' or name: 'TextInput' is also okay - submitFunctionNames: [ - 'onSubmitEditing' - ] // submitFunctionNames: 'onSubmitEditing' or submitFunctionName: 'onSubmitEditing' is also okay - focus: 'focus' - } - ] - } - - checkIfInput = (element) => { - for (let i = 0; i < this.props.inputElements.length; ++i) { + names: ['TextInput'], // names: 'TextInput' or name: 'TextInput' is also okay + submitFunctionNames: ['onSubmitEditing'], // submitFunctionNames: 'onSubmitEditing' or submitFunctionName: 'onSubmitEditing' is also okay + focus: 'focus', + }, + ]; + for (let input of inputElements) { let names = []; - if (this.props.names) { - names = names.concat(this.props.names) + if (input.names) { + names = names.concat(input.names); } - if (this.props.name) { - names .push(this.props.name); + if (input.name) { + names.push(input.name); } if (names.includes(element.type.name)) { - return i; + return input; } } return false; - } + }; cloneElement = (element, index, inputInfo) => { let functionNames = []; @@ -45,22 +39,27 @@ export default class Form extends React.Component { if (inputInfo.submitFunctionName) { functionNames.concat(inputInfo.submitFunctionName); } - let oldEnter = null; - for (let i = 0; i < functionNames.length && !oldEnter; ++i) { - oldEnter = element.props[functionNames[i]]; + const handleEnterBuilder = (oldEnter) => (...arg) => + this.inputs[index + 1] + ? this.inputs[index + 1][inputInfo['focus']]() + : oldEnter(...arg); + const submitFunctions = {}; + for (let func of functionNames) { + let oldFunc = element.props[func]; + submitFunctions[func] = handleEnterBuilder(oldFunc); } const oldRef = element.props.ref; - const handleEnter = (...arg) => - this.inputs[index + 1] ? this.inputs[index + 1][inputInfo['focus']]() : oldEnter(...arg); const handleRef = (ref, ...rest) => { this.inputs[index] = ref; if (oldRef) { oldRef(ref, ...rest); } - } - return React.cloneElement(element, - { onEnter: handleEnter, ref: handleRef ); - } + }; + return React.cloneElement(element, { + ...submitFunctions, + ref: handleRef, + }); + }; renderChildren(children, recursiveIndex = 0) { return React.Children.map(children, (child, index) => { diff --git a/package.json b/package.json index 586e066..daa939e 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "url": "https://github.com/zackify/react-native-autofocus/issues" }, "homepage": "https://github.com/zackify/react-native-autofocus#readme", - "devDependencies": { - "prop-types": "^15.6.1" + "dependencies": { + "react": "^16.2.0", + "react-native": "^0.54.0" } } From 7b1d45794b7929678ceb80822bd93a4edd61fcd7 Mon Sep 17 00:00:00 2001 From: halit-ozsoy-2016400141 Date: Sat, 3 Mar 2018 17:09:21 +0300 Subject: [PATCH 3/4] fixed bugs, and tested, added an example --- .idea/vcs.xml | 6 ++ example/demo1/.babelrc | 8 +++ example/demo1/.gitignore | 3 + example/demo1/.watchmanconfig | 1 + example/demo1/App.js | 57 +++++++++++++++++++ example/demo1/app.json | 21 +++++++ example/demo1/assets/icon.png | Bin 0 -> 2976 bytes example/demo1/assets/splash.png | Bin 0 -> 7178 bytes example/demo1/form.js | 94 ++++++++++++++++++++++++++++++++ example/demo1/package.json | 9 +++ form.js | 31 ++++++----- 11 files changed, 217 insertions(+), 13 deletions(-) create mode 100644 .idea/vcs.xml create mode 100644 example/demo1/.babelrc create mode 100644 example/demo1/.gitignore create mode 100644 example/demo1/.watchmanconfig create mode 100644 example/demo1/App.js create mode 100644 example/demo1/app.json create mode 100644 example/demo1/assets/icon.png create mode 100644 example/demo1/assets/splash.png create mode 100644 example/demo1/form.js create mode 100644 example/demo1/package.json diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/example/demo1/.babelrc b/example/demo1/.babelrc new file mode 100644 index 0000000..2bcd546 --- /dev/null +++ b/example/demo1/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": ["babel-preset-expo"], + "env": { + "development": { + "plugins": ["transform-react-jsx-source"] + } + } +} diff --git a/example/demo1/.gitignore b/example/demo1/.gitignore new file mode 100644 index 0000000..9f9e17e --- /dev/null +++ b/example/demo1/.gitignore @@ -0,0 +1,3 @@ +node_modules/**/* +.expo/* +npm-debug.* diff --git a/example/demo1/.watchmanconfig b/example/demo1/.watchmanconfig new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/example/demo1/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/example/demo1/App.js b/example/demo1/App.js new file mode 100644 index 0000000..da77e5f --- /dev/null +++ b/example/demo1/App.js @@ -0,0 +1,57 @@ +import React, { Component } from 'react'; + +import { View, TextInput, StyleSheet } from 'react-native'; +import { Constants } from 'expo'; + +import Form from './form'; + +export default class App extends Component { + state = { + inputValue1: 'You can change me!', + inputValue2: 'You can change me!', + inputValue3: 'You can change me!', + }; + + _handleTextChange = i => inputValue => { + const x = {}; + x[`inputValue${i}`] = inputValue; + this.setState(x); + }; + + render() { + return ( +
+ + + + + { console.log('poooop'); } } + /> + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + paddingTop: Constants.statusBarHeight, + backgroundColor: 'red', + } +}); \ No newline at end of file diff --git a/example/demo1/app.json b/example/demo1/app.json new file mode 100644 index 0000000..4ab6547 --- /dev/null +++ b/example/demo1/app.json @@ -0,0 +1,21 @@ +{ + "expo": { + "name": "demo1", + "description": "This project is really great.", + "slug": "demo1", + "privacy": "public", + "sdkVersion": "25.0.0", + "platforms": ["ios", "android"], + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "splash": { + "image": "./assets/splash.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "ios": { + "supportsTablet": true + } + } +} diff --git a/example/demo1/assets/icon.png b/example/demo1/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5bbc0ca199c3181d1f889011c7602e2daf51b9 GIT binary patch literal 2976 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 literal 0 HcmV?d00001 diff --git a/example/demo1/assets/splash.png b/example/demo1/assets/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..4f9ade699a4dc43aaf3c97ad983115cccd0e0640 GIT binary patch literal 7178 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 Fe*iU3xyt|m literal 0 HcmV?d00001 diff --git a/example/demo1/form.js b/example/demo1/form.js new file mode 100644 index 0000000..25bc30d --- /dev/null +++ b/example/demo1/form.js @@ -0,0 +1,94 @@ +import React from 'react'; +import { View } from 'react-native'; + +export default class Form extends React.Component { + constructor(props) { + super(props); + this.inputs = []; + } + + checkIfInput = element => { + const elemName = element.type.name || element.type.displayName; + const inputElements = this.props.inputElements || + [ + { + names: ['TextInput'], // names: 'TextInput' or name: 'TextInput' is also okay + submitFunctionNames: ['onSubmitEditing'], // submitFunctionNames: 'onSubmitEditing' or submitFunctionName: 'onSubmitEditing' is also okay + focus: 'focus', + }, + ]; + for (let input of inputElements) { + let names = []; + if (input.names) { + names = names.concat(input.names); + } + if (input.name) { + names.push(input.name); + } + console.log('z', names, elemName); + if (names.includes(elemName)) { + return input; + } + } + return false; + }; + + cloneElement = (element, index, inputInfo) => { + console.log('cloning'); + let functionNames = []; + if (inputInfo.submitFunctionNames) { + functionNames = functionNames.concat(inputInfo.submitFunctionNames); + } + if (inputInfo.submitFunctionName) { + functionNames = functionNames.concat(inputInfo.submitFunctionName); + } + const handleEnterBuilder = (oldEnter) => (...arg) => + this.inputs[index + 1] + ? this.inputs[index + 1][inputInfo['focus']]() + : oldEnter(...arg); + const submitFunctions = {}; + for (let func of functionNames) { + let oldFunc = element.props[func]; + submitFunctions[func] = handleEnterBuilder(oldFunc); + } + const oldRef = element.props.ref; + const handleRef = (ref, ...rest) => { + this.inputs[index] = ref; + if (oldRef) { + oldRef(ref, ...rest); + } + }; + return React.cloneElement(element, { + ...submitFunctions, + ref: handleRef, + }); + }; + + renderChildren(children, recursiveIndex = 0) { + console.log('renderChildren', children.length); + return React.Children.map(children, (child, index) => { + //return children.map((child, index) => { + if (child.props.children) + return React.cloneElement(child, { + ...child.props, + children: this.renderChildren(child.props.children, index) + }); + const childType = this.checkIfInput(child); + console.log(childType); + if (childType === false) return child; + console.log('action'); + const realIndex = index + recursiveIndex; + return this.cloneElement(child, realIndex, childType); + }); + } + + render() { + let { children, ...props } = this.props; + return ( + + {this.renderChildren(children)} + + ); + } +} + diff --git a/example/demo1/package.json b/example/demo1/package.json new file mode 100644 index 0000000..cc2c527 --- /dev/null +++ b/example/demo1/package.json @@ -0,0 +1,9 @@ +{ + "main": "node_modules/expo/AppEntry.js", + "private": true, + "dependencies": { + "expo": "^25.0.0", + "react": "16.2.0", + "react-native": "https://github.com/expo/react-native/archive/sdk-25.0.0.tar.gz" + } +} diff --git a/form.js b/form.js index 17dc345..221b7be 100644 --- a/form.js +++ b/form.js @@ -8,14 +8,15 @@ export default class Form extends React.Component { } checkIfInput = element => { + const elemName = element.type.name || element.type.displayName; const inputElements = this.props.inputElements || - [ - { - names: ['TextInput'], // names: 'TextInput' or name: 'TextInput' is also okay - submitFunctionNames: ['onSubmitEditing'], // submitFunctionNames: 'onSubmitEditing' or submitFunctionName: 'onSubmitEditing' is also okay - focus: 'focus', - }, - ]; + [ + { + names: ['TextInput'], // names: 'TextInput' or name: 'TextInput' is also okay + submitFunctionNames: ['onSubmitEditing'], // submitFunctionNames: 'onSubmitEditing' or submitFunctionName: 'onSubmitEditing' is also okay + focus: 'focus', + }, + ]; for (let input of inputElements) { let names = []; if (input.names) { @@ -24,7 +25,8 @@ export default class Form extends React.Component { if (input.name) { names.push(input.name); } - if (names.includes(element.type.name)) { + console.log('z', names, elemName); + if (names.includes(elemName)) { return input; } } @@ -32,12 +34,13 @@ export default class Form extends React.Component { }; cloneElement = (element, index, inputInfo) => { + console.log('cloning'); let functionNames = []; if (inputInfo.submitFunctionNames) { - functionNames.concat(inputInfo.submitFunctionNames); + functionNames = functionNames.concat(inputInfo.submitFunctionNames); } if (inputInfo.submitFunctionName) { - functionNames.concat(inputInfo.submitFunctionName); + functionNames = functionNames.concat(inputInfo.submitFunctionName); } const handleEnterBuilder = (oldEnter) => (...arg) => this.inputs[index + 1] @@ -62,18 +65,20 @@ export default class Form extends React.Component { }; renderChildren(children, recursiveIndex = 0) { + console.log('renderChildren', children.length); return React.Children.map(children, (child, index) => { + //return children.map((child, index) => { if (child.props.children) return React.cloneElement(child, { ...child.props, children: this.renderChildren(child.props.children, index) }); const childType = this.checkIfInput(child); + console.log(childType); if (childType === false) return child; - + console.log('action'); const realIndex = index + recursiveIndex; - - return this.cloneElement(child, realIndex, this.props.inputElements[childType]); + return this.cloneElement(child, realIndex, childType); }); } From 14e7204e06adfbc944f96402b5b04295a55db9fd Mon Sep 17 00:00:00 2001 From: halit-ozsoy-2016400141 Date: Sat, 3 Mar 2018 17:23:54 +0300 Subject: [PATCH 4/4] added keyboardavoidingview --- example/demo1/App.js | 55 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/example/demo1/App.js b/example/demo1/App.js index da77e5f..4435fe7 100644 --- a/example/demo1/App.js +++ b/example/demo1/App.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; -import { View, TextInput, StyleSheet } from 'react-native'; +import { View, TextInput, StyleSheet, KeyboardAvoidingView } from 'react-native'; import { Constants } from 'expo'; import Form from './form'; @@ -20,28 +20,30 @@ export default class App extends Component { render() { return ( -
- - - - - { console.log('poooop'); } } - /> - + +
+ + + + + { console.log('poooopie'); } } + /> + +
); } } @@ -49,9 +51,12 @@ export default class App extends Component { const styles = StyleSheet.create({ container: { flex: 1, - alignItems: 'center', - justifyContent: 'center', paddingTop: Constants.statusBarHeight, backgroundColor: 'red', + }, + form: { + flex: 1, + alignItems: 'center', + justifyContent: 'space-between' } }); \ No newline at end of file