Skip to content

Instantly share code, notes, and snippets.

@jonlong
Created March 20, 2016 12:35
Show Gist options
  • Save jonlong/4419a6105b3c4d59309c to your computer and use it in GitHub Desktop.
Save jonlong/4419a6105b3c4d59309c to your computer and use it in GitHub Desktop.
import React, {
Alert,
Component,
StyleSheet,
Text,
View,
TextInput,
PropTypes,
addons
} from 'react-native';
import _ from 'lodash';
import cairn from 'cairn';
import tinycolor2 from 'tinycolor2';
import emojiRegex from 'emoji-regex';
import validate from 'validate.js';
import errorFormatter from '../utils/validators/errorFormatter';
import style from '../styles/details';
import CloseDetailsButton from './CloseDetailsButton';
import Button from './shared/Button';
import { Map } from 'immutable';
import { Actions as RouterActions } from 'react-native-router-flux';
// Emoji Validator
validate.validators.emoji = require('../utils/validators/emoji');
/**
* Error Messages
*/
const errorMessages = errorFormatter({
name: {
emoji: 'Sorry, we don\'t support emoji yet!',
length: 'This name is too long',
required: 'You need to set Gram\'s name'
}
});
/**
* Validators
*/
var validationRules = {
name: {
presence: {
message: errorMessages.name.required
},
emoji: {
message: errorMessages.name.emoji
},
length: {
maximum: 20,
tooLong: errorMessages.name.length
}
}
};
/**
* Component
*/
class GramsName extends Component {
/**
* PropTypes
*/
static propTypes = {
gramsDetails: PropTypes.instanceOf(Map).isRequired,
setGramsDetail: PropTypes.func.isRequired
};
constructor(props) {
super(props);
// Inital State
this.state = {
form: {
name: this.props.gramsDetails.get('name') || '',
errors: []
}
};
}
handleValidation() {
const form = this.state.form;
const errors = validate(form, validationRules);
let errorState = addons.update(this.state, {
form: {
errors: { $set: errors || []}
}
});
this.setState(errorState);
return errors;
}
handleSubmit() {
const form = this.state.form;
const errors = this.handleValidation();
if (!errors) {
// set value in stores
}
return errors;
}
handleContinue() {
const errors = this.handleSubmit();
if (!errors) {
// Go to next scene
}
}
render() {
const formErrors = this.state.form.errors;
// Build JSX elements for the errors
const errorElements = _.flatMap(formErrors, (errs, parentId) => {
return _.map(errs, (err, childId) => {
return <Text key={ parentId + childId }>{ err }</Text>;
})
});
return (
<View { ...style('container') }>
<CloseDetailsButton { ...style('close') } />
<Text { ...style('header') }>What Do You Call Your Gram?</Text>
{ errorElements }
{/*
<TextInput> is the bit that I want to refactor. Right now I'd like this to be
a higher-order component, but I'm not sure how to manage the state,
as my validation checks the state of the entire form on submit right now.
*/}
<TextInput
{ ...style('input.noLabel inputError?', 'name' in formErrors) }
onChangeText={ (text) => {
let nameState = addons.update(this.state, {
form: {
name: { $set: text }
}
});
this.setState(nameState);
}}
value={ this.state.form.name }
onSubmitEditing={ this.handleSubmit.bind(this) }
/>
<Button
onPress={ this.handleContinue.bind(this)}
text="Continue"
/>
</View>
);
}
}
module.exports = GramsName;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment