it seems like, when a div tag is added between the following code:
<div id="fixed-drop">
<button type="button" class="dropdown-btn">Show;</button>
</div>
The following Javascript code is not able to get the item, failing with
Uncaught TypeError: Cannot read properties of undefined (reading 'getElementsByClassName')
But if that div tag is deleted, javascript is able to grab the button:
I have tried the following js codes:
var dropdown = document.getElementById("fixed-drop").document.getElementsByClassName("dropdown-btn");
var dropdown = document.getElementById("fixed-drop")[0].document.getElementsByClassName("dropdown-btn");
Without div this works:
var dropdown = document.getElementsByClassName("dropdown-btn");
The problem occurs that you first fetch the div with document.getElementById("fixed-drop"). If yor are remove it, the funtion will return null. and the next function cant access null.
Solution
Use querySelector instead of chaining getElementById() functions.
const btn1 = document.querySelector('.dropdown-btn')
console.log('without select parent div:',btn1)
const btn2 = document.querySelector('#fixed-drop .dropdown-btn')
console.log('with select parent div:',btn2)
<div id="fixed-drop">
<button type="button" class="dropdown-btn">Show;</button>
</div>
Document.querySelector() can be used to select the child element:
var dropdown = document.getElementById("fixed-drop").querySelector('.dropdown-btn');
dropdown.addEventListener('click', function() {
console.log('Clicked');
});
<div id="fixed-drop">
<button type="button" class="dropdown-btn">Show</button>
</div>
Try to remove accessing second time to the document.
var dropdown = document.getElementById("fixed-drop").getElementsByClassName("dropdown-btn");
var dropdown = document.getElementById("fixed-drop")[0].getElementsByClassName("dropdown-btn");
Since getElementById returns a element, you can not access document property on that.
you need to use it this way
const dropdown = document.getElementById('fixed-drop').getElementsByClassName('dropdown-btn');
In addition you should read this: https://developer.mozilla.org/es/docs/Web/API/Document/getElementsByTagName
<3
var dropdown = document.getElementById("fixed-drop").document.getElementsByClassName("dropdown-btn");
""" document.getElementById("fixed-drop") """ this is an element. You can't
element.getElementsByClassName("dropdown-btn") on element.
You can use querySelector.
var dropdown = querySelector('#fixed-drop .dropdown-btn');
Related
I have a template that I will be adding to the body multiple times. Each one will be the same, except the text in one of the elements will be different:
<template id="template">
<div class="activity">
<p class="activityName"> <!-- to be changed -->
</p>
<button type="button" class="btn btn-primary">
Edit
</button>
</div>
</template>
When I insert this template, I wants to edit the .activityName element. I could use Node.firstChild, but that means that if I change the HTML in the future, this setup might break if that element is no longer the first child. Is it possible to retrieve it by class from that specific node? Something like this:
var template = document.getElementById("template");
var clon = template.content.cloneNode(true);
clon.getElementsByClassName("activityName")[0].innerHTML = "text"; //this line needs changing
document.body.append(clon);
what about using:
clon.querySelector(".activityName").innerHTML = "text";
The querySelector function finds the first element that matches with the specified selector, in this case, our selector is .activityName this means that the function will find the first element with the class activityName
Now, if you want to get all the nodes with the same class, you have to use the querySelectorAll function
I see that you used template.content but there is not a property called content in template element, maybe you mean something like var clon = template.querySelector('.activity')
So the first image is what my page looks like. I am trying to grab the ID of the table at the top (the table that has the class trackingHistory and ID of ContentPlaceHolder1_ctl00_myRpt_ctl00_0_gdvTH_0) whenever the highlighted button is clicked.
Right now I can click the button and fire my Javascript method 'ToggleHistory()' and use jQuery to get the ID of my button. (.attr('id'))
but that's about as far as i can get. I have tried messing around with the closest() and prev() methods from jQuery but haven't had any luck. any help would be appreciated.
javascript method
function ToggleHistory(button)
{
console.log(button);
var x = $(button).prev();
var y = $(button).closest('table').find('.trackingHistory');
//var z = $(button).closest('.trackingHistory');
console.log(x);
console.log(y);
console.log($(y).attr('id'));
//console.log(z);
}
i dont want to have to hard code the id because there will be a dynamic amount of these tables and buttons.
The <button> and the <table> don't have a direct relationship, but do have the <div> in common.
<div>
<table class="toggleHistory"></table>
</div>
<button type="button" onclick="ToggleHistory(this)">click here to hide</button>
The <button> and <div> are immediate siblings, which you can traverse between with .prev() and back with .next().
$(button).prev()...
Then, the <div> and <table> are .parent() and child (.children()):
$(button).prev().children('.trackingHistory');
function ToggleHistory(button)
{
console.log(button);
var $historyTable = $(button).prev().children('.trackingHistory');
console.log($historyTable.attr('id'));
}
Can I select the element by its function?
for example
HTML
<button id="saveButton" onClick="javascript:fnSave(this)>
Save
</button>
then javascript
function fnSave(element){
console.log($(element).attr('id'));
}
clicking the button will result : saveButton
You can do that with using the currentTarget - like this:
save = function(object){
console.log($(object).attr('id'));
}
And, you would call this from your HTML like you mentioned - just including the quote:
<button id="saveButton" onClick="save(this)">Save</button>
To get the element you can do what you just did, add onClick='fnSave(this)' to the button, and on the function:
function fnSave(element){
//the element is in 'element'
}
But I see you are using jQuery, so you can remove the onClick and use this:
$("#saveButton").click(function(event){
var element = $(this);//the element is in 'element'
});
Note: if you are going to use this for multiple different buttons, it would be wise to select them by a clasName instead, or use the first function.
edited
I have 29 buttons: todayResultsbutton0 .. todayResultsbutton28,
and 29 divs: todayResultsUrls0 .. todayResultsUrls28.
I also have a function toggleVisibility(divName) that hide/show the given div.
I am trying to use the following code:
for (var i=0; i < 29; ++i) {
var b = "#todayResultsbutton"+i;
var d = "todayResultsUrls"+i;
$(b).click(function(){toggleVisibility(d);});
}
I thought that this will cause each button click to show/hide the matching div but the actual result is that clicking on any button (0 .. 28) show/hide the last div - todayResultsUrls28.
Can someone tell me where am I wrong?
Thanks.
Use a class.
$(".myClass").click(function() {
var d = $(this).attr("id").replace("button", "Urls");
toggleVisibility(d);
});
Instead of trying to use a loop, you'd be better off using the selector to "find" your divs..
say you have something like:
<table>
<tr><td>
<input type="button" id="myButton" value="test" text="test" />
</td><td><div id="myDiv"></div></td></tr></table>
You can find myDiv by :
$('#myButton').parent().find('#myDiv').hide();
You could use the "startsWith" attribute selector with the id, then build the url from the id of the clicked item.
$('[id^=todayResultsbutton]').click( function() {
var url = this.id.replace(/button/,'Urls');
toggleVisibility(url);
});
Use
var d = "#todayResultsUrls"+i;
Instead of
var d = "todayResultsUrls"+i;
You can use this:
$('button[id^="todayResultsbutton"]').click(function() {
var index = this.id.substring(18,this.id.length);
toggleVisibility("todayResultsUrls"+index);
});
This will find all <button> tags with id's starting with todayResultsbutton. It will then get the ID for the clicked tag, remove the todayResultsbutton part of it to get the id and then call the toggleVisibilty() function.
Example here.
Edit
Notes:
Using button before the starts with selector ([id^="todayResultsbutton"]) speeds up the jQuery selector because it can use the native getElementsByTagName function to get all button tags and then only check those for the specific ID.
this.id is used instead of jQuery's $(this).attr('id') because it's faster (doesn't require wrapping this or calling the extra function attr()) and shouldn't cause any cross-browser issues.
Toggle visibility by finding the relevent div usint the event target rather than classes etc.
Assuming:
<div id='todayResultsUrls1'>
<button id='todayResultsbutton'></button>
</div>
Using the event target you can get the button element and find the div you want to hide.
var parentDiv = $(e.target).parent();
toggleVisibility(parentDiv);
on a webpage in under developmnt i'm getting this error on IE
element = $(element);
this code is in prototype.js
Object expected
How to get rid of this error.
Update:
jQuery is also being used on site.
Is "element" the id of your element? If so try making it element = $("element")
your statement should be
element = $("id of element")
suppose you have the following code.
<div id="mainDiv">
...
</div>
To access this control, in prototype, it is
element = $("mainDiv");
UPDATE:
Based on your comment, you can combine both jquery and prototype in the same page.
var J = jQuery.noConflict();
After this statement, $("#foo") will be J("#foo").
See this stackoverflow question
You need to put a var in front of the variable assignment when the variable and element id are the same in IE.
var element = $(element);