React ve Redux kullanarak çok adımlı bir kayıt formu oluşturmaya çalışıyorum. aşağıdaki gibiKontrol edilecek tipte metinlerin kontrolsüz girişi uyarı
ana bileşenidir: Bazı basit doğrulama eklemeyi deneyin ve benim ana bileşende doğrulama işlevini ekledik
import React from 'react';
import Button from '../../common/formElements/button';
import RegistrationFormHeader from './registrationFormHeader';
import TextInput from '../../common/formElements/textInput';
import SelectInput from '../../common/formElements/selectInput';
const RegistrationFormStepOne = ({user, onChange, onButtonClick, errors, currentLanguage, countries}) => {
const language = currentLanguage;
return (
<div className="contact_form">
<form role="form" action="" method="post" id="contact_form">
<div className="row">
<RegistrationFormHeader activeTab={0} currentLanguage={language}/>
<div className="hideOnBigScreens descBox">
<div className="headerTitle">{language.businessInfoConfig}</div>
<div className="titleDesc">{language.businessBoxDesc}</div>
</div>
<div className="col-lg-12">
<h6 className="registrationFormDesc col-lg-10 col-lg-offset-1 col-lg-offset-right-2 col-xs-12">
{language.businessDesc}
</h6>
<div className="clearfix"></div>
<div className="col-sm-6">
<TextInput
type="text"
name="companyName"
label={language.companyNameLabel}
labelClass="control-label"
placeholder={language.companyNameLabel}
className="templateInput"
id="company"
onChange={onChange}
value={user.companyName}
errors={errors.companyName}
/>
</div>
<div className="col-sm-6">
<TextInput
type="text"
name="btwNumber"
label={language.vatNumberLabel}
placeholder={language.vatNumberLabel}
className="templateInput"
id="btwNumber"
onChange={onChange}
value={user.btwNumber}
errors={errors.btwNumber}
/>
</div>
<div className="col-sm-12" style={{marginBottom: 25}}>
<TextInput
type="text"
name="address"
label={language.addressLabel}
placeholder={language.address1Placeholder}
className="templateInput"
id="address"
onChange={onChange}
value={user.address}
errors={errors.address}
/>
</div>
<div className="col-sm-12" style={{marginBottom: 25}}>
<TextInput
type="text"
name="address1"
placeholder={language.address2Placeholder}
className="templateInput"
id="address"
onChange={onChange}
value={user.address1}
errors=""
/>
</div>
<div className="col-sm-12">
<TextInput
type="text"
name="address2"
placeholder={language.address3Placeholder}
className="templateInput"
id="address"
onChange={onChange}
value={user.address2}
errors=""
/>
</div>
<div className="col-sm-3">
<SelectInput name="country"
label={language.selectCountryLabel}
onChange={onChange}
options={countries}
className="templateInput selectField"
defaultOption={language.selectCountry}
value={user.country}
errors={errors.country}
/>
</div>
<div className="col-sm-3">
<TextInput
type="text"
name="zipcode"
label={language.zipcodeLabel}
placeholder={language.zipcodeLabel}
className="templateInput"
id="zipcode"
onChange={onChange}
value={user.zipcode}
errors={errors.zipcode}
/>
</div>
<div className="col-sm-6">
<TextInput
type="text"
name="place"
label={language.placeLabel}
placeholder={language.placeLabel}
className="templateInput"
id="place"
onChange={onChange}
value={user.place}
errors={errors.place}
/>
</div>
</div>
<div className="clearfix"></div>
<div className="col-lg-12" style={{marginLeft: 15, marginTop: 30}}>
<Button onClick={onButtonClick.bind(this)}
name="stepOneNext"
value={language.btnNext}
icon="arrow-circle-right"
style={{margin: '0 auto 60px'}}/>
</div>
</div>
</form>
</div>
);
};
export default RegistrationFormStepOne;
şöyle
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as actionCreators from '../../actions/actionCreators';
import countries from '../../data/countries';
import RegistrationFormStepOne from './registrationFormStepOne';
import RegistrationFormStepTwo from './registrationFormStepTwo';
import RegistrationFormStepThree from './registrationFormStepThree';
import RegistrationFormStepFour from './registrationFormStepFour';
class RegistrationPage extends React.Component {
constructor(props) {
super(props);
this.state = {
user: Object.assign({}, this.props.userData),
fileNames: {},
selectedFile: {},
icons: {
idCard: 'upload',
statuten: 'upload',
blankLetterhead: 'upload',
companyPhoto: 'upload'
},
step: 1,
errors: {}
};
this.setUser = this.setUser.bind(this);
this.onButtonClick = this.onButtonClick.bind(this);
this.onButtonPreviousClick = this.onButtonPreviousClick.bind(this);
this.changeCheckboxState = this.changeCheckboxState.bind(this);
this.onFileChange = this.onFileChange.bind(this);
this.routerWillLeave = this.routerWillLeave.bind(this);
}
componentDidMount() {
this.context.router.setRouteLeaveHook(this.props.route, this.routerWillLeave);
}
routerWillLeave(nextLocation) {
if (this.state.step > 1) {
this.setState({step: this.state.step - 1});
return false;
}
}
getCountries(){
return countries;
}
setUser(event) {
const field = event.target.name;
const value = event.target.value;
let user = this.state.user;
user[field] = value;
this.setState({user: user});
}
validation(){
const user = this.state.user;
const languageReg = this.props.currentLanguage.default.registrationPage;
let formIsValid = true;
let errors = {};
if(!user.companyName){
formIsValid = false;
errors.companyName = languageReg.companyNameEmpty;
}
if(!user.btwNumber){
formIsValid = false;
errors.btwNumber = languageReg.btwNumberEmpty;
}
if(!user.address){
formIsValid = false;
errors.address = languageReg.addressEmpty;
}
if(!user.country){
formIsValid = false;
errors.country = languageReg.countryEmpty;
}
if(!user.zipcode){
formIsValid = false;
errors.zipcode = languageReg.zipcodeEmpty;
}
if(!user.place){
formIsValid = false;
errors.place = languageReg.placeEmpty;
}
if(!user.firstName){
formIsValid = false;
errors.firstName = languageReg.firstnameEmpty;
}
this.setState({errors: errors});
return formIsValid;
}
onFileChange(name, event) {
event.preventDefault();
let file = event.target.value;
let filename = file.split('\\').pop(); //We get only the name of the file
let filenameWithoutExtension = filename.replace(/\.[^/.]+$/, ""); //We get the name of the file without extension
let user = this.state.user;
let fileNames = this.state.fileNames;
let selectedFile = this.state.selectedFile;
let icons = this.state.icons;
switch (name.btnName) {
case "idCard" :
fileNames[name.btnName] = filenameWithoutExtension;
//Check if file is selected
if(file){
selectedFile[name.btnName] = "fileSelected";
user["idCardFile"] = true;
icons["idCard"] = "check";
}else{
selectedFile[name.btnName] = "";
user["idCardFile"] = false;
icons["idCard"] = "upload";
}
break;
case "statuten" :
fileNames[name.btnName] = filenameWithoutExtension;
//Check if file is selected
if(file){
selectedFile[name.btnName] = "fileSelected";
user["statutenFile"] = true;
icons["statuten"] = "check";
}else{
selectedFile[name.btnName] = "";
user["statutenFile"] = false;
icons["statuten"] = "upload";
}
break;
case "blankLetterhead" :
fileNames[name.btnName] = filenameWithoutExtension;
//Check if file is selected
if(file){
selectedFile[name.btnName] = "fileSelected";
user["blankLetterheadFile"] = true;
icons["blankLetterhead"] = "check";
}else{
selectedFile[name.btnName] = "";
user["blankLetterheadFile"] = false;
icons["blankLetterhead"] = "upload";
}
break;
default:
fileNames[name.btnName] = filenameWithoutExtension;
//Check if file is selected
if(file){
selectedFile[name.btnName] = "fileSelected";
user["companyPhotoFile"] = true;
icons["companyPhoto"] = "check";
}else{
selectedFile[name.btnName] = "";
user["companyPhotoFile"] = false;
icons["companyPhoto"] = "upload";
}
}
this.setState({user: user, fileNames: fileNames, selectedFile: selectedFile, icons: icons});
}
changeCheckboxState(event) {
let chcName = event.target.name;
let user = this.state.user;
switch (chcName) {
case "chcEmailNotificationsYes":
user["emailNotifications"] = event.target.checked;
break;
case "chcEmailNotificationsNo":
user["emailNotifications"] = !event.target.checked;
break;
case "chcTerms":
if(typeof this.state.user.terms === "undefined"){
user["terms"] = false;
}else{
user["terms"] = !this.state.user.terms;
}
break;
case "chcSmsYes":
user["smsNotifications"] = event.target.checked;
break;
default:
user["smsNotifications"] = !event.target.checked;
}
this.setState({user: user});
this.props.actions.userRegistration(this.state.user);
}
onButtonClick(name, event) {
event.preventDefault();
this.props.actions.userRegistration(this.state.user);
switch (name) {
case "stepFourConfirmation":
this.setState({step: 1});
break;
case "stepTwoNext":
this.setState({step: 3});
break;
case "stepThreeFinish":
this.setState({step: 4});
break;
default:
if(this.validation()) {
this.setState({step: 2});
}
}
}
onButtonPreviousClick(){
this.setState({step: this.state.step - 1});
}
render() {
const languageReg = this.props.currentLanguage.default.registrationPage;
console.log(this.state.user);
let formStep = '';
let step = this.state.step;
switch (step) {
case 1:
formStep = (<RegistrationFormStepOne user={this.props.userData}
onChange={this.setUser}
onButtonClick={this.onButtonClick}
countries={this.getCountries(countries)}
errors={this.state.errors}
step={step}/>);
break;
case 2:
formStep = (<RegistrationFormStepTwo user={this.props.userData}
onChange={this.setUser}
onButtonClick={this.onButtonClick}
onButtonPreviousClick={this.onButtonPreviousClick}
errors={this.state.errors}/>);
break;
case 3:
formStep = (<RegistrationFormStepThree user={this.props.userData}
onFileChange={this.onFileChange}
onButtonClick={this.onButtonClick}
onButtonPreviousClick={this.onButtonPreviousClick}
errors={this.state.errors}
fileNames={this.state.fileNames}
icons={this.state.icons}
fileChosen={this.state.selectedFile}/>);
break;
default:
formStep = (<RegistrationFormStepFour user={this.props.userData}
onChange={this.setUser}
onChangeCheckboxState={this.changeCheckboxState}
onButtonClick={this.onButtonClick}
onButtonPreviousClick={this.onButtonPreviousClick}
errors={this.state.errors}/>);
}
return (
<div className="sidebar-menu-container" id="sidebar-menu-container">
<div className="sidebar-menu-push">
<div className="sidebar-menu-overlay"></div>
<div className="sidebar-menu-inner">
<div className="contact-form">
<div className="container">
<div className="row">
<div className="col-md-10 col-md-offset-1 col-md-offset-right-1">
{React.cloneElement(formStep, {currentLanguage: languageReg})}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
RegistrationPage.contextTypes = {
router: PropTypes.object
};
function mapStateToProps(state, ownProps) {
return {
userData: state.userRegistrationReducer
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(actionCreators, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(RegistrationPage);
ilk adım bileşenidir ve sonra döndürülen değer true veya false ise düğmeye tıkladım. Eğer doğruysa, adım durumunu uygun bir değere ayarladım. Ve yalnızca ilk adımın form alanlarını doğrularsam çalışır, ancak bir sonraki adımın bir veya daha fazla form alanını da doğrulamaya çalıştığımda (şimdi ikinci adımın ilk alanını doğrulamaya çalışıyorum)
if(!user.firstName){
formIsValid = false;
errors.firstName = languageReg.firstnameEmpty;
}
Ben
Uyarı fazlasını bulacaksınız: TextInput kontrol edilmesi tip metnin kontrolsüz girişini değişiyor. Giriş elemanları kontrolsüzden kontrole geçmemelidir (veya tersi). Bileşenin kullanım ömrü boyunca kontrollü veya kontrolsüz bir giriş elemanı kullanmak arasında karar verin.
Doğrulama işlevi olmadan her şey mükemmel çalışır.
Herhangi bir öneri?
DÜZENLEME Bu ikinci aşama bileşeni
import React, {propTypes} from 'react';
import _ from 'lodash';
const TextInput = ({errors, style, name, labelClass, label, className, placeholder, id, value, onChange, type}) => {
let wrapperClass = "form-group";
if (errors) {
wrapperClass += " " + "inputHasError";
}
return (
<div className={wrapperClass} style={style}>
<label htmlFor={name} className={labelClass}>{label}</label>
<input type={type}
className={className}
placeholder={placeholder}
name={name}
id={id}
value={value}
style={{}}
onChange={onChange}
/>
<div className="errorBox">{errors}</div>
</div>
);
};
TextInput.propTypes = {
name: React.PropTypes.string.isRequired,
label: React.PropTypes.string,
onChange: React.PropTypes.func.isRequired,
type: React.PropTypes.string.isRequired,
id: React.PropTypes.string,
style: React.PropTypes.object,
placeholder: React.PropTypes.string,
className: React.PropTypes.string,
labelClass: React.PropTypes.string,
value: React.PropTypes.string,
errors: React.PropTypes.string
};
export default TextInput;
:
import React from 'react';
import Button from '../../common/formElements/button';
import RegistrationFormHeader from './registrationFormHeader';
import TextInput from '../../common/formElements/textInput';
const RegistrationFormStepTwo = ({user, onChange, onButtonClick, onButtonPreviousClick, errors, currentLanguage}) => {
const language = currentLanguage;
return (
<div className="contact_form">
<form role="form" action="" method="post" id="contact_form">
<div className="row">
<RegistrationFormHeader activeTab={1} currentLanguage={language}/>
<div className="hideOnBigScreens descBox">
<div className="headerTitle">{language.personalInfoConfig}</div>
<div className="titleDesc">{language.personalBoxDesc}</div>
</div>
<div className="col-lg-12">
<h6 className="registrationFormDesc col-lg-10 col-lg-offset-1 col-lg-offset-right-2 col-xs-12">
{language.personalDesc}
</h6>
<div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<TextInput
type="text"
name="firstName"
label={language.firsnameLabel}
placeholder={language.firsnameLabel}
className="templateInput"
id="name"
onChange={onChange}
value={user.firstName}
errors={errors.firstName}
/>
</div>
<div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<TextInput
type="text"
name="lastName"
label={language.lastnameLabel}
placeholder={language.lastnameLabel}
className="templateInput"
id="name"
onChange={onChange}
value={user.lastName}
errors={errors.lastName}
/>
</div>
<div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<TextInput
type="text"
name="phone"
label={language.phoneLabel}
placeholder={language.phoneLabel}
className="templateInput"
id="phone"
onChange={onChange}
value={user.phone}
errors={errors.phone}
/>
</div>
<div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<TextInput
type="text"
name="mobilePhone"
label={language.mobileLabel}
placeholder={language.mobileLabel}
className="templateInput"
id="phone"
style={{}}
onChange={onChange}
value={user.mobilePhone}
errors={errors.mobilePhone}
/>
</div>
<div className="clearfix"></div>
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<TextInput
type="text"
name="email"
id="email"
label={language.emailLabel}
placeholder={language.emailLabel}
className="templateInput"
style={{}}
onChange={onChange}
value={user.email}
errors={errors.email}
/>
</div>
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<TextInput
type="text"
name="userName"
label={language.usernameLabel}
placeholder={language.usernameLabel}
className="templateInput"
id="name"
onChange={onChange}
value={user.userName}
errors={errors.userName}
/>
</div>
<div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<TextInput
type="password"
name="password"
label={language.passwordLabel}
placeholder={language.passwordLabel}
className="templateInput"
id="password"
onChange={onChange}
value={user.password}
errors={errors.password}
/>
</div>
<div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
<TextInput
type="password"
name="confirmPassword"
label={language.passwordConfirmLabel}
placeholder={language.passwordConfirmLabel}
className="templateInput"
id="password"
onChange={onChange}
value={user.confirmPassword}
errors={errors.confirmPassword}
/>
</div>
</div>
<div className="clearfix"></div>
<div className="col-lg-6 col-xs-6" style={{marginTop: 30}}>
<Button onClick={onButtonPreviousClick}
name="btnPrevious"
value={language.btnPrevious}
icon="arrow-circle-left"
style={{marginRight: 10, float: 'right'}}/>
</div>
<div className="col-lg-6 col-xs-6" style={{marginTop: 30}}>
<Button onClick={onButtonClick} name="stepTwoNext" value={language.btnNext}
icon="arrow-circle-right" style={{marginLeft: 10, float: 'left'}}/>
</div>
</div>
</form>
</div>
);
};
export default RegistrationFormStepTwo;
TextInput nedir? –