Skip to content

Instantly share code, notes, and snippets.

@phoenixbox
Created July 9, 2016 07:02
Show Gist options
  • Save phoenixbox/d569a03fcc901f672a6a6fcea1c4ce5a to your computer and use it in GitHub Desktop.
Save phoenixbox/d569a03fcc901f672a6a6fcea1c4ce5a to your computer and use it in GitHub Desktop.
/*
Tcomb-Form
*/
import t from 'tcomb-form-native';
const Form = t.form.Form
var Contact = t.struct({
name: t.Str,
photo_url: t.Str
});
const Profile = t.struct({
first_name: t.String,
last_name: t.String,
contact: Contact
}
const formOptions = {
contact: {
factory: ContactRow
},
}
/*
Attempt to make a factory in the right way :)
*/
class ContactRow extends Textbox {
constructor (props) {
super(props);
const contact = props.value;
this.state = {
contact
}
}
getTemplate () {
let self = this;
return (locals) => {
const imageProps = {
resizeMode: 'contain',
source: require('./profilePlaceholder.png')
}
const username = this.props.value.name || 'Choose a contact...';
/*
When this TouchableHighlight onPress action is triggered...
The form emits a blank formField state to its onChange handler
{
first_name: '',
last_name: '',
contact: {
name: '',
photo_url: ''
}
}
This in effect wipes the state of the form
Im wondering how I can prevent this?
*/
return (
<TouchableHighlight onPress={() => {
/*
Here I navigate to a sibling route to show the contact list
which the user can then select from to set their contact
*/
Actions.contactList();
}}>
<View>
<Text>Contact</Text>
<View>
<View>
<Image {...imageProps} />
<Text>{username}</Text>
</View>
<View><Text> > </Text></View>
</View>
</View>
</TouchableHighlight>
);
}
}
}
/*
**** Profile Form Component ****
*/
const mapStateToProps = (state) => {
return {
formFields: state.profile.formFields
};
}
const mapDispatchToProps = (dispatch) => ({
actions: bindActionCreators(
{
updateProfileForm
},
dispatch
)
});
class ProfileForm extends Component {
constructor (props) {
this.state = {
formValues: {
first_name: '',
last_name: '',
contact: {}
}
}
}
componentWillMount() {
const {formFields} = this.props;
this.setFormState(formFields)
}
componentWillReceiveProps(props) {
const {formFields} = props;
this.setFormState(formFields)
}
setFormState(formFields) {
this.setState({
formValues: {
first_name: formFields.first_name,
last_name: formFields.last_name,
contact: formFields.contact
}
});
}
onChange(formValues) {
this.props.actions.updateProfileForm(formValues);
}
render () {
return (
<View style={{flex: 1}}>
<Form ref='form'
type={Profile}
value={this.state.formValues}
options={formOptions}
onChange={this.onChange.bind(this)}
/>
</View>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ProfileForm)
/*
**** ContactList Component ****
*/
class ContactList extends Component {
constructor(props) {
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([contactsArray]),
}
}
/*
How do I pass back this selection data to the parent form?
Currently I have:
> an action which dispatches the selection to the redux store
> the parent form is populated with this redux form state
*/
chooseContact(contact) {
this.props.actions.updateProfileForm({contact});
}
contactRow(contact) {
const imageProps = {
style: {
width: 30,
height: 30,
borderRadius: 15
},
resizeMode: 'contain',
source: {uri: contact.photo_url}
};
return (
<TouchableHighlight onPress={this.chooseContact.bind(this)}>
<Image {...imageProps} />
<Text>{contact.name}</Text>
</TouchableHighlight>
)
}
render() {
return (
/* Some searchbar el here */
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => {
this.contactRow(rowData);
}}
/>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment