Rajan Bosh
Rajan Bosh

Reputation: 249

rendering formio custom component is not working

I have one formio js file like checkbox.js,and i register that component into my custom_formio component as follows...

checkbox.js

import _ from 'lodash';
import BaseComponent from 'formiojs/components/base/Base';

export default class CheckBoxComponent extends BaseComponent {
  static schema(...extend) {
    return BaseComponent.schema({
      type: 'checkbox',
      inputType: 'checkbox',
      label: 'Checkbox',
      key: 'checkbox',
      dataGridLabel: true,
      labelPosition: 'right',
      value: '',
      name: ''
    }, ...extend);
  }
 
  static get builderInfo() {
    return {
      title: 'Checkbox',
      group: 'basic',
      icon: 'fa fa-check-square',
      documentation: 'http://help.form.io/userguide/#checkbox',
      weight: 50,
      schema: CheckBoxComponent.schema()
    };
  }
 
  get defaultSchema() {
    return CheckBoxComponent.schema();
  }
 
  get defaultValue() {
    return this.component.name ? '' : (this.component.defaultValue || false).toString() === 'true';
  }
 
  get hasSetValue() {
    return this.hasValue();
  }
 
  elementInfo() {
    const info = super.elementInfo();
    info.type = 'input';
    info.changeEvent = 'click';
    info.attr.type = this.component.inputType || 'checkbox';
    info.attr.class = 'form-check-input';
    if (this.component.name) {
      info.attr.name = `data[${this.component.name}]`;
    }
    info.attr.value = this.component.value ? this.component.value : 0;
    return info;
  }
 
  build() {
    if (this.viewOnly) {
      return this.viewOnlyBuild();
    }
 
    if (!this.component.input) {
      return;
    }
    this.createElement();
    this.input = this.createInput(this.element);
    this.createLabel(this.element, this.input);
    if (!this.labelElement) {
      this.addInput(this.input, this.element);
    }
    this.createDescription(this.element);
    this.restoreValue();
    if (this.shouldDisable) {
      this.disabled = true;
    }
    this.autofocus();
    this.attachLogic();
  }
 
  get emptyValue() {
    return false;
  }
 
  isEmpty(value) {
    return super.isEmpty(value) || value === false;
  }
 
  createElement() {
    let className = `form-check ${this.className}`;
    if (!this.labelIsHidden()) {
      className += ` ${this.component.inputType || 'checkbox'}`;
    }
    this.element = this.ce('div', {
      id: this.id,
      class: className
    });
    this.element.component = this;
  }
 
  labelOnTheTopOrLeft() {
    return ['top', 'left'].includes(this.component.labelPosition);
  }
 
  labelOnTheTopOrBottom() {
    return ['top', 'bottom'].includes(this.component.labelPosition);
  }
 
  setInputLabelStyle(label) {
    if (this.component.labelPosition === 'left') {
      _.assign(label.style, {
        textAlign: 'center',
        paddingLeft: 0,
      });
    }
 
    if (this.labelOnTheTopOrBottom()) {
      _.assign(label.style, {
        display: 'block',
        textAlign: 'center',
        paddingLeft: 0,
      });
    }
  }
 
  setInputStyle(input) {
    if (!input) {
      return;
    }
    if (this.component.labelPosition === 'left') {
      _.assign(input.style, {
        position: 'initial',
        marginLeft: '7px'
      });
    }
 
    if (this.labelOnTheTopOrBottom()) {
      _.assign(input.style, {
        width: '100%',
        position: 'initial',
        marginLeft: 0
      });
    }
  }
 
  createLabel(container, input) {
    const isLabelHidden = this.labelIsHidden();
    let className = 'control-label form-check-label';
    if (this.component.input
      && !this.options.inputsOnly
      && this.component.validate
      && this.component.validate.required) {
      className += ' field-required';
    }
 
    this.labelElement = this.ce('label', {
      class: className
    });
    this.addShortcut();
 
    const labelOnTheTopOrOnTheLeft = this.labelOnTheTopOrLeft();
    if (!isLabelHidden) {
      // Create the SPAN around the textNode for better style hooks
      this.labelSpan = this.ce('span');
 
      if (this.info.attr.id) {
        this.labelElement.setAttribute('for', this.info.attr.id);
      }
    }
    if (!isLabelHidden && labelOnTheTopOrOnTheLeft) {
      this.setInputLabelStyle(this.labelElement);
      this.setInputStyle(input);
      this.labelSpan.appendChild(this.text(this.component.label));
      this.labelElement.appendChild(this.labelSpan);
    }
    this.addInput(input, this.labelElement);
    if (!isLabelHidden && !labelOnTheTopOrOnTheLeft) {
      this.setInputLabelStyle(this.labelElement);
      this.setInputStyle(input);
      this.labelSpan.appendChild(this.text(this.addShortcutToLabel()));
      this.labelElement.appendChild(this.labelSpan);
    }
    this.createTooltip(this.labelElement);
    container.appendChild(this.labelElement);
  }
 
  createInput(container) {
    if (!this.component.input) {
      return;
    }
    const input = this.ce(this.info.type, this.info.attr);
    this.errorContainer = container;
    return input;
  }
 
  set dataValue(value) {
    const setValue = (super.dataValue = value);
    if (this.component.name) {
      _.set(this.data, this.component.key, setValue === this.component.value);
    }
    return setValue;
  }
 
  get dataValue() {
    const getValue = super.dataValue;
    if (this.component.name) {
      _.set(this.data, this.component.key, getValue === this.component.value);
    }
    return getValue;
  }
 
  get key() {
    return this.component.name ? this.component.name : super.key;
  }
 
  getValueAt(index) {
    if (this.component.name) {
      return this.inputs[index].checked ? this.component.value : '';
    }
    return !!this.inputs[index].checked;
  }
 
  getValue() {
    const value = super.getValue();
    if (this.component.name) {
      return value ? this.setCheckedState(value) : this.setCheckedState(this.dataValue);
    }
    else {
      return value;
    }
  }
 
  setCheckedState(value) {
    if (!this.input) {
      return;
    }
    if (this.component.name) {
      this.input.value = (value === this.component.value) ? this.component.value : 0;
      this.input.checked = (value === this.component.value) ? 1 : 0;
    }
    else if (value === 'on') {
      this.input.value = 1;
      this.input.checked = 1;
    }
    else if (value === 'off') {
      this.input.value = 0;
      this.input.checked = 0;
    }
    else if (value) {
      this.input.value = 1;
      this.input.checked = 1;
    }
    else {
      this.input.value = 0;
      this.input.checked = 0;
    }
    if (this.input.checked) {
      this.input.setAttribute('checked', true);
    }
    else {
      this.input.removeAttribute('checked');
    }
    return value;
  }
 
  setValue(value, flags) {
    flags = this.getFlags.apply(this, arguments);
    if (this.setCheckedState(value) !== undefined) {
      return this.updateValue(flags);
    }
  }
 
  getView(value) {
    return value ? 'Yes' : 'No';
  }
 
  destroy() {
    super.destroy();
    this.removeShortcut();
  }
}

custom_formio.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { FormioAuthService } from 'angular-formio/auth';
import { Formio } from 'formiojs';
import { CheckBoxComponent }from './Checkbox'
@Component({
  selector: 'app-custom_formio',
  templateUrl: './custom_formio.component.html',
  styleUrls: ['./custom_formio.component.less']
})
export class CustomFormioComponent  {
  title = 'app';
  offlineCount = 0;
  offlineMode: any = null;
  offlineError = '';
  constructor(private auth: FormioAuthService, private router: Router) {
    this.auth.onLogin.subscribe(() => {
      this.router.navigate(['/home']);
    });

    this.auth.onLogout.subscribe(() => {
      this.router.navigate(['/auth/login']);
    });

    this.auth.onRegister.subscribe(() => {
      this.router.navigate(['/home']); 
    });
    Formio.registerComponent('custom_formio', CheckBoxComponent);
  }
}

but i don't know what code i have to write in custom_formio.component.html to render the custom checkbox component into my application.

custom_formio.component.html

    <div class="m-content">
        <div class="m-portlet m-portlet--mobile">
            <div class="m-portlet__body">
                    <div id="custom_formio"></div>  
                </div>
        </div>
    </div>
    

but it is not working,can any one help...

Upvotes: 2

Views: 3021

Answers (1)

Omar Fendri
Omar Fendri

Reputation: 119

It's the ES5 class CheckBoxComponent that should contain the custom HTML you want to rendrer providing it in Build() using super class BaseComponent method renderTemplate().

Custom formio components should be created with native html so you can not use angular components.

But, there is a solution using new angular feature (Angular elements aka web compoenents)

Check-out avan2s's angular project https://github.com/avan2s/angular-app-starterkit

useful: https://github.com/formio/angular-formio/issues/201

Upvotes: 1

Related Questions