Skip to content

Commit f4dd9fe

Browse files
author
Marco Cesarato
committed
Added InputText and moved to src, Improved some features
1 parent d7ad9d0 commit f4dd9fe

File tree

4 files changed

+741
-320
lines changed

4 files changed

+741
-320
lines changed

index.js

Lines changed: 3 additions & 318 deletions
Original file line numberDiff line numberDiff line change
@@ -1,322 +1,7 @@
1-
import React, {Component} from 'react';
2-
import {Animated, Easing, Keyboard, TextInput, TouchableOpacity} from 'react-native';
3-
import {Palette, Style, CleanStyle, DirtyStyle} from "./style";
4-
import validator from "validator";
5-
61
/**
7-
* Text Input Validator
2+
* react-native-input-validator
83
* @author Marco Cesarato <[email protected]>
94
*/
10-
class InputValidator extends Component {
11-
12-
/**
13-
* Constructor
14-
* @param props
15-
*/
16-
constructor(props) {
17-
super(props);
18-
19-
const value = this.parseValue(this.props.value);
20-
21-
this.state = {
22-
value: value,
23-
validated: true,
24-
dirty: (value || this.props.placeholder),
25-
inputStyle: {
26-
borderBottomColor: "#ccc"
27-
},
28-
};
29-
30-
this.style = this.state.dirty ? DirtyStyle : CleanStyle;
31-
32-
this.state.labelStyle = {
33-
fontSize: new Animated.Value(this.style.fontSize),
34-
top: new Animated.Value(this.style.top)
35-
};
36-
}
37-
38-
/**
39-
* Component did update
40-
* @param prevProps
41-
*/
42-
componentDidUpdate(prevProps) {
43-
const value = this.parseValue(this.props.value);
44-
if (!validator.isEmpty(value) && value !== this.state.value && prevProps.value !== value) {
45-
this.validate(value);
46-
}
47-
}
48-
49-
/**
50-
* Component did mount
51-
*/
52-
componentDidMount() {
53-
this.validate();
54-
}
55-
56-
/**
57-
* Get input type
58-
* @returns {string}
59-
*/
60-
getType(){
61-
return (this.props.type != null ? this.props.type : "");
62-
}
63-
64-
/**
65-
* Get Label Style
66-
* @returns {{fontSize: *|AnimatedValue|AnimatedImplementation.Value, top: *|AnimatedValue|AnimatedImplementation.Value}}
67-
*/
68-
getLabelStyle(){
69-
return {
70-
fontSize: new Animated.Value(this.state.style.fontSize),
71-
top: new Animated.Value(this.state.style.top)
72-
};
73-
}
74-
75-
/**
76-
* Null to empty
77-
* @param value
78-
* @returns string
79-
*/
80-
parseValue(value) {
81-
value = (value == null ? '' : value);
82-
value = String(value).trim();
83-
return value;
84-
}
85-
86-
/**
87-
* Is valid
88-
* @param _text
89-
* @returns {boolean}
90-
*/
91-
isValid(_text) {
92-
93-
let is_valid = true;
94-
const text = this.parseValue(_text != null ? _text : this.state.value).trim();
95-
96-
switch (this.getType()) {
97-
case "email":
98-
if (!validator.isEmail(text)) {
99-
is_valid = false;
100-
}
101-
break;
102-
case "phone":
103-
if (!validator.isMobilePhone(text, 'any')) {
104-
is_valid = false;
105-
}
106-
break;
107-
case "postal-code":
108-
if (!validator.isPostalCode(text, 'any')) {
109-
is_valid = false;
110-
}
111-
break;
112-
case "numeric":
113-
if (!validator.isInt(text)) {
114-
is_valid = false;
115-
}
116-
break;
117-
default:
118-
is_valid = !(this.props.required);
119-
}
120-
121-
if (validator.isEmpty(text)){
122-
is_valid = !(this.props.required);
123-
}
124-
125-
return is_valid;
126-
}
127-
128-
/**
129-
* Validate
130-
* @param _text
131-
*/
132-
validate(_text) {
133-
134-
let text = this.parseValue(_text != null ? _text : this.state.value);
135-
136-
this.setState({value: text, dirty: (text != null && !validator.isEmpty(text) || this.input.isFocused())});
137-
this.animate((text != null && !validator.isEmpty(text) || this.input.isFocused()));
138-
139-
let is_valid = this.isValid(text);
140-
141-
let labelStyle = {...this.state.labelStyle};
142-
let inputStyle = {...this.state.inputStyle};
143-
144-
if (is_valid === false) {
145-
inputStyle.borderBottomColor = Palette.dangerColor;
146-
labelStyle.color = Palette.dangerColor;
147-
} else if (text != null && !validator.isEmpty(text) && is_valid === true) {
148-
inputStyle.borderBottomColor = Palette.successColor;
149-
labelStyle.color = Palette.successColor;
150-
} else {
151-
inputStyle.borderBottomColor = "#ccc";
152-
labelStyle.color = "#AAA";
153-
}
154-
155-
this.setState({labelStyle: labelStyle, inputStyle: inputStyle, validated: is_valid});
156-
}
157-
158-
/**
159-
* Animate floating label
160-
* @param dirty
161-
*/
162-
animate(dirty) {
163-
let nextStyle = dirty ? DirtyStyle : CleanStyle;
164-
let labelStyle = this.state.labelStyle;
165-
let anims = Object.keys(nextStyle).map(prop => {
166-
return Animated.timing(
167-
labelStyle[prop],
168-
{
169-
toValue: nextStyle[prop],
170-
duration: 200
171-
},
172-
Easing.ease
173-
)
174-
});
175-
176-
Animated.parallel(anims).start()
177-
}
178-
179-
/**
180-
* Blur
181-
*/
182-
blur() {
183-
this.input.blur();
184-
Keyboard.dismiss();
185-
}
186-
187-
/**
188-
* On Focus
189-
* @param event
190-
* @param refName
191-
*/
192-
onFocus(event, refName) {
193-
this.animate(true);
194-
this.setState({dirty: true});
195-
if (this.props.onFocus) {
196-
this.props.onFocus(event, refName);
197-
}
198-
199-
}
200-
201-
/**
202-
* On Blur
203-
*/
204-
onBlur() {
205-
Keyboard.dismiss();
206-
if (this.state.value == null || validator.isEmpty(this.state.value)) {
207-
this.animate(false);
208-
this.setState({dirty: false});
209-
}
210-
if (this.props.onBlur) {
211-
this.props.onBlur(arguments);
212-
}
213-
}
214-
215-
/**
216-
* On Change Text
217-
* @param text
218-
*/
219-
onChangeText(text) {
220-
this.validate(text);
221-
if (this.props.onChangeText) {
222-
this.props.onChangeText(text);
223-
}
224-
}
225-
226-
/**
227-
* On ending Editing
228-
* @param event
229-
*/
230-
onEndEditing(event) {
231-
Keyboard.dismiss();
232-
if (this.props.onEndEditing) {
233-
this.props.onEndEditing(event);
234-
}
235-
}
236-
237-
/**
238-
* Render label
239-
* @returns {*}
240-
*/
241-
renderLabel() {
242-
return (
243-
<Animated.Text
244-
ref='label'
245-
pointerEvents={"none"}
246-
numberOfLines={this.props.numberOfLines}
247-
style={[Style.label, this.props.labelStyle, this.state.labelStyle]}>
248-
{this.props.children} {this.props.required ? "(*)" : ""}
249-
</Animated.Text>
250-
)
251-
}
252-
253-
/**
254-
* Render
255-
* @returns {*}
256-
*/
257-
render() {
258-
259-
let props = {
260-
...this.props,
261-
onBlur: this.onBlur.bind(this),
262-
onChangeText: this.onChangeText.bind(this),
263-
onEndEditing: this.onEndEditing.bind(this),
264-
onFocus: this.onFocus.bind(this),
265-
password: this.props.secureTextEntry || this.props.password, // Compatibility
266-
secureTextEntry: this.props.secureTextEntry || this.props.password, // Compatibility
267-
style: [Style.input, this.state.inputStyle],
268-
}, elementStyles = [Style.element];
269-
270-
if (this.props.inputStyle) {
271-
props.style.push(this.props.inputStyle);
272-
}
273-
274-
if (this.props.style) {
275-
elementStyles.push(this.props.style);
276-
}
277-
278-
let keyboardType = "default";
279-
280-
if (this.props.type) {
281-
switch (this.props.type) {
282-
case "email":
283-
keyboardType = "email-address";
284-
break;
285-
case "numeric":
286-
keyboardType = "numeric";
287-
break;
288-
case "phone":
289-
keyboardType = "phone-pad";
290-
break;
291-
}
292-
}
293-
294-
let onPress = props.onTouchStart;
295-
296-
delete props.children;
297-
delete props.placeholder;
298-
delete props.inputStyle;
299-
delete props.labelStyle;
300-
delete props.onTouchStart;
301-
302-
if (props.editable === false)
303-
props.pointerEvents = "none";
304-
305-
return (
306-
<View style={elementStyles}>
307-
{this.renderLabel()}
308-
<TextInput
309-
ref={(r) => {
310-
this.input = r;
311-
}}
312-
keyboardType={keyboardType}
313-
autoFocus={false}
314-
{...props}
315-
underlineColorAndroid={'transparent'}>
316-
</TextInput>
317-
</View>
318-
);
319-
}
320-
}
3215

322-
export default InputValidator;
6+
export {default as InputValidator} from "./src/InputValidator";
7+
export {default as InputText} from "./src/InputText";

0 commit comments

Comments
 (0)