Skip to content

Instantly share code, notes, and snippets.

@whisher
Created October 4, 2018 07:48
Show Gist options
  • Save whisher/f00b66139cb6501de1adb8c76fbfa424 to your computer and use it in GitHub Desktop.
Save whisher/f00b66139cb6501de1adb8c76fbfa424 to your computer and use it in GitHub Desktop.
import React from 'react';
import classes from './Input.css';
const input = ( props ) => {
let inputElement = null;
const inputClasses = [classes.InputElement];
if (props.invalid && props.shouldValidate && props.touched) {
inputClasses.push(classes.Invalid);
}
switch ( props.elementType ) {
case ( 'input' ):
inputElement = <input
className={inputClasses.join(' ')}
{...props.elementConfig}
value={props.value}
onChange={props.changed} />;
break;
case ( 'textarea' ):
inputElement = <textarea
className={inputClasses.join(' ')}
{...props.elementConfig}
value={props.value}
onChange={props.changed} />;
break;
case ( 'select' ):
inputElement = (
<select
className={inputClasses.join(' ')}
value={props.value}
onChange={props.changed}>
{props.elementConfig.options.map(option => (
<option key={option.value} value={option.value}>
{option.displayValue}
</option>
))}
</select>
);
break;
default:
inputElement = <input
className={inputClasses.join(' ')}
{...props.elementConfig}
value={props.value}
onChange={props.changed} />;
}
return (
<div className={classes.Input}>
<label className={classes.Label}>{props.label}</label>
{inputElement}
</div>
);
};
export default input;
USAGE
class ContactData extends Component {
state = {
orderForm: {
name: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Your Name'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
},
street: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Street'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
},
zipCode: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'ZIP Code'
},
value: '',
validation: {
required: true,
minLength: 5,
maxLength: 5,
isNumeric: true
},
valid: false,
touched: false
},
country: {
elementType: 'input',
elementConfig: {
type: 'text',
placeholder: 'Country'
},
value: '',
validation: {
required: true
},
valid: false,
touched: false
},
email: {
elementType: 'input',
elementConfig: {
type: 'email',
placeholder: 'Your E-Mail'
},
value: '',
validation: {
required: true,
isEmail: true
},
valid: false,
touched: false
},
deliveryMethod: {
elementType: 'select',
elementConfig: {
options: [
{value: 'fastest', displayValue: 'Fastest'},
{value: 'cheapest', displayValue: 'Cheapest'}
]
},
value: 'fastest',
validation: {},
valid: true
}
},
formIsValid: false
}
orderHandler = ( event ) => {
event.preventDefault();
const formData = {};
for (let formElementIdentifier in this.state.orderForm) {
formData[formElementIdentifier] = this.state.orderForm[formElementIdentifier].value;
}
const order = {
ingredients: this.props.ings,
price: this.props.price,
orderData: formData
}
this.props.onOrderBurger(order);
}
checkValidity(value, rules) {
let isValid = true;
if (!rules) {
return true;
}
if (rules.required) {
isValid = value.trim() !== '' && isValid;
}
if (rules.minLength) {
isValid = value.length >= rules.minLength && isValid
}
if (rules.maxLength) {
isValid = value.length <= rules.maxLength && isValid
}
if (rules.isEmail) {
const pattern = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
isValid = pattern.test(value) && isValid
}
if (rules.isNumeric) {
const pattern = /^\d+$/;
isValid = pattern.test(value) && isValid
}
return isValid;
}
inputChangedHandler = (event, inputIdentifier) => {
const updatedOrderForm = {
...this.state.orderForm
};
const updatedFormElement = {
...updatedOrderForm[inputIdentifier]
};
updatedFormElement.value = event.target.value;
updatedFormElement.valid = this.checkValidity(updatedFormElement.value, updatedFormElement.validation);
updatedFormElement.touched = true;
updatedOrderForm[inputIdentifier] = updatedFormElement;
let formIsValid = true;
for (let inputIdentifier in updatedOrderForm) {
formIsValid = updatedOrderForm[inputIdentifier].valid && formIsValid;
}
this.setState({orderForm: updatedOrderForm, formIsValid: formIsValid});
}
render () {
const formElementsArray = [];
for (let key in this.state.orderForm) {
formElementsArray.push({
id: key,
config: this.state.orderForm[key]
});
}
let form = (
<form onSubmit={this.orderHandler}>
{formElementsArray.map(formElement => (
<Input
key={formElement.id}
elementType={formElement.config.elementType}
elementConfig={formElement.config.elementConfig}
value={formElement.config.value}
invalid={!formElement.config.valid}
shouldValidate={formElement.config.validation}
touched={formElement.config.touched}
changed={(event) => this.inputChangedHandler(event, formElement.id)} />
))}
<Button btnType="Success" disabled={!this.state.formIsValid}>ORDER</Button>
</form>
);
if ( this.props.loading ) {
form = <Spinner />;
}
return (
<div className={classes.ContactData}>
<h4>Enter your Contact Data</h4>
{form}
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment