1

I have two components. From componentA i am getting value of roles fields and using this values i need to create another record for componentB of users.

The structure of componentA is like this:

[
  {
    "id": "507f1f77bcf86cd799439011",
    "title": "admin",
    "status": "active"
  },
  ...
]

The structure of componentB is like this in which i am getting roles data and when i create another record then at that time the value of roles should be inserted like this format.

[
  {
    "id": "507f1f77bcf86cd799439017",
    "email": "admin@admin.com",
    "roles": {
      "id": "507f1f77bcf86cd799439011",
      "title": "admin",
      "status": "active"
    }
  },
  ...
]

=> User insert component to insert records.

import { BootstrapTable, TableHeaderColumn } from "react-bootstrap-table";
import RolesField from "./Editor/Roles/Field";

class UserInsertRow extends React.Component {
  constructor(props) {
    super(props);
    this.roles = [];
    this.getRoles();
  }

  customRoleField = (
    column,
    attr,
    editorClass,
    ignoreEditable,
    defaultValue
  ) => (
    <RolesField
      roles={this.roles}
      ref={attr.ref}
      {...this.props}
      editorClass={editorClass}
      ignoreEditable={ignoreEditable}
    />
  );

  render() {
    return (
      <BootstrapTable
        ref="table"
        insertRow={true}
        deleteRow={true}
        pagination={true}
        data={this.props.data}
      >
        <TableHeaderColumn
          dataField="role"
          customInsertEditor={{ getElement: this.customRoleField }}
          customEditor={{
            getElement: this.roleEditor,
            customEditorParameters: { roles: this.roles }
          }}
        >
          Role
        </TableHeaderColumn>
      </BootstrapTable>
    );
  }
}

=> RolesField component

import { rolesContext } from "../../Context";
class RolesField extends React.Component {
  constructor(props) {
    super(props);
  }

  getFieldValue = () => rolesContext._currentValue.selectedRoles;

  render() {
    console.log(this.props.roles);
    return (
      <div className="form-group">
        <select
          className="form-control editor edit-select"
          onChange={this.selectRole}
        >
          {this.props.roles.map(name => (
            <option ref={name.id} key={name.id} value={JSON.stringify(role)}>
              {name.title}
            </option>
          ))}
        </select>
      </div>
    );
  }

  selectRole(e) {
    var options = e.target.options;
    var value = [];
    for (var i = 0, l = options.length; i < l; i++) {
        if (options[i].selected) {
            value.push(options[i].value);
        }
    }
    rolesContext._currentValue.selectedRoles = [];
    value.map(value => rolesContext._currentValue.selectedRoles.push(value));
}

export default RolesField;

Context API which i am using to store data.

import React from 'react';
export const roles = {selectedRoles: []};
export const rolesContext = React.createContext(roles);



email: "qqq@qqq.com"
id: "507f1f77bcf86cd799439123"
role: []

How can i manage the <select> tag for roles field so that the new inserted record from selected drop down values should be like this:

{
"id": "507f1f77bcf86cd799439017",
"email": "qqqq@qqqq.com",
"roles": {
  "id": "507f1f77bcf86cd799439123",
  "title": "admin",
  "status": "active"
}
},

P.S Please bare with this bit lengthy code.

TMA
  • 1,004
  • 1
  • 15
  • 31

3 Answers3

1

You can break through it by using a map to store the role_id -> role_data pairs. Assign the role_id as value to each of option, and get the value in the onChange handler. With this value, you will be able to find the exact role. Then do whatever you need next.

edit: Add sample code

roles come from eighter state/props

const roles = [
  {id: 'id_1', name: 'Admin'},
  {id: 'id_2', name: 'Super Admin'}
]

the onChange handler

onChange = e => {
  const id = e.target.value
  const seletedRole = roles.find(role => role.id === id)
  this.setState({
    selectedRole
  })
}

Render select and options

<select value={this.state.selectedRole.id} onChange={this.onChange}>
  {
    roles.map(role => <option id={role.id} value={role.id}>{role.name}</option>)
   }
</select>
Pengson
  • 641
  • 4
  • 10
0

as you want to get the whole object by selecting an option from the list, you can store the whole object as data-value of <option> like this, you can replace your custom object as data-value

<option data-value='{"name":"abc","status":"active"}'>a</option>
Abhi Patel
  • 208
  • 1
  • 6
  • Hi, sorry for the super late response... by using this it returns like this `data-value="[object Object]"` Code: `data-value={{title:`${name.title}`,id:`${name.id}`}}` – TMA Dec 03 '19 at 07:00
0

I think you can convert your class component into functional component and using with hooks you can make your life easy. to use value of context and update the value context have look at this link. How to change Context value while using React Hook of useContext