将可点击表格行中的数据动态显示为模态

时间:2016-10-07 09:11:29

标签: javascript html twitter-bootstrap reactjs jsx

我正在尝试创建一个由数据行组成的组件,单击这些组件时,打开一个包含与该表行相关的信息的模式。例如,当用户点击“团队1”时,会出现一个模式,显示一个新表格,显示分配给该团队的每个用户。

我已经设法使用手动提供的参数来实现这一点,但我不知道如何根据单击的表行动态显示模态数据。 Here is a link to a jsfiddle that i've made to show my problem.

    getInitialState: function () {
    return {
      teams:[
        {
          id: '1',
          teamName: 'team 1',
          users: ['dave', 'steve', 'jim', 'barry', 'tom', 'harry']
        },
      ]
    };


    render: function () {
    var self = this;
    var projectsTable = this.state.teams.map(function (obj, index) {
      return (
        <tr className="table-teamProject" key={index} data-toggle="modal" data-target="#projectUsersModal" data-id='3'>
          <div className="mCellsContainer">
            <div className="mCellsNames">{obj.teamName}</div>
            <div className="mCellsCount">{obj.users.length} Users</div>
          </div>
        </tr>
      );
    });

    var projectUsersModal = this.state.teams.map(function (obj, index) {
      return (
        <div className="modal projectUsersModal fade" id="projectUsersModal" tabIndex={-1} role="dialog" aria-labelledby="myModalLabel">
          <div className="modal-dialog" role="document">
            <div className="modal-content">
              </div>
            </div>
          </div>
      );
    });

    return (
      <div>
        <div className="projectsColContainer">
          <div className="panel panel-default">
            <div className="panel-heading">Projects</div>
            <table className="scroll-table">
              {projectsTable}
              {projectUsersModal}
            </table>
          </div>
        </div>
      </div>
    );
  }

2 个答案:

答案 0 :(得分:2)

render()方法正在为团队数组中的每个团队创建一个隐藏的模式,我想这将是一个隐藏的模式,无论用户是否请求显示模式(点击团队的链接)或不。更好的方法是按需创建特定模式,即当用户点击团队链接时。

这可以通过创建一个单击处理程序来完成,在该函数中你可以通过设置模态所在团队的id来修改状态,如下所示:

onClickTeam: function(teamId) {
  this.setState({ 
    openModalTeamId: this.state.openModalTeamId == teamId ? null : teamId 
  });
}

然后在您的render()方法中,您需要检查此openModalTeamId州属性是否具有某些价值,如果是这样,并且由于您正在那里存储团队的ID,您可能希望查看对于使用Array.prototype.find的州团队数组中的特定团队,然后使用返回的结果构建模态的内容。

render: function() {
  ...

  var modalBody;
  if (this.state.openModalTeamId) {
    var team = this.state.teams.find(function(el) {
      return el.id == self.state.openModalTeamId 
    });

    modalBody = 
      ...
      <div className="modal-body">
        Lets assume this is your modal containing the 
        following info about the selected team:
        <br /><br />
        {JSON.stringify(team)}
        <br /><br />
        <div onClick={(this.onClickTeam.bind(this, team.id))}>
          Click me to close
        </div>
      </div>
      ...
  }

  ...
}

完成后,您可以将新的modalBody变量附加到渲染的JSX中,就像使用projectUsersModal变量在代码中一样。如果没有点击任何团队,则此变量将为undefined,并且不会显示任何模式。

return (
  <div>
    <div className="projectsColContainer">
      <table className="scroll-table">
        {projectsTable}
        {modalBody}
      </table>
    </div>
  </div>
);

jsFiddle

答案 1 :(得分:0)

您可以使用https://github.com/fckt/react-layer-stack

它允许您同时使用闭包中的变量(如果您将其提供给&#34;使用&#34; Layer的属性,它将自动传播),还可以将事件数据从切换设置为模态窗口。你也可以拥有&#34; stack&#34; zIndex的图层,一个在另一个上。

import { Layer, LayerContext } from 'react-layer-stack'
// ... for each `object` in array of `objects`
const modalId = 'DeleteObjectConfirmation' + objects[rowIndex].id
return (
    <Cell {...props}>
        // the layer definition. The content will show up in the LayerStackMountPoint when `show(modalId)` be fired in LayerContext
        <Layer use={[objects[rowIndex], rowIndex]} id={modalId}> {({
            hideMe, // alias for `hide(modalId)`
            index } // useful to know to set zIndex, for example
            , e) => // access to the arguments (click event data in this example)
          <Modal onClick={ hideMe } zIndex={(index + 1) * 1000}>
            <ConfirmationDialog
              title={ 'Delete' }
              message={ "You're about to delete to " + '"' + objects[rowIndex].name + '"' }
              confirmButton={ <Button type="primary">DELETE</Button> }
              onConfirm={ this.handleDeleteObject.bind(this, objects[rowIndex].name, hideMe) } // hide after confirmation
              close={ hideMe } />
          </Modal> }
        </Layer>

        // this is the toggle for Layer with `id === modalId` can be defined everywhere in the components tree
        <LayerContext id={ modalId }> {({showMe}) => // showMe is alias for `show(modalId)`
          <div style={styles.iconOverlay} onClick={ (e) => showMe(e) }> // additional arguments can be passed (like event)
            <Icon type="trash" />
          </div> }
        </LayerContext>
    </Cell>)
// ...