当表单具有文件输入类型时,如何使用Material UI表单验证器成功提交表单

问题描述 投票:0回答:1

我有一个使用实质性UI表单验证器构建的表单。参见Material UI form Validator。表单具有文本和文件(多个)类型的输入。但是,当我使用内容类型提交表单时:将multipart / form-data作为请求标头,会发生两件事(我的表单数据未提交到数据库,上传的图像显示空对象)。当我使用content-type:application / json时,我的表单数据已提交到数据库,但是图像显示为空。在这两种情况下,当我检查浏览器的“网络”选项卡时,都可以看到formData,但图像显示的是空对象数组。

这是我的表格:

const CreateBusinessPartial = ()=>{
  
  const classes = UseStyles();
    const dispatch = useDispatch();

    useEffect(()=>dispatch(fetchCategories()), []);
    const categories = useSelector(state=>state).generalReducer.category;
    
   const handleSubmission= ()=>{
    console.log(formState);
    if(formState.image.length === 0){
      alert("You must include at least one image");
    }
    else{
      dispatch(postBusiness(formState));
    }
   
    
   };
   const handleInputChange=(e)=>{
    const inputName = e.target.name;
    const value = e.target.value;
    setFormState({...formState, [inputName]:value })
   };

  

  const handleFile=(e)=>{
    const fileValue =[];    
    for (var i = 0; i < e.target.files.length; ++i) {
      fileValue.push(e.target.files[i]);
  }
    setFormState({...formState, image:fileValue});
}

const handleChangeMultiple = (event) => {
  const { options } = event.target;
  const value = [];
  for (let i = 0, l = options.length; i < l; i += 1) {
    if (options[i].selected) {
      value.push(options[i].value);
    }
  }
  setFormState({...formState, category_id:value});
};

  
const [formState, setFormState] = useState({name: '', description: '', url:'', phone:'', address: '', category_id: [], email:'', image: []  });
  console.log(formState);

    return(<Grid container={true}  >
      <Grid xs={12} className={classes.innerGrid} container item justify="center"  alignItems="center" >
       
       <ValidatorForm
          //ref="form"
          // className="form"
          encType="multipart/form-data"
          
          onSubmit={handleSubmission}
          onError={errors => console.log(errors)}>
     
        <TextValidator
              className={classes.formInput}
              label="Business Name"
              fullWidth={true}
              // variant="outlined"
              name="name"
              onChange={handleInputChange}
              value={formState.name}
              margin="none"
              type="text"
              validators={['required']}
              errorMessages={['This field is required',]}
              autoFocus={true}

          />
     
      <FormControl className={classes.formControl}>
        <InputLabel shrink htmlFor="select-multiple-native">
          Business Category
        </InputLabel>
        <Select
          multiple
          native
          value={formState.category_id}
          onChange={handleChangeMultiple}
          inputProps={{
            id: 'select-multiple-native',
          }}
        >
          {categories.map((category) => (
            <option key={category.id} value={category.id}>
              {category.name}
            </option>
          ))}
        </Select>
      </FormControl>

       
       
                
        
        <TextValidator
            className={classes.formInput}
            label="url"
            fullWidth={true}
            // variant="outlined"
            name="url"
            margin="none"
            type="url"
            onChange= {handleInputChange}
            // validators={['isUrl']}
            // errorMessages={['Must be a weblink']}
            value={formState.url}

        />

    <TextValidator
            className={classes.formInput}
            label="Email"
            fullWidth={true}
            // variant="outlined"
            name="email"
            margin="none"
            type="email"
            onChange= {handleInputChange}
            // validators={['isemail']}
            // errorMessages={['Must be a weblink']}
            value={formState.email}

        />
                
        
        <TextValidator
            className={classes.formInput}
            label="Phone(s)"
            fullWidth={true}
            // variant="outlined"
            name="phone"
            margin="none"
            type="text"
            onChange= {handleInputChange}
            validators={['required']}
            errorMessages={['This field is required']}
            value={formState.phone}

        />
                
        
        <TextValidator
            className={classes.formInput}
            label="Address"
            fullWidth={true}
            // variant="outlined"
            name="address"
            margin="none"
            type="text"
            onChange= {handleInputChange}
            // validators={['required']}
            errorMessages={['This field is required']}
            value={formState.address}

        />

        
       
              
        
        <TextValidator
              className={classes.formInput}
              label="Description"
              fullWidth={true}
              // variant="outlined"
              name="description"
              margin="none"
              type="text"
              multiline={true}
              rows={3}
              onChange= {handleInputChange}
              validators={['required']}
              errorMessages={['This field is required']}
              value={formState.description}

          />

          <input type="file" name="image" multiple onChange={handleFile} />
         

          <input
              accept="image/*"
              className={classes.input}
              style={{ display: 'none' }}
              id="raised-button-file"
              multiple
              type="file"
              name="image"
              onChange={handleFile}
            />
            <label htmlFor="raised-button-file">
              <Button variant="raised" component="span" className={classes.button}>
                Upload
              </Button>
            </label> 
    
       
        <Button color="primary"  className={classes.btn} type="submit"  variant="contained">Submit</Button>
              
               

      </ValidatorForm>


    </Grid>
  </Grid>)
}

这是我发出axios请求的标头:

const header=(token=undefined)=>({
  headers: {
    'Accept': 'application/json',
    'Authorization': `Bearer ${token}`,
    //'content-type': 'application/json',
    'content-type': 'multipart/form-data',
  }
 });

我想念的是什么。我需要能够将图像推送到服务器

javascript reactjs api content-type
1个回答
0
投票

您在enctype组件上错误地写入了ValidatorForm属性。

encType更改为enctype

 <ValidatorForm enctype="multipart/form-data">
     ....
 </ValidatorForm>
© www.soinside.com 2019 - 2024. All rights reserved.