• 0

Passing a variable to a jQuery selector


Question

I have some JavaScript code that loops through a record set using a for loop. The ID of each record is assigned dynamically using this script. For example:

id="header1", id="header2", id="header3"

The numeral at the end of the id is assigned via script.

I also need to select these IDs via jQuery but I do not understand how to insert a variable into my jQuery selector.

I have tried the following (simplified for clarity):

$("#header[i]")...;
$("#header"+[i])...;
$("#header+[i]")...;
$("#header"+i)...;

None of these things seem to work as jQuery doesn't select the objects I'm trying to get.

Any ideas on how to dynamically create jQuery objects using a counter variable?

10 answers to this question

Recommended Posts

  • 0

I can't get this technique to work.

My code:

var currentIMHeader = "IM-header"+[i];
			var currentIMData = "IMData"+[i];
			alert("binding a function to "+currentIMData);
			$(currentIMHeader).toggle( function() {
				alert("showing "+currentIMData);
				$(currentIMData).show();
				}, function() {
				alert("hiding "+currentIMData);
				$(currentIMData).hide();
				});

The alerts are there for testing purposes. I have also tried passing a "#" to the selector as I am trying to select based on ID.

  • 0

This is a basic thing on JavaScript syntax, not on jQuery really.

var i = 5;

$("#header"+i).fadeOut();

I see no reason why this would not work - fading out the element with an ID of header5.

Edited by Rob
  • 0
  Rob said:
This is a basic thing on JavaScript syntax, not on jQuery really.

var i = 5;

$("#header"+i).fadeOut();

I see no reason why this would not work - fading out the element with an ID of header5.

It might work outside of a for loop but it doesn't seem to work in one.

The following code with hardcoded jQuery selectors should bind a function to the "defName0" object but it doesn't bind when used within a for loop.

$("#defName0").bind("click", function() {
			 $("#defValue0").fadeIn("normal");
			 });

I'm completely stuck.

Is there some basic incompatibility betwen standard JS For loops and jQuery? jQuery has an "Each()" function that I have not used yet - is this the path to salvation?

  • 0

Quick usage note:

$(".headers").fadeOut();

This would fade out all elements with a class of 'headers'.

$(".headers").each(function() { 
  alert("Fading out element: "+$(this).attr("id"));
  $(this).fadeOut(); 
} );

That would find all elements with a class of 'headers', alert to the screen their ID, and fade them out.

  • 0

To append on what Rob posted, you can put a variable in function() to have an iterated value for the loop

$(".headers").each(function(i) {
  alert("Fading out element "+i+": "+$(this).attr("id"));
  $(this).fadeOut();
} );

Do note that it works like an indexed array, so i will start at 0, not at 1.

  • 0
  raskren said:
When passing the counter variable "i" to my jQuery function is there a need to reference the variable using brackets ""?

$(".headers").each(function([i]) {

No, the only time (that I know of) that it is necessary is for arrays or lists:

var locations = Array();
locations[0] = 'Neowin.net';

var sites = ["Neowin.net", "Microsoft.com"];

  • 0

Long explanation incoming.

jQuery is JavaScript. All JavaScript rules apply to everything jQuery. jQuery doesn't change how the language (and interpreters) function and behave. Case in point:

var i = 5
$("#myElement" + i).bind(...);

In the above code, "#myElement" + i always returns the string #myElement5. Therefore, the jQuery function $() receives the string #myElement5 as a parameter.

The code your provided has some issues with it. I won't say that what you did is wrong, because you wrote it the way you thought it would work. It's wrong in the sense that the interpreter interprets the code differently than what you thought it would. Your code follows; I added the for loop because I assumed that's what you're doing:

for (var i = 0; i < 5; i++) {
	var currentIMHeader = "IM-header"+[i];
	var currentIMData = "IMData"+[i];
	alert("binding a function to "+currentIMData);

	$(currentIMHeader).toggle(
		function() {
			alert("showing "+currentIMData);
			$(currentIMData).show();
		}, 
		function() {
			alert("hiding "+currentIMData);
			$(currentIMData).hide();
		}
	);
}

First, is used incorrectly. The [] operators are for arrays (and objects, but we won't go there) to pick an item in the array at a specific index. For instance, say I have an array with ten items. You use the [] operators to pick which item you want from the array:

alert(myArray[5]); // alerts the sixth item in the array

You don't receive an error from the usages above, but it is incorrect.

The issues in your code are scope and closures. Variables defined in a function are function scoped... meaning any variable you define in the function can be used anywhere in that function as long as the variable is defined. Take the following code samples as an example:

alert(i); // alerts undefined

for (var i = 0; i < 5; i++) {
	alert(i); // alerts 0, 1, 2, 3, or 4
}

alert(i); // alerts 5 (because the loop iterated i to 5, then exited because 5 isn't less than 5)

...

alert(foo); // undefined

if (true) {
	var foo = "bar";
}

alert(foo); // alerts bar

Even though the i and foo variables are defined within a block (designated by {}) of code, they can be used outside that block and still retain their value. That in itself doesn't cause the problem you see, but throw in a closure and things can start to behave differently than you'd think.

Looking back at your code, the function declarations for the toggle() method are closures. The problem comes from using the currentIMData variable within the enclosed functions. Each function passed to the toggle() method contains a reference to the same currentIMData variable, and currentIMData's value changes with each iteration of the loop. So in actuality, after the loop exists, this is what the the interpreter sees for every heading when toggle() is called:

function() {
	alert("showing IMData5");
	$("IMData5").show();
}, 
function() {
	alert("hiding IMData5");
	$("IMData5").hide();
}

The way to get around this issue is, ironically, another closure; a function to return a function. The code below works:

for (var i = 0; i < 5; i++) {
	var currentIMHeader = "IM-header"+ i;
	var currentIMData = "IMData"+ i;
	alert("binding a function to "+currentIMData);

	$(currentIMHeader).toggle(
		function(elementId) { // function that accepts a parameter
			return function() { // the function to return
				alert("showing "+ elementId);
				$(elementId).show(); // use the variable from the parameter
			};
		}(currentIMData), // call the function and pass currentIMData as the parameter
		function(elementId) { // function that accepts a parameter
			return function() { // the function to return
				alert("hiding "+ elementId);
				$(elementId).hide(); // use the variable from the parameter
			};
		}(currentIMData) // call the function and pass currentIMData as the parameter
	);
}

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • I guess we can agree to disagree. I had the completely opposite experience, and not just that it annoyed me, I was frequently unable to use the sites I visited regularly.
    • Yeah, so reliable, it kept failing to install via Windows Update with the following error on my i7 Surface Pro 7+, stating it's not even ready almost a year later:
    • Reminds me of the meme with Obama giving Obama a medal.
    • 😂😂😂😂. ok whatever you say MS.
    • Samsung rolls out next big UI update to Galaxy Watch Ultra by Devesh Beri Samsung has announced that its Galaxy Watch Ultra now receives One UI 8 Watch, which means that Galaxy Watch Ultra users now have access to new health tools designed to support daily wellness, including Running Coach, Vascular Load, and Antioxidant Index. The new interface on One UI 8 Watch has been made to give important information swiftly on the watch’s small screen. One can customize Multi-Info Tiles, which have health data, weather, and other metrics. The Now Bar, first introduced in One UI 7, keeps current actions and tasks always within reach. Samsung says the update brings more tools to improve sleep, heart health, fitness, and nutrition. The Galaxy Watch Ultra now features Bedtime Guidance, which provides personalized sleep times based on recent sleep trends, and the ability to measure vascular load during rest, allowing the watch to track the stress placed on the heart during sleep. These features, even though they are visible on the Samsung Health app for users of older watch models, can only be used by Watch8 users. It also comes with a Running Coach. The watch will analyze a 12-minute run to set a level and then give a training plan for goals like a marathon or a new distance. The Antioxidant Index measures the levels of skin carotenoids in seconds. It provides feedback on lifestyle choices that can help with healthy aging. Samsung says these updates are aimed at giving a more complete health experience, using instant feedback to help guide users’ choices. The Samsung Galaxy Watch8 was officially unveiled on July 9, 2025, at the Galaxy Unpacked event along with all-new Galaxy Z Fold7, Galaxy Z Flip7, and Galaxy Z Flip7 FE. This series consists of 3 different watches: the Watch8, Watch8 Classic (the one with rotating bezel), and Watch Ultra (2025). Source: Samsung
  • Recent Achievements

    • Week One Done
      SmileWorks Dental earned a badge
      Week One Done
    • Community Regular
      vZeroG went up a rank
      Community Regular
    • Collaborator
      Snake Doc earned a badge
      Collaborator
    • Week One Done
      Snake Doc earned a badge
      Week One Done
    • One Month Later
      Johnny Mrkvička earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      589
    2. 2
      Michael Scrip
      199
    3. 3
      ATLien_0
      195
    4. 4
      +FloatingFatMan
      133
    5. 5
      Xenon
      122
  • Tell a friend

    Love Neowin? Tell a friend!