Cat Overlord
Cat Overlord

Reputation: 173

Detect element that has the same attribute value as another element

I have some content that is loaded from a XML file with XMLHttpRequest:

<div uid="29710" >
content....
</div>
<div uid="19291" >
content....
</div>
<div uid="099181" >
content....
</div>

The code used to get the content:

xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","notes.xml",false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML; 

var x = xmlDoc.getElementsByTagName("noteboard");
var newHTML = "";
for (i=0;i<x.length;i++) { 
   newHTML += "<div><div uid='"+ x[i].getAttribute('uid')+"'>"
            + x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue
            + "<br>"+ x[i].getElementsByTagName("message")[0].childNodes[0].nodeValue
           +"</div></div>";
}
document.querySelector('#panel').innerHTML += newHTML;

The content is updated every 3 seconds, but the problem starts when the old content is repeated and piled up, as well as the new content. Also, the UID attribute value is loaded from the same XML file as the content - so all the new repeated content has the same UID as the old repeated content.

If I am not clear enough, this is the sort of thing that is happening:

<div uid="19291">Old Content</div>
<div uid="77191">New Content</div>
<div uid="19291">Old Content</div>
<div uid="19291">Old Content</div>
<div uid="21503">New Content</div>

So how would you remove all the divs that have the same UID value as each other, except for the original one ?

Upvotes: 1

Views: 68

Answers (3)

Buzinas
Buzinas

Reputation: 11725

You can see if your document already has a div with that uid.

var div = document.querySelector('div[uid=' + items[i].getAttribute('uid') + ']');

The code above will search the document any div that has an attribute uid with the same value.

So, your final code will be something like:

var xhr = new XMLHttpRequest();

xhr.addEventListener('load', function(e) {
  var items = xhr.responseXML.getElementsByTagName("noteboard");

  for (var i = 0; i < items.length; i++) {
    var div = document.querySelector('div[uid=' + items[i].getAttribute('uid') + ']');
    var newHTML = '';
    if (!div) { // it doesn't exist yet
      newHTML += "<div><div uid='"+ x[i].getAttribute('uid')+"'>"
            + x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue
            + "<br>"+ x[i].getElementsByTagName("message")[0].childNodes[0].nodeValue
           +"</div></div>";
    }
  }
  document.getElementById('panel').innerHTML += newHTML;
});

xhr.open("GET", "notes.xml", false);
xhr.send();

Upvotes: 1

Y-Love
Y-Love

Reputation: 161

One option (using "vanilla javascript", no jQuery), if you are sure that the correct element is first in the DOM, is to use document.querySelectorAll to loop through the elements, removing each of them except the first one. For instance, if you had a <div> with an ID of panel and you wanted to remove divs with a duplicate UID (using 11111 as an example) from inside of this container:

var divs = document.querySelectorAll('div[uid="11111"]');
Array.prototype.forEach.call(divs, function(el, idx) { 
    if(idx > 0) { 
        document.getElementById('panel').removeChild(el);    
    }
});

Array.prototype is used because document.querySelectorAll returns an array-like NodeList, not an actual Array.

(Update following OP's update: this would go after the data has been retrieved from the XML file.)

Upvotes: 1

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196051

You could check if the uid you are adding already exists in the page before adding it.

xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","notes.xml",false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML; 

var x = xmlDoc.getElementsByTagName("noteboard");
var newHTML = "";
for (i=0;i<x.length;i++) { 

  // check if the UID exists in the page and only add it if it does not
  var uid = x[i].getAttribute('uid');
  if ( !document.querySelector('#panel *[uid="'+ uid +'"]') ){

    newHTML += "<div><div uid='"+ x[i].getAttribute('uid')+"'>"
            + x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue
            + "<br>"+ x[i].getElementsByTagName("message")[0].childNodes[0].nodeValue
            + "</div></div>";
  }
}

document.querySelector('#panel').innerHTML += newHTML;

Upvotes: 1

Related Questions