How do I find the Parent Attribute for a data-element (data-qa). I have a data attribute id, data-qa=productId1 , productid2, productid3. (for each row in the grid)
For each row number in a grid.
How do I tell if the parent Element has kendogridcell above?
I don't know what kendogridcell is, its not a class.
let dataQaElements = document.querySelectorAll(`[data-qa]`);
for (let i = 0; i < dataQaElements.length; i++) {
let attr = dataQaElements[i].parentElement;
// not sure what next code is
}
Currently team is doing Selenium test automation.
const dataQaElements = document.querySelectorAll(`[data-qa]`);
for (let el of dataQaElements) {
const parent = el.parentElement;
const kendogridcell = parent.getAttribute("kendogridcell"); // if exists "" or null if does not exist
}
Related
I want to read an element's children and for each of the children, read their children.
I have done this but do not understand why it does not work:
var myElement = $('.a-container');
var myChildren = myElement.children();
for(var i = 0; i < myChildren.length; i++) {
var myGrandChildren = myChildren[i].children();
}
The error I get is myChildren[i].children() is not a function.
Is this not how to achieve what I'm trying to do?
You need to select the element inside the loop:
myGrandChildren = $(myChildren[i]).children();
Although in this case, jQuery.eq is more suitable:
myGrandChildren = myChildren.eq(i).children();
I've recently started to work my Todo list without relying on coding tutorials and it's so difficult. I'm able to add items in my list, but I'm not able to remove items. When I click on items, all items gets deleted. Could you help please?
<fieldset>
<legend class="task-list-title">Goals that I need to work on</legend>
<input
id="inpKey"
type="text"
placeholder="add new goal"
aria-label="new list name"
<button type="button" id="btnInsert">New Goal</button>
<div id="task_list">
</div>
</fieldset>
JavaScript Code
const inpKey = document.getElementById("inpKey");
const btnInsert = document.getElementById("btnInsert");
const task_list = document.getElementById("task_list");
btnInsert.onclick = function() {
const key = inpKey.value;
if(key) {
localStorage.setItem(key, inpKey.value);
location.reload();
}
}
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
task_list.innerHTML += `${key}<br />`
}
task_list.onclick = function() {
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
window.localStorage.removeItem(key);
task_list.innerHTML = key;
}
}
So I believe the problem was you not checking for which particular todo to delete, instead you were deleting them all
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
// I it would be better if you wrapped each key in its own element
task_list.innerHTML += `<div>${key}</div>`; // I'm using a `div` so there'll be no need for a `<br/>` tag
}
task_list.onclick = function(e) {
// I want to use the event data to find out exactly which localStorage key to delete
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
// Here i'm checking if the key is the same as the todo that you want to delete
if (key == e.target.innerText) {
localStorage.removeItem(key); // Removing the todo from storage
e.target.remove(); // Removing the todo element from the DOM
}
}
}
Appending the new key to the innerHTML for tasks_list makes it very difficult to get the key when you want to delete the item. Instead it would be easier to make each new task a <p> element (or an unordered list element) and to append that new element as a child to tasks_list like so-
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const newTask = document.createElement('p') //create a new html element
newTask.classList.add('task') //add a class of "task" to it
newTask.innerHTML = key //set the innerHTML to equal the key
task_list.appendChild(newTask) //add the newTask element as a child element of task_list
}
You can add event listeners to each element with the task class by looping through each and adding your event listener. The nice thing here is that when you want the key for an individual task you need only grab the innerHTML and use that-
for(let i = 0; i < tasks.length; i++) {
tasks[i].addEventListener("click", () => {
const key = tasks[i].innerHTML
window.localStorage.removeItem(key)
location.reload()
})
}
The way you currently removed items by looping through localStorage was actually removing an element on each pass through of the loop and not checking to see if the item it was removing was the item that had been clicked.
EDIT- a. mola's answer does something similar to mine but you don't need to loop through the entirety of local storage to find your matching key. That's the beauty of having key/value pairs! As long as you know the key you can manipulate the data without having to first search for it through a loop.
Well, the result I want to get is my div element should have the same numbers of p elements as the array.
In order to do this, I tried using a for loop but it just create one p element, so I didn't work.
Anyone have idea how to do this? (I'm just learning js).
const diccionario = () => {
var dama = ["bird:pajaro", "car:carro", "house:csa", "camis"];
document.getElementById("dic").addEventListener("click", () => {
var pes = document.createElement("p");
for(var i = 0; i < dama.length; i++){
pes.innerHTML = dama[i];
document.getElementById("cuadro").appendChild(pes);
}
})
}
You need to create the element inside the loop. If you create it outside the loop, then when you call appendChild, it will get removed from wherever it was previously in the DOM:
const diccionario = () => {
var dama = ["bird:pajaro", "car:carro", "house:csa", "camis"];
document.getElementById("dic").addEventListener("click", () => {
for(var i = 0; i < dama.length; i++){
var pes = document.createElement("p"); // <----------------
pes.innerHTML = dama[i];
document.getElementById("cuadro").appendChild(pes);
}
})
}
appendChild doesn't create a copy of the existing element - rather, it just appends the existing element.
Inside the loop in the function thirdNavFunction, I need to target all the .third-nav classes except the one clicked on and it needs to be done without jQuery, how do I do this?
var thirdNav = document.getElementsByClassName("third-nav");
for (var i = 0; i < thirdNav.length; i++){
thirdNav[i].addEventListener("click", thirdNavFuntion);
}
function thirdNavFuntion() {
for (i = 0; i < thirdNav.length; i++) {
thirdNav[i].parentElement.className = "";
}
if (this.parentElement.className === "") {
this.parentElement.className = "nav-sub-li-active";
} else {
this.parentElement.className = "";
}
}
In the code here, I target all the .third-nav divs, but that doesn't work as intended, I need to exclude the one that is clicked. I hope it makes sense.
Convert thirdNav to array using Array.from().
Filter out the clicked element using the filter() method.
Call the forEach method to change the class name of all parent elements.
function thirdNavFuntion() {
const elements = Array.from(thirdNav).filter(el => el !== this)
elements.forEach(el => el.parentElement.className = "")
}
I have an array of class names that I want to search a page for. Then I'd like to find all those elements, grab the text inside, and append it to a div.
var div = document.createElement('div');
div.innerHTML = 'List of names from this page';
document.body.appendChild(div);
var classNameArray = ['user', 'username', 'fullname', 'profile-field', 'author', 'screen-name'];
for (var i = 0; i < classNameArray.length; i++) {
element = classNameArray[i];
getSuggestedAuthors(element);
function getSuggestedAuthors(element) {
var classes = document.getElementsByClassName(element);
var index;
for (var index = 0; index < classes.length; index++) {
var class = classes[index];
var textInsideClass = class.innerHTML;
div.appendChild(textInsideClass);
}
}
}
When I run this, it gives me:
Uncaught NotFoundError: An attempt was made to reference a Node in a context where it does not exist.
I believe the problem is occuring at var textInsideClass = class.innerHTML, because when I remove that, it simply grabs all the classes and appends them to the div. However, I'd like to only get the text inside the class.
Anyone know how to do this without jQuery? I'm injected this hs through Google Chrome's executeScript injection.
Thanks so much!
I think your issue is that appendChild only works with nodes. You might be better off just appending to innerHTML using something along the lines of a.innerHTML += f.innerHTML.
You should also be sure to move the getSuggestedAuthors function out of the loop. It works ok as it is, but it's much better form not to declare functions inside a loop.
If you only need to support chrome then all of the handy methods on the Array.prototype should exist :)
var a = document.createElement('div');
a.innerHTML = 'List of names from this page';
document.body.appendChild(a);
function getSuggestedAuthors(elements) {
for (var d = 0; d < elements.length; d++) {
a.appendChild(document.createTextNode(elements[d].innerText));//append loop items text to a
}
}
['user', 'username', 'fullname', 'profile-field', 'author', 'screen-name'].map(function(cls) {
return document.getElementsByClassName(cls);
}).forEach(getSuggestedAuthors);