2

Good evening, I have a problem with the construction of form in Javascript. For avoid the repetition of code I'd like to use the same function:

function addCheckBoxItem(p, name, value) {

    // add checkbox
    var newCheckbox = document.createElement("input");
    newCheckbox.type = "checkbox";
    newCheckbox.setAttribute("value", p);
    newCheckbox.setAttribute("id", p);
    newCheckbox.setAttribute("name", name);

     newCheckbox.onchange = function(){ 

            var cbs = document.getElementsByName(name);
            for (var i = 0; i < cbs.length; i++) {
                cbs[i].checked = false;
            }
            this.checked = true;
            // define the peer selected as choice
            value = this.value;
           // TODO: MY PROBLEM IS HERE
    };

   form.appendChild(newCheckbox);


    // add label to checkbox
    var label = document.createElement('label');
    label.setAttribute("name", name);
    label.htmlFor = p;
    label.appendChild(document.createTextNode(p));

    form.appendChild(label);

    // add br tag to checkbox 
    var br = document.createElement("br")
    br.setAttribute("name", name);
    form.appendChild(br);

}

I call my function inside loop

for (i = 0; i < array.length; i++) { 
        addCheckBoxItem(array[i].key, nameItemCheckbox, peer_choice);
    }

I know that value = this.value isn't possible because onchange event is Async but i want retrieve the value of this event and associate it with my param. I have find different response to this problem. One of this is: Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference I have understand the basic concept but none of the example is relevant to my problem. Someone could help me?

EDIT - SOLUTION

Thanks to @Tibrogargan i have modified my function in this way:

for (i = 0; i < array.length; i++) {
        addCheckBoxItem(form, array[i].key, form_peer_available_class, peer_choice, (value) => peer_choice = value);
    }

and

function addCheckBoxItem(p, name, value, callback) {

// add checkbox
var newCheckbox = document.createElement("input");
newCheckbox.type = "checkbox";
newCheckbox.setAttribute("value", p);
newCheckbox.setAttribute("id", p);
newCheckbox.setAttribute("name", name);

 newCheckbox.onchange = function(){ 

        var cbs = document.getElementsByName(name);
        for (var i = 0; i < cbs.length; i++) {
            cbs[i].checked = false;
        }
        this.checked = true;
        // define the peer selected as choice
        callback(this.value);
};

form.appendChild(newCheckbox);


// add label to checkbox
var label = document.createElement('label');
label.setAttribute("name", name);
label.htmlFor = p;
label.appendChild(document.createTextNode(p));

form.appendChild(label);

// add br tag to checkbox 
var br = document.createElement("br")
br.setAttribute("name", name);
form.appendChild(br);

}
faienz93
  • 161
  • 2
  • 18
  • 1
    Pass in a callback function as well (`function addCheckBoxItem(p, name, value, callback)` and instead of trying to modify a parameter that was (presumably) passed by value, use the callback: `if (callback) { callback(this.value) }` .... `addCheckBox(foo, bar, baz, (value) => baz = value)`. (Your value *is* altered, but because it's pass by value, not reference, you don't see the change) – Tibrogargan Jul 13 '18 at 23:03
  • @Tibrogargan it work but i don't understand this piece of code `if (callback) { callback(this.value) }` It was enough to pass `addCheckBoxItem(array[i].key, nameItemCheckbox, peer_choice, (value) => peer_choice = value); `. Furthermore if i try (immediatly) to alert `peer_choice` (the value passed) it returns `undefined' even if the form now is formed. Why ? – faienz93 Jul 13 '18 at 23:35
  • 1
    All it's doing is checking that `callback` exists before you try and call it. `peer_choice` is immediately undefined because the `onchange` function has not been called yet. The function you're passing in still hasn't been called, so it has not been set yet. You're just passing in the function as a 1st class object, not actually calling it yet. – Tibrogargan Jul 13 '18 at 23:42

1 Answers1

0

Pass callback into addCheckBoxItem like that

// accumulator
var data = {}
// callback
var storeData = (name, value, p) => data[name] = value;
// callback as third argument
addCheckBoxItem('data1', 'checkbox1', storeData);
addCheckBoxItem('data2', 'checkbox2', storeData);
addCheckBoxItem('data3', 'checkbox3', storeData);

Check full example here http://jsfiddle.net/gtqnc109/9/

Firanolfind
  • 1,559
  • 2
  • 17
  • 36
  • this doen't change the value of my variable. Maybe I wrong something. But if i try to print `storeData` outside the function the result is undefined. – faienz93 Jul 13 '18 at 23:45
  • I dont get it. See example, value is being stored in `data` object – Firanolfind Jul 14 '18 at 23:28