jquery pass value into function AFTER function? - javascript

I am new to javascript & jQuery. I'm trying to create a feature for my site that let's people display badges they have earned on their own site (and I would supply a bit of code they could just copy/paste). I had someone help me with the javascript and I have it working perfectly, but I can't find any jQuery documents that explains it to me?
<script type="text/javascript">
(function(id) {
// include js via php file with the id in as a parameter
})("myid");
</script>
The id is passed in the area labeled "myid", in jQuery can you pass in a static variable this way? When I try to delete ("myid") and change it to var id = 'myid', the function no longer works.

The occurrence of "myid" in the code you are showing is not a static variable. It is a string literal that is being passed as an argument to an anonymous function. The anonymous function is declared and then is immediately getting called.
If you are wondering why the programmer wrote the JavaScript the way they did. The following might help.
Both of the examples below will display "myid" in an alert:
Example 1:
<script type="text/javascript">
var id = 'myid';
alert(id);
</script>
Example 2:
<script type="text/javascript">
(function(id) {
alert(id);
})('myid');
</script>
The first example declares "id" as a variable. It is a global variable and is actually added as a property to the window object. The second example defines an anonymous function and immediately calls it, passing in 'myid' as the value of the "id" parameter. This technique avoids using a global variable.
Of course, you could also avoid the global variable by doing the following:
<script type="text/javascript">
(function() {
var id = 'myid';
alert(id);
})();
</script>

If you stick "myid" in a variable and then pass in that variable, it'll work. Like this:
var memberID = "myid";
(function(id) {
// include js via php file with the id in as a parameter
})(memberID);
If you say this...
(function(id) {
// include js via php file with the id in as a parameter
})(var id = 'myid');
...you're attempting to stick a variable declaration in a function call, which won't work. That's why declaring the variable above and apart from the function call won't throw any errors.

Related

pass variable to new HTML with window.open

Im opening html file from js function:
function initCategoryPage(url){
var catUrl=url;
window.open("category.html");
}
I putted this script in "category.html" but it doesnt get the var catUrl:
<script>
myUrl = window.opener.catUrl;
alert(myUrl)
id=1;
firstTime=true;
ArticlesBlock();
</script>
how can I pass it to category.html?
The reason it can not read it is because the variable is not global. The scope is limited to that method.
function initCategoryPage(url){
window.catUrl=url; /*make it global*/
window.open("category.html");
}
A better solution would be to pass it as a querystring or use postMessage to get the value.

JSON.stringify in js

How do I get reference of the <div> id and title from a external JS by using the code below:
function recordedEvent() {
var v_Id = $(this).attr('Id');
var v_Title = $(this).attr('Title');
var o = { Title : v_Title, ObjectId : v_Id };
alert(JSON.stringify(o));
}
The function is called in the HTML with a onclick called box1().
Code in CplTemplateSetup.js is where I want to run the function from into the HTML:
content_left_30_four_click_images_right_70_head_content_template.html
Any help would be appreciated.
P.S.: JSON data (zip archive)
Well the most obvious problem is that you don't have a closing parenthesis after your callback.. otherwise the code looks good
Edit
window.lastClickedBoxData = {}; // just reassign that within your function
or
window.runThisWhenClicked = function () {
var v_Id = $(this).attr('Id');
var v_Title = $(this).attr('Title');
var o = { Title : v_Title, ObjectId : v_Id };
};
then just
$(".box").click(window.runThisWhenClicked);
I don't think that the problem that you're facing would be apparent to anyone who doesn't view your code.
You defined a function within a script tag, in the html, and called that function in the onclick attribute of the box being clicked on. To that function, this refers to the box that was clicked on. From there, you call a function within an external js document. In that function, this refers to the window object. In other words, for the code that you posted, $(this) is a jquery instance of the window object which doesn't have the attributes that you're looking for, such as id and title, so they're blank.
To see what I'm talking about open the console and add the following line of code to each of your functions:
console.log(this);
If you're having trouble doing that, the following code should work as well, but it's not as good for debugging:
alert(this);
You need all of your code to be in the html script tag or in the external document. Also, you shouldn't define the function to be called during a click event using onclick within the html. It's better to do it using javascript or jquery so that your javascript is completely separate from your html.
EDIT: You shouldn't update your question with an answer. You should edit the original question with this information so that anyone having a similar problem can find the solution. I'd have commented on the answer directly, but I don't have the reputation to do this.

Razor Syntax in External Javascript

So as you might know, Razor Syntax in ASP.NET MVC does not work in external JavaScript files.
My current solution is to put the Razor Syntax in a a global variable and set the value of that variable from the mvc view that is making use of that .js file.
JavaScript file:
function myFunc() {
alert(myValue);
}
MVC View file:
<script language="text/javascript">
myValue = #myValueFromModel;
</script>
I want to know how I can pass myValue directly as a parameter to the function ? I prefer to have explicit calling with param than relying on globals, however I'm not so keen on javascript.
How would I implement this with javascript parameters? Thanks!
Just have your function accept an argument and use that in the alert (or wherever).
external.js
function myFunc(value) {
alert(value);
}
someview.cshtml
<script>
myFunc(#myValueFromModel);
</script>
One thing to keep in mind though, is that if myValueFromModel is a string then it is going to come through as myFunc(hello) so you need to wrap that in quotes so it becomes myFunc('hello') like this
myFunc('#(myValueFromModel)');
Note the extra () used with razor. This helps the engine distinguish where the break between the razor code is so nothing odd happens. It can be useful when there are nested ( or " around.
edit
If this is going to be done multiple times, then some changes may need to take place in the JavaScript end of things. Mainly that the shown example doesn't properly depict the scenario. It will need to be modified. You may want to use a simple structure like this.
jsFiddle Demo
external.js
var myFunc= new function(){
var func = this,
myFunc = function(){
alert(func.value);
};
myFunc.set = function(value){
func.value = value;
}
return myFunc;
};
someview.cshtml
<script>
myFunc.set('#(myValueFromModel)');
myFunc();//can be called repeatedly now
</script>
I often find that JavaScript in the browser is typically conceptually tied to a specific element. If that's the case for you, you may want to associate the value with that element in your Razor code, and then use JavaScript to extract that value and use it in some way.
For example:
<div class="my-class" data-func-arg="#myValueFromModel"></div>
Static JavaScript:
$(function() {
$('.my-class').click(function() {
var arg = $(this).data('func-arg');
myFunc(arg);
});
});
Do you want to execute your function immediately? Or want to call the funcion with the parameter?
You could add a wrapper function with no parameter and inside call your function with the global var as a parameter. And when you need to call myFunc() you call it trough myFuncWrapper();
function myFuncWrapper(){
myFunc(myValue);
}
function myFunc(myParam){
//function code here;
}

Call variable from another script in HTML

I currently have a HTML file that has one script that is declared as follows:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
code.......
var a = "hello"
});
</script>
I am trying to add another script within the HTML file that will call on this variable "a". Right now, I am doing something like this:
<script type="text/javascript">
alert(a);
</script>
But it is not alerting anything. If I replace a with a string like "hello", I do get alerted. Am I calling the variable wrong? I've tried searching for solutions but all of them say you should be able to easily call variables from another script assuming that script is declared and initialized before. Thanks.
Move the a declaration outside of the function.
E.g.,
var a;
$(document).ready(function() {
code.......
a = "hello"
});
And then later on...
alert(a);
Remember that variables are function-scoped, so if you define it inside of a function, it won't be visible outside of the function.
Update based on comments:
Because you now have a timing issue when trying to interact with the a variable, I would recommend introducing an event-bus (or some other mechanism) to coordinate on timing. Given that you're already using jQuery, you can create a simple bus as follows:
var bus = $({});
bus.on('some-event', function() {});
bus.trigger('some-event', ...);
This actually lends itself to some better code organization, too, since now you really only need the bus to be global, and you can pass data around in events, rather than a bunch of other random variables.
E.g.,
var bus = $({});
$(document).ready(function() {
var a = 'hello';
bus.trigger('some-event', { a: a });
});
And then in your other file:
bus.on('some-event', function(e, data) {
alert(data.a);
});
JSBin example (obviously not spread across multiple files, but the same principles apply).
Replace your code as
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">
var a="";
$(document).ready(function() {
a = "hello";
});
</script>
Now you can access the variable a as below.
<script type="text/javascript">
alert(a);
</script>
The problem with your code was that, you was declaring the variable a inside $(document).ready() which made it local to the ready().
When you write a inside function block you make it a local variable, you can move variable declaration outside of the function block as other answer say or you can use:
$(document).ready(function() {
window.a = "hello";
});
and later:
alert(a);
In both cases you are declaring a as a global variable and that is not recommended.

How do I pass argument to anonymous Javascript function?

I am writing a simple counter, and I would like to make installation of this counter very simple for users. One of the simplest counter code (for users who install it) I ever see was Google Analytics Code
So I would like to store main code in a file and user who will install my counter will need just to set websiteID like this:
<html><head><title></title></head><body>
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var websiteId = 'XXXXX';
</script>
</body></html>
Here is my code:
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var page = _gat.init('new');
</script>
and this is my JS file:
(function() {
var z = '_gat';
var aa = function init(data) { alert(data); alert(z);};
function na() {
return new z.aa();
}
na();
})();
I tried to understand Google Analytics javascript code but I failed to do this. Can anyone suggest how can I specify variable between tags and then read it in anonymous function which is located in a javascript file ?
Thanks.
In your example, websiteId is a global variable. So it is accessible everywhere including anonymous functions unless there is a local variable with the same name
<script> var websiteId = "something"; </script>
Later in the page or included js file...
(function() {
alert(websiteId); //this should work
})();
Can anyone suggest how can I specify variable between tags and then read it [...]
Not if your tag has both a SRC attribute and JS content.
<script type="text/javascript" src="http:/x.com/x.js"></script>
.. is different from,
<script type="text/javascript">
var x = 1;
</script>
One framework that optionally adds JS variables to SCRIPT tags is Dojo. So if you're using Dojo you can add variables to the global djConfig hash by writing,
<script type="text/javascript" src="mxclientsystem/dojo/dojo.js"
djConfig="
usePlainJson: true,
parseOnLoad: true
">
</script>
Dojo does this by running through the SCRIPT tags and evaluating the custom djConfig attribute.
This does not, however solve your problem.
You do really want two SCRIPT tags. One saying,
<script type="text/javascript">
var websiteId = '123456';
</script>
which will set a global variable websiteId and a second one,
<script type="text/javascript" src="http:/x.com/myreporter.js"></script>
which can load from anywhere and read out the websiteId variable and, I assume, report it back.
You can pass variables to an anonymous function like so:
(function(arg1, arg2, arg3) {
alert(arg1);
alert(arg2);
alert(arg3);
})("let's", "go", "redsox");
// will alert "let's", then "go", then "redsox" :)
I'm not entirely clear about what you're asking, but...
You can tag any HTML element with an id attribute, then use
document.getEntityById() to retrieve that specific element.
You can also give any HTML element user-defined attributes having names of your own choosing, then get and set them for that element within Javascript.
I think you've got a bit confused with how JS objects are called.
z is a String, '_gat'. You can't call aa() on it because a String has no member called aa. aa is a standalone function stored in a local variable. Even if you did call aa(), it doesn't return anything, so using the new operator on its results is meaningless. new can only be called on constructor-functions.
I guess you mean something like:
var _gat= function() {
// Private variable
//
var data= null;
// Object to put in window._gat
//
return {
// Set the private variable
//
init: function(d) {
data= d;
}
};
}();
Then calling _gat.init('foo') as in your second example would set the variable to website ID 'foo'. This works because the _gat object is the return {init: function() {...}} object defined inside the anonymous function, keeping a reference (a ‘closure’) on the hidden data variable.
If you specify a src attribute as part of a script element, any code within the script element tags themselves will not be executed. However, you can add this functionality with the following code. I got this technique from Crockford (I believe it was him), where he uses it in of his talks on the unrelated topic of rendering performance and asynchronously loading scripts into a page to that end.
JavaScript:
(function() {
// Using inner class example from bobince's answer
var _gat = (function() {
var data= null;
return {
init: function(d) {
console.info("Configuration data: ", d);
data = d;
}
}
})();
// Method 1: Extract configuration by ID (SEE FOOT NOTE)
var config = document.getElementById("my-counter-apps-unique-and-long-to-avoid-collision-id").innerHTML;
// Method 2: search all script tags for the script with the expected name
var scripts = document.getElementsByTagName("script");
for ( var i=0, l=scripts.length; i<l; ++i ) {
if ( scripts[i].src = "some-script.js" ) {
config = scripts[i].innerHTML;
break;
}
}
_gat.init( eval("(" +config+ ")") );
})();
HTML:
<script type="text/javascript" src="some-script.js" id="my-counter-apps-unique-and-long-to-avoid-collision-id">
{some: "foo", config: "bar", settings: 123}
</script>
Both methods have their draw backs:
Using a unique and non-colliding ID will make determining the proper script element more precise and faster; however, this is not valid HTML4/XHTML markup. In HTML5, you can define arbitrary attributes, so it wont be an issue at that time
This method is valid HTML markup; however, the simple comparison that I have shown can be easily broken if your url is subject to change (e.g.: http vs https) and a more robust comparison method may be in order
A note on eval
Both methods make use of eval. The typical mantra concerning this feature is that "eval is evil." However, that goes with say that using eval without knowing the dangers of eval is evil.
In this case, AFAIK, the data contained within the script tags is not subject to inject attack since the eval'ing script (the code shown) is executed as soon as that element is reached when parsing the HTML into the DOM. Scripts that may have been defined previously are unable to access the data contained within the counter's script tags as that node does not exist in the DOM tree at the point when they are executed.
It may be the case that a well timed setTimeout executed from a previously included script may be able to run at the time between the counter's script's inclusion and the time of the eval; however, this may or may not be the case, and if possible, may not be so consistently depending on CPU load, etc.
Moral of the story, if you're worried about it, include a non-eval'ing JSON parser and use that instead.

Categories