With this script I can sum all the values set in the cells of a formIO table element
value = Object.keys(data).reduce((acc, key) => {
if (key === "totalTableData") return acc;
if (data[key]) {
return acc + data[key];
}
return acc;
}, 0);
The problem is when I sum 1 + 1, for example, the result I get is 32 (1+1=32). I don't know why this happens even after copying the solution example in this question (Get column data sum from FormIO table element). Also, how could be the script to sum specific fields and not the whole table?
JSON:
{
"label": "Table",
"cellAlignment": "left",
"key": "table",
"type": "table",
"numRows": 4,
"input": false,
"tableView": false,
"rows": [
[
{
"components": []
},
{
"components": [
{
"label": "HTML",
"attrs": [
{
"attr": "",
"value": ""
}
],
"content": "Column 1",
"refreshOnChange": false,
"key": "html111",
"type": "htmlelement",
"input": false,
"tableView": false
}
]
},
{
"components": [
{
"label": "HTML",
"attrs": [
{
"attr": "",
"value": ""
}
],
"content": "Column 2",
"refreshOnChange": false,
"key": "html121",
"type": "htmlelement",
"input": false,
"tableView": false
}
]
},
{
"components": [
{
"label": "HTML",
"attrs": [
{
"attr": "",
"value": ""
}
],
"content": "Column total",
"refreshOnChange": false,
"key": "html124",
"type": "htmlelement",
"input": false,
"tableView": false
}
]
}
],
[
{
"components": [
{
"label": "HTML",
"attrs": [
{
"attr": "",
"value": ""
}
],
"content": "Row 1",
"refreshOnChange": false,
"key": "html125",
"type": "htmlelement",
"input": false,
"tableView": false
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"tableView": false,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "column1row1",
"type": "number",
"input": true
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"tableView": false,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "column2row1",
"type": "number",
"input": true
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"disabled": true,
"tableView": false,
"defaultValue": 0,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "totalRow1",
"type": "number",
"input": true
}
]
}
],
[
{
"components": [
{
"label": "HTML",
"attrs": [
{
"attr": "",
"value": ""
}
],
"content": "Row 2",
"refreshOnChange": false,
"key": "html126",
"type": "htmlelement",
"input": false,
"tableView": false
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"tableView": false,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "column1row2",
"type": "number",
"input": true
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"tableView": false,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "column2row2",
"type": "number",
"input": true
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"disabled": true,
"tableView": false,
"defaultValue": 0,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "totalRow2",
"type": "number",
"input": true
}
]
}
],
[
{
"components": [
{
"label": "HTML",
"attrs": [
{
"attr": "",
"value": ""
}
],
"content": "Row total",
"refreshOnChange": false,
"key": "html127",
"type": "htmlelement",
"input": false,
"tableView": false
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"disabled": true,
"tableView": false,
"defaultValue": 0,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "totalColumn1",
"type": "number",
"input": true
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"disabled": true,
"tableView": false,
"defaultValue": 0,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "totalColumn2",
"type": "number",
"input": true
}
]
},
{
"components": [
{
"label": "Number",
"hideLabel": true,
"mask": false,
"disabled": true,
"tableView": false,
"defaultValue": 0,
"delimiter": false,
"requireDecimal": false,
"inputFormat": "plain",
"truncateMultipleSpaces": false,
"key": "totalTableData",
"type": "number",
"decimalLimit": 0,
"input": true
}
]
}
]
],
"numCols": 4
}
The answer has disappeared... This is what they answered me:
Set this script in Calculated Value (element's data tab):
const fieldsToSum = ['field1', 'field2', 'field3'];
value = fieldsToSum.reduce((acc, key) => {
if (data[key]) {
return acc + Number(data[key]);
} return acc;
}, 0);
Related
From the OneTrust API that I mentioned below, I just receive the default language but I do not receive all supported languages of a purpose. The languages have already been added to the purpose in OneTrust portal.
API Endpoint:
/v2/preferencecenterpage/{preferencecenterpageid}/schema
Response:
{
"id": "8bb68470-d29e-4789-a661-a3e8f3tcbc60",
"order": 0,
"isHidden": false,
"navigationEnabled": false,
"displaySubscribeSettings": true,
"displayUnsubscribeAll": true,
"displaySubscribeAll": false,
"sections": [
{
"id": "497e2fc3-4adb-44ef-bcb6-7cb4567c2cd4",
"identifierType": "",
"isHeaderHidden": false,
"order": 0,
"purposes": [
{
"id": "73032567-bv24-3986-b388-d19cb5c5bef1",
"order": 0,
"languages": [
{
"name": "[qa-p1-v5] ทดสอบ",
"language": "th-th",
"isDefault": true
}
],
"label": "[qa-p1-v5] ทดสอบ",
"version": 48,
"topics": [],
"customPreferences": [],
"visibility": "VISIBLE_TO_ALL"
}
],
"customDataElements": [],
"elements": [],
"languages": [
{
"name": "New Section",
"language": "th-th",
"isDefault": true
},
{
"name": "New Section",
"language": "en",
"isDefault": false
}
],
"isSubscriptionSettings": false
}
],
"languages": [
{
"name": "Page 1",
"language": "th-th",
"isDefault": true
}
]
}
I know we can create custom components, but I am curious if there is a way to group a few together into either a Container or a Panel?
For instance, why make everyone create the same 4 fields in a pleasing layout over and over to create a panel for getting a user's Address? Seems like it would be nice to be able to define some buttons on the left that says "Address Form Block", or "Contact Info Block" which then inserts everything in a group.
I am still pretty new to using Formio.JS, so I don't know if this is possible, but I would hope I am not the first to want something like this.
Example form:
Sample Code:
Formio.builder(document.getElementById('builder'), {
"display": "form",
"components": [
{
"title": "Demographics",
"collapsible": false,
"key": "demographics",
"type": "panel",
"label": "Panel",
"input": false,
"tableView": false,
"components": [
{
"label": "Columns",
"columns": [
{
"components": [
{
"label": "Last Name",
"tableView": true,
"key": "lastName1",
"type": "textfield",
"input": true
}
],
"width": 5,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 5
},
{
"components": [
{
"label": "First Name",
"tableView": true,
"key": "lastName",
"type": "textfield",
"input": true
}
],
"width": 5,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 5
},
{
"components": [
{
"label": "Middle Initial",
"tableView": true,
"key": "middleInitial",
"type": "textfield",
"input": true
}
],
"size": "md",
"width": 2,
"offset": 0,
"push": 0,
"pull": 0,
"currentWidth": 2
}
],
"key": "columns",
"type": "columns",
"input": false,
"tableView": false
},
{
"label": "Birthdate",
"hideInputLabels": false,
"inputsLabelPosition": "top",
"useLocaleSettings": false,
"tableView": false,
"fields": {
"day": {
"hide": false
},
"month": {
"hide": false
},
"year": {
"hide": false
}
},
"key": "birthdate",
"type": "day",
"input": true,
"defaultValue": "00/00/0000"
},
{
"label": "Phone Number",
"tableView": true,
"key": "phoneNumber",
"type": "textfield",
"input": true
}]},
{
"title": "Address",
"collapsible": false,
"key": "address",
"type": "panel",
"label": "Panel",
"input": false,
"tableView": false,
"components": [
{
"label": "Street Address",
"tableView": true,
"key": "streetAddress",
"type": "textfield",
"input": true
},
{
"label": "Columns",
"columns": [
{
"components": [
{
"label": "City",
"tableView": true,
"key": "city",
"type": "textfield",
"input": true
}
],
"width": 6,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 6
},
{
"components": [
{
"label": "State",
"tableView": true,
"key": "state",
"type": "textfield",
"input": true
}
],
"width": 3,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 3
},
{
"components": [
{
"label": "Zipcode",
"tableView": true,
"key": "zipcode",
"type": "textfield",
"input": true
}
],
"size": "md",
"width": 3,
"offset": 0,
"push": 0,
"pull": 0,
"currentWidth": 3
}
],
"key": "columns1",
"type": "columns",
"input": false,
"tableView": false
}
]
},
{
"label": "Signature",
"tableView": false,
"key": "signature",
"type": "signature",
"input": true
},
{
"type": "button",
"label": "Submit",
"key": "submit",
"disableOnInvalid": true,
"input": true,
"tableView": false
}
]
});
You can use a custom component option like.
const AddressTool = {
"title": "Address",
"collapsible": false,
"key": "address",
"type": "panel",
"label": "Panel",
"input": false,
"tableView": false,
"components": [{
"label": "Street Address",
"tableView": true,
"key": "streetAddress",
"type": "textfield",
"input": true
},
{
"label": "Columns",
"columns": [{
"components": [{
"label": "City",
"tableView": true,
"key": "city",
"type": "textfield",
"input": true
}],
"width": 6,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 6
},
{
"components": [{
"label": "State",
"tableView": true,
"key": "state",
"type": "textfield",
"input": true
}],
"width": 3,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 3
},
{
"components": [{
"label": "Zipcode",
"tableView": true,
"key": "zipcode",
"type": "textfield",
"input": true
}],
"size": "md",
"width": 3,
"offset": 0,
"push": 0,
"pull": 0,
"currentWidth": 3
}
],
"key": "columns1",
"type": "columns",
"input": false,
"tableView": false
}
]
};
const DemographicsTool = {
"title": "Demographics",
"collapsible": false,
"key": "demographics",
"type": "panel",
"label": "Panel",
"input": false,
"tableView": false,
"components": [{
"label": "Columns",
"columns": [{
"components": [{
"label": "Last Name",
"tableView": true,
"key": "lastName1",
"type": "textfield",
"input": true
}],
"width": 5,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 5
},
{
"components": [{
"label": "First Name",
"tableView": true,
"key": "lastName",
"type": "textfield",
"input": true
}],
"width": 5,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 5
},
{
"components": [{
"label": "Middle Initial",
"tableView": true,
"key": "middleInitial",
"type": "textfield",
"input": true
}],
"size": "md",
"width": 2,
"offset": 0,
"push": 0,
"pull": 0,
"currentWidth": 2
}
],
"key": "columns",
"type": "columns",
"input": false,
"tableView": false
},
{
"label": "Birthdate",
"hideInputLabels": false,
"inputsLabelPosition": "top",
"useLocaleSettings": false,
"tableView": false,
"fields": {
"day": {
"hide": false
},
"month": {
"hide": false
},
"year": {
"hide": false
}
},
"key": "birthdate",
"type": "day",
"input": true,
"defaultValue": "00/00/0000"
},
{
"label": "Phone Number",
"tableView": true,
"key": "phoneNumber",
"type": "textfield",
"input": true
}
]
};
let formioOptions = {
noDefaultSubmitButton: false,
builder: {
basic: false,
advanced: false,
data: false,
premium: false,
layout: false,
custom: {
title: 'Custom Component Set',
weight: 10,
components: {
Demographics: {
title: 'Demographics',
key: 'demographics',
icon: 'terminal',
schema: DemographicsTool
},
Address: {
title: 'Address',
key: 'address',
icon: 'terminal',
schema: AddressTool
}
}
}
}
};
and then call the builder
Formio.builder(document.getElementById('builder'), {
"components": [{
"title": "Test1",
"input": false,
"key": "panel1",
"tableView": false,
"label": "Test 1",
"type": "panel",
"collapsed": false,
"collapsible": true,
"components": [AddressTool, DemographicsTool]
}]
}, formioOptions);
I have a key value that I am searching for. Each object has the a key of key for each object in the array. I would like to match the term I am searching for to the value of the key and return the value for the sibling with a key of name.
Here is a sample object:
{
"test1": {
"functions": {
"function1": {
"inputs": [
{
"key": "key1",
"name": "name1"
},
{
"key": "key2",
"name": "name3"
},
{
"key": "key3",
"name": "name3"
}
]
},
"function2": {
"inputs": [
{
"key": "key4",
"name": "name4"
},
{
"key": "key5",
"name": "name5"
},
{
"key": "key6",
"name": "name6"
}
]
}
}
}
}
Let's say I want to find the name of an input with a key of key4. How would I achieve this in javascript?
Is this what you want?
var yourObject = {
"inputs": [
{
"key": "callset_name",
"name": "Callset Name",
"type": "STRING",
"required": false,
"fromPrevious": false,
"internalOnly": false
},
{
"key": "reference_genome",
"name": "Reference Genome",
"description": "A reference genome.",
"type": "DATASET",
"required": true,
"fromPrevious": false,
"internalOnly": false,
"constraints": {
"dataset": {
"types": [
"REFERENCE_GENOME"
],
"components": [
"bwa_reference_genome"
]
}
}
},
{
"key": "bam",
"name": "BAM",
"type": "FILE",
"required": true,
"fromPrevious": true,
"internalOnly": false,
"constraints": {
"file": {
"types": [
"BAM"
],
"indexedBy": "bai"
}
}
},
{
"key": "bai",
"name": "BAM Index",
"type": "FILE",
"required": true,
"fromPrevious": true,
"internalOnly": false,
"constraints": {
"file": {
"types": [
"BAM_INDEX"
]
}
}
},
{
"key": "dbsnp_vcf",
"name": "dbSNP VCF",
"description": "Single Nucleotide Polymorphism Database",
"type": "FILE",
"required": false,
"fromPrevious": false,
"internalOnly": false,
"constraints": {
"file": {
"types": [
"VCF"
],
"indexedBy": "dbsnp_vcf_index"
}
}
},
{
"key": "dbsnp_vcf_index",
"name": "dbSNP VCF Index",
"description": "Single Nucleotide Polymorphism Database Index",
"type": "FILE",
"required": false,
"fromPrevious": false,
"internalOnly": false,
"constraints": {
"file": {
"types": [
"VCF_INDEX",
"VCF_IDX"
]
}
}
}
]
};
function getData(key, outputKey) {
const output = yourObject.inputs.find(data => data.key === key);
if (output && output.hasOwnProperty(outputKey)) {
return output[outputKey];
}
return;
}
console.log(getData('reference_genome', 'name'));
I am just starting to mess around with form.io and am a bit stuck. I am trying to create some conditionals within each row of a datagrid. E.g. If a radio button equaling "payIn" is selected then another field should appear in that same row. I can do this statically by assigning the array number to the component's JSON but that obviously doesn't solve the problem of this working dynamically (this was just used to test the logic since it always points to the first row). What could I do/use to make this logic work independently in each row within the datagrid?
{
"label": "Pay In Reason",
"widget": "choicesjs",
"hidden": true,
"tableView": true,
"data": {
"values": [
{
"label": "Employee",
"value": "employee"
},
{
"label": "Bank",
"value": "bank"
}
],
"json": "",
"url": "",
"resource": "",
"custom": ""
},
"selectThreshold": 0.3,
"key": "payInReason",
"conditional": {
"show": true,
"when": "dataGrid[0].payInOut",
"eq": "payIn"
},
"type": "select",
"indexeddb": {
"filter": {}
},
"input": true,
"placeholder": "",
"prefix": "",
"customClass": "",
"suffix": "",
"multiple": false,
"defaultValue": null,
"protected": false,
"unique": false,
"persistent": true,
"clearOnHide": true,
"refreshOn": "",
"redrawOn": "",
"modalEdit": false,
"labelPosition": "top",
"description": "",
"errorLabel": "",
"tooltip": "",
"hideLabel": false,
"tabindex": "",
"disabled": false,
"autofocus": false,
"dbIndex": false,
"customDefaultValue": "",
"calculateValue": "",
"calculateServer": false,
"attributes": {},
"validateOn": "change",
"validate": {
"required": false,
"custom": "",
"customPrivate": false,
"strictDateValidation": false,
"multiple": false,
"unique": false
},
"overlay": {
"style": "",
"left": "",
"top": "",
"width": "",
"height": ""
},
"allowCalculateOverride": false,
"encrypted": false,
"showCharCount": false,
"showWordCount": false,
"properties": {},
"allowMultipleMasks": false,
"clearOnRefresh": false,
"limit": 100,
"dataSrc": "values",
"valueProperty": "",
"lazyLoad": true,
"filter": "",
"searchEnabled": true,
"searchField": "",
"minSearch": 0,
"readOnlyValue": false,
"authenticate": false,
"template": "<span>{{ item.label }}</span>",
"selectFields": "",
"searchThreshold": 0.3,
"uniqueOptions": false,
"fuseOptions": {
"include": "score",
"threshold": 0.3
},
"customOptions": {},
"id": "eas39m"
}
Thanks for your help!
Something like this works: show = (row.component === 'value')
I am using the latest build of alpaca 1.5.15 and, when i try to load the schema which have multi dimensional arrays and data it is not rendering correctly. I think it is considering the first value and displaying. I guess this is bug in the library. Below is the code sample and the screen shot. Please help me.
$('#div').alpaca({
"schema": {
"type": "object",
"required": false,
"properties": {
"email": {
"type": "string",
"required": false,
"properties": {}
},
"file1": {
"type": "array",
"required": false,
"items": {
"type": "array",
"required": false,
"items": {}
},
"properties": {}
},
"file": {
"type": "string",
"required": false,
"properties": {}
},
"password": {
"type": "string",
"required": false,
"pattern": {},
"properties": {}
},
"check": {
"type": "boolean",
"required": false,
"default": true,
"properties": {}
}
}
},
"options": {
"focus": false,
"type": "object",
"helpers": [],
"validate": true,
"disabled": false,
"showMessages": true,
"collapsible": true,
"legendStyle": "button",
"fields": {
"email": {
"type": "text",
"label": "Email Address",
"helpers": [],
"validate": true,
"disabled": false,
"showMessages": true,
"renderButtons": true,
"data": {},
"attributes": {},
"allowOptionalEmpty": true,
"autocomplete": false,
"disallowEmptySpaces": false,
"disallowOnlyEmptySpaces": false,
"fields": {}
},
"file1": {
"type": "array",
"label": "File Upload1",
"helpers": [],
"validate": true,
"disabled": false,
"showMessages": true,
"collapsible": true,
"legendStyle": "button",
"toolbarStyle": "button",
"actionbarStyle": "top",
"items": {},
"rubyrails": false,
"hideToolbarWithChildren": true,
"fields": {}
},
"file": {
"type": "file",
"label": "File Upload",
"helpers": [],
"validate": true,
"disabled": false,
"showMessages": true,
"renderButtons": true,
"data": {},
"attributes": {},
"allowOptionalEmpty": true,
"autocomplete": false,
"disallowEmptySpaces": false,
"disallowOnlyEmptySpaces": false,
"fields": {}
},
"password": {
"type": "password",
"label": "Password",
"helpers": [],
"validate": true,
"disabled": false,
"showMessages": true,
"renderButtons": true,
"data": {},
"attributes": {},
"allowOptionalEmpty": true,
"autocomplete": false,
"disallowEmptySpaces": false,
"disallowOnlyEmptySpaces": false,
"fields": {}
},
"check": {
"type": "checkbox",
"rightLabel": "Sign me up for the News Letter!",
"label": "Newsletter",
"helpers": [],
"validate": true,
"disabled": false,
"showMessages": true,
"renderButtons": true,
"fields": {}
}
}
},
"data": {
"email": "Joe Smith",
"file1": [
[
"d1",
"d2"
],
[
"d1",
"d2",
"d3"
]
],
"password": "MyPassword",
"check": true
}
});