1

import React, { Component } from 'react';
let _ = require('lodash');

import {bindActionCreators} from "redux";
import {connect} from 'react-redux';

import {fetchedBeaconsEdit} from '../../actions/';
import {editBeacon} from '../../actions/index';

// TODO - come up with a decent name

class InfoRow extends Component {

    render() {
        return (

            <tr>
                <td>
              { this.props.beacon === "name" 
                || this.props.beacon === "major" 
                || this.props.beacon === "minor" 
                || this.props.beacon === "beaconType" ?
                  <span>{this.props.beacon}<span className="font-css top">*</span></span>:
                  <span>{this.props.beacon}</span>
              }

                </td>
                <td>

                { this.props.beacon !== "beaconType" && 
                  this.props.beacon !== "uuid" && 
                  this.props.beacon !== "status" && 
                  this.props.beacon !== "store"&&
                  this.props.beacon !== "group" ?
                <div>
                    <input type="text"
                       className="form-control"
                       defaultValue={this.props.beaconValue}
                       name={this.props.beaconValue}
                       onChange={(e) =>this.props.handleInputChangeProp(e.target.value)}
                    /></div>:

                    this.props.beacon === "uuid" && this.props.beacon === "status" && this.props.beacon=== "store"?
                  <span></span>:

                    this.props.beacon === "beaconType"?

                    <select defaultValue={this.props.beaconValue} name={this.props.beaconValue} className="form-control" onChange={(e) =>this.props.handleInputChangeProp(e.target.value)}>
                      
                      <option name="ibeacon">IBEACON</option>
                      <option name="eddystone">EDDYSTONE</option>
                    </select>:this.props.beaconValue

                    

                }



                </td>
            </tr>
        )
    }
}

class BeaconEdit extends Component {

  constructor(props){
    super(props);
    this.state = {
            
        };
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }

  handleInputChange(beacon, value) {

        this.setState({
            [beacon]: value
        });
    }

 handleClick = () =>{
       Object.keys(this.props.ebcn).map((key)=> {
        if (this.state[key] !== undefined) {
          this.props.editBeaconGroup[key]=this.state[key];
        }
            
       })
        this.props.handleSubmitProp(this.props.editBeaconGroup);
  }
 
    render() {

        const rows = [];
        let a = this.props.ebcn;

        

       Object.keys(this.props.ebcn).map((keyName, keyIndex) =>{

          if (keyName === "store" || keyName === "group") {
            return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].name.toString()} name={this.state[keyName]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>);
          }else{
            return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].toString()} name={this.state[keyName]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>);
       }
       });

        return (


            <div className="col-md-6">
                <div className="">

                  <table className="table table-clear">
                    <tbody>
              
                    {rows}
                    
                    </tbody>
                  </table>
                 </div>
                 <div className="px-1" >
                        <button className="btn btn-sm btn-info btn-size btn-block" onClick={this.handleClick}>Save</button>
                 </div>
          </div>

        )

    }


}

class BeaconDetailEditComponent extends Component {
  
  constructor(props){
    super(props);
    this.state = {
        editbeacons: {}
        };
        this.handleSubmit = this.handleSubmit.bind(this);

        this.validateName = this.validateName.bind(this);
        this.validateMajor = this.validateMajor.bind(this);
        this.validateMinor = this.validateMinor.bind(this);
    }

    validateMinor = (minor) => {
      var re = /^[0-9]+$/;
      return re.test(minor);
    }

    validateMajor = (major) => {
      var re = /^[0-9]+$/;
      return re.test(major);
    }

    validateName = (name) => { 
      var re = /^[A-Za-z ]+$/;
      return re.test(name); 
    };


  handleSubmit (beaconedited) {

    console.log(beaconedited.name);

    if (!this.validateName(beaconedited.name)) { 
              alert('Name can not be an integer')  
          }

    else if (!this.validateMajor(beaconedited.major)) { 
              alert('Major number can only be an integer')  
          }

        else if (beaconedited.major.length > 5) {
          alert('Major number can not exceed 5 digits')
        }

        else if (!this.validateMinor(beaconedited.minor)) { 
              alert('Minor number can only be an integer')  
          }

        else if (beaconedited.major > 65535) {
          alert('Major number can not exceed the limit of 65535')
        }

        else if (beaconedited.minor > 65535) {
          alert('Minor number can not exceed the limit of 65535')
        }

    else {

      this.props.editBeacon(beaconedited, this.props.location.query.id);
    
  }
    }

  componentWillMount = () => {
        this.props.fetchedBeaconsEdit(this.props.location.query.id);  
    };

  
  render() {
    
    return (
        <div className="container px-3 mr-3">
            <div>
              <div className="col-md-6 col-md-offset-3"><h1>Edit Beacon Information</h1></div>
            </div>
            <br/>
            <br/>
                { this.props.ebcn != null?
            <div>
                <BeaconEdit ebcn={this.props.ebcn} handleSubmitProp={this.handleSubmit} editBeaconGroup={this.state.editbeacons}/>
            </div> :
                    <center><img className="gif-size" src={'img/avatars/default.gif'} alt="Loading"/></center>

            }
        </div>
    )
  }
}

function mapStateToProps(state) {
    return {
        eBeacon: state.eBeacon,
        ebcn: state.beacons
    }

}


function matchDispatchToProps(dispatch){
    return bindActionCreators({editBeacon: editBeacon, fetchedBeaconsEdit: fetchedBeaconsEdit}, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(BeaconDetailEditComponent);

This is the output I'm getting right now

enter image description here

i had provided the code snippet what i am doing is i had fetched the values from the server and were shown in the fields and I'm making this page as editable form what i want to do is now to take the values changed or changed by the user and to print them in console. i had applied handleInputChange and its showing changed values while changing but i want to see those values in console on button click as well how to do it?

5
  • on which ButtonClick do you want to see those values and also if it for all the values or only specific ones Commented Apr 21, 2017 at 8:37
  • wanted all the form values on clicking save button as you can see in the image Commented Apr 21, 2017 at 8:40
  • One small question more, you are not passing any prop as name to the InfoRow component, how is it working?? Shouldn't it be this.props.beacon Commented Apr 21, 2017 at 8:43
  • i had uploaded one more pic you can see that as well Hope u got my point Commented Apr 21, 2017 at 8:46
  • Any solution you got brother? Commented Apr 21, 2017 at 8:53

2 Answers 2

1

First, the manner your are changing the state is not good. You are setting the new state to have only a single attribute which is the name and value of the field which is modified.

Coming to how to print the value of the field you are modifying, you should do a console log in the handle change method.

That said, your code should look like:

handleInputChange(event) {

    //const {name, value} = event.target;
    //const oldState = this.state;
    //const newState = Object.assign({},oldState,{[name]:value});
    //this.setState(newState);

    this.setState({
        [event.target.name]: event.target.value
    });

    //printing the input name and value as it is being modified.
    console.log(name + ":" + value);

    //if you want to see the value of the current state uncomment the line below
    //console.log("State=" + JSON.stringify(newState));

}

printState = () => {
  console.log("State="+JSON.stringify(this.state));
}

For more insight on how to modify objects with assign method see: MDN doc on Object.assign()

If you want to print the current state on clicking the save button then add the onClick attribute to the button as shown in the code below:

<button value="Save" onClick={this.printState}/>
Sign up to request clarification or add additional context in comments.

11 Comments

i got it but i want to print to console on clicking on save button and also i want to print every value on Click whether it was changed or not
I just added some more stuff to my answer.
button already added as you can see inn code but it doesn't helped what u suggested
@cdaiga the manner your are changing the state is not good. You are setting the new state to have only a single attribute - I don't agree. setState performs shallow merge of next state object into current state so new state will not have only single property. Please check React docs: facebook.github.io/react/docs/react-component.html#setstate
can you provide solution?
|
1

Change InfoRow to

class InfoRow extends Component {

    render() {
        return (

            <tr>
                <td>
                  {this.props.beacon}
                </td>
                <td>
                <input type="text"
                   className="form-control"
                   defaultValue={this.props.beaconValue}
                   value={this.props.name}
                   name={this.props.beaconValue}
                   onChange={(e) =>this.props.handleInputChangeProp(e.target.value)}
                />
                </td>
            </tr>
        )
    }
}

and render to

Object.keys(this.props.ebcn).map((keyName, keyIndex) =>{

          return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].toString()} name={this.state[keyName]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>);
       });

and

handleInputChange(beacon, value) {

        this.setState({
            [beacon]: value
        });
    }

and handleClick to

 handleClick = () =>{
       Object.keys(this.props.ebcn).map((key)=> {
            console.log(this.state[key]);
       }))
  }

13 Comments

Try this solution, and let me know if it works, Of course its not tested and may have a few bugs
syntax error was removed but having error in this line as 'beacon' is not defined return rows.push(<InfoRow beacon={keyName} beaconValue={a[keyName].toString()} name={this.state[beacon]} key={keyIndex} handleInputChangeProp={(inp) =>this.handleInputChange(keyName, inp)}/>); });
Warning: InfoRow is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component
on button click Cannot read property 'state' of undefined in this console.log(this.state[key]);
The second error occurs because of context binding, andthe first one because initially this.state[keyName] is undefined
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.