Using Jquery, call function on selection just once - javascript

Say i have a selection of textboxes like this;
var arrayoftextboxes = $('.textbox1, .textbox2, .textbox3');
Is there a way I can call a function on each one in a simpler way than this?
It only needs to be called once.
arrayoftextboxes.each(function(i){foo(arrayoftextboxes[i]);});
I tried
arrayoftextboxes.load(function(){foo(this)});
and
arrayoftextboxes.bind(function(){foo(this)});
but the functions dont seem to be called.

You can do this:
$('.textbox1, .textbox2, .textbox3').each(function() { foo(this); });
The .each() call creates a closure, inside it this refers to the DOM element you're currently on, but it may be better to write what you have as a jQuery plugin. Or, if you just use this inside foo (instead of the DOM element as a parameter) you can shorten it down to:
$('.textbox1, .textbox2, .textbox3').each(foo);
Here's a demonstration of that method
Also, make sure you're running this on document.ready like this:
$(function() {
$('.textbox1, .textbox2, .textbox3').each(foo);
});
Otherwise the DOM elements may not be there to find, making that selector return an empty array (so nothing to run on).

Related

Writing a jquery handler more efficiently

$("#element").on("change", function(){
calculateValue();
});
function calculateValue(){
$("#result").html($("#int1").val() + $("#int2").val());
}
calculateValue();
In the above (example) code, I am calculating the results of an element every time an element is changed.
However I also want to do this calculation before the user has changed any values. So in the above example I just call the function.
It seems messy that I am calling the function in two places. When I have a few of these, it starts looking very messy. Is there any better way to write this?
You can simply declare two events to the elements as below:
$("#element").ready(function(){calculateValue();})
.bind("change", function() {
calculateValue();
});
FROM THE API:
The .ready() method offers a way to run JavaScript code as soon as the page's Document Object Model (DOM) becomes safe to manipulate.

How do you assign onclick within for loop in javascript?

function initnav(){
var cbox=document.getElementsByClassName('box');
for(var i=0;i<cbox.length;i++){
cbox[i].innerHTML=cbox[i].id;
<!--so far I have set their captions after setting their ids same as how I want them to appear.-->
<!--what comes next is what doesn't really work.-->
getElementById(cbox[i].id).onclick=Mclick(cbox[i].id);
}
};
function Mclick(id){alert(id);}
The whole thing is in a js file, and promptly linked from my html file.
As planned, all the buttons should appear and be clickable, but what is happening instead is only one of them is visible and that one is not working when I click on it.
When I create a lot of div-oriented buttons, I wish I could run for loop and be able to assign each of them as clickable instead of writing lines as many as they are.
How do you assign onclick within for loop in javascript?
You're calling the function instead of assigning it.
getElementById(cbox[i].id).onclick = Mclick;
Of course, now your function will receive an event argument instead of an id. (Passing the id inside the loop is a huge pain; easiest fix is to not bother trying.) But it also gets the attached element as this, which is convenient:
function Mclick() {
alert(this.id);
}
Other comments:
You should try not to be in the habit of using innerHTML if you're not assigning a string that contains known HTML. Saves you from having to care about escaping. Use textContent instead.
Assigning to onclick is a bit inflexible; you can only ever assign one click handler this way, and it's hard to notice if you accidentally overwrote an existing handler. Use addEventListener.
getElementById(element.id) should surely be equivalent to element.
Don't use HTML comments within JavaScript! :) They only work for... weird backwards-compatibility reasons. JavaScript comments are either // ... or /* ... */.
Best not to capitalize a function name unless it's supposed to be a constructor; you may notice that SO's highlighting made Mclick green, because it thinks it's a class name.
So I'd end up with:
function initnav() {
var cbox = document.getElementsByClassName('box');
for(var i = 0; i < cbox.length; i++) {
cbox[i].textContent = cbox[i].id;
cbox[i].addEventListener('click', alert_id);
}
}
function alert_id(event) {
alert(this.id);
}
So basically you don't call the for loop since the for loop is in the function. If you want to call all your variables and the statements in the for loop you have put the statements in the function and call the function outside of the function but inside of the script.

setting default root element in jquery

jQuery currently uses window as its default element so any call like $('div') will look for div tags inside window.
Is there any way to change defaults on jQuery like:
$.defaultRoot = $('.anyOtherRootElement');
$('div').text("Hello");
this will select any div inside the elements containing .anyOtherRootElement class.
Thanks in advance
Upate
just an update refining the question a bit more here:
I would like to perform the actions above based on external queries coming from external script which won't know what defaultRoot is so they can still be calling what is supposed to be the current base, so in this instance, I'm afraid adding the a second parameter wouldn't be an option, unfortunately.
And at the same time creating a function which returns defaultRoot.find(el) would prevent me of using first-level methods such $.trim, $.each, etc… so unfortunately that would not be possible as well.
Ideally (for performance reasons) you'd want to use find()
$.defaultRoot.find("div");
Otherwise you can use the 2 argument form that sets a context
$("div", $.defaultRoot);
In general you don't want to do these types of things implicitly since someone else could easily end up thoroughly confused when having to work with your code later. If you want to do it consistently and make it shorter you should create your own function to do so like:
var $s = function(selector) {
return $.defaultRoot.find(selector);
}
and then you'd just be able to use
$s("div")
or you could also do a scoped higher order function with something like
var withScope = function(scope$) {
return function(selector) {
return scope$.find(selector);
}
}
var $s = withScope($.defaultRoot);
$s("div")
If for some reason you really want to screw around with the default state for client code (begging for chaos IMO), you should look at the functional practice: currying.
$('SELECTOR', 'CONTEXT')
You can use context. As in your case $('div', '.anyOtherRootElement')
For more details, visit http://api.jquery.com/jQuery/
Given that you can pass the context as a second argument, you can easily overwrite the $() operator in Javascript with a version which internally calls JQuery using jQuery.noConflict(); and always passes your new root as the second argument.
I don't think jQuery provide such method or variable. But you can pass second parameter in jQuery method to set context.
$.defaultRoot = $('.anyOtherRootElement');
$('div', $.defaultRoot ).text("Hello"); // all div inside $('.anyOtherRootElement')
$('div' ).text("Hello"); //all div inside body tag

Jquery Replace with return value of Javascript function

OK I am just starting out with jQuery.
I have a page with a table of date-values. Each is wrapped in a tag which I can find with
$('mytag').
<mytag>2009-10-31</mytag>
How, using Jquery, would I
take each of the source values and
pass it to a Javascript function
then replace that source value within the table with the result of the function calculation.
So <mytag>2009-10-31</mytag>would be replaced with <mytag>Very Late</mytag>
I have the Javascript function written. My question is the jQuery syntax to pass the individual value.
Firstly, you will need an element selector, e.g.
$('table')
Will select all <table> elements in your html. So,
$('mytag')
will give you your elements. You will get a jQuery object (not a DOM object) returned. See http://docs.jquery.com/Selectors
Then you want to call a function for each of your elements. For this we call the .each function, and pass the function to call for each element:
$('mytag').each(function(){
//function code goes here
});
(See http://docs.jquery.com/Utilities/jQuery.each)
The function in this case is called an Anonymous function
Then you want to reference the current object in the iteration, so we use the DOM this item and wrap it into a jquery object. To get the value, we use the .text() function (http://docs.jquery.com/Attributes/text)
$('mytag').each(function(){
$(this).text()
});
Note: if it were an input element then you would have used .val()
Passing it to a function is easy:
...
MyFunction($(this).text());
...
The text() function has an overloaded implementation which allows you to set the text if you pass a value:
$(this).text(someval);
So, we can factor this into our code
...
$(this).text(MyFunction($(this).text()));
...
Making our final code block:
$('mytag').each(function(){
$(this).text(MyFunction($(this).text()));
});
$('mytag').each(function (index,tag) {
$(tag).text( myFunc($(tag).text()) );
});
$("mytag").each(function() {
$(this).html("Very Late");
});
$('mytag').each(function() {
$(this).text(someFunction($(this).text()));
});
But, from the sound of your problem, you might be better served by the jQuery-timeago plugin. For your particular case, you'd possibly want to allow dates in the future:
jQuery.timeago.settings.allowFuture = true;
...and you'd want to create your own language override. See the language override examples. You could define several "late" and "very late" values. You can also pass a function to each one to change the value depending on how many days ago a timestamp was.

JQuery Loop over JQueryObjects

I have a method, which will accept a parameter of a JQuery Object and will calculate totals for a section. So if you give it a JQuery Object of a div containing the section it will calculate a total for it
so you can do this:
var $totalcompletion = CalculateSectionCompletion(jQuery("#Section1"));
Now I have multiple divs with the class of section container. I want to be able to call the above method on any div with that class.
I'm doing this:
jQuery("div.SectionContainer").each(
function(i, valueOfElement){
CalculateSectionCompletion(valueOfElement);
});
The problem is the valueOfElement is actually the DOM object and not the JQuery Object, so I can't pass this in to my method.
Is there anyway I can loop through all JQuery Objects selected by a query, without writing some dirty code to extract the Id from the DOM object, and call JQuery(valueOfElement.id) and pass it in?
You can wrap any DOM element in $(..), as you do with $(document).
So I think you should be able to
jQuery("div.SectionContainer").each( function(i, valueOfElement){
CalculateSectionCompletion($(valueOfElement));
});
You could also ignore the i and valueOfElement arguments altogether and use this.
jQuery("div.SectionContainer").each(function(){
CalculateSectionCompletion(jQuery(this));
});
You could even make the CalculateSectionCompletion function wrap it's argument in the jQuery object.
jQuery("div.SectionContainer").each(function(){
CalculateSectionCompletion(this);
});
function CalculateSectionCopletion(e){
jQuery(e).dostuff();
}

Categories

Resources