Redux表单材料用户界面:使用嵌套列表进行选择时不起作用 [英] Redux Form Material UI: Select with Nested Lists not working

查看:39
本文介绍了Redux表单材料用户界面:使用嵌套列表进行选择时不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些情况下,我需要显示项目的分组列表: https://v0.material-ui.com/#/components/list (转到嵌套列表)

I have a situation where I need to show grouped lists of items: https://v0.material-ui.com/#/components/list (Go to Nested Lists)

  1. redux-form Select字段可以使用< ListItem/> 而不是< MenuItem/> 吗?

我无法从嵌套下拉列表中选择任何项目.Redux的 onChange 回调不会启动.

I can't select any item from the nested dropdown. Redux's onChange callback doesn't fire up.

这是代码:形式:

<form>
    <Field
            name="camops"
            normalize={normalizeMultipleSelectValues}
            component={MySelectFormField}
            floatingLabelText="Item(s)"
            fullWidth
            multiple
          />
</form>

组件 MySelectFormField :

import get from 'lodash/get';
import groupBy from 'lodash/groupBy';
import isEmpty from 'lodash/isEmpty';
import { List, ListItem } from 'material-ui/List';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Typography from '@material-ui/core/Typography';
import SelectFormField from './common/SelectFormField';

class MySelectFormField extends Component {
  static propTypes = {
    bookingId: PropTypes.string,
    multiple: PropTypes.bool,
    disabled: PropTypes.bool,
    input: PropTypes.object.isRequired,
    camops: PropTypes.array,
    camopsFetch: PropTypes.func.isRequired,
  };

  static defaultProps = {
    bookingId: null,
    multiple: false,
    disabled: false,
    camops: [],
  };

  componentDidMount() {
    const { camopsFetch } = this.props;

    camopsFetch();
  }

  renderListItems(data) {
    let listItems = null;

    if (!isEmpty(data)) {
      listItems = Object.keys(data).map(region => {
        const count = data[region].length;

        const nestedItems = this.renderNestedListItem(data[region]);

        const primaryText = (
          <Typography variant="h6" component="div">
            {`${region}(${count})`}
          </Typography>
        );

        return (
          <ListItem
            key={region}
            primaryText={primaryText}
            initiallyOpen={true}
            primaryTogglesNestedList={true}
            nestedItems={nestedItems}
          />
        );
      });
    }

    return listItems;
  }

  renderNestedListItem(data) {
    let nestedList = null;

    if (!isEmpty(data)) {
      nestedList = data.map(camop => {
        const uuid = get(camop, 'uuid', '');
        const fullName = get(camop, 'full_name', '');
        const email = get(camop, 'email', '');
        const label = `${fullName} (${email})`.trim();

        let checked = false;
        if (this.props.multiple) {
          checked = this.props.input.value.indexOf(uuid) > -1;
        }

        return <ListItem key={uuid} value={uuid} primaryText={label} checked={checked} />;
      });
    }

    return nestedList;
  }

  render() {
    const { bookingId, disabled, camops, camopsFetch, ...restProps } = this.props;

    const hasCamOps = !!camops && !!camops.length;
    const enabled = !disabled && hasCamOps;
    let groupedCamops = groupBy(camops, 'region');

    // Sort the grouped camops
    groupedCamops = Object.keys(groupedCamops)
      .sort()
      .reduce((r, k) => Object.assign(r, { [k]: groupedCamops[k] }), {});

    const listItems = this.renderListItems(groupedCamops);

    return (
      <SelectFormField {...restProps} disabled={!enabled}>
        <List style={{ maxHeight: '100%', overflow: 'auto' }}>{listItems}</List>
      </SelectFormField>
    );
  }
}

export default MySelectFormField;

组件 SelectFormField :

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { SelectField } from 'redux-form-material-ui';

class SelectFormField extends Component {
  static propTypes = {
    children: PropTypes.node,
    helpText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
    meta: PropTypes.object.isRequired,
    input: PropTypes.object.isRequired,
    isRequired: PropTypes.bool,
  };

  static defaultProps = {
    children: null,
    helpText: null,
    isRequired: false,
  };

  render() {
    const { children, helpText, isRequired, ...restProps } = this.props;

    return (
      <div className="select-form-field">
        <SelectField {...restProps}>{children}</SelectField>

        {!!isRequired && <span className="select-form-field__marker">*&nbsp;</span>}

        {!!helpText && <div className="form-help-text">{helpText}</div>}
      </div>
    );
  }
}

export default SelectFormField;

推荐答案

我使用名为 renderSelectField 的自定义选择字段制作了 redux-form 字段.

I've made a redux-form field using a custom select field named renderSelectField.

select中的options项是一个普通的html option:

The options items in the select is a regular html option:

import { Field, reduxForm } from 'redux-form'

<Field name="type" component={renderSelectField} label="Type">
      {materialTypes.map(materialType => {
        return (
          <option key={materialType} value={materialType}>
            {materialType}
          </option>
        )
      })}
</Field>

renderSelectField :

The renderSelectField:

import SelectField from 'material-ui/Select'
import FormControl from 'material-ui/Form/FormControl'
import InputLabel from 'material-ui/Input/InputLabel'
import { FormHelperText } from 'material-ui'

const renderSelectField = ({
  input,
  label,
  meta: { touched, error },
  children,
  ...custom
}) => (
  <FormControl className="admin-form-field">
    <InputLabel error={touched && error}>{label}</InputLabel>
    <SelectField
      floatingLabelText={label}
      error={touched && error}
      {...input}
      children={children}
      {...custom}
    />
    <FormHelperText error={touched && error}>{error}</FormHelperText>
  </FormControl>
)

不需要 redux-form-material-ui .只是 redux-form material-ui .

希望它会有所帮助.

这篇关于Redux表单材料用户界面:使用嵌套列表进行选择时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆