How do I display a unique id value with GTM? - javascript

I have multiple elements on a page with the same class name, but each element has a unique id name.
Example:
<div class="video-image" id="get-googled">
<div class="video-image" id="email-marketing">
I want to display the id value, but right now I am only able to have GTM return and display the first element on the page. I read this post: "Getting value of ID from class" and it didn't help and even explains doing it the simple way will only display the first elements value.
Do I need custom Javascript to create this properly?

If you want to get a specific div and you know where it is on the page you might be able to use a DOM variable with an nth of type query selector. But this seems cumbersome, and since it seems you want a list in any case I think you are better of with a custom javascript variable:
function() {
return document.querySelectorAll(".video-image");
}
which return a collection of DOM elements (you might want to check if there are actually elements with that class first).

The initial answer is the right start - this completes the loop:
<script>
var inputs = document.querySelectorAll(".video-image");
for (var i = 0; i < inputs.length; i++) {
alert(inputs[i].id);
}
</script>
Here is a JSFiddle to try it out - [https://jsfiddle.net/JMurphy22/kduybmsp/2/][1]

Related

jQuery .not() doesn't remove element?

I am grabbing a copy of some info from a page, but I do not want to include certain <option> elements that appear inside <select> elements on the page.
Therefore, while I grab all the elements I want and am storing them in the variable fields, I check to see if each element is a <select> and if they have the specific <option> that I don't want.
var field = allFields[i].innerHTML; //allFields is the raw HTML I'm iterating through
if ($(field).find("select").length > 0) { //If the element we're looking at contains a select
console.log("Found a select. It is in " + field);
console.log($(field).find(".bad-option");
field = $(field).not(".bad-option").prop("outerHTML"); //Use .not() to remove the elements which have the .bad-option class
// (and .prop("outerHTML") is just there to convert it back to a String instead of a jQuery object)
}
console.log("Adding " + field);
fields[i] = field; //Add the HTML, free of any unwanted options, to the `fields` variable
Based on jQuery's documentation, I would expect the .not() function to remove any elements out of field which have the bad-option class. Yet that is not the case at all. When I log field before and after using .not(), it prints out the same thing. See the console output from the code above:
Found a select. It is in <label>Description: <select><option>thing1</option><option class="bad-option">thing2</option></select></label>
-----------------
[jQuery list object size 1, containing an object called option.bad-option]
-----------------
Adding <label>Description: <select><option>thing1</option><option class="bad-option">thing2</option></select></label>
So what's going on? How do I remove an option with a certain class from from within a jQuery object? Why isn't .not() working?
If I need to clarify anything, please let me know. I tried to make this question as specific as possible and would be happy to elaborate on any details further.
The documentation is perhaps a bit confusing: not removes elements from the selection, not the DOM. If you want to remove the elements, then just filter and remove:
const processed = $(field);
processed.filter(".bad-option").remove();
field = processed.prop("outerHTML");

How to iterate over elements of same class to find first visible

If I had multiple objects of a class present, but only some are visible, what would be the best way to find the first visible one. I currently try:
browser.waitForElementVisible('.myClass', timeOut)
which sees all of the elements, but will only act on the first found. OR
browser.waitForElementVisible('(//div[#class="myClass"])[1]')
which specifies an index, but that may or may not be visible, since new data is loaded every time the page refreshes.
I need to loop through all present and just click on the first instance of one that is visible. I know I can achieve this through custom commands, but I'm new to js and nightwatch, so I'm not sure how to go about it.
I think I would probably use .elementIdDisplayed() to accomplish this.
The snippet below should help you
get a list of the elements
check if one is displayed
If displayed, click on the element
Usually I would use a forEach loop but since you can't break out of that without doing some hacky stuff just use a regular old for loop like this:
browser.elements('css selector', '.myClass', function(elements) {
for(let i = 0; i < elements.value.length; i++) {
browser.elementIdDisplayed(elements.value[i].ELEMENT, function(isDisplayed) {
if(isDisplayed.value) {
browser.elementIdClick(element.value[i].ELEMENT);
break; //this will break out of the loop when you find the first displayed element
}
});
}
});

Changing the ID of html elements

I have a form which allows user to add elements(which might be a field set or a text box) dynamically. I'm able to assign a new ID to the elements when added but I'm not able to make it in a sequence as the user can add elements in between as well.
So for example, there is an Id named XXX1 and the user adds a new element after it which is xxx2. Now if the user adds a new element again after XXX1, it comes up as XXX3. So the order of the elements is XXX1, XXX3, XXX2. I'm not able to control the names when it is being added. So I'm trying to re-assign the names after add.
I'm trying to get all elements in an array and change the ID as follows
document.getElementById('xxx3').setAttribute('id', 'xxx2');
But this doesn't work as ID XXX2 already exists for another element. Please help me with a solution for this.
So why not change the ID of xxx2 first, to move it out of the way, then putting it back in place later?
document.getElementById('xxx2').setAttribute('id', 'temporaryId');
document.getElementById('xxx3').setAttribute('id', 'xxx2');
document.getElementById('temporaryId').setAttribute('id', 'xxx3');
Why not go from the last element to the first(the one's after the position you are inserting to) and add one to the ID?
for example:
var insertAt = 2; // for an element to be called xxx2
var els = [...]; // an array with all of the elements
if(els.length >= insertAt){
for(var i = els.length-1; i >= insertAt-1; --i){
els[i].setAttribute('id', 'xxx'+(i+2));
}
}
// Add the new element here which will be called xxx2

HTML - Accessing div in document exactly by position in one go

I have a page generated by Yii CListView which contains a div andmultiple child divs.I need to access a specific the child div and add one more div into that.
Although I managed to solve it using one approach but dont think its the right one. Following is the overview of my solution (the code below does not contain all necessary variables declarations and other stuff, I have pasted the core code not the complete.):
Accessed the parent div by Id (Since the Id was available as I can
code this into Yii)
Obtained all the elements in this div using :
var div_childern = document.getElementById('StudentGridViewId').getElementsByTagName('*');
Iterated through and when reached to the desired div, added my new div. Please note that the div in which I want to add new div has the class name as "items". Code as below:
for (var i = 0; i < div_childern.length; i++) {
if (div_childern[i].getAttribute('class')=='items'){
document.getElementById('StudentGridViewId').getElementsByTagName('*')[i].appendChild(newdiv);
i=div_childern.length+1;
}
}
The only problem in this solution is, I am accessing the whole document twice, the call to getElementsByTagName. First to obtain the list of all items and then again to add my new div. Is there a better way to this ?
and also, could anyone point me to set the Id of the "items" div that Yii generates?
Thanks
Faisal
You might be able to get a much more elegant solution if you use JQuery.
But, if you want to use the traditional javascript, here is what you could do
for (var i = 0; i < div_childern.length; i++) {
if (div_childern[i].getAttribute('class')=='items'){
div_childern[i].appendChild(newdiv);
i=div_childern.length+1;
}
}

javascript get child by id

<div onclick="test(this)">
Test
<div id="child">child</div>
</div>
I want to change the style of the child div when the parent div is clicked. How do I reference it? I would like to be able to reference it by ID as the the html in the parent div could change and the child won't be the first child etc.
function test(el){
el.childNode["child"].style.display = "none";
}
Something like that, where I can reference the child node by id and set the style of it.
Thanks.
EDIT: Point taken with IDs needing to be unique. So let me revise my question a little. I would hate to have to create unique IDs for every element that gets added to the page. The parent div is added dynamically. (sort of like a page notes system). And then there is this child div. I would like to be able to do something like this: el.getElementsByName("options").item(0).style.display = "block";
If I replace el with document, it works fine, but it doesn't to every "options" child div on the page. Whereas, I want to be able to click the parent div, and have the child div do something (like go away for example).
If I have to dynamically create a million (exaggerated) div IDs, I will, but I would rather not. Any ideas?
In modern browsers (IE8, Firefox, Chrome, Opera, Safari) you can use querySelector():
function test(el){
el.querySelector("#child").style.display = "none";
}
For older browsers (<=IE7), you would have to use some sort of library, such as Sizzle or a framework, such as jQuery, to work with selectors.
As mentioned, IDs are supposed to be unique within a document, so it's easiest to just use document.getElementById("child").
This works well:
function test(el){
el.childNodes.item("child").style.display = "none";
}
If the argument of item() function is an integer, the function will treat it as an index. If the argument is a string, then the function searches for name or ID of element.
If the child is always going to be a specific tag then you could do it like this
function test(el)
{
var children = el.getElementsByTagName('div');// any tag could be used here..
for(var i = 0; i< children.length;i++)
{
if (children[i].getAttribute('id') == 'child') // any attribute could be used here
{
// do what ever you want with the element..
// children[i] holds the element at the moment..
}
}
}
document.getElementById('child') should return you the correct element - remember that id's need to be unique across a document to make it valid anyway.
edit : see this page - ids MUST be unique.
edit edit : alternate way to solve the problem :
<div onclick="test('child1')">
Test
<div id="child1">child</div>
</div>
then you just need the test() function to look up the element by id that you passed in.
If you want to find specific child DOM element use method querySelectorAll
var $form = document.getElementById("contactFrm");
in $form variable we can search which child element we want :)
For more details about how to use querySelectorAll check this page

Categories

Resources