1

I have a form, id="myForm" or document.forms[0], with checkbox inputs, which I am writing dynamically with the help of Javascript functions and another HTML form, id="addForm" or document.forms[1], which has a text box and a clickable button.

The myForm is:

<form id="myForm" action="Save.php" method="post">
    <div id="skillSet"></div>
    <input type="submit">    
</form>

My addForm is:

<form id="addForm"><input id="skillAdd" type="text" name="newSkillName">
    <input class="button" type="button" value="Add" onClick="addSkill(document.forms[1].newSkillName.value)">
</form>

and my javascript function addSkill() is:

function addSkill(newSkill)
{
    if(newSkill.length > 0)
    {
        var inner = document.getElementById("skillSet").innerHTML;
        var newSkillDefinition = ('<div class="skillName"><label><input type="checkbox" checked name="skill[]" value="' + newSkill + '" title="Toggle Selection">' + newSkill + '</label></div>');
        document.getElementById("skillSet").innerHTML = inner + newSkillDefinition;
    }
}

All right, so I'll give you guys a scenario: Using addForm, i've added 5 checkbox items to myForm, all 5 are checked by default of course, because of the checkbox "checked" attribute. But i decide to uncheck 3 of them. After this, I add another checkbox item. As soon as i do that, ALL of my previous checkbox items get checked automatically. So my previous selection has all vanished!

I know this definitely has something to do with the "checked" attribute and also innerHTML that I am using.

It's been a real headache. Is there any fix or way around this problem?

Barmar
  • 741,623
  • 53
  • 500
  • 612
GothamCityRises
  • 2,072
  • 2
  • 27
  • 43
  • How do you uncheck? Some methods do not change the underlying html and on redrew your changes are discarded – raam86 Jul 16 '13 at 12:43
  • It's a checkbox, but it is checked by default, one can always toggle it, right? – GothamCityRises Jul 16 '13 at 12:44
  • 3
    `.innerHTML` doesn't contain user inputs, it's just the DOM source. Instead of appending to `.innerHTML`, you should create nodes and append them to the DOM. – Barmar Jul 16 '13 at 12:45
  • 1
    What @Barmar means is that the text returned when you access the `innerHTML` property of a container element will not include attribute updates caused by user interaction (that is, "value", "checked", "selected"). – Pointy Jul 16 '13 at 12:47
  • possible duplicate of [Is it possible to append to innerHTML without destroying descendants' onclick functions?](http://stackoverflow.com/questions/595808/is-it-possible-to-append-to-innerhtml-without-destroying-descendants-onclick-fu) – Ian Clark Jul 16 '13 at 12:48

3 Answers3

0

InnerHTML will "causes the destruction of all child elements, even if you're trying to append". Both of the solutions from raam86 and Rotem Harel should help you, as you should be using the appendChild method for this problem.

See this answer

Community
  • 1
  • 1
Ian Clark
  • 9,237
  • 4
  • 32
  • 49
  • Well if the value of `innerHTML` included properties altered by user interaction, that wouldn't be a problem. However, it doesn't, so it is :) – Pointy Jul 16 '13 at 12:48
  • Yes you're right, but I suppose it's something you should really make a note of so that you don't run into this problem in the future. – Ian Clark Jul 16 '13 at 12:56
0

Add a node instead of using innerHTML:

var skillSet = document.getElementById("skillSet")
 //Create elements
var div = document.createElement('div'),
var label =  document.createElement('label');
var input = document.createElement('input');
var newSkill = "This is a new skill";
//Setup input
input.type  = "checkbox";
input.checked = true;
input.name = "skill[]";
input.val = newSkill;
input.title = "Toggle Selection";
//Append new elements to div
var text = document.createTextNode(newSkill);
label.appendChild(text);
label.appendChild(input);
div.appendChild(label);
//Append div to original skillSet
skillSet.appendChild(div);

OUTPUT

<div>
  <label>This is a new skill
    <input type="checkbox" name="skill[]" title="Toggle Selection">
  </label>
</div>
raam86
  • 6,785
  • 2
  • 31
  • 46
0

You can avoid that hassle by using the JavaScript appendChild method, instead of replacing the whole HTML. Something like that:

function addSkill(newSkill)
{
    if(newSkill.length > 0)
    {
        var skillSet = document.getElementById("skillSet"),
            skill = document.createElement('div'),
            label = document.createElement('label'),
            input = document.createElement('input');

        input.type = "checkbox";
        input.checked = "true";
        input.name = "skill[]";
        input.value = newSkill;
        input.title = "Toggle Selection";

        label.appendChild(input);
        skill.appendChild(label);

        skill.className = "skillName";

        skillSet.appendChild(skill);
    }
}
Rotem Harel
  • 736
  • 8
  • 16