-
-
Save sibelius/c564ded5bfd39534cf035e0460f2ee9a to your computer and use it in GitHub Desktop.
| import React from 'react'; | |
| import { | |
| View, | |
| Text, | |
| } from 'react-native'; | |
| import { TextInputMask } from 'react-native-masked-text' | |
| export default function maskedInputTemplate(locals) { | |
| if (locals.hidden) { | |
| return null; | |
| } | |
| const stylesheet = locals.stylesheet; | |
| let formGroupStyle = stylesheet.formGroup.normal; | |
| let controlLabelStyle = stylesheet.controlLabel.normal; | |
| let textboxStyle = stylesheet.textbox.normal; | |
| let helpBlockStyle = stylesheet.helpBlock.normal; | |
| const errorBlockStyle = stylesheet.errorBlock; | |
| if (locals.hasError) { | |
| formGroupStyle = stylesheet.formGroup.error; | |
| controlLabelStyle = stylesheet.controlLabel.error; | |
| textboxStyle = stylesheet.textbox.error; | |
| helpBlockStyle = stylesheet.helpBlock.error; | |
| } | |
| if (locals.editable === false) { | |
| textboxStyle = stylesheet.textbox.notEditable; | |
| } | |
| const label = locals.label ? <Text style={controlLabelStyle}>{locals.label}</Text> : null; | |
| const help = locals.help ? <Text style={helpBlockStyle}>{locals.help}</Text> : null; | |
| const error = locals.hasError && locals.error ? <Text accessibilityLiveRegion="polite" style={errorBlockStyle}>{locals.error}</Text> : null; | |
| let maskType = 'money'; | |
| let maskOptions = {}; | |
| if (locals.config) { | |
| if (locals.config.mask) { | |
| maskType = locals.config.mask; | |
| } | |
| if (locals.config.options) { | |
| maskOptions = locals.config.options; | |
| } | |
| } | |
| return ( | |
| <View style={formGroupStyle}> | |
| {label} | |
| <TextInputMask | |
| type={maskType} | |
| options={maskOptions} | |
| accessibilityLabel={locals.label} | |
| ref="input" | |
| autoCapitalize={locals.autoCapitalize} | |
| autoCorrect={locals.autoCorrect} | |
| autoFocus={locals.autoFocus} | |
| blurOnSubmit={locals.blurOnSubmit} | |
| editable={locals.editable} | |
| keyboardType={locals.keyboardType} | |
| maxLength={locals.maxLength} | |
| multiline={locals.multiline} | |
| onBlur={locals.onBlur} | |
| onEndEditing={locals.onEndEditing} | |
| onFocus={locals.onFocus} | |
| onLayout={locals.onLayout} | |
| onSelectionChange={locals.onSelectionChange} | |
| onSubmitEditing={locals.onSubmitEditing} | |
| placeholderTextColor={locals.placeholderTextColor} | |
| secureTextEntry={locals.secureTextEntry} | |
| selectTextOnFocus={locals.selectTextOnFocus} | |
| selectionColor={locals.selectionColor} | |
| numberOfLines={locals.numberOfLines} | |
| underlineColorAndroid={locals.underlineColorAndroid} | |
| clearButtonMode={locals.clearButtonMode} | |
| clearTextOnFocus={locals.clearTextOnFocus} | |
| enablesReturnKeyAutomatically={locals.enablesReturnKeyAutomatically} | |
| keyboardAppearance={locals.keyboardAppearance} | |
| onKeyPress={locals.onKeyPress} | |
| returnKeyType={locals.returnKeyType} | |
| selectionState={locals.selectionState} | |
| onChangeText={(value) => locals.onChange(value)} | |
| onChange={locals.onChangeNative} | |
| placeholder={locals.placeholder} | |
| style={textboxStyle} | |
| value={locals.value} | |
| /> | |
| {help} | |
| {error} | |
| </View> | |
| ); | |
| } |
This worked really well for me. However, I wanted the value that was submitted in my form to be different than the value in the masked input. I ended up wrapping this template inside of a factory and using a transformer to change the value when the form is submitted. My particular application was a phone number. For anyone else that has used this they can use the below code as a reference. I am open to suggestions for different ways to achieve this as well.
Options for the form:
phoneNumber: {
factory: MaskedInputFactory,
transformer: {
format: (value) => value,
parse: (str) => str ? phoneFormatter.normalize(str) : '',
},
config: {
mask: 'custom',
options:{
mask: '(999)-999-9999',
}
},
},
Relevant snippet from the factory definition
import tcomb from "tcomb-form-native"
var Component = tcomb.form.Component;
export default class MaskedInputFactory extends Component {
getTemplate() {
return MaskedInputTemplate
}
}
you can use getRawValue of TextInputMask
@sibelius, any example how to use getRawValue?
@alfarioekaputra one way to use getRawValue is in your factory. You can use the getLocals to modify onChange so it returns the raw value.
export default class MaskedInputFactory extends Component {
getTemplate() {
return MaskedInputTemplate
}
getLocals() {
const locals = super.getLocals();
const { onChange } = locals;
// eslint-disable-next-line react/no-string-refs
locals.onChange = () => onChange(this.refs.input.getRawValue());
return locals;
}Since you're using a custom mask you'll need to define a custom getRawValue which takes the place of the transformer
phoneNumber: {
factory: MaskedInputFactory,
config: {
mask: 'custom',
options:{
mask: '(999)-999-9999',
getRawValue: (str) => str ? phoneFormatter.normalize(str) : '',
}
},
},
@sibelius, how to get the ref of a masked field?
@sibelius, how to get the ref of a masked field?
anyone can solve this?
when value is already fill (default value) from tcomb-form-native, when submit value from mask is null, how to solve this?
Use Formik instead
Use Formik instead
mean use transformers and factory from tcomb-form-native?
Usage