Related
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);
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
}
]
}
Requirement:
I have to iterate multiple objects, it contains properties. so I have to iterate each object and check properties values(the key name is mapping) matching with the first object key.
for example:
Node1, Node2, Node3
JSON:
{
"Node1": {
"type": "object",
"properties": {
"x": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"y": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
}
},
"defChecked": true
},
"Node2": {
"type": "object",
"properties": {
"body": {
"type": "string",
"mapping": "Node1.inputs.x",
"checked": false,
"defChecked": true
},
"subject": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"toemail": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"body_placeholders": {
"type": "string",
"mapping": "",
"checked": true,
"defChecked": true
},
"subject_placeholders": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
}
},
"defChecked": true
},
"Node3": {
"type": "object",
"properties": {
"email": {
"type": "text",
"description": null,
"default": null,
"mapping": "Node2.inputs.toemail",
"isSelected": true,
"defChecked": true
},
"firstname": {
"type": "text",
"description": null,
"default": null,
"mapping": "",
"isSelected": true,
"defChecked": true
},
"lastname": {
"type": "text",
"description": null,
"default": null,
"mapping": "Node2.inputs.body_placeholders",
"isSelected": true,
"defChecked": true
},
"id": {
"type": "uuid",
"description": null,
"default": null,
"mapping": "",
"isSelected": true,
"defChecked": true
}
},
"defChecked": true
}
}
Output:
{
"Node1": {
"type": "object",
"properties": {
"y": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
}
},
"defChecked": true
},
"Node2": {
"type": "object",
"properties": {
"subject": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"subject_placeholders": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
}
},
"defChecked": true
},
"Node3": {
"type": "object",
"properties": {
"firstname": {
"type": "text",
"description": null,
"default": null,
"mapping": "",
"isSelected": true,
"defChecked": true
},
"id": {
"type": "uuid",
"description": null,
"default": null,
"mapping": "",
"isSelected": true,
"defChecked": true
}
},
"defChecked": true
}
}
for the above JSON - Node1 has a property 'x's and this property mapped or not another object properties(Node2 and Node3). if you see the JSON it x mapped with Node2 like ( Node1.inputs.x)
if it's matches then i have to remove the object Node1.x from the json. similary for others
You could do something like this:
let input = {
"Node1": {
"type": "object",
"properties": {
"x": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"y": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
}
},
"defChecked": true
},
"Node2": {
"type": "object",
"properties": {
"body": {
"type": "string",
"mapping": "Node1.inputs.x",
"checked": false,
"defChecked": true
},
"subject": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"toemail": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
},
"body_placeholders": {
"type": "string",
"mapping": "",
"checked": true,
"defChecked": true
},
"subject_placeholders": {
"type": "string",
"mapping": "",
"checked": false,
"defChecked": true
}
},
"defChecked": true
},
"Node3": {
"type": "object",
"properties": {
"email": {
"type": "text",
"description": null,
"default": null,
"mapping": "Node2.inputs.toemail",
"isSelected": true,
"defChecked": true
},
"firstname": {
"type": "text",
"description": null,
"default": null,
"mapping": "",
"isSelected": true,
"defChecked": true
},
"lastname": {
"type": "text",
"description": null,
"default": null,
"mapping": "Node2.inputs.body_placeholders",
"isSelected": true,
"defChecked": true
},
"id": {
"type": "uuid",
"description": null,
"default": null,
"mapping": "",
"isSelected": true,
"defChecked": true
}
},
"defChecked": true
}
};
for (let i = 1; i < 3; i++) {
Object.entries(input["Node" + (i + 1)].properties).forEach(prop => {
if (prop[1].mapping.includes("Node" + i)) {
let attrToCancel = prop[1].mapping.split('.')[prop[1].mapping.split('.').length -1];
delete input["Node" + i].properties[attrToCancel];
delete input["Node" + (i + 1)].properties[prop[0]];
}
});
}
console.log(input)
Get the Object.entries of input, then intercept the mapping property, read it and cancel the property on previous Node.
if you post your code we can help you more
but for now, if you want to replace values between that array you can make that there's a lot of ways but that depends on much of the data and the way to use it
const updateData = (YourData) => {
for (const [MyNodeName, MyNodeValue] of Object.entries(YourData)) {
if (MyNodeValue.properties) {
for (const [propKey, propValue] of Object.entries(MyNodeValue.properties)) {
if (propValue.mapping && propValue.mapping !== "") {
var updateKeyArr = propValue.mapping.split(".inputs.");
console.log(updateKeyArr)
if (updateKeyArr.length > 0) {
if (YourData[updateKeyArr[0]] &&
YourData[updateKeyArr[0]].properties[updateKeyArr[1]]
) {
YourData[MyNodeName].properties[propKey].mapping = YourData[updateKeyArr[0]].properties[updateKeyArr[1]];
}
}
}
}
}
}
return YourData;
}
console.log(updateData(data))
I'm trying to make a rule which makes the user select only nodes that belong to a specific tree ; The user mustn't have the possibily to choose multiple nodes from different levels like this :
Do you have any idea how to do so ?
Thanks in advance.
I found the solution if anyone is facing the same issue :
the html part :
<div id="jstree"/>
The javascript part :
$(function() {$("#jstree").on("select_node.jstree", function (evt, data) {
var selectedNode= $('#jstree').jstree(true).get_selected(true);
for(var i = 0, j = selectedNode.length; i < j; i++) {
if(selectedNode.length > 1){
var res = selectedNode[i].parents[selectedNode[i].parents.length-2];
if(data.node.parent != res){
$('#jstree').jstree("deselect_all");
}
}
}
});
$('#jstree').jstree({
'core': {
'data': [{
"id": "1.0",
"text": "Fresh Products",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [{
"id": "2.06.0",
"text": "Ethnic & Specialty",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [{
"id": "2.16.0",
"text": "Ethnic & Specialty",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}, {
"id": "2.17.0",
"text": "Natural & Organic",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}],
"liAttributes": null,
"aAttributes": null
}, {
"id": "2.07.0",
"text": "Natural & Organic",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}, {
"id": "2.08.0",
"text": "Prepared Foods",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}, {
"id": "2.09.0",
"text": "Seafood",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}, {
"id": "2.010.0",
"text": "Seafood",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}],
"liAttributes": null,
"aAttributes": null
}, {
"id": "2.0",
"text": "Frozen Products",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [],
"liAttributes": null,
"aAttributes": null
}, {
"id": "3.0",
"text": "Store Equipment ",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [],
"liAttributes": null,
"aAttributes": null
}, {
"id": "4.0",
"text": "Packaged Grocery",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [],
"liAttributes": null,
"aAttributes": null
}, {
"id": "5.0",
"text": "Retail Technology",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [],
"liAttributes": null,
"aAttributes": null
}, {
"id": "6.0",
"text": "HBC/Non-Foods",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": [{
"id": "2.090.0",
"text": "Seafood",
"icon": "",
"state": {
"opened": false,
"disabled": false,
"selected": false
},
"children": false,
"liAttributes": null,
"aAttributes": null
}],
"liAttributes": null,
"aAttributes": null
}]
},
"search": {
"case_insensitive": true,
"show_only_matches" : true
},
"plugins": ["search"]
});
});
I am parsing the JSON object. I want to set value which is stored in session against id. I have this JSON:
[
{
"id": "a",
"text": "a",
"icon": true,
"li_attr": {
"id": "a"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "b",
"text": "b\n ",
"icon": true,
"li_attr": {
"id": "b"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
{
"id": "b-a-1",
"text": "b-a",
"icon": true,
"li_attr": {
"id": "b-a-1"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "b-b-2",
"text": "b-b\n ",
"icon": true,
"li_attr": {
"id": "b-b-2"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
{
"id": "b-b-a",
"text": "b-b-a",
"icon": true,
"li_attr": {
"id": "b-b-a"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "b-b-b",
"text": "b-b-b",
"icon": true,
"li_attr": {
"id": "b-b-b"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
}
]
}
]
},
{
"id": "c-1",
"text": "c\n ",
"icon": true,
"li_attr": {
"id": "c-1"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
{
"id": "not-c-a-1",
"text": "c-a",
"icon": true,
"li_attr": {
"id": "not-c-a-1"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "not-c-b-2",
"text": "b-b",
"icon": true,
"li_attr": {
"id": "not-c-b-2"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
}
]
}
]
I want to make same type array having object. Inside the object there might be possibility of nested objects. I just want to set value against it id.
Can we get the information of children? If there are children, I need to set value. Here is my fiddle:
http://jsfiddle.net/fuu94/91/
$('#json').click(function(){
var json_list=$('#tree').jstree(true).get_json(); console.log(json_list.length);
for(var i=0;i<json_list.length;i++){
var obj={};
alert(json_list[i].id)
obj=sessionStorage.getItem(json_list[i].id);
arr[i]=obj;
}
console.log(arr)
})
});
Expected output is:
[
{
"a": "value_a",
"arr": [
]
},
{
"b": "value_b",
"arr": [
{
"b-a-1": "value_b-a-1",
"arr": [
]
},
{
"b-b-1": "value_b-b-2",
"arr": [
{
"b-b-a": "value_b-b-a",
"arr": [
]
},
{
"b-b-b": "value_b-b-b",
"arr": [
]
}
]
}
]
},
{
"c-1": "value_c-1",
"arr": [
{
"not-c-a-1": "value_not-c-a-1",
"arr": [
]
},
{
"not-c-b-2": "value_not-c-b-2",
"arr": [
]
}
]
}
]
You could use a reviver function that you pass to JSON.parse.
JSFIDDLE
var json = JSON.stringify([{ id: 'root', children: [ { id: 'nested' } ]}]);
var p = JSON.parse(json, function (k, v) {
if (!k) return v;
if (k === 'id' || k === 'children') return v;
if (+k == k && typeof v === 'object' && v != null && 'id' in v) {
v[v.id] = 'value_' + v.id;
delete v.id;
if (v.children) v.arr = v.children;
delete v.children;
return v;
}
});
JSON.stringify(p); //[{"root":"value_root","arr":[{"nested":"value_nested"}]}]
EDIT: I tried to make the code more robust by using a different approach, but it did not work as expected because the children key did not always came before we started to iterate over the array. Have a look at the edit history, perhaps I overlooked something.
Assuming that "b-b-1": "value_b-b-2" in the expected output is a type and really should be "b-b-2": "value_b-b-2" it should be very easy to map the original array to the expected output.
Use the map method on arrays (or, if you need to support older browsers, use the map implementation of some library you are using (e.g. jQuery or Underscore).
For each of the items in your array, you need to create an item which has two properties. The first property should be named according to the value of the id property of the input object and the value of the property seems like it should be the literal value_ followed by the value of the id property from the input object.
Furthermore, each item should also have an arr property, which is the result of applying our item mapping function to the items in the children array.
So the code could look something like
function mapItem(inputItem){
var item = {};
item[inputItem.id] = "value_" + inputItem.id;
item.arr = inputItem.children.map(mapItem);
return item;
};
var results = originalArray.map(mapItem);
I have the above mapping function running against your sample data at http://jsfiddle.net/tJ7Kq/