I have a bunch of divs of classname foo within a div of classname fooContainer (these foo divs have been dynamically added to fooContainer).
I have a function operateOnFoo(fooObjectToBeOperatedOn) that operates on a single foo div (that is passed into operateOnFoo as a parameter).
I would like to use the jQuery each() feature to run the operateOnFoo function on all/each of the divs of classname foo within fooContainer. I have tried using calls like:
operateOnFoo( $("#fooContainter").each( ".foo" ) );
and
$("#fooContainter").each( operateOnFoo( foo ) );
and
$("#fooContainer").find(".foo").each( operateOnFoo( ".foo" ) );
but I just can't get it to work. How do I proceed?
I'm a little new to web developing, teaching myself as I go along, so I apologize if this question is overly basic - but I couldn't seem to get it working using other similar Stack Exchange posts as I have been able to do with most of my other issues.
Thanks!
The .each() callback is what it is and you can't change the number of arguments to it or the order in which they appear. So, because your operateOnFoo() function wants different arguments, you can't have .each() call it directly as it is. You can work around it though like this with a stub function that makes the arguments work like you want:
$("#fooContainer .foo").each(function(index, element) {
operateOnFoo(element);
});
Also, the single selector "#fooContainer .foo" will select all items with class="foo" that are contained within the object with id=fooContainer.
If you can change operateOnFoo() to accept the exact two arguments that .each() uses (even if you ignore the first argument), so it was declared like this:
function operateOnFoo(index, element) {...}
then you would be able to just do:
$("#fooContainer .foo").each(operateOnFoo);
each require a function call back ,so give it a function.
$("#fooContainer").find(".foo").each( function(k, div){ operateOnFoo(div) } );
Considering fooContainer to be a class and not the ID of the container. You can use it like so:
$(".fooContainer .foo").each(function(index, element){
operateOnFoo(element);
});
Try this:
$("#fooContainer .foo").each(function(index, element){
//Your code goes here...
alert("Foo index: " + index + "\nContent: " + element);
});
Try this $(".fooContainter .foo").each(function (i, foo) { operateOnFoo( foo )}; );
The $(".fooContainter .foo") will select all the elements with class foo under fooContainer
Related
I want to be able to select multiples images when pressing the upload button and be able to see all of them. At the moment I made a simplify version where I want to see the url of the images in a label. At the moment I only can accomplish it by getting the first or last element:
var media_attachment = meta_image_frame.state().get('selection').first().toJSON()
meta_label.text(media_attachment.url)
But i really want to see all the url, so keeping that code in mind i tried to made a modified version using .each like this:
var media_attachment = meta_image_frame.state().get('selection').each(function(){
var media_attachment_tr = $(this).first().toJSON();
meta_label.append(media_attachment_tr.url);
});
meta_label.append(" isdone");
But this does nothing, even the "isdone" part is not appending to the code and i have no idea of why this is happening. There is a way to make this itereable?
You are using .each wrong. jQuery's .each takes 2 arguments. The first being the object that you want to iterate over and the second one is the callback, see this example from the documentation:
$.each([ 52, 97 ], function( index, value ) {
alert( index + ": " + value );
});
Additionally, the callback function takes also 2 arguments that you can use in the body of the function: the index and the value of the item from the object that it iterates over.
If you want to use jQuery's .each, you'll need to restructure the code, but I'd suggest using JavaScript's .forEach instead, which does sort of what you have in your code. You just need to add one or two argument in the callback function - the first being the current item from the list and the second, optional, is the index.
Your code (without insuring functionality) could look like this:
var media_attachment = meta_image_frame.state().get('selection').forEach(function(media){
var media_attachment_tr = media.toJSON();
meta_label.append(media_attachment_tr.url);
});
Seemingly-easy problem here: I'm trying to create a streamlined way to hide/show a collection of DOM elements using some jQuery/vanilla JS. This was from a refactor where several fragmented functions were re-done as better encapsulated versions of their former selves.
What these functions are trying to do take elements from an array (by ID), use map to convert them to jQuery objects, and then hide or show them.
Using jQuery 1.11 in an Angular project, but the angular aspect doesn't seem to interfere with this case, since it won't work in a jsFiddle either.
main problem: When I run the function (usually using a click event), I don't get any sort of error from console and I don't get any sort of result in the DOM either. Any ideas? I'm sure it's a simple thing I'm missing, but I need other eyes on it.
Here's a jsFiddle with the below code loaded in, ready for fixin'. Thanks!
http://jsfiddle.net/sLgqvdku/
function showItem(item) {
return item.show();
}
function hideItem(item) {
return item.hide();
}
function showItemsWithIDs(ids) {
ids.map($).forEach(showItem);
}
function hideItemsWithIDs(ids) {
ids.map($).forEach(hideItem);
}
var itemsHiddenToFocusTribute = ['#form', '#ask', "#submitButton", "#sidebar", "#AmountCtrl", "#giftbutton"];
It appears that only the first element in the array is actually being converted into a jQuery object in your code.
Here's what's happening: vanilla-JS .map passes three arguments to the specified callback function: the current element, the index, and the array.
If the callback function takes only one argument, the second and third are ignored. However, jQuery's $ actually allows two arguments: a selector, and a context (container element). So your code is passing (as the second argument) the array index as a context, resulting in an empty jQuery object -- except for the first element in itemsHiddenToFocusTribute, which has index 0 which is interpreted as no context at all.
You can fix this with an anonymous function that only passes the selector string to $:
function hideItemsWithIDs(ids) {
ids.map(function (i) {
return $(i);
}).forEach(hideItem);
}
http://jsfiddle.net/mblase75/e23qgad5/
However, a more jQuery-friendly way would be to create a single jQuery object of all the desired elements and loop through them using .each:
function hideItem(i,item) {
return $(item).hide();
}
function hideItemsWithIDs(ids) {
$(ids.join()).each(hideItem);
}
http://jsfiddle.net/mblase75/mm2L4xn1/
This is probably more efficient, too, since you're calling $ just once instead of array.length times.
All you're wanting is to send each id through the foreach loop? Then I'd just use each like so:
$(ids).each(function(index, id) {
hideItem(id);
});
You don't need to use map($) to convert them to jQuery objects, just put the object inside the dollar sign function call, like so: $(ids).
Also make sure you pass the actual id to showItem and hideItem when you call them, like so: hideItem(id). You also need to make sure that you use a jQuery object in your hideItem and showItem functions. I changed your code to this:
function showItem(item) {
return $(item).show();
}
function hideItem(item) {
return $(item).hide();
}
function showItemsWithIDs(ids) {
$(ids).each(function(index, id) {
showItem(id);
});
}
function hideItemsWithIDs(ids) {
$(ids).each(function(index, id) {
hideItem(id);
});
}
var itemsHiddenToFocusTribute = ['#form', '#ask', "#submitButton", "#sidebar", "#AmountCtrl", "#giftbutton"];
$('#clicker').click(function(){
hideItemsWithIDs(itemsHiddenToFocusTribute);
});
And here's the updated Fiddle
This question already has answers here:
Calling an event handler with an argument [duplicate]
(5 answers)
Closed 8 years ago.
Fiddle Example
Can I pass selectors other than $(this) selector as function parameters?
What I mean is that the selectors (#Aarea and Barea) I want to pass are the ones that I want to append some HTML content to.
function info(a){
var source = $(this).data('source')
$(a).html(source)
console.log(source);
}
$('#one').click(info('#Aarea'))
$('#two').click(info('#Barea'))
<button data-source="AAA" id='one'>Button</button>
<div id="Aarea"></div>
<div id='Barea'></div>
<a href='#' data-source='BBB' id='two'>Click</a>
But it doesn't work unless I don't use the parameters and specify those selectors in the function.
What your code:
$('#one').click(info('#Aarea'))
...is doing is calling info and passing its return value into click, exactly like foo(bar()) calls bar and passes its return value into foo.
What you want to give click is a function to call. In your case, the simplest way is to use a wrapper function:
$('#one').click(function() {
info(this, '#Aarea');
});
...and update info to accept the element as an argument:
function info(element, a){
var source = $(element).data('source')
$(a).html(source)
console.log(source);
}
Updated Fiddle
Alternately, you can use Function#call to call your original info without changing it:
$('#one').click(function() {
info.call(this, '#Aarea');
});
Function#call calls a function, setting this during the function call to the first argument you give it (and then passing along any other arguments you give to it).
Updated Fiddle
I think your problem is that you're passing the evaluated function into your click handler.
The proper format is something more like this:
$('#one').click(function(){ info('#Aarea'); })
$('#two').click(function(){ info('#Barea'); })
Here's a fiddle with working code -http://jsfiddle.net/2548hkvg/
Alternatively, you could define the target area as a data attribute as well, and only have one function, seen in this fiddle - http://jsfiddle.net/k42ahykb/
In the code for that, we're defining info as our function expression that we pass to the click handler, and this is properly retained.
function info(e){
var source = $(this).data('source');
var target = $(this).data('target');
$(target).html(source)
console.log(source);
}
$('#one').click(info)
$('#two').click(info)
$('#one').click(info('#Aarea'))
You are calling the function here, so the result passed to .click() is undefined. Like #iabw said, you need to wrap it in a function expression so the click event can invoke info() successfully.
Just passthrough this from onclick function to info.
$('#one').click(function(){ info.call(this, '#Aarea'); })
$('#two').click(function(){ info.call(this, '#Barea'); })
I have several <select> boxes all using the same prefix and I would like to set up a recursive function to essentially do the work for me.
$('[id^="by_"]').change(function(e)
{
var elem = e;
console.log(e.value);
});
Based on this code is my intention pretty clear? Am I on the right track?
console prints out: undefined
I think you're on the right track - the selector you're using matches a prefix of "by_", and you're binding the change event to all of them. Make sure you put this in $(document).ready or similar. Are you having any problems with this code? Instead of using the e parameter, I would just use this inside of the function to refer to the element and $(this) to get the jQuery object of it. So to get the value, you'd use:
this.value
// or
$(this).val()
(ignore the e and elem stuff, although it wouldn't be a bad idea to store $(this) in something like elem so you can have a reference to it instead of re-creating the jQuery object every time you need it)
When using callbacks to events with jQuery, the (first) parameter of the callback is an event object that explains many things about the event that occurred ( http://api.jquery.com/category/events/event-object/ ) and does not hold the element - that's what this is for!
e in your code is the event object which has no value property, you should use this instead:
$('[id^="by_"]').change(function(e) {
var elem = this;
console.log(this.value);
});
Or if you want to use event object, you can use target property:
e.target.value
Since you're already using jQuery, why not something like this:
$('[id^="by_"]').change(function(e)
{
var $elem = $( this );
console.log( $elem.val() );
});
Isn't it more something like that:
$('[id^="by_"]').change(function()
{
console.log($('option:selected',this).val());
});
jsfiddle
i'm having some problems with jQuery
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
foo.filter("h1,h2").map(function(id) {
$(this).wrap('<span color="red"/>');
});
alert(foo.html());
});
This code outputs
<h1>Bar</h1><p>Hi</p><h1>Baz</h2><p>bye</p>
The span's are nowhere to be seen. What am I doing wrong?
It doesn't have any effect because .filter() filters elements at that level, you could need .find() to get descendants like this:
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
foo.find("h1,h2").wrap('<span color="red"/>');
alert(foo.html());
});
You can test it out here. Also note you should use .each() instead of .map() for looping...but there's no need here, since you can just call .wrap() directly.
You don't want to use filter here, you want to use find. Also, why are you using map?
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h2><p>bye</p></div>");
foo.find("h1,h2").wrap('<span color="red"/>');
alert(foo.html());
});
Live test
First off: your markup is invalid (Baz is wrapped by an opening h1 and a closing h2). But the .map reference says you need to return the value.
$(document).ready(function() {
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
var bar = foo.find("h1,h2").map(function(id) {
return $(this).wrap('<span color="red"/>');
});
});
You need .find() instead of .filter() since the heading elements are nested.
var foo = $("<div><h1>Bar</h1><p>Hi</p><h1>Baz</h1><p>bye</p></div>");
foo.find("h1,h2").wrap('<div color="red"/>');
Also, I changed it to wrap using a <div> instead of a <span> since I don't think it is valid to have a <span> wrapped around heading elements.