How to add custom toggle button in formsflow.ai

333 Views Asked by At

I am using latest version of formsflow.ai and I want to create a custom toggle button. How can I do that in formflow.ai. I refer the following documents of formio to do that.

I am expecting to include a custom toggle button in drag and drop mechanism of formsflow.ai

1

There are 1 best solutions below

0
On

step 1:create the components inside the forms-flow-web in the following order Custom Toggle button structure

step 2:Toggle.js code

import React  from "react";
import ReactDOM from "react-dom";
import { ReactComponent } from "react-formio";
import settingsForm from "./Toggle.settingsForm";
import ToggleCustomComp from "./Togglechange";


export default class Toggle 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: "Toggle",
      icon: "square",
      group: "basic",
      documentation: "",
      weight: 120,
      schema: Toggle.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: "toggleCustomComp",
      label: "ToggleButton"
    });
  }

  /*
   * 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) {
    let instance;
    return ReactDOM.render(
      <ToggleCustomComp
        ref={(refer) => {instance = refer;}}
        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}
        data={this.data}
        disabled={this.disabled}
         // The onChange event to call when the value changes.
      />,
      element,() => (this.reactInstance = instance)
    );
  }

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

step 3:Toggle.settingsForm.js

    import baseEditForm from 'formiojs/components/_classes/component/Component.form';

const settingsForm = (...extend) => {
  return baseEditForm([
    {
      key: 'display',
      components: [
        {
          // You can ignore existing fields.
          key: 'placeholder',
          ignore: true,
        },
      ]
    },
    {
      key: 'data',
      components: [],
    },
    {
      key: 'validation',
      components: [],
    },
    {
      key: 'api',
      components: [],
    },
    {
      key: 'conditional',
      components: [],
    },
    {
      key: 'logic',
      components: [],
    },
  ], ...extend);
}

export default settingsForm;

step 4:Togglechange.jsx

import React, {Component} from 'react';
import '../Toggle/toggle.css';
/**
 * An example React component this is simply a controlled input element.
 *
 */
export default class ToggleCustomComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: props.value
    }
  }

  updateCommentData = (event) => {
    //const {type} = this.props.component;
    this.setState({value: {checked:event.target.checked}}, () => this.props.onChange(this.state.value));
  };

  render() {
    const {disabled, name} = this.props;
    let { value } = this.state;
    const checked = value?.checked || false;
    return  (
      /*<input type="text" value={value} className={this.props.component.customClassName} onChange={this.setValue}></input>*/
      // <input type="checkbox" id="vehicle3" name="vehicle3" value="Boat"></input>
      <label class="switch">
      <input
        name={name}
        value={checked}
        type="checkbox" 
        className="form-control"
        onChange={(e)=>this.updateCommentData(e)}
        disabled={disabled}
      />
      <span class="slider round" />
      </label>
    );
  }
};

step 5 :css file

.switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 34px;
  }
  
  .switch input { 
    opacity: 0;
    width: 0;
    height: 0;
  }
  
  .slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    -webkit-transition: .4s;
    transition: .4s;
  }
  
  .slider:before {
    position: absolute;
    content: "";
    height: 26px;
    width: 26px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
  }
  
  input:checked + .slider {
    background-color: #2196F3;
  }
  
  input:focus + .slider {
    box-shadow: 0 0 1px #2196F3;
  }
  
  input:checked + .slider:before {
    -webkit-transform: translateX(26px);
    -ms-transform: translateX(26px);
    transform: translateX(26px);
  }
  
  /* Rounded sliders */
  .slider.round {
    border-radius: 34px;
  }
  
  .slider.round:before {
    border-radius: 50%;
  }

step 6:index.js file

import TextAreaWithAnalytics from "./TextAreaWithAnalytics/TextAreaWithAnalytics";
import Toggle from "./Toggle/Toggle";

const components = {
  textAreaWithAnalytics: TextAreaWithAnalytics,
  toggleCustomComp: Toggle
};

export default components;