ICode4Fun
ICode4Fun

Reputation: 47

Dynamic button not working when clicked on - Javascript

I am able to create the delete button dynamically, but the action that I have set for it doesn't execute correctly. I am trying to delete one item at a time. I have to only use JavaScript and I can not edit the HTML, but I have provided the code for it, so it can be tested. Any tips would be helpful.

var form = document.getElementsByTagName("form")[0];
form.method = "POST";
form.action = "form-handler";
form.onsubmit = validateForm;


var add = document.getElementsByClassName('add');
add[0].onclick = houseList;
var lastId = 0;


var age = document.getElementsByName("age")[0];
age.type = "number";
age.required = true;
age.min = "0";
age.max = "120";

var dropDown = document.getElementsByName("rel")[0];
dropDown.type = "option";
dropDown.required = true;

var newDiv = document.createElement("div");
newDiv.setAttribute("id", "houseMem");
document.body.appendChild(newDiv);

//var title = document.createElement("h2");
//title = "Member List";
//newDiv.appendChild(title);*

var ul = document.createElement("ul");
ul.setAttribute("id", "memList");
newDiv.appendChild(ul);


function houseList() {

  var li = document.createElement("li"); 
  li.appendChild(document.createTextNode(dropDown.value + ' ' + age.value + " ")); 
  li.setAttribute('id', 'item' + lastId);
  ul.appendChild(li);


  var remove = document.createElement('button'); 
  remove.appendChild(document.createTextNode("delete")); 
  remove.onclick = removeItem;
  // remove.setAttribute('onclick', 'removeItem()');
  remove.setAttribute('onclick', 'removeItem("' + 'item' + lastId + '")');

  li.appendChild(remove);
  lastId += 1;
  ul.appendChild(li);

  return false;

}

function removeItem(itemid) { 
  var item = document.getElementById(itemid);
  ul.remove(item); 
}

function validateForm() {

  if (age == null || age.value === "") {
    alert("Age must be filled out");
    return false;
  } else if (dropDown.value == null) {
    alert("Please choose a relationship");
    return false;
  } else {
    alert("You entered: " + age.value + " and selected: " + dropDown.value);
    return addToList;
  }
}
.debug {
  font-family: monospace;
  border: 1px solid black;
  padding: 10px;
  display: none;
}
<title>Household builder</title>

</head>

<body>
  <h1>Household builder</h1>
  <div class="builder">
    <o class="household"></o>
    <form>
      <div>
        <label>Age
                        <input type="text" name="age">
                    </label>
      </div>
      <div>
        <label>Relationship
                        <select name="rel">
                            <option value="">---</option>
                            <option value="self">Self</option>
                            <option value="spouse">Spouse</option>
                            <option value="child">Child</option>
                            <option value="parent">Parent</option>
                            <option value="grandparent">Grandparent</option>
                            <option value="other">Other</option>
                        </select>
                    </label>
      </div>
      <div>
        <label>Smoker?
                        <input type="checkbox" name="smoker">
                    </label>
      </div>
      <div>
        <button class="add">add</button>
      </div>
      <div>
        <button type="submit" class="GapViewItemselected">submit</button>
      </div>
    </form>
  </div>
  <pre class="debug"></pre>
  <script type="text/javascript" src="./index.js"></script>
</body>

Upvotes: 1

Views: 112

Answers (4)

Zakaria Acharki
Zakaria Acharki

Reputation: 67505

The problem is the remove function that will remove all the ul elements, should get the related parent of the current clicked element like :

function removeItem(itemid) { 
    var item = document.getElementById(itemid);
    item.parentNode.removeChild(item);
}

Code:

var form = document.getElementsByTagName("form")[0];
form.method = "POST";
form.action = "form-handler";
form.onsubmit = validateForm;


var add = document.getElementsByClassName('add');
add[0].onclick = houseList;
var lastId = 0;


var age = document.getElementsByName("age")[0];
age.type = "number";
age.required = true;
age.min = "0";
age.max = "120";

var dropDown = document.getElementsByName("rel")[0];
dropDown.type = "option";
dropDown.required = true;

var newDiv = document.createElement("div");
newDiv.setAttribute("id", "houseMem");
document.body.appendChild(newDiv);

//var title = document.createElement("h2");
//title = "Member List";
//newDiv.appendChild(title);*

var ul = document.createElement("ul");
ul.setAttribute("id", "memList");
newDiv.appendChild(ul);


function houseList() {

  var li = document.createElement("li"); 
  li.appendChild(document.createTextNode(dropDown.value + ' ' + age.value + " ")); 
  li.setAttribute('id', 'item' + lastId);
  ul.appendChild(li);


  var remove = document.createElement('button'); 
  remove.appendChild(document.createTextNode("delete")); 
  remove.onclick = removeItem;
  // remove.setAttribute('onclick', 'removeItem()');
  remove.setAttribute('onclick', 'removeItem("' + 'item' + lastId + '")');

  li.appendChild(remove);
  lastId += 1;
  ul.appendChild(li);

  return false;

}

function removeItem(itemid) { 
  var item = document.getElementById(itemid);
  item.parentNode.removeChild(item);
}

function validateForm() {

  if (age == null || age.value === "") {
    alert("Age must be filled out");
    return false;
  } else if (dropDown.value == null) {
    alert("Please choose a relationship");
    return false;
  } else {
    alert("You entered: " + age.value + " and selected: " + dropDown.value);
    return addToList;
  }
}
.debug {
  font-family: monospace;
  border: 1px solid black;
  padding: 10px;
  display: none;
}
<h1>Household builder</h1>
<div class="builder">
  <o class="household"></o>
  <form>
    <div>
      <label>Age<input type="text" name="age"></label>
    </div>
    <div>
      <label>Relationship
          <select name="rel">
              <option value="">---</option>
              <option value="self">Self</option>
              <option value="spouse">Spouse</option>
              <option value="child">Child</option>
              <option value="parent">Parent</option>
              <option value="grandparent">Grandparent</option>
              <option value="other">Other</option>
          </select>
        </label>
    </div>
    <div>
      <label>Smoker?<input type="checkbox" name="smoker"></label>
    </div>
    <div>
      <button class="add">add</button>
    </div>
    <div>
      <button type="submit" class="GapViewItemselected">submit</button>
    </div>
  </form>
</div>
<pre class="debug"></pre>

Upvotes: 3

Ofir G
Ofir G

Reputation: 754

in the removeItem function

 function removeItem(itemid) { 
   var item = document.getElementById(itemid);
   ul.remove(item);  // HERE
 }    

change the line to ul.removeChild(item);

BTW

i suggest you to write any code that outside the functions you defined, in a function that caled after the window as been loaded .. (you trying access a dom elements that has not been created yet)

 document.addEventListener('DOMContentLoaded', function() 

// side note - remember to define any variables is a scope according to the range you want them to be known

Upvotes: 0

crapier
crapier

Reputation: 373

As everyone else has mentioned the element.remove() function removes that element from the DOM not the child as a parameter. You can simply tell the item to remove itself from the DOM with item.remove() in your example or any of the other suggestions where you get the parent element and then do parent.removeChild(item). The benefit of the first method in your case is that you already have item, so there is no need to get the parent where as remove is a shortcut that might not be available in older browsers though.

Second I would not recommend setting your onclick event with setAttribute as that isn't compatible with some older browsers and is kinda hacky.

A more proper way to to this is with the onclick = functionif you only want to add one function the event or the addEventListener("click", function) (attachEvent in very old IE) used in more complicated cases where you need to add multiple events to fire.

var form = document.getElementsByTagName("form")[0];
form.method = "POST";
form.action = "form-handler";
form.onsubmit = validateForm;


var add = document.getElementsByClassName('add');
add[0].onclick = houseList;
var lastId = 0;


var age = document.getElementsByName("age")[0];
age.type = "number";
age.required = true;
age.min = "0";
age.max = "120";

var dropDown = document.getElementsByName("rel")[0];
dropDown.type = "option";
dropDown.required = true;

var newDiv = document.createElement("div");
newDiv.setAttribute("id", "houseMem");
document.body.appendChild(newDiv);

//var title = document.createElement("h2");
//title = "Member List";
//newDiv.appendChild(title);*

var ul = document.createElement("ul");
ul.setAttribute("id", "memList");
newDiv.appendChild(ul);

function deleteFunction(item) {
  return function(event) {removeItem(item)};
}

function houseList() {

  var li = document.createElement("li"); 
  li.appendChild(document.createTextNode(dropDown.value + ' ' + age.value + " ")); 
  li.setAttribute('id', 'item' + lastId);
  ul.appendChild(li);


  var remove = document.createElement('button'); 
  remove.appendChild(document.createTextNode("delete")); 
  remove.onclick = deleteFunction('item' + lastId);

  li.appendChild(remove);
  lastId += 1;
  ul.appendChild(li);

  return false;

}

function removeItem(itemid) { 
  var item = document.getElementById(itemid);
  item.remove(); 
}

function validateForm() {

  if (age == null || age.value === "") {
    alert("Age must be filled out");
    return false;
  } else if (dropDown.value == null) {
    alert("Please choose a relationship");
    return false;
  } else {
    alert("You entered: " + age.value + " and selected: " + dropDown.value);
    return addToList;
  }
}
.debug {
  font-family: monospace;
  border: 1px solid black;
  padding: 10px;
  display: none;
}
<title>Household builder</title>

</head>

<body>
  <h1>Household builder</h1>
  <div class="builder">
    <o class="household"></o>
    <form>
      <div>
        <label>Age
                        <input type="text" name="age">
                    </label>
      </div>
      <div>
        <label>Relationship
                        <select name="rel">
                            <option value="">---</option>
                            <option value="self">Self</option>
                            <option value="spouse">Spouse</option>
                            <option value="child">Child</option>
                            <option value="parent">Parent</option>
                            <option value="grandparent">Grandparent</option>
                            <option value="other">Other</option>
                        </select>
                    </label>
      </div>
      <div>
        <label>Smoker?
                        <input type="checkbox" name="smoker">
                    </label>
      </div>
      <div>
        <button class="add">add</button>
      </div>
      <div>
        <button type="submit" class="GapViewItemselected">submit</button>
      </div>
    </form>
  </div>
  <pre class="debug"></pre>
  <script type="text/javascript" src="./index.js"></script>
</body>

Upvotes: 1

Ryan Hanekamp
Ryan Hanekamp

Reputation: 618

function removeItem(itemid) { 
  var item = document.getElementById(itemid);
  ul.remove(item); 
}

This requires an ID, but is called with only an event reference:

remove.onclick = removeItem;

I'd suggest keeping the calling part and editing the removeItem function:

function removeItem(event) { 
  var item = event.target;
  item.parentNode.remove(item); 
}

Upvotes: 0

Related Questions