具有主/从字段处理的Redux表单-显示/隐藏字段

问题描述

我正在开发一个应用程序-使用redux表单和材料ui组件。在我需要填写的表格中-字段上需要进行某种主/从处理。

因此,如果有单选按钮-袋糖果-并且用户选择其他-则出现other_sweets的文本字段。如果他们选择其他选项,它将隐藏。

在字段制作工具中,您可以看到

  1. 我从道具中获取了fields数组并设置了状态-this.state.fields-2.在组件上进行了挂载-然后,我循环遍历this.state.fields并将可见性属性应用于每个对象-第一次运行时设置为可见的所有对象-我还选择了奴隶及其与主人的关系。设置this.state.slaves后,我将调用hideSlaves()
  2. hideSlaves再次遍历这些字段,这次将所有从属设置为可见性为假。
  3. 在onHandle内-在任何字段更改时都会调用-字段名,newValue回来-我使用这些informaton片段遍历从属对象,并且如果fieldName是主字段,并且如果newValue是触发器,那么-在this.field.states中显示或隐藏从属字段-以便此代码正常工作-但我渴望改进代码库以使其更易于管理-避免以较少的步骤循环或处理逻辑

字段对象的一个​​例子是这样的-这个对象将显示所有可能的字段以帮助测试表单-所有输入都是不同的-诸如select / radio框之类的东西是相似的-但复选框被视为分组资产-因此,我尝试至少保留属性名称上的数组约定。

let fieldsForm = [
    {
      "type": "text","label": "Lucy","name": ["lucy"],"options": [],"validate": ["required"],},{
      "type": "slider","label": "Ranger","name": ["ranger"],{
      "type": "hidden","label": "Barbara","name": ["barbara"],//"validate": ["required"],{
      "type": "buttons","label": "Sweets2","name": ["sweets2"],"options": [
        {
          "label": "Sherbert","value": "0"
        },{
          "label": "Peach Jam","value": "1"
        },{
          "label": "Almond Butter","value": "2"
        }
      ],{
      "type": "radio","label": "Bag of sweets","name": ["bag_of_sweets"],"options": [
        {
          "label": "Grape Jelly",{
          "label": "Oreo",{
          "label": "Smores","value": "2"
        },{
          "label": "Other -xx","value": "3"
        }
      ],"slave":{
        "name": ["other_sweet"],"onMasterVal": "3"
      }
    },{
      "type": "text","label": "Other sweet","name": ["other_sweet"],{
      "type": "select","label": "Shopping basket","name": ["shopping_basket"],"options": [
        {
          "label": "Pecan Pie",{
          "label": "Red Velvet Cake",{
          "label": "Cookie Dough",{
      "type": "toggle","label": "Agree","name": ["agree"],{
      "type": "date","label": "Start Date","name": ["start_date"],{
      "type": "checkBox","label": "Groceries","name": ["peanuts","grapes","oranges"],"options": [
        {
          "label": "Peanuts"
        },{
          "label": "Grapes"
        },{
          "label": "Oranges"
        }
      ],{
      "type": "comment","label": "Comment Box","name": ["comment"],}
  ];

FieldMaker.js

import React,{ Component } from 'react';
import { Field,Fields } from 'redux-form';

import renderTextField from '../../_SharedFormComponents/renderTextField';
import renderDateField from '../../_SharedFormComponents/renderDateField';
import renderRadioGroup from '../../_SharedFormComponents/renderRadioGroup';
import renderHiddenField from '../../_SharedFormComponents/renderHiddenField';
import renderSelectGroup from '../../_SharedFormComponents/renderSelectGroup';
import renderToggle from '../../_SharedFormComponents/renderToggle';
import renderGroupedCheckBoxes from '../../_SharedFormComponents/renderGroupedCheckBoxes';
import renderSlider from '../../_SharedFormComponents/renderSlider';
import renderButtonGroup from '../../_SharedFormComponents/renderButtonGroup';

import FormControl from '@material-ui/core/FormControl';
import Formlabel from '@material-ui/core/Formlabel';
import FormGroup from '@material-ui/core/FormGroup';

class FieldMaker extends Component {
 
 constructor(props,context) {
    super(props,context);
    this.onHandle = this.onHandle.bind(this);
    this.state = {
      fields: this.props.fields
    };
 }  

componentDidMount() {

    //identify slaves and hide by default
    let slaves = [];
    for(let i = 0; i < this.state.fields.length; i++){
      //apply field visibility in all states
      this.state.fields[i]["visibility"] = true;

      //create slave array
      if(this.state.fields[i].slave){
        let slaveRelationObj = {
          "master": this.state.fields[i].name,"slave" : this.state.fields[i].slave.name,"onMasterVal": this.state.fields[i].slave.onMasterVal
        }
        slaves.push(slaveRelationObj);
      }

      console.log("slaves",slaves);
    }

    this.setState({ slaves: slaves },this.hideSlaves);

  
}

hideSlaves(){

  if(this.state.slaves){  

    for(let i = 0; i < this.state.fields.length; i++){
      for(let j = 0; j < this.state.slaves.length; j++){


          if(this.state.slaves[j].slave[0] === this.state.fields[i].name[0]){
              //hide only slaves
              this.state.fields[i]["visibility"] = false;            
          }
      }
    }

  }
}


 renderSwitch(param) {
    switch(param) {
        case "text":
          return renderTextField;
        case "hidden":
          return renderHiddenField;
        case "radio":
          return renderRadioGroup;
        case "select":
          return renderSelectGroup;
        case "checkBox":
          return renderGroupedCheckBoxes;          
        case "toggle":
          return renderToggle;
        case "date":
          return renderDateField;
        case "comment":
          return renderTextField;
        case "slider":
          return renderSlider;
        case "buttons":
          return renderButtonGroup;
        default:
          return renderTextField;
    }
  }

  onHandle(fieldName,newValue){

    if(this.state.slaves){
      //loop over the slaves

      for(let i = 0; i < this.state.slaves.length; i++){
        if(this.state.slaves[i].master.includes(fieldName)){
            if(this.state.slaves[i].onMasterVal === newValue){
              console.log("MASTER FIELD IS ON MASTER VAL -- set slave to visible show me");
            
              //find slave and set field obj to toggle visibility
              for(let j = 0; j < this.state.fields.length; j++){


                if(this.state.slaves[i].slave[0] === this.state.fields[j].name[0]){

                  //this.setState({ slaves: slaves },this.hideSlaves);
                  this.state.fields[j].visibility = true;
                }

              }
            } else{



              //find slave and set field obj to toggle visibility
              for(let j = 0; j < this.state.fields.length; j++){


                if(this.state.slaves[i].slave[0] === this.state.fields[j].name[0]){

                  console.log("FOUND THE SLAVE -- FOUND THE FIELD - SHOW ME!")
                  this.state.fields[j].visibility = false;
                }

              }


            }


        }
      }

      this.setState({ fields: this.state.fields });
    }



    this.props.fieldChanged(fieldName,newValue);
  }
 
  render() {

    return (
      <>
          {
            this.state.fields.map((item,j) => {
              if(item.visibility){


                if (item.type !== "checkBox") {
                  return(
                      <Field 
                        key={j} 
                        name={item.name[0]} 
                        label={item.label} 
                        component={this.renderSwitch(item.type)}
                        type={(item.type === "radio" || item.type === "date" || item.type === "slider")? null :  item.type}
                        options={item.options}
                        rows={item.type === "comment" ? 4 : null}
                        multiline={item.type === "comment" ? true : false}
                        onChange={(item.type === "slider" || item.type === "date" || item.type === "buttons")? null : (e,value) => {
                            console.log("into on change")
                            this.onHandle(e.target.name,value);
                        }}
                        onHandle={this.onHandle}
                      />
                  )
                } else {
                   return(
                      <Fields
                        key={j} 
                        names={item.name}
                        label={item.label}
                        component={this.renderSwitch(item.type)}
                        options={item.options}
                        onHandle={this.onHandle}
                      />
                   )
                }

              }

            })
          }
      </>
    )
  }

}

export default FieldMaker

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)