lukassz
lukassz

Reputation: 3340

JavaScript how to refer to button generated by for

I I generate a table of data in a loop. Each line has its own button.

    <script>
    document.addEventListener('DOMContentLoaded', function () {
        function liste() {
            var request = new XMLHttpRequest();
            request.addEventListener('load', function(data) {
                var site = JSON.parse(data.target.responseText);
                var new_html = '';
                    new_html += '<table class="table table-responsive">';
                    new_html += '<thead>';
                    new_html +='<tr>';
                    new_html +='<th>delete</th>';
                    new_html +='<th>id</th>';
                    new_html +='<th>lieu</th>';
                    new_html +='<th>type</th>';
                    new_html +='<th>latitude</th>';
                    new_html +='<th>longitude</th>';
                    new_html +='<th>tarif</th>';
                    new_html +='<th>date</th>';
                    new_html +='<th>photo</th>';
                    new_html +='<th>prenom</th>';
                    new_html +='<th>nom</th>';
                    new_html +='<th>commentaire</th>';
                    new_html +='</tr>';
                    new_html +='</thead>';
                    new_html +='<tbody>';
                    for (var i1 in site){
                    new_html +='<tr id="row"'+i1+'>';
                    new_html +='<td>';
                    new_html +='<button id="delete" class="btn btn-success topbuttons">DELETE</button>';
                    new_html +='</td>';
                    for (i2 in site[i1]){
                    new_html +='<td>';
                    if(i2 == 'photo'){
                    new_html += '<img src="'+site[i1][i2]+'" width="300" height="200">';
                    }else{
                    new_html += site[i1][i2];
                    }
                    new_html +='</td>';
                    }
                    new_html += '</tr>';                
                    }

                document.querySelector('#resultat').innerHTML = new_html;
            });


            request.open("GET", "webservice_liste_get.php?search="+document.getElementById('search').value);
            request.send();
        }
    });
    </script>

<div id="resultat"></div>

I have a problem with writing action listener for button so that when you click on the button appeared message: you clicked on the row number $id. How can I do this?

Upvotes: 0

Views: 61

Answers (3)

Domino
Domino

Reputation: 6778

While all browsers will parse .innerHTML, the canonical way to add content to a page in JavaScript is through the DOM methods which interact with Node and Element objects instead of concatenating strings together.

document.createElement('tagname'); creates blank elements.
element.id = 'myid'; sets the id attribute.
element.className = 'class'; sets the whole class attribute.
element.classList.add('classname'); adds a class...

Different elements will have specific properties as well, such as the HTMLImageElement which has a .src property. These properties all directly map to the tag attributes.

The older way to set the text of an element was do create a Text node and append it to the element. element.appendChild(document.createTextNode('mytext'));
Modern browsers support the shorthand textContent property which allows you to just do
element.textContent = 'mytext'; which should be cleaner than using .innerHTML which has to get parsed.

If you start creating content dynamically with these, you'll be able to bind events to them as well:

function buttonClickListener(e) {
  alert('You clicked on the button with id = ' + e.currentTarget.id);
}

var button = document.createElement('button');
button.id = 'delete';
button.className = 'btn btn-success topbuttons';
button.textContent = 'DELETE';

button.addEventListener('click', buttonClickListener);

But it you don't want to restart you current code, you might just want to retrieve all buttons from the code you get in HTML. You can retrieve elements with a CSS selector in the querySelectorAll method.

var resultat = document.querySelector('#resultat');
resultat.innerHTML = new_html;
// select all button elements in resultat
var buttons = resultat.querySelectorAll('button');

for(var i=0; i<buttons.length; ++i) {
  buttons[i].addEventListener('click', buttonClickListener);
}

Now I'm not sure exactly what you wanted to detect and what message you wanted to show, but the tools are in your hands :)

Upvotes: 2

Mosh Feu
Mosh Feu

Reputation: 29347

  1. You can't generate multiple id="delete" buttons. id attribute should be unique. Do this new_html +='<button id="delete' + i1 + '" class="btn btn-success topbuttons">DELETE</button>'; instead.

The id attribute specifies a unique id for an HTML element (the value must be unique within the HTML document). http://www.w3schools.com/tags/att_global_id.asp

  1. When you generate DOM elements you have to bind the events (click for example) after it. If those elements was generated from the response's ajax request, you have to bind their event after they are added to the DOM.

So, the easy way, use jQuery on event like this:

document.addEventListener('DOMContentLoaded', function () {
  function liste() {
    //var request = new XMLHttpRequest();
    //request.addEventListener('load', function(data) {
      //var site = JSON.parse(data.target.responseText);
      var site = [{id:1, name: 2}, {id:1, name: 2}, {id:1, name: 2}];
      var new_html = '';
      new_html += '<table class="table table-responsive">';
      new_html += '<thead>';
      new_html +='<tr>';
      new_html +='<th>delete</th>';
      new_html +='<th>id</th>';
      new_html +='<th>lieu</th>';
      new_html +='<th>type</th>';
      new_html +='<th>latitude</th>';
      new_html +='<th>longitude</th>';
      new_html +='<th>tarif</th>';
      new_html +='<th>date</th>';
      new_html +='<th>photo</th>';
      new_html +='<th>prenom</th>';
      new_html +='<th>nom</th>';
      new_html +='<th>commentaire</th>';
      new_html +='</tr>';
      new_html +='</thead>';
      new_html +='<tbody>';
      for (var i1 in site){
        console.log(i1);
        new_html +='<tr id="row'+i1+'">';
        new_html +='<td>';
        new_html +='<button id="delete" class="btn btn-success topbuttons">DELETE</button>';
        new_html +='</td>';
        for (i2 in site[i1]){
          new_html +='<td>';
          if(i2 == 'photo'){
            new_html += '<img src="'+site[i1][i2]+'" width="300" height="200">';
          }else{
            new_html += site[i1][i2];
          }
          new_html +='</td>';
        }
        new_html += '</tr>';                
      }

      document.querySelector('#resultat').innerHTML = new_html;
    //});


    //request.open("GET", location.href);
    //request.send();
  }
  
  document.querySelector('#resultat').addEventListener('click', function(event) {
    var clickedEl = event.target;
    if(clickedEl.tagName === 'BUTTON') {
      alert(clickedEl.parentNode.parentNode.getAttribute('id'));
    }
  });
  
  liste();
});
<input type="search" id="search" />
<div id="resultat"></div>

Upvotes: 2

RomanPerekhrest
RomanPerekhrest

Reputation: 92904

Try this:

for (var i1 in site){

    new_html +='<tr id="row"'+i1+'>';
    new_html +='<td>';
    new_html +='<button id="delete" data-row-id="' + i1 +'" class="btn btn-success topbuttons" onclick="clickHandler(this)">DELETE</button>';
    new_html +='</td>';

...

function clickHandler(el){
    alert("You\'ve clicked on the row with number: " + el.getAttribute('data-row-id'));
}

Upvotes: 1

Related Questions