pee2pee
pee2pee

Reputation: 3792

Concat values in associative array given same key/value

Let's say I have the following from pushing to an object which I then perform JSON.stringify against

"support_advice": [{
        "text": "",
        "group": "check_lifestyle_26",
        "value": "Physical activity & Exercise"
    }]

I now want to push a new item

"support_advice": [{
        "text": "",
        "group": "check_lifestyle_26",
        "value": "Overall General Health & Wellbeing"
    }]

So normally, I'd get the following

"support_advice": [{
        "text": "",
        "group": "check_lifestyle_26",
        "value": "Physical activity & Exercise"
    }, {
        "text": "",
        "group": "check_lifestyle_26",
        "value": "Overall General Health & Wellbeing"
    }]

However, would it be possible to concatenate the values based on the group so the actual output is more like

"support_advice": [{
        "text": "",
        "group": "check_lifestyle_26",
        "value": "Physical activity & Exercise, Overall General Health & Wellbeing"
    }]

THE FULL SCRIPT

What the script below does is loop through every element in a form and then creates JSON which then gets passed to where it needs to.

This works fine. However checkboxes are when the issue comes in. Part of the system allows you to add parts of the form again, which have the same name.

For something like a textarea, or text input, this is fine. However for checkboxes, because there may be multiple of the same name in the first instance, if I add another section that includes the checkboxes again, the script below won't be able to decipher between sections...

var elem = document.getElementById('rn_QuestionSubmit').elements;

            var a = [];
            var result = {};

            for(var i = 0; i < elem.length; i++)
            {
                var element = elem[i];
                var item = {};
                //item.id = element.id;
                //item.type = element.type;
                if (element.type === 'select-one') {
                    item.text = element.options[element.selectedIndex].text;
                }
                else {
                    item.text = '';
                }

                item.group = elem[i].dataset.group;

                if (element.type === 'radio' || element.type === 'checkbox') {
                    if (element.checked) {
                        item.value = element.value;
                        if (result[element.name]) { result[element.name].push(item) } else { result[element.name] = [item]};
                    }
                }
                else {
                    item.value = element.value;
                    if (result[element.name]) { result[element.name].push(item) } else { result[element.name] = [item]};
                }
            } 
            a.push(JSON.stringify(result));
            console.log('['+a.join(',') + ']');
            return('['+a.join(',') + ']');

Upvotes: 0

Views: 205

Answers (1)

trincot
trincot

Reputation: 350137

You need a minor change to your code to make that happen for the checkbox/radiobutton case: when the element.name key exists in result then the next check would be if the last entry in the result array has the same group. If so, then modify its value property, if not, do what you already did now.

Here is that part of the code:

        if (result[element.name]) {
            // Get the last entry in the array 
            var lastEntry = result[element.name].slice(-1)[0];
            // If same group, then concatenate the value instead of adding the item 
            if (lastEntry.group === item.group) {
                lastEntry.value += "," + element.value;
            } else {
                // You already had this:
                result[element.name].push(item);
            }
        // You already had this:
        } else { 
            result[element.name] = [item]
        }

Upvotes: 3

Related Questions