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);
Related
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');
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'));
}
I have a grid with values
I need to disable the textbox with ID as minutes for 2nd row. Following sample does not work.
document.getElementById("h_ID")[2].readOnly = true;
Can someone help me with the syntax?
document.getElementById returns only one element, because you are not supposed to have more than one element with an id on the page. Switch all the id="minutes" to class="minutes" and then use:
document.getElementsByClassName('minutes')[2].readOnly = true;
Only one element can have a given id in a HTML document.
That's why document.getElementById("minutes") doesn't return a collection but a unique element. Don't use id in your case but classes.
So your code will be
document.getElementsByClassName("minutes")[2].readOnly = true;
So I know that using "a:first" will get the first link of a page. Lets assume we have the following:
<div class="masterclass">
Link 1
Link 2
</div>
<div class="masterclass">
Link 1
Link 2
</div>
Naturally I can use the following code to get the first "a" of the class "masterclass"
$('.masterclass a:first').click(function() {
alert('yayfirstlink');
});
However I do not understand how to get the first link of every "masterclass"
You need to use find() here because your selector will find all the anchor elements with in .masterclass then filter only the very first one. But when you use .find(), it will find all the .masterclass elements first then will find the first anchor element in each of them.
$('.masterclass').find('a:first').click(function() {
alert('yayfirstlink');
});
or if you are sure that the target element will be the first child of its parent then you can use :first-child
$('.masterclass a:first-child').click(function() {
alert('yayfirstlink');
});
Try this,
var oFirstAnchor = $(".masterclass a:first-child");
$(".masterclass a:first-child") is what you are looking for.
so:
$('.masterclass a:first-child').click(function() {
alert('yayfirstlink');
});
This is how u loop through each of the masterclass and get the first link of it.
i don't know what you want to do with it though so i can only provide this
$(document).ready(function(){
var fields = $('.masterclass a:first-child');
$.each(fields, function(index, val){
alert(index);
});
});
this alerts the current links array index
http://jsfiddle.net/kBd82/6/
I would recommend using the first of type selector for this.
$('.masterclass a:first-of-type')
This way it will always select the first anchor tag in each masterclass div even if you put other things in the div later.
http://api.jquery.com/first-of-type-selector/
I dont know Javascript at all, so sorry for asking a question like this...
This is what I have:
$(document).ready(function(){$("#more0").click(function(){$("#update0").slideToggle("normal");});});
$(document).ready(function(){$("#more1").click(function(){$("#update1").slideToggle("normal");});});
$(document).ready(function(){$("#more2").click(function(){$("#update2").slideToggle("normal");});});
$(document).ready(function(){$("#more3").click(function(){$("#update3").slideToggle("normal");});});
$(document).ready(function(){$("#more4").click(function(){$("#update4").slideToggle("normal");});});
$(document).ready(function(){$("#more5").click(function(){$("#update5").slideToggle("normal");});});
$(document).ready(function(){$("#more6").click(function(){$("#update6").slideToggle("normal");});});
$(document).ready(function(){$("#more7").click(function(){$("#update7").slideToggle("normal");});});
$(document).ready(function(){$("#more8").click(function(){$("#update8").slideToggle("normal");});});
$(document).ready(function(){$("#more9").click(function(){$("#update9").slideToggle("normal");});});
$(document).ready(function(){$("#more10").click(function(){$("#update10").slideToggle("normal");});});
And So On.. Until #more30 and #update30...
So... Right now, my pages has 30 lines :)
Is there a way to do it less complicated?
Thanks!
Use attribute selector ^= . The [attribute^=value] selector is used to select elements whose attribute value begins with a specified value.
$(document).ready(function(){
$("[id^='more']").click(function(){
$("#update" + $(this).attr('id').slice(4)).slideToggle("normal");
});
});
Try to use attribute starts with selector to select all the elements having id starts with more , then extract the numerical value from it using the regular expression and concatenate it with update to form the required element's id and proceed,
$(document).ready(function(){
$("[id^='more']").click(function(){
var index = $(this).attr('id').match(/\d+/)[0];
$("#update" + index).slideToggle("normal");
});
});
use attribute start with selector
$(document).ready(function(){
$("[id^='more']").click(function(){
$("[id^='update']").slideToggle("normal");
});
});
//select all elements that contain 'more' in their id attribute.
$('[id^=more]').click(function(){
//get the actual full id of the clicked element.
var thisId = $(this).attr("id");
//get the last 2 characters (the number) from the clicked elem id
var elemNo= thisId.substr(thisId.length-2);
//check if last two chars are actually a number
if(parseInt(elemNo))
{
var updateId = "#update"+elemNo;//combine the "#update" id name with number e.g.5
}
else
{
//if not, then take only the last char
elemNo= thisId.substr(thisId.length-1);
var updateId = "#update"+elemNo;
}
//now use the generate id for the slide element and apply toggle.
$(updateId).slideToggle("normal");
});
Well first of all, you could replace the multiple ready event handler registrations with just one, e.g
$(document).ready(
$("#more0").click(function(){$("#update0").slideToggle("normal");});
//...
);
Then, since your buttons/links has pretty much the same functionality, I would recommend merging these into a single click event handler registration as such:
$(document).ready(
$(".generic-js-hook-class").click(function(){
var toggleContainer = $(this).data('toggleContainer');
$(toggleContainer).slideToggle("normal");
});
);
The above solution uses HTML Data Attributes to store information on which element to toggle and requires you to change the corresponding HTML like so:
<div class=".generic-js-hook-class" data-toggle-container="#relatedContainer">Click me</div>
<div id="relatedContainer>Toggle me</div>
I would recommend you to use Custom Data Attributes (data-*). Here You can store which element to toggle in the data attributes which can be fetched and used latter.
JavaScript, In event-handler you can use .data() to fetch those values.
$(document).ready(function () {
$(".more").click(function () {
$($(this).data('slide')).slideToggle("normal");
});
});
HTML
<div class="more" data-slide="#update1">more1</div>
<div class="more" data-slide="#update2">more2</div>
<div id="update1">update1</div>
<div id="update2">update2</div>
DEMO