Skip to content

Instantly share code, notes, and snippets.

@travist
Last active April 21, 2020 15:22
Show Gist options
  • Save travist/30c2a3fbb40296fbd13a4c00ee5d534c to your computer and use it in GitHub Desktop.
Save travist/30c2a3fbb40296fbd13a4c00ee5d534c to your computer and use it in GitHub Desktop.
Custom Component 4.x
/**
* IMPORTANT NOTE!!!
*
* THIS NO LONGER WORKS. Please go to https://github.com/formio/contrib to learn the recommended way of creating Custom Components.
*/
var InputComponent = Formio.Components.components.input;
/**
* Create a new CheckMatrixComponent "class" using ES5 class inheritance notation.
* https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance
*
* Here we will derive from the base component which all Form.io form components derive from.
*
* @param component
* @param options
* @param data
* @constructor
*/
function CheckMatrixComponent(component, options, data) {
InputComponent.prototype.constructor.call(this, component, options, data);
}
// Perform typical ES5 inheritance
CheckMatrixComponent.prototype = Object.create(InputComponent.prototype);
CheckMatrixComponent.prototype.constructor = CheckMatrixComponent;
/**
* Define what the default JSON schema for this component is. We will derive from the InputComponent
* schema and provide our overrides to that.
* @return {*}
*/
CheckMatrixComponent.schema = function() {
return InputComponent.schema({
type: 'checkmatrix',
numRows: 3,
numCols: 3
});
};
/**
* Register this component to the Form Builder by providing the "builderInfo" object.
*
* @type {{title: string, group: string, icon: string, weight: number, documentation: string, schema: *}}
*/
CheckMatrixComponent.builderInfo = {
title: 'Check Matrix',
group: 'customBasic',
icon: 'fa fa-table',
weight: 70,
documentation: 'http://help.form.io/userguide/#table',
schema: CheckMatrixComponent.schema()
};
/**
* Tell the renderer how to render this component.
*/
CheckMatrixComponent.prototype.render = function(element) {
var tpl = '<div class="table-responsive">';
tpl += this.renderTemplate('label', {
label: this.labelInfo,
component: this.component,
element: element,
tooltip: this.interpolate(this.component.tooltip || '').replace(/(?:\r\n|\r|\n)/g, '<br />'),
});
tpl += '<table class="table">';
tpl += '<tbody>';
for (let i = 0; i < this.component.numRows; i++) {
tpl += '<tr>';
for (let j = 0; j < this.component.numCols; j++) {
tpl += '<td>';
tpl += this.renderTemplate('input', {
input: {
type: 'input',
attr: {
type: 'checkbox'
},
id: 'check-' + i + '-' + j
}
});
tpl += '</td>';
}
tpl += '</tr>';
}
tpl += '</tbody>';
tpl += '</table>';
tpl += '</div>';
return tpl;
};
/**
* Provide the input element information. Because we are using checkboxes, the change event needs to be
* 'click' instead of the default 'change' from the InputComponent.
*
* @return {{type, component, changeEvent, attr}}
*/
CheckMatrixComponent.prototype.elementInfo = function() {
const info = InputComponent.prototype.elementInfo.call(this);
info.changeEvent = 'click';
return info;
};
/**
* Tell the renderer how to "get" a value from this component.
*
* @return {Array}
*/
CheckMatrixComponent.prototype.getValue = function() {
var value = [];
if (!this.refs.input || !this.refs.input.length) {
return value;
}
for (let i = 0; i < this.component.numRows; i++) {
value[i] = [];
for (let j = 0; j < this.component.numCols; j++) {
var index = (i * this.component.numCols) + j;
if (this.refs.input[index]) {
value[i][j] = !!this.refs.input[index].checked;
}
}
}
return value;
};
/**
* Tell the renderer how to "set" the value of this component.
*
* @param value
* @return {boolean}
*/
CheckMatrixComponent.prototype.setValue = function(value) {
var changed = InputComponent.prototype.updateValue.call(this, value);
if (!value) {
return changed;
}
for (let i = 0; i < this.component.numRows; i++) {
if (!value[i]) {
break;
}
for (let j = 0; j < this.component.numCols; j++) {
if (!value[i][j]) {
return false;
}
let checked = value[i][j] ? 1 : 0;
var index = (i * this.component.numCols) + j;
this.refs.input[index].value = checked;
this.refs.input[index].checked = checked;
}
}
return changed;
};
/**
* Here we can just use an existing components EditForm like below shows.
*
* OR: you can define you own custom EditForm like this.
*
* CheckMatrixComponent.editForm = function() {
* return {
* components: [
* {
* type: 'textfield',
* label: 'Label',
* key: 'label',
* },
* ...
* ...
* ]
* };
* };
*/
CheckMatrixComponent.editForm = Formio.Components.components.table.editForm;
// Register the component to the Formio.Components registry.
Formio.Components.addComponent('checkmatrix', CheckMatrixComponent);
/**
* You can also define "pre-defined" compoennts using the following method.
*/
Formio.FormBuilder.options = {
builder: {
custom: {
title: 'Pre-Defined Fields',
weight: 10,
components: {
firstName: {
title: 'First Name',
key: 'firstName',
icon: 'terminal',
schema: {
label: 'First Name',
type: 'textfield',
key: 'firstName',
input: true
}
},
lastName: {
title: 'Last Name',
key: 'lastName',
icon: 'terminal',
schema: {
label: 'Last Name',
type: 'textfield',
key: 'lastName',
input: true
}
},
email: {
title: 'Email',
key: 'email',
icon: 'at',
schema: {
label: 'Email',
type: 'email',
key: 'email',
input: true
}
},
phoneNumber: {
title: 'Mobile Phone',
key: 'mobilePhone',
icon: 'phone-square',
schema: {
label: 'Mobile Phone',
type: 'phoneNumber',
key: 'mobilePhone',
input: true
}
}
}
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment