【问题标题】:React Material UI deselectReact Material UI 取消选择
【发布时间】:2018-01-30 15:29:06
【问题描述】:

我正在关注this 示例以在我的应用程序中实现 MUI 选择字段。我可以让代码为我工作,但我有一些问题。它不允许我取消选择我选择的值。如果值不在呈现的列表中,我也希望能够通过键入来添加新值。这可能吗?

这是我的代码:

export class FormPage extends React.Component {

    constructor() {
      super();

      this.state = {'resource': '', 'catvalues': '', 'subcatvalues': '', 'prodvalues': '', 'solutionValues': '', 'nsocValues': '', 'statusValues': ''};

      this.selectionRenderer1 = this.selectionRenderer1.bind(this);
      this.selectionRenderer2 = this.selectionRenderer2.bind(this);
      this.selectionRenderer3 = this.selectionRenderer3.bind(this);
      this.selectionRenderer4 = this.selectionRenderer4.bind(this);
      this.selectionRenderer5 = this.selectionRenderer5.bind(this);
      this.selectionRenderer6 = this.selectionRenderer6.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
      this.addResource = this.addResource.bind(this);
    }

    handleChange1 = (event, key, catvalues) => {
      this.setState({catvalues});
    };

    selectionRenderer1 = catvalues => {
      // change the default comma separated rendering
      return (
          <span style={{color: '#ff4081'}}>
              {catvalues.join('; ')}
          </span>
      ).bind(this);
    };

    menuItems1(catvalues) {
      return categorylist.map(cl => (
          <MenuItem
              key={cl}
              insetChildren
              checked={catvalues.includes(cl)}
              value={cl}
              primaryText={cl}
          />
      ));
    }

    handleChange2 = (event, key, subcatvalues) => {
      this.setState({subcatvalues});
    };

    selectionRenderer2 = subcatvalues => {
      // change the default comma separated rendering
      return (
          <span style={{color: '#ff4081'}}>
              {subcatvalues.join('; ')}
          </span>
      );
    };

    menuItems2(subcatvalues) {
      return subcategorylist.map(scl => (
          <MenuItem
              key={scl}
              insetChildren
              checked={subcatvalues.includes(scl)}
              value={scl}
              primaryText={scl}
          />
      ));
    }

    handleChange3 = (event, key, prodvalues) => {
      this.setState({prodvalues});
    };

    selectionRenderer3 = prodvalues => {
      // change the default comma separated rendering
      return (
          <span style={{color: '#ff4081'}}>
              {prodvalues.join('; ')}
          </span>
      ).bind(this);
    };

    menuItems3(prodvalues) {
      return prodlist.map(pl => (
          <MenuItem
              key={pl}
              insetChildren
              checked={prodvalues.includes(pl)}
              value={pl}
              primaryText={pl}
          />
      ));
    }

    handleChange4 = (event, key, solutionValues) => {
      this.setState({solutionValues});
    };

    selectionRenderer4 = solutionValues => {
      // change the default comma separated rendering
      return (
          <span style={{color: '#ff4081'}}>
                          {solutionValues.join('; ')}
                  </span>
      ).bind(this);
    };

    menuItems4(solutionValues) {
      return solutionList.map(sl => (
          <MenuItem
              key={sl}
              insetChildren
              checked={solutionValues.includes(sl)}
              value={sl}
              primaryText={sl}
          />
      ));
    }

    handleChange5 = (event, key, nsocValues) => {
      this.setState({nsocValues});
    };

    selectionRenderer5 = nsocValues => {
      // change the default comma separated rendering
      return (
          <span style={{color: '#ff4081'}}>
                          {nsocValues.join('; ')}
                  </span>
      ).bind(this);
    };

    menuItems5(nsocValues) {
      return nsocList.map(nl => (
          <MenuItem
              key={nl}
              insetChildren
              checked={nsocValues.includes(nl)}
              value={nl}
              primaryText={nl}
          />
      ));
    }

    handleChange6 = (event, key, statusValues) => {
      this.setState({statusValues});
    };

    selectionRenderer6 = statusValues => {
      // change the default comma separated rendering
      return (
          <span style={{color: '#ff4081'}}>
                          {statusValues.join('; ')}
                  </span>
      ).bind(this);
    };

    menuItems6(statusValues) {
      return statusList.map(sll => (
          <MenuItem
              key={sll}
              insetChildren
              checked={statusValues.includes(sll)}
              value={sll}
              primaryText={sll}
          />
      ));
    }

    addResource(resource) {
      console.log('Adding resource:', resource);
      $.ajax({
        type: 'POST', url: '/api/resources', contentType: 'application/json',
        data: JSON.stringify(resource),
        success: function(data) {
          console.log(data);
          browserHistory.push('/home');
        }.bind(this),
        error: function(xhr, status, err) {
          // ideally, show error to user.
          console.log('Error adding resource:', err);
        }
      });
    }

    handleSubmit(e) {
      e.preventDefault();
      var form = document.forms.resourceAdd;
      this.addResource({
        category: form.category.value,
        subcategory: form.subcategory.value,
        product: form.product.value,
        solution: form.solution.value,
        weight: form.weight.value,
        nsoc: form.nsoc.value,
        status: form.status.value,
        date_product_added: form.date_product_added.value,
        design_status: form.design_status.value,
        design_combined: form.design_combined.value,
        implement_status: form.implement_status.value,
        implement_combined: form.implement_combined.value,
        operate_status: form.operate_status.value,
        operate_combined: form.operate_combined.value});
      // clear the form for the next input
      form.category.value = ''; form.subcategory.value = ''; form.product.value = ''; form.solution.value = ''; form.weight.value = ''; form.nsoc.value = ''; form.status.value = '';form.date_product_added.value = '';
      form.design_status.value = ''; form.design_combined.value = ''; form.implement_status.value = ''; form.implement_combined.value = ''; form.operate_status.value = ''; form.operate_combined.value = '';
    }

    render() {
      const {catvalues} = this.state;
      const floatingLabelText1 = 'Categories' +
          (catvalues.length > 1 ? ` (${catvalues.length})` : '');

      const {subcatvalues} = this.state;
      const floatingLabelText2 = 'Sub Categories' +
          (subcatvalues.length > 1 ? ` (${subcatvalues.length})` : '');

      const {prodvalues} = this.state;
      const floatingLabelText3 = 'Products' +
          (prodvalues.length > 1 ? ` (${prodvalues.length})` : '');

      const {solutionValues} = this.state;
      const floatingLabelText4 = 'Solutions' +
          (solutionValues.length > 1 ? ` (${solutionValues.length})` : '');

      const {nsocValues} = this.state;
      const floatingLabelText5 = 'NSOC' +
          (nsocValues.length > 1 ? ` (${nsocValues.length})` : '');

      const {statusValues} = this.state;
      const floatingLabelText6 = 'Status' +
          (statusValues.length > 1 ? ` (${statusValues.length})` : '');

      return (
        <PageBase title="Form Page"
                  navigation="Application / Form Page">
                                                  <form>

                                                      <SelectField
                              multiple
                              floatingLabelText={floatingLabelText1}
                              fullwidth={true}
                              value={catvalues}
                              onChange={this.handleChange1}
                              selectionRenderer={this.selectionRenderer1}
                          >
                                                              {this.menuItems1(catvalues)}
                                                      </SelectField>

                                                      <SelectField
                              multiple
                              floatingLabelText={floatingLabelText2}
                              fullwidth
                              value={subcatvalues}
                              onChange={this.handleChange2}
                              selectionRenderer={this.selectionRenderer2}
                          >
                                                              {this.menuItems2(subcatvalues)}
                                                      </SelectField>

                                                      <SelectField
                              multiple
                              floatingLabelText={floatingLabelText3}
                              fullwidth
                              value={prodvalues}
                              onChange={this.handleChange3}
                              selectionRenderer={this.selectionRenderer3}
                          >
                                                              {this.menuItems3(prodvalues)}
                                                      </SelectField>

                                                    <SelectField
                                                        multiple
                                                        floatingLabelText={floatingLabelText4}
                                                        fullwidth
                                                        value={solutionValues}
                                                        onChange={this.handleChange4}
                                                        selectionRenderer={this.selectionRenderer4}
                                                    >
                                                        {this.menuItems4(solutionValues)}
                                                    </SelectField>

                                                          <TextField
                hintText="Weight"
                floatingLabelText="Weight"
                fullWidth
            />

                                                    <SelectField
                                                        multiple
                                                        floatingLabelText={floatingLabelText5}
                                                        fullwidth
                                                        value={nsocValues}
                                                        onChange={this.handleChange5}
                                                        selectionRenderer={this.selectionRenderer5}
                                                    >
                                                        {this.menuItems5(nsocValues)}
                                                    </SelectField>


                                                    <SelectField
                                                        multiple
                                                        floatingLabelText={floatingLabelText6}
                                                        fullwidth
                                                        value={statusValues}
                                                        onChange={this.handleChange6}
                                                        selectionRenderer={this.selectionRenderer6}
                                                    >
                                                        {this.menuItems6(statusValues)}
                                                    </SelectField>

                                                          <DatePicker
                hintText="Date Product Added"
                floatingLabelText="date_product_added"
                fullWidth/>

                                                          <TextField
                hintText="Design Status"
                floatingLabelText="design_status"
                fullWidth
            />

                                                          <TextField
                hintText="Design Players"
                floatingLabelText="design_combined"
                fullWidth
            />

                                                          <TextField
                hintText="Implement Status"
                floatingLabelText="implement_status"
                fullWidth
            />

                                                          <TextField
                hintText="Implement Players"
                floatingLabelText="implement_combined"
                fullWidth
            />

                                                          <TextField
                hintText="Operate Status"
                floatingLabelText="operate_status"
                fullWidth
            />

                                                          <TextField
                hintText="Operate Players"
                floatingLabelText="operate_players"
                fullWidth
            />



                                                          <Divider/>

                                                          <div style={styles.buttons}>
                                                                  <Link to="/">
                                                                          <RaisedButton label="Cancel"/>
                                                                  </Link>

                                                                  <RaisedButton label="Save"
                            style={styles.saveButton}
                            type="submit"
                            onClick={this.handleSubmit.bind(this)}
                            primary/>
                                                          </div>
                                                  </form>
                                          </PageBase>

    );
    }
}

export default FormPage;

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    我建议您根据发送到组件的事件来定位不同的行为(单击事件触发正常行为,双击切换到向集合添加名称的输入)或在之前或之后添加第二个组件你的选择也一样(想像一个按钮组和 pre-post-button 触发开关)。

    然后,您可以使用当前的 staterender 中呈现的组件之间切换。

    您的组件在我看来有点大。我会尝试将其分解为子组件(编号的事件处理程序尤其看起来像是子组件的道具)。

    编辑

    See this CodePen.
    它是我使用 Foundation 6 编写的前一个示例的一个分支。同样的原则也适用于 Material-UI,因为它的要点涉及 ReactJS。
    听双击选择输入不起作用:p。我添加了一个更改组件状态的按钮。父组件的 render 方法打开该状态并相应地呈现不同的输入。

    我使用这个技巧在其他项目中根据用户的权限在只读字段和输入字段之间切换。双击在该用例上完美运行,并提供了超级用户体验。

      ...
    
      switchComponent(){
        this.setState({
          inputShown : !this.state.inputShown
        });
      }
    
      render() {
        const children = this.state.inputShown ? 
          (<Input label="Add: " id="input1" onChange={this.inputChanged} className="columns small-4" />)
              :
          (<Select label="Choose: " id="select1" onChange={this.selectChanged} className="columns small-4">
              {this.state.options.map((o,i) => <Option key={i} label={o} defaultValue={o}/>)}
            </Select>)
        return <div>
          <div className="row">
            <a className="button primary columns small-1" onClick={this.switchComponent}>Switch</a>
            {children}
          </div>
        </div>;
      }
    
      ...
    

    NBCSS 完全没有调整,它是 Foundation 6 的股票。不过,您可以绑定切换按钮和选择/输入与 CSS 轻松。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-26
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 2018-04-11
      • 2023-03-16
      • 2019-12-08
      相关资源
      最近更新 更多