querySelector syntax for nested elements - javascript

I'm trying to get the div element that's nested deep within another div, but can't get the CSS Selector string to work.
The div I want does not have a unique identifier, but resides deep within another div that has. I've gotten that top level div, but have no clue how to get the nested one.
DOM:
var obj = document.body.querySelector('.qvobject[data-qlikobjectid="XFvnjF"]');
console.log(obj);
var cont = obj.querySelector('.kpi-value');
console.log(cont);
<div class="qvobject" data-qlikobjectid="XFvnjF">
<div>
<div>
<div class="kpi-value">I WANT THIS</div>
</div>
</div>
</div>
The result is that "obj" is the right object, but "cont" is null, so it can't find it.

You can select it using the child selector. Just put a space between the parent selector and the child selector.
This makes the traverser go further to any level in the dom to select the desired element.
var element = document.querySelector('.qvobject[data-qlikobjectid="XFvnjF"] .kpi-value');
console.log(element);
<div class="qvobject" data-qlikobjectid="XFvnjF">
<div>
<div>
<div class="kpi-value">I WANT THIS</div>
</div>
</div>
</div>

Related

Is there a way to add different Id's to multiple elements with Javascript?

Let's say I have
<iframe> id="iframeid"
<div> </div>
<div> </div>
<div> </div>
<div> </div>
</iframe>
Is there a way to add unique Id's to the divs using javascript?
For example
<iframe> id="iframeid"
<div>id="divid1"</div>
<div>id="divid2" </div>
<div>id="divid3" </div>
<div>id="divid4" </div>
</iframe>
You can return all the div elements with document.getElementsByTagName. This return a NodeList (of div in this case) that you can access with bracket notation (or item method, it's the same) that return the Element Node. You can set its attribute id with .id=value or setAttribute(id,value). In my example I set the div elements with id=id0 id=id1 and so on.
let myDivs = document.getElementsByTagName("div");
for(let i=0 ; i<myDivs.length ;i++)
myDivs[i].id = `id${i}`;
Furthermore note that document.getElementsByTagName("div") returns all the div in the page, if you want only the div of an element, for instance an iframe element with id=myiframe you can do:
document.getElementById("myiframe").getElementsByTagName("div");
Also note that this method detects all the div in the subtree, it is not limited to direct children

Querying Deep Nested Elements in Javascript

I am having an issue targeting deep nested div tags in vanilla javascript. what's happening is when I run a query check I seem to be getting null. Keep in mind the DOM elements are js injected from an API so I need to target the selector and add a class.
var select = document.querySelector('#wrapper div div div div');
<div id="wrapper">
<div>
<div>
<div>
<div>div to target</div>
</div>
</div>
</div>
</div>

Get all children of the current node

<div class='1'>
<div class='2'>
<div class='3'>
</div>
</div>
</div>
query('.1').children() // returns [<div class='2'></div>]
Is is possible to access 3rd level children by using query().children() instead of using something like query('.1 .2 .3')?
Basically, I would like to access all children of the current element without hard-coding its Id, e.g. query('#foo .3')
You could use:
element.querySelectorAll('div') to get all <div> children of element
element.querySelectorAll('[class]') to get all children of element that does have a class attribute
document.querySelectorAll('div[class]') for the whole html document
You can use any CSS selector as a parameter for querySelectorAll().

how do i get div childs from jquery/javascript in this example?

i'm trying to access to the div's child by using jquery's .eq() function, but it looks like something's wrong, despite the fact is not throwing an error, looks like when i do a .innerHTML to the desired child div element, nothing happens.
This is my HTML:
<div id="status_container">
<div class="status_item_wrapper">
<div class="status_item_title">
<span>TITLE 1</span>
</div>
<div class="status_item_content">
<table id="box-table"></table>
</div>
</div>
<div class="status_item_wrapper">
<div class="status_item_title">
<span>TITLE 2</span>
</div>
<div class="status_item_content">
<table id="box-table"></table>
</div>
</div>
</div>
And this is my javascript:
function doSomething(message) {
var data = message.data;
var index_container = 0;
var container = $("#status_container").eq(0);
var content_wrapper = container.eq(1); // this would be the content div of each child
content_wrapper.html(JSON.stringify(data));
}
I thought this would get the "TITLE 1" status_item_wrapper div, and then, content_wrapper would contain the "status_item_content" object.
How am i supposed to reach the "status_item_content" div from the very first parent "status_container"?
Thanks.
content_wrapper is a jQuery object, as that is what eq() returns, and does'nt have an innerHTML method, you should use jQuery's html() :
content_wrapper.html( JSON.stringify(data) );
to return the native DOM element instead, you can use get(), and do :
var content_wrapper = container.get(1);
content_wrapper.innerHTML = JSON.stringify(data);
EDIT:
Now that you've added container, there are some issues. eq() will get a certain element in a collection of elements based on a zero based index, and you're using an ID as a selector, so there should'nt really be a collection, as ID's are unique, and should only select one single element.
If you're trying to select the second child inside the #status_container element, you'd do
var content_wrapper = $("#status_container").children().eq(1);

Hiding many divs with one onclick function

I am looking for a Javascript solution for this problem. I have the following HTML:
<div id = "container">
<div id = "data">
<div>
<h3> Address</h3>
<b>Expand...</b>
<div id="content">ul. Pomorska</div>
</div>
<div>
<h3> Telefon </h3> <b>Expand...</b>
<div id="content">26565352</div>
</div>
<div>
<h3>Email</h3>
<b>Expand...</b>
<div id="content">asdasdag#aga.com</div>
</div>
</div>
</div>
I would like to hide the content div when an onclick Expand is made. So far I have made a function which hides the content divs and tries to assign an event handler to the node.
function hideinfo() {
var node = document.getElementById("data");
var contactdata = node.getElementsByTagName("div");
for(var i=0; i<contactdata.length;i++) {
if(contactdata[i].id == "content") {
alert(contactdata[i].previousSibling.innerHTML);
contactdata[i].previousSibling.addEventListener('click',ShowHide,false);
contactdata[i].style.display="none";
}
}
}
The problem is that the alert displays undefined. Why can't it see the node? Is there a better way to do this in Javascript?
Because previousSibling is most likely the text node before the div element. You probably want to use previousElementSibling instead :)
In most browser today, querySelectorAll, which lets you use CSS selectors for finding elements, is also a good alternative (IE8+)
The previousSibling property returns the previous sibling node (the previous node in the same tree level) of the selected element
which returns in your case the TEXT node.
As you can see in this jsfiddle: http://jsfiddle.net/Xu383/
alert(contactdata[i].previousSibling.nodeName);
You are better of using the querySelectorAll.
Also you can't have multiple divs with the SAME id, use class instead.

Categories