reactJS表单输入元素可以验证但不会更新

时间:2018-09-03 18:37:40

标签: javascript reactjs forms

我在reactJS应用程序中有一个表单。这是到目前为止的代码(很抱歉,很多)

import React from 'react';
import '../styles/app.css';

function validateDollar(value) {
var regex = /^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/;
if (regex.test(value))
{
    //Input is valid, check the number of decimal places
    var twoDecimalPlaces = /\.\d{2}$/g;
    var oneDecimalPlace = /\.\d{1}$/g;
    var noDecimalPlacesWithDecimal = /\.\d{0}$/g;

    if(value.match(twoDecimalPlaces))
    {
        //all good, return as is
        return value;
    } 
    else 
    {
      if(value.match(noDecimalPlacesWithDecimal))
      {
          //add two decimal places
          return value + "00";
      }
      else
      {
        if(value.match(oneDecimalPlace ))
        {
            //ad one decimal place
            return value + "0";
        }
        else
        {
        //else there is no decimal places and no decimal
        return value + ".00";               
        }           
      }
    }
}
else
{
  return -1;
}
}

class Enterproperty extends React.Component {

constructor(props) {
  super(props);
  this.state = { 
    numberUnits: 0,
    name: {
      valid: true,
      value: '',
      label: 'Property Nickname',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    address: {
      valid: true,
      value: '',
      label: 'Property Address',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    city: {
      valid: true,
      value: '',
      label: 'Property City',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    price: {
      valid: true,
      value: '',
      label: 'Asking price',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    taxes: {
      valid: true,
      value: '',
      label: 'Taxes per year',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    expenses: {
      valid: true,
      value: '',
      label: 'Net Operating Expenses',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    caprate: {
      valid: true,
      value: '',
      label: 'Cap Rate',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    yearbuilt: {
      valid: true,
      value: '',
      label: 'Building built in:',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    },
    numberofunits: {
      valid: true,
      value: '',
      label: 'Nuber of units:',
      length: 0,
      css: 'input-group-text text-black input-size-200'
    }
  }

  this.saveData = this.saveData.bind(this);
  this.yearBuilt = this.yearBuilt.bind(this);
  this.setUnitNumber = this.setUnitNumber.bind(this);

} 


setUnitNumber() {

  let currentComponent = this;

  var localUnitCount = document.getElementById("inputNumberOfUnits").value;
  currentComponent.setState({ numberUnits:localUnitCount });

}

saveData() {
let currentComponent = this;

var validData = true;
var localName = {
  valid: true,
  value: '',
  label: 'Property Nickname',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}
var localAddress = {
  valid: true,
  value: '',
  label: 'Property Address',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}
var localCity = {
  valid: true,
  value: '',
  label: 'Property City',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}
var localPrice = {
  valid: true,
  value: '',
  label: 'Asking price',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}
var localExpenses = {
  valid: true,
  value: '',
  label: 'Net Operating Expenses',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}
var localCapRate = {
  valid: true,
  value: '',
  label: 'Cap Rate',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}
var localTaxes = {
  valid: true,
  value: '',
  label: 'Taxes per year',
  length: 0,
  css: 'input-group-text text-black input-size-200'
}

// validate the property nickname
localName.value = document.getElementById("lblName").value;
localName.length = localName.value.length;

if (localName.length < 5) {
  validData = false;
  localName.valid = false;
  //localName.label = "You did not enter a property nickname (minimum of 5 charaters)";
  localName.css = "input-group-text text-danger input-size-200";
}

// validate the property address
localAddress.value = document.getElementById("lblAddress").value;
localAddress.length = localAddress.value.length;

if (localAddress.length < 3) {
  validData = false;
  localAddress.valid = false;
  //localAddress.label = "You did not enter a property Address (minimum of 5 characters)";
  localAddress.css = "input-group-text text-danger input-size-200";
}

// validate the property city
localCity.value = document.getElementById("lblCity").value;
localCity.length = localCity.value.length;

if (localCity.length < 3) {
  validData = false;
  localCity.valid = false;
  //localCity.label = "You did not enter a property city (minimum of 3 characters)";
  localCity.css = "input-group-text text-danger input-size-200";
}

// validate the property price
localPrice.value = validateDollar(document.getElementById("lblPrice").value);

if (localPrice.value < 0){
  localPrice.value = "";
  validData = false;
  localPrice.valid = false;
  //localPrice.label = "You entered an invalid dollar amount for the cost of the building";
  localPrice.css = "input-group-text text-danger input-size-200";
}

// validate the property taxes
localTaxes.value = validateDollar(document.getElementById("lblTaxes").value);

if (localTaxes.value < 0){
  localTaxes.value = "";
  validData = false;
  localTaxes.valid = false;
  //localTaxes.label = "You entered an invalid dollar amount for the taxes on the building";
  localTaxes.css = "input-group-text text-danger input-size-200";
}

// validate the Cap Rate
localCapRate.value = validateDollar(document.getElementById("lblCapRate").value);

if (localCapRate.value < 0){
    localCapRate.value = "";
  validData = false;
  localCapRate.valid = false;
  //localTaxes.label = "You entered an invalid dollar amount for the taxes on the building";
  localCapRate.css = "input-group-text text-danger input-size-200";
}

// validate the net operating expenses
localExpenses.value = validateDollar(document.getElementById("lblExpenses").value);

if (localExpenses.value < 0){
    localExpenses.value = "";
  validData = false;
  localExpenses.valid = false;
  //localExpenses.label = "You entered an invalid dollar amount for the taxes on the building";
  localExpenses.css = "input-group-text text-danger input-size-200";
}

currentComponent.setState({ name:localName, address:localAddress, city:localCity, price:localPrice, taxes:localTaxes, expenses:localExpenses, caprate:localCapRate });

}

yearBuilt() {

  var date = new Date();
  var startYear = date.getFullYear();
  var endYear = startYear - 120;

  let items = [];         
  for (let i = startYear;i>endYear;i--) {             
      items.push(<option key={i} value={i}>{i}</option>);   
      //here I will be creating my options dynamically based on
      //what props are currently passed to the parent component
  }
  return items;

}


 renderData = () => {       

    var localUnitCount = this.state.numberUnits;
    var idArray = [];

    for (var counter=0;counter<localUnitCount;counter++) {
      var id = '';
      var idObject = {
        counter: 0,
        idNameBedroom: '',
        idNameBathroom: '',
        idRent: '',
        idMarket: '',
        idRentedStatus: ''
      }

      //build the id for the bedroom item
      if (counter<10) {id="Bedroom0"} else {id="Bedroom"};
      id=id+counter;
      idObject.idNameBedroom  = id+(counter+1);

      //build the id for the bathroom item
      if (counter<10) {id="Bathroom0"} else {id="Bathroom"};
      id=id+counter;
      idObject.idNameBathroom  = id+(counter+1);

      //build the id for the rent item
      if (counter<10) {id="Rent0"} else {id="Rent"};
      id=id+counter;
      idObject.idRent  = id;

      //build the id for the mareket item
      if (counter<10) {id="Market0"} else {id="Market"};
      id=id+counter;
      idObject.idMarket  = id;

      //build the id for the rented status item
      if (counter<10) {id="RentedStatus0"} else {id="RentedStatus"};
      id=id+counter;
      idObject.idRentedStatus  = id;

      idObject.counter = counter+1;
      idArray[counter] = idObject;

    }

    return idArray.map( item => (

        <div>
            <hr />
            <div className="text-black text-bold">
                <label> Unit {item.counter} </label>
            </div>    
            <div className="input-group mb-3">
                <div className="input-group-prepend">
                    <span className="input-group-text text-black input-size-200">Rent for Unit {item.counter}</span>
                </div>
                <input id={item.idRent} type="text" className="form-control" />
            </div> 
            <div className="input-group mb-3">
                <div className="input-group-prepend">
                    <span className="input-group-text text-black input-size-200">Rented status of Unit {item.counter}</span>
                </div>                                        
                <select className="custom-select text-black" id={item.idRentedStatus}>
                    <option value="rented" selected>Rented</option>
                    <option value="vacant">Vacant</option>
                </select>
            </div> 
            <div className="input-group mb-3">
                <div className="input-group-prepend">
                    <span className="input-group-text text-black input-size-200">Bedrooms in Unit {item.counter}</span>
                </div>                                        
                <select className="custom-select text-black" id={item.idNameBedroom}>
                    <option value="1" selected>1 bedroom</option>
                    <option value="2">2 bedrooms</option>
                    <option value="3">3 bedrooms</option>
                    <option value="4">4 bedrooms</option>
                    <option value="5">5 bedrooms</option>
                </select>
            </div> 
            <div className="input-group mb-3">
                <div className="input-group-prepend">
                    <span className="input-group-text text-black input-size-200">Bathrooms in Unit {item.counter}</span>
                </div>                                        
                <select className="custom-select text-black" id={item.idNameBathroom}>
                    <option value="1" selected>1 bathroom</option>
                    <option value="2">2 bathrooms</option>
                    <option value="3">3 bathrooms</option>
                    <option value="4">4 bathrooms</option>
                    <option value="5">5 bathrooms</option>
                </select>
            </div> 
            <div className="input-group mb-3">
                <div className="input-group-prepend">
                    <span className="input-group-text text-black input-size-200">Rent category for Unit {item.counter}</span>
                </div>                                        
                <select className="custom-select text-black" id={item.idMarket}>
                    <option value="market" selected>Market value</option>
                    <option value="stabalized">Rent stabalized</option>
                    <option value="controlled">Rent controlled</option>
                </select>
            </div> 
        </div>
      ) )
  }

  render() {
    console.log(this.state.caprate.value);
    return (
        <div className="App">      
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <a className="navbar-brand" href="#">Property Management</a>
                <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon"></span>
                </button>

                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul className="navbar-nav mr-auto">
                    <li className="nav-item">
                        <a className="nav-link" href="/loadProperty">View Saved Properties</a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="/Enterproperty">Enter New Property</a>
                    </li>
                    </ul>
                </div>
            </nav>

            <div className="d-flex flex-wrap justify-content-center position-absolute w-100 align-items-center align-content-center">
                <div className="container">
                    <div className="row">
                        <div md="6">
                            <form>
                                <p className="h4 text-center py-4">Enter the property information</p>
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.name.css}>{this.state.name.label}</span>
                                    </div>
                                    <input id="lblName" type="text" className="form-control" />
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.address.css}>{this.state.address.label}</span>
                                    </div>
                                    <input id="lblAddress" type="text" className="form-control" />
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.city.css}>{this.state.city.label}</span>
                                    </div>
                                    <input id="lblCity" type="text" className="form-control" />
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.price.css}>{this.state.price.label}</span>
                                    </div>
                                    <input id="lblPrice" type="text" className="form-control" />
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.taxes.css}>{this.state.taxes.label}</span>
                                    </div>
                                    <input id="lblTaxes" type="text" className="form-control" />
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.expenses.css}>{this.state.expenses.label}</span>
                                    </div>
                                    <input id="lblExpenses" type="text" className="form-control" />
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.caprate.css}>{this.state.caprate.label}</span>
                                    </div>
                                    <input id="lblCapRate" type="text" className="form-control" value={this.state.caprate.value}/>
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.yearbuilt.css}>Tax abatements?</span>
                                    </div>                                        
                                    <select className="custom-select text-black" id="inputTaxAbatement">
                                        <option value="yes" selected>Yes</option>
                                        <option value="no">No</option>
                                    </select>
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.yearbuilt.css}>Fuel Type</span>
                                    </div>                                        
                                    <select className="custom-select text-black" id="inputFuelType">
                                        <option value="gas" selected>Gas</option>
                                        <option value="oil">Oil</option>
                                    </select>
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.yearbuilt.css}>Tennants pay utilities</span>
                                    </div>                                        
                                    <select className="custom-select text-black" id="inputTennantsPayUtilities">
                                        <option value="yes" selected>Yes</option>
                                        <option value="no">No</option>
                                    </select>
                                </div>
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.yearbuilt.css}>{this.state.yearbuilt.label}</span>
                                    </div>                                        
                                    <select className="custom-select text-black" id="inputYearBuilt">
                                        {this.yearBuilt()}
                                    </select>
                                </div> 
                                <div className="input-group mb-3">
                                    <div className="input-group-prepend">
                                        <span className={this.state.numberofunits.css}>{this.state.numberofunits.label}</span>
                                    </div>                                        
                                    <select className="custom-select text-black" id="inputNumberOfUnits" onChange={() => { 
                                    this.setUnitNumber();
                                    }}>
                                        <option value="0" selected>Select</option>
                                        <option value="1">One</option>
                                        <option value="2">Two</option>
                                        <option value="3">Three</option>
                                        <option value="4">Four</option>
                                        <option value="5">Five</option>
                                        <option value="6">Six</option>
                                        <option value="7">Seven</option>
                                        <option value="8">Eight</option>
                                        <option value="9">Nine</option>
                                        <option value="10">Ten</option>
                                        <option value="11">Eleven</option>
                                        <option value="12">Twelve</option>
                                        <option value="13">Thirteen</option>
                                        <option value="14">Fourteen</option>
                                        <option value="15">Fifteen</option>
                                        <option value="16">Sixteen</option>
                                        <option value="17">Seventeen</option>
                                        <option value="18">Eighteen</option>
                                        <option value="19">Nineteen</option>
                                        <option value="20">Twenty</option>
                                    </select>
                                </div> 
                                <div>
                                    {this.renderData()}
                                </div> 
                                <div className="text-center py-4 mt-3">
                                    <button type="button" className="btn btn-primary" onClick={() => { 
                                    this.saveData();
                                    }}>Save</button>
                                </div> 
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}
}

export default Enterproperty;

saveData()中的代码验证输入字段的值。

我专门查看需要确保将其输入为美元金额的数字字段。

验证字段之后,我执行setState以使用新值更新状态。状态更新后,react将重新呈现并显示表单。

我的问题是,如果我在上限率的表单字段中输入12345并单击按钮,则console.log()显示我将值12345验证为“ 12345.00”。我在return()之前的渲染器中有一个console.log(),this.state.caprate.value的值是12345.00,但是当渲染发生时,表单仍然显示旧值。

验证字段并在验证完成后使字段可编辑的正确方法是什么?

0 个答案:

没有答案