confusion over simple variable declaration jQuery "$variable" vs javascript "var" - javascript

I have this simple ghost text implementation:
HTML code:
<div id="searchPanel">
<form method="get" id="searchBox" action="somePage.php">
<input class="ghText" type="text" name="query" value="search here"/>
</form>
</div>
jQuery code:
$(document).ready(function(){
$txtField = "#searchPanel form input.ghText";
var value = $($txtField).val();
$($txtField).focus(function(){
if($(this).val() == value)
$(this).val("").removeClass("ghText");
});
$($txtField).blur(function(){
if($(this).val()==""){
$(this).val(value).addClass("ghText");
}
});
});
The example above is not going to work. When the user focuses the cursor on the search bar, the class "ghText" wont be removed for some reason.
However now if I change the "var value" (variable initialization) and "value" with
"$value" as in:
$value = $($txtField).val();
$(this).val($value).removeClass("ghText");
$(this).val($value).addClass("ghText");
everything works perfectly.
I can just go to sleep and not worried too much about it..but I am very curious why something like that can happen?
is it because of the "this" not referreing to the right object, or is it because i tried storing jQuery object in non-jQuery variable or is it about something else..can somebody point out to me what was wrong? I have always thought that "var x" is the same as "$x"..?

You seem to be confused about JavaScript variables. There is no such thing as "jQuery variables" and "non-jQuery variables". Some specific cases:
A variable declared with var is different to a variable without. "var x" is a local variable, so it will not share a value with other functions which also have a variable called "x". This is almost always a good thing, so you should almost always declare variables with "var".
The $ in jQuery is sort of special. It isn't that special; it's just that jQuery has declared a variable called "$" which does some fancy operations.
There is nothing special about variables that begin with "$". In other words, "$x" is just a variable name. It is a different variable to "x", and it isn't a "jQuery variable". It's just a JavaScript variable called "$x". (This is different from PHP, where the $ is actually a special variable syntax.)
So you can just call it "value" instead of "$value".
Possibly the fact that you removed the "var" changed things by making it into a global variable.
As for "this", yes, that is a tricky aspect of JavaScript, and might be causing your problem. The value of "this" inside the inner 'focus' and 'blur' functions is likely to be different from the value of "this" outside. I'm not sure exactly what "this" refers to in an event handler, but it will not be the same object. So what you probably want to do is assign "this" to a variable in the outer function, and then refer to that variable on the inside in place of "this".

When storing a jQuery selection in a variable, it's common practice to add a $ before the variable name like this:
var $banner = $('#banner');
It's not necessary to include the dollar sign — var banner = $('#banner') would work just as well. However, the dollar sign reminds you that the variable holds a jQuery selection and not just any value like a number or a string.

#mgiuca is entirely right about Javascript variables - the '$' that precedes them is just a naming convention that most use to identify jQuery objects. I add this because you say
because i tried storing jQuery object
in non-jQuery variable
but this is wrong. $txtField is a string that you are using to select an object. If you want to store the object itself you should do $txtField = $(#searchPanel form input.ghText) and then use it thusly $txtField.val().
Having said that your code works fine for me unaltered. I've set up a demo which works on Chrome - is this a cut down version of you code?

In to addition #mgiuca's answer here is a little more elaborate approach to your problem that also shows some of the jQuery concep:
$(document).ready(function () {
// define two helper functions
var removeDefault = function () {
if( $(this).val() == $(this).data("defaultValue") ) {
$(this).val("").removeClass("ghText");
}
};
var setDefault = function () {
if( $(this).val() == "" ) {
$(this).val( $(this).data("defaultValue") ).addClass("ghText");
}
};
// the following works on all input elements
$("#searchPanel form input.ghText").each(function () {
$(this)
.data("defaultValue", $(this).val())
.focus(removeDefault)
.blur(setDefault);
});
});
Note
the use of .data() to associate a value with a specific element.
the use of .each() to apply the same behavior to any number of elements
the use function references for .focus() and .blur() - jQuery will always set the this correctly on its own
see it working over here http://jsfiddle.net/xsXxn/

So $x is a jQuery variable after all :) ... Well, anyway, here is one instance when $ or not $ did make a big difference in my code:
...load("whatever.php", {par1: var1, par2: var2})
didn't work, at least inside the $(obj).attr() assignment, unless $var1, $var2 where used. This worked:
$(obj).attr("onClick",$("#wherever").load("whatever.php", {par1: $var1, par2: $var2})...

Related

Why when a variable is used within another variable, its value its fixed to first declaration?

In the following code, I would expect the output to be "text something different" but instead it is "text something".
var dynamic = "something";
var thistext = "text " + dynamic;
dynamic = "something different";
console.log(thistext);
Changing the variable "dynamic" after declaring the variable "thistext", which contains it, does not change the value of "dynamic" within the "thistext".
I am sure this is something basic, but I think I do not know this rule or the best way to avoid this situation.
A Jsfiddle:
https://jsfiddle.net/k5wwpvgt/
Why when a variable is used within another variable, its value is fixed to first declaration?
You are not "using a variable within another variable". You are using a variable in an expression, the evaluated result of which happens to be being assigned to another variable. Expressions are evaluated when they are encountered, with the current values of any variables within them. There's no particular word for this behavior, since it is so fundamental to JS (and all other imperative/procedural languages).
Expressions are not dynamic definitions of calculations which are magically kept updated when their inputs change, much less magically updating variables to which the expression happened to have been assigned in the past. There is a word for such dynamic definitions of calculations: they are called functions. If you want some calculation to be dynamically redone when its inputs change, then write it as a function and call it when you need to recalculate, and if you want to (re-)assign the result of the invocation (the return value) to a variable, then do so.
Is there a way to contain a reference to a variable within another variable, and not the value of the variable when the assignment was evaluated?
Again, you're confusing variables and expressions and possibly functions. A variable is merely a box, referring to some value. It maintains no record of when or how it was assigned to, or what expression was used to calculate the value being assigned to it, nor does it have any means of automatically updating itself. Being a box, a variable cannot "contain a reference to another variable".
the best way to avoid this situation.
This is not a "situation" to be "avoided". It is the basic behavior of JavaScript.
Indeed, as others pointed out, this is expected behaviour; to do what you want, you could use a function:
var dynamic = "something";
var thistext = () => "text " + dynamic;
dynamic = "something different";
console.log(thistext());
Mind the diferences! Now thistext is a function, you must call it with (), and it gets evaluated every time.
thistext does not "contain" the variable dynamic, it contains the contents of that variable as it was at the time the expression was evaluated.
When browser will compile your javascript it will look something like
var dynamic = undefined;
var thisText = undefined;
dynamic = "something";
thistext = "text " + dynamic;
dynamic = "something different";
console.log(thistext);
when you are logging the value, you are just logging the value of thisText, which is populated when the value of dynamic is "something".
If you do the same operation after changing dynamic value you will see your desired result.
Hope this helps.

In Javascript/JQuery what is $. for?

I'm writing a utility file and I've gotten some examples from online and this a form of writing the utility I've come across:
$.util = $.extend($.util || {}, {
//functions here...
});
and so I think I understand what it's doing. It allows me to call $.util.function() somewhere else, however when I remove the . in front of the $ the code breaks. What does this notation mean? What's the difference between $. and $?
$.util = something means "assign something to property util of object $".
$util = something means "assign something to variable $util"
Similarly, $.extend is "get value of property extend of object $" (which is a function in this exact scenario) and $extend is "get value of variable $extend"
If you're using jQuery, $ is just a variable contaning the jQuery object. So by writing $., you're essentially accessing jQuery properties and functions. Instead of $, you could also write jQuery and it should work the same way.
There's no special meaning to the $ character in JavaScript other than that. It acts like any other character, so $util is just a variable name.
jQuery is an object that is assigned to both jQuery and $ on the window
It has methods that act on collections of elements eg $('.some-element').someMethod() and static methods that are just attached to the jQuery object but don't modify a collection, They are just normal function attached to the jQuery object to prevent exposing too many functions to the global context.
$. - allows you to proceed to $ (jQuery) object property or method directly
$ - usually used as shortcut for invoking jQuery object
Whilst prefixing anything with $ won't make it jQueryable bec. this character can be used in variable name along with others (e.g. what is not applicable for PHP).
Consider jQuery as a big class woth a lot of static functions and constructs.
The right way for calling any of its functions should be jQuery.someFunc() for static functions and var obj = jQuery('css selectors') for creating an object for HTML objects and then executing functions on that object.
Now for easier coding, jQuery added $ as an alias for jQuery. It's nothing more than an alias.
Try this code:
<script type="text/javascript">
document.write('(jQuery === $) is ' + (jQuery === $) + '<br />');
document.write('typeof(jQuery) = ' + typeof(jQuery) + '<br />');
</script>
You will see:
(jQuery === $) is true
typeof(jQuery) = function
So jQuery is a function with a bunch of extra properties and functions attached to it.
If you're coming from a strongly-typed language background, the concept of attaching properties and methods to a function might seem strange, but you can do it in javascript.

Using this this in Jquery

I am having trouble with this in Jquery. When I do that on my website, it returns me the window.width. I just want to access the element from within. This is an example.
<div class="section " style="width:400px"></div>
$( ".section" ).html($(this).width());
or
<div class="section "><p></p></div>
$( ".section p" ).html($(this).parent().width());
also here is JSFiddle jsfiddle.net/XY66w/1
I'm going to assume that when you attempt to write this code:
<div class="section " style="width:400px"></div>
$( ".section" ).html($(this).width());
What you're trying to do is show 400px inside the div.section. If that is what you're trying to do, then here's what's happening:
This statement:
$( ".section" ).html($(this).width());
if Javascript, or most other languages I know, is syntactically equivalent to this:
var newHTML = $(this).width();
$( ".section" ).html(newHTML);
As you can see, this isn't a jQuery issue - but more a JavaSciprt / any programming language problem. You're telling the browser to pass in a value to the .html() method, so it must calculate that value first, in the scope of the function that you're calling the method from. In this case, you're calling the method from the window or global scope (or some other undefined scope, so you will never get what you expect.
The simple fix is this:
var section = $('.section');
section.html(section.width());
On the other hand, there are some jQuery methods that accept functions and these are the ones that you seem to be thinking of in this case. For instance, things would be slightly different in case you were using the each method, which accepts a function:
$('.section').each(function(index, element){
$(this).html($(this).width());
});
In this case, you're passing in a function that jQuery will then call in the scope of each element that is matched by your selector.
The big difference is to differentiate when you're passing in a value and when you're passing in a function that will be evaluated later.
You can do what you want this way, I think:
$(".section").each(function() {
$(this).html($(this).width());
});
JavaScript, like a lot of common languages, is not a "lazy" language. An expression statement like yours is evaluated such that all the function parameters are determined before anything's actually called. By using the jQuery .each() API, you can act on each element of the selected set.
jQuery only binds this when it's calling a function, such as an event handler, a callback function, a function supplied to something like $.each, etc.
In your examples, you're just supplying an argument to a jQuery method, and it's not inside a function that was called by jQuery. So this just contains whatever the browser's context is, which is window for top-level code. It's not the element(s) matched by the selector .section.

How can i replace some "this" only outside functions?

I would like to replace some "this" in a script.
$(this).find('option').each(function() {
$(this).hide();
})
Is there a possibility to replace only the outer this, or only the "this" that are not inside a function block? My idea doesn't work ...
.replace(/([^{])\bthis\b([^}])/gm, $1replacement$2)
addendum: The first code is handled as a string, not as javascript!
I am search for a regexp to replace only the outer "this".
If I understand your issue correctly, you are wanting to refer to the $(this) variable from within your function, however that variable gets changed to the local scope of the function. So within the function, $(this) will refers to the item you are currently iterating over.
You'll want to cache the scope of the $(this) object before you enter your function.
var cached_this = $(this);
$(this).find('option').each(function() {
cached_this.hide();
})
Now you have access the value of the outer $(this) from within a different scope using the cached_this variable.
The way to distinguish "outer" from "inner" text is that for inner, the next curly bracket is a right one, which closes the block its in.
So, using a negative look ahead to exclude this within a block:
str = str.replace(/\bthis\b(?![^{]*\})/gs, replacement);
Also note the simplification of the replacement term, since the match is just the target text "this".
See a live demo of this regex working.
In that case this is an object. It's not a string that you can replace. You may assign another value, but such a replacement will not work.
If you want to replace only certain divs, simply change your jQuery selector to select those with a certain class, or child elements of a parent div, for example.
You can try to use call. Due to this function you can replace this object:
$(this).find('option').each(function() {
// here this === replacement
$(this).hide();
}.call(replacement))
If it's in a function, you can "replace" this by assigning a different variable to it when you call it.
var func = function() {
$(this).find('option').each(function() {
$(this).hide();
});
};
func.apply(annotherThis);

Assignement of a variable inside a concatenation

I have a global variable var num_tab=1;, a function that creates a link a href :
function Addsomething()
{
$("#tout").html("<a style=\""+"margin-left:-20px;"+"\" onClick=\"eval(num_tab=2)\" href=\""+"#tab1"+"\" data-toggle=\""+"tab"+"\">SELECT</a>");
Bla,Bla..
$("#champ1").append('<li id=\"1\" class="champ" onclick="insertAtCaret("sousTab'+num_tab+'");" value=\"1\">1</li>');
}
What i want to do is to create a href that when clicked changes the value of the variable num_tab, but if you can see the href is inside a jquery html(), which makes me confused about how to assign a value to the variable. I almost tried everything: onClick=\"num_tab=2\",onClick=\""+num_tab+"=2\"
Actually i tried something: when i write onclick='num_tab=2;alert("+num_tab+");' i still get the initial value of num_tab, seems it's more like a problem of local and global variable and i can't figure out it yet.
Please don't use eval(). It's insecure and not the appropriate tool for this job. Just assign a function to the onclick:
$("#tout").html("<a onclick='set_num_tab(2)'">); //fill out the rest of this line
function set_num_tab(value) {
num_tab = value;
}
That should give you an idea of how to do it. btw there's no reason you can't use single quotes around an onclick like that.
Alternately, this would work:
$("#tout").html("<a onclick='num_tab=2'">);
But that's pretty messy. I try to avoid inline JavaScript.

Categories