Mahi Parmar
Mahi Parmar

Reputation: 525

how to bind data in reactjs form

I have started working on reactjs technology and i am totally new for this technology. I wanted to bind data with my drop down in form and on drop down item selection i wanted to feed my other form fields.Here i am creating form to generate bill for society members and i wanted to fill society member name to be bind on drop down box and bill changes on text fields. Sometimes i have got issue says 'TypeError: node is null".And i dont understand how to bind the data to fields.

here is my logic please check and let me know what am i missing over here

 constructor(props, fdb) {
        super(props);

        this.state = {
            bill_nm: '',
            bill_eml: '',
            bill_total: '',
            bill_id: '',
            inputs:[],
            userInput:[]
        };
        this.userState = {
            user_id:'',
            email:'',
            first_name:'',
            last_name:''
        };
        this.chargeState ={
            charge_id:'',
            charge_title:'',
            charge_type:'',
            charge_amt:''
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmitFirebase = this.handleSubmitFirebase.bind(this);
        this.sendCallback = this.sendCallback.bind(this);
        this.appendInput = this.appendInput.bind(this);
        this.getInitialState = this.getInitialState.bind(this);
        this.appendUserInput = this.appendUserInput.bind(this);
        this.usercharge = [];

        const rootRef = DbConfig.database().ref();
        const post = rootRef.child('billing').orderByKey();
        const users = rootRef.child('users').orderByKey();
        const bill_charges = rootRef.child('billing_charges').orderByKey();

    }

    componentDidMount() {

             this.users.once('value', snap => {
            snap.forEach(child => {
                this.userState = {
                    user_id: child.key,
                    email: child.val().email,
                    first_name: child.val().first_name,
                    last_name: child.val().last_name
                };

            });

        });

        this.bill_charges.once('value', snap => {
            snap.forEach(child => {
                this.chargeState = {
                    chrage_key:child.key,
                    charge_id: child.charge_id,
                    charge_title: child.val().charge_title,
                    charge_type: child.val().charge_type,
                    charge_amt: child.val().charge_amt
                };
                this.usercharge = this.chargeState;
               //console.log( this.usercharge);
            });
        });

        }

           handleChange(event) {
        this.setState({ value: event.target.value });
    }


   getInitialState() {
        return {inputs:[]};
    }
    appendUserInput() {
        //e.preventDefault();

        // DbConfig.database().ref().child('users').orderByKey().once('value', snap => {
        //     snap.forEach(child => {
        //         this.userState = {
        //             user_id: child.key,
        //             email: child.val().email,
        //             first_name: child.val().first_name,
        //             last_name: child.val().last_name
        //         };
        //     });
        // });
        var newInput1 = this.state.userInput.length;
       // var newInput = this.userState.length;
        console.log('len1='+newInput1);
       // console.log('len'+newInput);
        this.setState({ userInput: this.state.userInput.concat(newInput1)});

    }
    appendInput(e) {
        e.preventDefault();
        var newInput = this.state.inputs.length;
            console.log('newinput'+newInput);
        this.setState({ inputs: this.state.inputs.concat(newInput)},function(){
            return;
        });
        console.log('input concate'+this.state.inputs);
    }

      render() {
        return (
            <div className="content">
                <NavBar></NavBar>
                <div className="row">
                    <div className="col-md-10">
                        <div className="card">
                            <div className="card-header card-header-icon" data-background-color="rose">
                                <i className="material-icons">receipt</i>
                            </div>
                            <div className="card-content">
                                <h4 className="card-title">Add Bill</h4>
                                <form onSubmit={this.handleSubmitFirebase}>
                                    <div className="form-group label-floating is-empty">
                                        <label className="control-label">Person Name</label>

                                        <div className="room-main">
                                        <div className="online-est">                                         
                                                <a href="javascript:void(0);" onClick={this.appendUserInput} className="rednew-btn"><i className="fa fa-plus-circle"></i> Add user</a>
                                            <select className="room-form">
                                           {this.state.userInput.map(function(item){
                                               console.log('i'+item);
                                                return (
                                                          <option ref={item}>{item}</option> 
                                                       )
                                           })}
                                           </select>
                                        </div>
                                    </div>
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                    <label className="control-label">Person Name</label>
                                        <div className="room-main">
                                        <div className="online-est"> 
                                                <a href="javascript:void(0);" onClick={this.appendInput} className="rednew-btn"><i className="fa fa-plus-circle"></i> Add charge</a>
                                            <select>
                                           {this.state.inputs.map(function(item){
                                                return (
                                                            <option ref={item}>{item}</option>
                                                       )
                                           })}
                                           </select>
                                        </div>
                                    </div>
                                    <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                            <label className="control-label">status</label>
                                            <select>
                                                <option value="Unpaid">Unpaid</option>
                                                <option value="Paid">Paid</option>
                                            </select>
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                            <label className="control-label">total</label>
                                            <input type="text" className="form-control" ref={el => this.billtotal = el} onChange={this.handleChange} />
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                            <label className="control-label">Bill period</label>
                                            <input type="date" className="form-control" ref={el => this.billto = el} onChange={this.handleChange} />
                                            <input type="date" className="form-control" ref={el => this.billfrom = el} onChange={this.handleChange} />
                                        <span className="material-input"></span></div>
                                    <div className="form-group label-floating is-empty">
                                        <span className="material-input"></span></div>
                                    <button type="submit" className="btn btn-fill btn-rose">Submit</button>
                                </form>
                            </div>
                        </div>
                    </div>

                </div>
            </div>
        )
    }

Upvotes: 1

Views: 1027

Answers (3)

Josh Pittman
Josh Pittman

Reputation: 7324

Rather than using get initial state you can use a constructor, initialise state in your constructor and bind your methods in the constructor.

constructor(props) {
  super(props);
  this.state = {
    listVisible: false
  };
 this.select = this.select.bind(this)
 this.show = this.show.bind(this)
 this.hide = this.hide.bind(this)
 this.renderListItems = this.renderListItems.bind(this)
}

Then when you call select in your render method you should just be able to say...

<div onClick={this.select(item)}>
  <span>{item.name}</span>
</div> 

although you need to add a key in react to keep track fo lists so change the first line to <div key={i} onClick={this.select(item)}>. You can read up on keys seperately https://reactjs.org/docs/lists-and-keys.html#keys

Upvotes: 2

KerSplosh
KerSplosh

Reputation: 466

As an alternative, you could try Redux Form https://redux-form.com which will do a good part of the work for you

Upvotes: 0

Josh Pittman
Josh Pittman

Reputation: 7324

<div className="post">
  <h3>{this.state.bill_nm}</h3>
  <h2>{this.state.bill_eml}</h2>
  <p>{this.state.bill_total}</p>
</div>

These state values above have never been defined. You need to define them in your initial state, or set them before they can be called.

In your onChange handlers on the inputs in render, you are calling this.handleChange but they havn't been defined either.

<input type="text" className="form-control" ref={el => this.pnm = el} onChange={this.handleChange} />

I think this code example is incomplete.

To answer the title question, this article explains your options for binding this in react https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

Upvotes: 1

Related Questions