2016-06-24 17 views
6

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; 
+0

TextInput nedir? –

cevap

15

Bu uyarı neden var olduğunu: değer tanımsız olarak belirtildiğinde, Tepki eğer bilmenin bir yolu vardır Bir bileşeni boş bir değere ya da bileşenin denetimsiz olmasını istiyorsanız. Bu bir hata kaynağıdır.

Değeri girişe geçirmeden önce boş/tanımsız bir kontrol yapabilirsiniz.

a source

+0

Ama neden bu uyarıyı doğrulama fonksiyonu olmadan alamıyorum? Doğrulama işlevi alan değerleriyle hiçbir şey yapmaz. – Boky

+0

@Boky repo verebilir misiniz? "İkinci adım" yazdınız, ama bu bileşeni görmedim –

+0

İlk adımı çok benzer. Sorumu güncelledim. Eğer bir şey eklerseniz (if = value == null || typeof value == "undefined") { alanValue = ""; } else { alanValue = value; } 'Hiçbir uyarı almıyorum ama ikinci adıma geçmeyecek. Doğrulama işlevini kaldırırsam, mükemmel çalışır. – Boky

1

@Kokovin Vladislav haklı. kodunda bu koymak için, tüm giriş value s yapabilirsiniz: İlk adının değerini bulamazlarsa olduğunu

<TextInput 
    // your other code 
    value={user.firstName || ''} 
/> 

sonra bunu boş bir değer verir.

İlgili konular