├── .gitignore ├── LICENSE ├── README.md ├── components ├── input.js └── switch.js ├── demo.gif ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Yuhao Ju 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fastui-form 2 | 3 | A form component built with React Native. **All components as seen in [fastui](https://github.com/roscoe054/fastui).** 4 | 5 | ![alt tag](https://raw.githubusercontent.com/roscoe054/fastui-form/master/demo.gif) 6 | 7 | ## Setup 8 | ``` 9 | npm install fastui-form 10 | ``` 11 | 12 | ## Example 13 | ```javascript 14 | 'use strict'; 15 | 16 | var React = require('react-native'); 17 | var f = require('fastui-form'); 18 | 19 | var { 20 | View, 21 | AppRegistry, 22 | StyleSheet, 23 | Text, 24 | TouchableHighlight, 25 | } = React; 26 | 27 | var model = { 28 | studentName: { 29 | type: f.fieldType.String, 30 | label: "学生姓名", 31 | value: "Giulio", 32 | disabled: true, 33 | placeholder: "请填写姓名" 34 | }, 35 | age: { 36 | type: f.fieldType.Number, 37 | label: "年龄", 38 | value: 18, 39 | placeholder: "请填写年龄" 40 | }, 41 | password: { 42 | type: f.fieldType.Password, 43 | label: "密码", 44 | value: "", 45 | placeholder: "请填写密码" 46 | }, 47 | year: { 48 | type: f.fieldType.Spinner, 49 | label: "入学年份", 50 | value: "2015", 51 | }, 52 | rememberMe: { 53 | type: f.fieldType.Boolean, 54 | label: "记住我", 55 | value: true, 56 | } 57 | }, 58 | Form = f.Form 59 | 60 | var xform = React.createClass({ 61 | render: function() { 62 | return ( 63 | 64 |
65 | 66 | 提交 67 | 68 | 69 | ); 70 | }, 71 | onPress : function() { 72 | var value = this.refs.form.getValue(); 73 | if (value) { 74 | alert(JSON.stringify(value)); 75 | } 76 | }, 77 | }); 78 | 79 | var styles = StyleSheet.create({ 80 | container: { 81 | flex: 1, 82 | backgroundColor: '#f2f2f2', 83 | paddingTop: 30, 84 | paddingLeft: 10, 85 | paddingRight: 10, 86 | }, 87 | button: { 88 | marginTop: 10, 89 | paddingTop: 10, 90 | paddingBottom: 10, 91 | paddingLeft: 10, 92 | paddingRight: 10, 93 | borderRadius: 5, 94 | alignItems: 'center', 95 | backgroundColor: '#26B4D3', 96 | }, 97 | buttonText: { 98 | fontSize: 17, 99 | color: '#fff', 100 | } 101 | }); 102 | 103 | AppRegistry.registerComponent('xform', () => xform); 104 | ``` 105 | -------------------------------------------------------------------------------- /components/input.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var React = require('react-native') 4 | 5 | var {TextInput, StyleSheet,} = React 6 | 7 | var Input = React.createClass({ 8 | getInitialState() { 9 | return { 10 | value: this.props.value, 11 | }; 12 | }, 13 | render() { 14 | return ( 15 | this.setState({value: value})} 18 | editable={this.props.editable} 19 | secureTextEntry={this.props.type === "password"} 20 | placeholder={this.props.placeholder} 21 | /> 22 | ); 23 | }, 24 | getValue: function(){ 25 | return this.props.type === "string" ? this.state.value : Number(this.state.value) 26 | } 27 | }) 28 | 29 | var styles = StyleSheet.create({ 30 | input: { 31 | height: 32, 32 | paddingTop: 8, 33 | paddingBottom: 8, 34 | paddingLeft: 7, 35 | paddingRight: 7, 36 | borderWidth: 1, 37 | borderRadius: 3, 38 | borderColor: '#ccc', 39 | color: '#333', 40 | fontSize: 17, 41 | }, 42 | disabled: { 43 | color: '#aaa' 44 | }, 45 | }) 46 | 47 | module.exports = Input 48 | -------------------------------------------------------------------------------- /components/switch.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var React = require('react-native') 4 | 5 | var {SwitchIOS,} = React 6 | 7 | var Switch = React.createClass({ 8 | getInitialState() { 9 | return { 10 | value: this.props.value, 11 | disabled: this.props.disabled 12 | }; 13 | }, 14 | render() { 15 | return ( 16 | this.setState({value: value})} 18 | disabled={this.props.disabled} 19 | /> 20 | ); 21 | }, 22 | getValue: function(){ 23 | return this.state.value 24 | } 25 | }) 26 | 27 | module.exports = Switch 28 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuhaoju/fastui-form/c1195c0cfc93f5ef7e7c4620d91bcdbfd3b915bc/demo.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | var React = require('react-native') 4 | var extend = require('extend') 5 | 6 | // common components 7 | var Switch = require('./components/switch'); 8 | var Input = require('./components/input'); 9 | 10 | // custom components 11 | var Spinner = require('react-native-spinner'); 12 | 13 | var {StyleSheet, Text, View, TouchableOpacity, TextInput, SwitchIOS,} = React 14 | 15 | var fieldType = { 16 | String: "string", 17 | Number: "number", 18 | Boolean: "boolean", 19 | Spinner: "spinner", 20 | Password: "password", 21 | }, rowId = 0 22 | 23 | var inited = false 24 | var Form = React.createClass({ 25 | getInitialState: function () { 26 | return {} 27 | }, 28 | getDefaultProps: function () { 29 | return {} 30 | }, 31 | componentDidMount: function(){ 32 | inited = true 33 | }, 34 | render: function () { 35 | var model = this.props.model, 36 | values = this.props.value, 37 | rows = [], 38 | defaultRowModel = { 39 | style: {}, 40 | disabled: false, 41 | } 42 | 43 | for (var i in model) { 44 | var rowModel = extend(true, {}, defaultRowModel, model[i]), 45 | rowContent = null 46 | 47 | switch (rowModel.type) { 48 | case "number": 49 | case "string": 50 | case "password": 51 | rowContent = 59 | break; 60 | case "boolean": 61 | rowContent = 67 | break; 68 | case "spinner": 69 | rowContent = 75 | break; 76 | default: 77 | } 78 | 79 | rows.push( 80 | 81 | {rowModel.label} 82 | {rowContent} 83 | 84 | ) 85 | } 86 | 87 | return ( 88 | 89 | {rows} 90 | 91 | ) 92 | }, 93 | getValue: function(){ 94 | var values = {} 95 | for(var i in this.refs){ 96 | var row = this.refs[i] 97 | if(row.getValue){ 98 | values[row.props.name] = row.getValue() 99 | } 100 | } 101 | console.log(values); 102 | return values 103 | } 104 | }) 105 | 106 | var styles = StyleSheet.create({ 107 | container: { 108 | paddingTop: 2, 109 | paddingBottom: 12, 110 | paddingLeft: 8, 111 | paddingRight: 8, 112 | backgroundColor: '#fff', 113 | }, 114 | label: { 115 | marginBottom: 5, 116 | fontWeight: 'bold', 117 | fontSize: 15, 118 | }, 119 | formRow: { 120 | marginTop: 10, 121 | }, 122 | }) 123 | 124 | module.exports = { 125 | Form: Form, 126 | fieldType: fieldType 127 | } 128 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fastui-form", 3 | "version": "0.0.2", 4 | "description": "基于React Native的form表单", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "\"echo \\\"Error: no test specified\\\" && exit 1\"" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/roscoe054/fastui-form.git" 12 | }, 13 | "keywords": [ 14 | "form", 15 | "react native" 16 | ], 17 | "author": "roscoe054", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/roscoe054/fastui-form/issues" 21 | }, 22 | "homepage": "https://github.com/roscoe054/fastui-form", 23 | "dependencies": { 24 | "extend": "^3.0.0", 25 | "react-native-spinner": "0.0.3" 26 | } 27 | } 28 | --------------------------------------------------------------------------------