3

I am learning ReactJS and trying to develop small CRUD form using it. At this point, I am trying to set input values from other sibling component to perform update. enter image description here

So, if I click on edit button in first row on grid, Organzation Name and Description input boxes should get "abc com" and "company Abc" values respectively.

var OrganizationHandler = React.createClass(
    render: function() {
        return (
            <div>
                <OrganizationAPP onOrganizationSubmit=this.handleOrganizationSubmit} />
                <OrganizationList external_DeleteOrganization={this.DeleteOrganizationFromServer} data= {this.state.data}  />
            </div>
       );
    }
});

var OrganizationList = React.createClass({
    internal_DeleteOrganization: function(id) {
        this.props.external_DeleteOrganization(id);
    },
    render: function() {
        var results = this.props.data;
        var parsed_results = results.objects;
        var that = this;
        var organizations = parsed_results.map(function(organization){
            return <Organization onDeleteOrganization={that.internal_DeleteOrganization} id={organization.id} name={organization.name} description={organization.description} />
        });

        return(
            <div>
                {organizations}
            </div>
        );
    }
});

var Organization = React.createClass({
    handleDeleteClick: function() {
        console.log(this.props);
        this.props.onDeleteOrganization(this.props.id);
    },
    handleEditClick: function () {
        alert(this.props.name);
    },
    render: function() {
        return (
            <div className="row">
                <div className="small-2 large-2 columns">{this.props.id}</div>
                <div className="small-4 large-4 columns">{this.props.name}</div>
                <div className="small-4 large-4 columns"> this.props.description}</div>
                <div className="small-2 large-2 columns">
                    <input type="button" onClick={this.handleDeleteClick} data-order={this.props.id} value="Delete" />
                    <input type="button" onClick={this.handleEditClick} data-order={this.props.id} value="Edit" />
                </div>
            </div>
        );
    }
});

var OrganizationAPP= React.createClass({
    getInitialState: function() {
        return {name: '',  description:''};
    },
    onChangename: function(e) {
        this.setState({name: e.target.value});
    },
    onChangedescription: function(e) {
        this.setState({description: e.target.value});
    },
    handleSubmit: function() {
        var name = this.refs.name.getDOMNode().value.trim();
        var description = this.refs.description.getDOMNode().value.trim();
        if (!description || !name) {
            return false;
        }

        this.props.onOrganizationSubmit('{"name":"' + name +'", "description": "' + description +'"}');
        this.refs.name.getDOMNode().value = '';
        this.refs.name.getDOMNode().value = '';
        this.setState({name: '', description: ''});
        return false;
    },
    render: function() {
        return (
            <div>
                <h1>Organization Setup:</h1>
                <form onSubmit={this.handleSubmit}>
                    <div className="row">
                        <div className="small-12 large-3 columns">
                            <label>Organization Name:</label>
                            <input type="text" ref="name" required value={this.props.name} onChange={this.onChangename}/>
                        </div>
                    </div>
                    <div className="row">
                        <div className="small-12 large-7 columns">
                            <label>description:</label>
                            <input type="text" required ref="description" value={this.props.description} onChange={this.onChangedescription}  />
                        </div>
                    </div> 
                    <div className="row">
                        <div className="small-2 large-3  columns">
                            <button type="submit"> Add </button>
                        </div>
                    </div>
                </form>
            </div>
        )
    }
});

I have successfully performed addition and deletion operations but I don't know how can I set values to be edit in input boxes from sibling component. Please let me know if you don't understand anything as I just started learning reactjs and I know my code is not up to the mark.

2
  • To communicate between siblings, the data they depend on should be controlled by a common ancestor. Changes from one sibling will affect changes in the ancestor, which will pass the new data to the other sibling. Can you simplify your code example and/or fix the indentation? It would make it easier to offer advice. Commented Jun 17, 2014 at 2:54
  • @ssorallen Thank you for your response. I have edited the codes, would you please suggest me how to achieve this task. Thanks in advance. Commented Jun 17, 2014 at 7:57

1 Answer 1

15

Here is an example list editing app where editing an item content is done with a parent input (could easily be a sibling).

/** @jsx React.DOM */

//React is for rendering our app UI. 
//Not for writing the app. 
//So the first step is building out your logic in whatever you prefer.
//That could be Backbone, some other framework, or plain JS as we do here.

//our app
var app = {

  //we'll tell this listener when we change
  listener: null,

  //a cheap way of creating IDs for our new data
  nextId: 3,

  //pre-populate our data
  rows: [
    {id: 1, name: "entry 1"},
    {id: 2, name: "entry 2"}
  ],

  //what data are we focused on
  focusedId: 1,

  //add a new row of data and set it to focused
  addRow: function () {
    var id = this.nextId++;
    this.rows.push({id: id, name: ("entry " + id)});
    this.setFocusedId(id);
  },

  //get the name property given the data id
  getName: function(id){
    return _.findWhere(this.rows, {id: id}).name;
  },

  //update the name property of the currently focused data
  updateName: function (name) {
    var id = this.focusedId;
    _.findWhere(this.rows, {id: id}).name = name;
    this.listener.changed();
  },

  //set the focused data
  setFocusedId: function (id) {
    this.focusedId = id;
    this.listener.changed();
  },
};

//a row component 
var Row = React.createClass({
  render: function () {
    if (this.props.focused) {
      return <span>Value: {this.props.name} [editing]</span>;
    } else {
      return <span>
      Value: {this.props.name} 
        [<a href='#' onClick={this.props.focus}>edit</a>]
      </span>;
    }
  }
});

//the main view
var View = React.createClass({

  //our state is the app
  getInitialState: function () {
    return {
      app: app
    };
  },

  //before we render, start listening to the app for changes
  componentWillMount: function () {
    this.state.app.listener = this;
  },

  //update if the app tells us it changed
  changed: function () {
    this.forceUpdate();
  },

  //a handler we'll use for input fields
  textChanged: function (event) {
    this.state.app.updateName(event.target.value);
  },

  //let's render
  render: function () {
    var app = this.state.app;

    //build an array of row components
    var rows = _.map(app.rows, function (row) {
      var focus = function () {
        app.setFocusedId(row.id);
      };
      //the actual row component
      //give the row a unique id
      //give it a name, the focus handler function,
      //and tell it if it has the current focus
      return <li key={row.id}>
        <Row 
          name={row.name}
          focused={row.id == app.focusedId}
          focus={focus}
        />
      </li>;
    });
    //the main app view
    return <div>
    EDIT:
      <input 
        type="text" 
        value={app.getName(app.focusedId)} 
        onChange={this.textChanged}
      />
      <ul>{rows}</ul>
      <a href="#" 
        onClick={function(){app.addRow()}}>
        add row
      </a>
    </div>;
  }
});

React.renderComponent(
    <View />
    , document.body); 

Here is a working example: http://jsbin.com/laxejufila/2/edit

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. would you please give example with some jsfiddle as I am sorry I couldn't get the idea clearly. Your help would be appreciated.
Sorry for being late in responding, I had issues with my development machine. I followed the steps you explained, its pretty much what I wanted. Thanks

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.