0

DEMO

createBtns function create as many buttons as data array is long.

What I want to do is to delete (from DOM) single button when we click on it. The problem is all buttons has the same class, they are all the same, except text value inside of each. There should be a way to get to know which button has been clicked and delete this and only one, but I don't know it.

There is btnClick function which should do it (it alerts for now).

var data = [
  {name: "Date", value: "12/31/2018", type: "visible"},
  {name: "Car", value: "Ford", type: "visible"},
  {name: "Country", value: "Russia", type: "visible"},
  {name: "Age", value: "20", type: "visible"},
];

var outer = $(".outerPanel");

var createBtns = () => {
    for (var i = 0; i < data.length; i++) {
    var btn = $('<div class="btn"></div>');
    var name = data[i].name;
    var value = data[i].value;

    btn.html(name + ": " + value);
    btn.click(() => btnClick());
    outer.append(btn);
  }
}

var btnClick = () => {
    alert("test");
}

createBtns();
hames
  • 93
  • 12
  • Inside the click handler, you can access the button via `this` or the function's first argument: `btn.click(btnClick);` and `var btnClick = e => { // access e.target }` –  Dec 30 '18 at 22:50
  • Possible duplicate of [JavaScript - onClick to get the ID of the clicked button](https://stackoverflow.com/questions/4825295/javascript-onclick-to-get-the-id-of-the-clicked-button) –  Dec 30 '18 at 22:52

5 Answers5

1

If you use const and let (block scoped rather than function scoped), you can simply reference the created btn again inside the handler and .remove() it in the closure:

btn.click(() => btn.remove());

const data = [
 {name: "Date", value: "12/31/2018", type: "visible"},
  {name: "Car", value: "Ford", type: "visible"},
  {name: "Country", value: "Russia", type: "visible"},
  {name: "Age", value: "20", type: "visible"},
];

const outer = $(".outerPanel");

const createBtns = () => {
 for (let i = 0; i < data.length; i++) {
    const btn = $('<div class="btn"></div>');
    const name = data[i].name;
    const value = data[i].value;

    btn.html(name + ": " + value);
    btn.click(() => btn.remove());
    outer.append(btn);
  }
}

createBtns();
.outerPanel {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.btn {
  width: 20%;
  height: 40px;
  border: 2px solid red;
  text-align: center;
  vertical-align: center;
  cursor: pointer;
}

.btn:hover {
  background: black;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outerPanel"></div>

(without const and let, you'd have to use something like this instead - still works, but it's a lot uglier)

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • And if I'd like to also update `data` array, how would it look like? I mean delete the object from `data` when button disappears. – hames Dec 31 '18 at 18:10
  • 1
    Use `.findIndex` to find the index of the item with the same `name` in the `data` array, and then `splice` at that index to remove the item. – CertainPerformance Dec 31 '18 at 23:57
1

You can do this like below:

var btnClick = (e) => {
    // get index of clicked button relative to parent element
    var index = Array.prototype.indexOf.call(e.target.parentNode.children, e.target);
    // remove data entry in array
    data.splice(index, 1);
    // remove the clicked button
    e.target.parentNode.removeChild(e.target);
}

Updated version of your demo:

var data = [{
        name: "Date",
        value: "12/31/2018",
        type: "visible"
    },
    {
        name: "Car",
        value: "Ford",
        type: "visible"
    },
    {
        name: "Country",
        value: "Russia",
        type: "visible"
    },
    {
        name: "Age",
        value: "20",
        type: "visible"
    },
];

var outer = $(".outerPanel");

var createBtns = () => {
    for (var i = 0; i < data.length; i++) {
        var btn = $('<div class="btn"></div>');
        var name = data[i].name;
        var value = data[i].value;

        btn.html(name + ": " + value);
        btn.click((e) => btnClick(e));
        outer.append(btn);
    }
}

var btnClick = (e) => {
    // get index of clicked button relative to parent element
    var index = Array.prototype.indexOf.call(e.target.parentNode.children, e.target);
    // remove data entry in array
    data.splice(index, 1);
    // refresh displayed text
    refreshText();
    // remove the clicked button
    e.target.parentNode.removeChild(e.target);
}

var refreshText = () => {
    document.getElementById("dataText").innerHTML = JSON.stringify(data);
}

createBtns();
refreshText();
.outerPanel {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.btn {
  width: 20%;
  height: 40px;
  border: 2px solid red;
  text-align: center;
  vertical-align: center;
  cursor: pointer;
}

.btn:hover {
  background: black;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outerPanel"></div>
<h3>Data array contents</h1>
<p id="dataText"></p>
Laurens Deprost
  • 1,653
  • 5
  • 16
1
var data = [
  {name: "Date", value: "12/31/2018", type: "visible"},
  {name: "Car", value: "Ford", type: "visible"},
  {name: "Country", value: "Russia", type: "visible"},
  {name: "Age", value: "20", type: "visible"},
];

var outer = $(".outerPanel");

var createBtns = () => {
    for (var i = 0; i < data.length; i++) {
    var btn = $('<div class="btn"></div>');
    var name = data[i].name;
    var value = data[i].value;

    btn.html(name + ": " + value);
    btn.click((e) => btnClick(e));
    outer.append(btn);
  }
}

var btnClick = (e) => {
    e.currentTarget.remove()
}

createBtns();

I assume $ is JQuery?

edit: (from comments)

And if I'd like to also update data array, how would it look like? I mean delete the object from data when button disappears

On this I can think of two kind of approach, the first is to embed the data into the button

var data = [
  {name: "Date", value: "12/31/2018", type: "visible"},
  {name: "Car", value: "Ford", type: "visible"},
  {name: "Country", value: "Russia", type: "visible"},
  {name: "Age", value: "20", type: "visible"},
];

var outer = $(".outerPanel");

var createBtns = () => {
    for (var i = 0; i < data.length; i++) {
    var btn = $('<div class="btn"></div>');
    btn[0].data = data[i];
    var name = data[i].name;
    var value = data[i].value;

    btn.html(name + ": " + value);
    btn.click((e) => btnClick(e));
    outer.append(btn);
  }
}

var btnClick = (e) => {
    var index = data.indexOf(e.currentTarget.data);
    data = data.slice(0,index).concat(data.slice(index+1,data.length));
    e.currentTarget.remove()
}

createBtns();

the second approach is just delete the data and re-render the whole thing

var data = [
  {name: "Date", value: "12/31/2018", type: "visible"},
  {name: "Car", value: "Ford", type: "visible"},
  {name: "Country", value: "Russia", type: "visible"},
  {name: "Age", value: "20", type: "visible"},
];

var outer = $(".outerPanel");

var createBtns = () => {
    for (var i = 0; i < data.length; i++) {
    var btn = $('<div class="btn"></div>');
    btn[0].data = data[i];
    var name = data[i].name;
    var value = data[i].value;

    btn.html(name + ": " + value);
    btn.click((e) => btnClick(e));
    outer.append(btn);
  }
}

var btnClick = (e) => {
    var index = data.indexOf(e.currentTarget.data);
    data = data.slice(0,index).concat(data.slice(index+1,data.length));
    outer[0].innerHTML = "";
    createBtns();
}

createBtns();
Averman
  • 441
  • 2
  • 8
  • Yes, $ is JQuery. This and Laurens' answer is exactly what I needed. Thanks! – hames Dec 30 '18 at 23:58
  • And if I'd like to also update `data` array, how would it look like? I mean delete the object from `data` when button disappears. – hames Dec 31 '18 at 18:10
0

You can try add an event to the button, like this :

 function addHideEvent(element) { 
                     
 for(i=0;i<element.length;i++) { 
  element[i].onclick = function(e) { 
   this.remove()
  }
 }
}
                
addHideEvent(document.getElementsByClassName("btn"))
<button class="btn"> CLICK HERE </button>  </br>
<button class="btn"> CLICK HERE </button>  </br>
<button class="btn"> CLICK HERE </button>  </br>
<button class="btn"> CLICK HERE </button>  </br>
gaaaaaa
  • 336
  • 1
  • 14
0

Update

removing the btn from DOM instead of CSS change

Solution

You can add an event listener to the button when u create it inside the for loop.

Example code here:

var data = [{
    name: "Date",
    value: "12/31/2018",
    type: "button"
  },
  {
    name: "Car",
    value: "Ford",
    type: "button"
  },
  {
    name: "Country",
    value: "Russia",
    type: "button"
  },
  {
    name: "Age",
    value: "20",
    type: "button"
  },
];

const createBtns = () => {
  for (var i = 0; i < data.length; i++) {
    let btn = document.createElement('input');
    btn.setAttribute('class', 'btn');
    btn.setAttribute('value', data[i].value);
    btn.setAttribute('type', data[i].type);
    btn.addEventListener('click', () => {
      document.body.removeChild(btn)
    });
    document.body.appendChild(btn);
  }
}

createBtns();
Community
  • 1
  • 1