formio / formio.js

JavaScript powered Forms with JSON Form Builder

Home Page:https://formio.github.io/formio.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue while fetching the file object with custom File input Component

prabhjotkaur10 opened this issue · comments

This is a sample code to create a file input component, where user can upload attach files in the input and get the files in the final submission

import React, { Component } from 'react';

import { ReactComponent } from '@formio/react';
import { CloudUpload } from '@material-ui/icons';
import ReactDOM from 'react-dom';

// import settingsForm from './Toggle.settingsForm';

/**
 * An example React component
 *
 * Replace this with your custom react component. It needs to have two things.
 * 1. The value should be stored is state as "value"
 * 2. When the value changes, call props.onChange(null, newValue);
 *
 * This component is very simple. When clicked, it will set its value to "Changed".
 */
const FileCustomComp = class extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: null,
      stringText: null,
      allFiles: [],
    };
  }

  onChange = (event) => {
    const file = event.target.files[0];
    const fileName = file ? file.name : null;
    const files = event.target.files;

    let allFiles = [];
    if (event.target.files.length > 0) {
      for (let index = 0; index < files.length; index++) {
        allFiles.push(files[index]);
      }
    }
    this.props.onChange(files);
  };

  render() {
    const { stringText, allFiles } = this.state;

    return (
      <div>

        <input
          type="file"
          multiple
          name={this.props.component.key}
          onChange={this.onChange}
        />
      </div>
    );
  }
};

export default class CustomFileInput extends ReactComponent {
  /**
   * This function tells the form builder about your component. It's name, icon and what group it should be in.
   *
   * @returns {{title: string, icon: string, group: string, documentation: string, weight: number, schema: *}}
   */
  static get builderInfo() {
    return {
      title: 'Custom file',
      icon: 'file',
      group: 'Data',
      documentation: '',
      weight: 10,
      schema: CustomFileInput.schema(),
    };
  }

  /**
   * This function is the default settings for the component. At a minimum you want to set the type to the registered
   * type of your component (i.e. when you call Components.setComponent('type', MyComponent) these types should match.
   *
   * @param sources
   * @returns {*}
   */
  static schema() {
    return ReactComponent.schema({
      type: 'FileCustomComp',
      label: 'Upload',
      key: 'file',
      image: false,
      uploadOnly: false,
    });
  }

  /*
   * Defines the settingsForm when editing a component in the builder.
   */
  // static editForm = settingsForm;

  /**
   * This function is called when the DIV has been rendered and added to the DOM. You can now instantiate the react component.
   *
   * @param DOMElement
   * #returns ReactInstance
   */
  attachReact(element) {
    return ReactDOM.render(
      <FileCustomComp
        component={this.component} // These are the component settings if you want to use them to render the component.
        value={this.dataValue} // The starting value of the component.
        onChange={this.updateValue} // The onChange event to call when the value changes.
      />,
      element
    );
  }

  /**
   * Automatically detach any react components.
   *
   * @param element
   */
  detachReact(element) {
    if (element) {
      ReactDOM.unmountComponentAtNode(element);
    }
  }
}

I have following schema for showing the above component

const builderOptions = {
    // resource: false,
    basic: {
      title: 'Mostly Used',
      weight: 0,
      components: {
        toggleCustomComp: false,
        datetime: true,
        signature: true,
      },
    },
    advanced: {
      title: 'Extras',
      weight: 20,
      components: {
        // premium component
        recaptcha: true,
        form: true,
        resource: false,
        unknown: false,
        datetime: false,
        signature: false,
        FileCustomComp: {
          title: 'Upload file',
          key: '_file_others',
          icon: 'file',
          schema: {
            type: 'FileCustomComp',
            label: 'Upload file',
            key: '_file_others',
            input: true,
            inputType: 'file',
            persistent: true,
            image: true,
            dataValue: null,
          },
        },
      },
    },
    layout: {
      title: 'Format',
    },
    premium: false,
  };

I am able to attach file from "FileCustomComp" component, I can even see the file object, but when I submit the form then file objects is returned as empty file. I am not able to understand where is the issue. when I submit a simple string from the "FileCustomComp" for testing then things work fine, its only the file object that is not being returned in the form.