Rails including .js file - javascript

I am curious about the way Rails includes .js files.
Asside from the asset pipeline, I'm curious about the .js files stored in the view.
For example, if you want to apply ajax call to an action called like in PostsController, you simply put the relevant ajax code in like.js.erb in the posts view folder. Then, the javascript is triggered automatically when the user calls the action like.
My questions are
Is it right that javascript files whose names match certain actions are called automatically when the action is invoked?
If I want to include a javascript file, which does not correspond to any action, in a certain view, what do I do? Just include it in the application manifest?
More specifically, I have tag-autocomplete.js.erb in views/post right now. Do I move it to the assets folder and include it from the application.css?
Thank you.

Yes, though I don't see immediately what will happen if you have both like.js.erb and like.html.erb. It seems like one or the other will be chosen, and it might be arbitrary.
I would normally inline the javascript in that situation, in a script tag. If it truly will only ever be used in that view, that's reasonable. On the other hand, the application.js is cached and that saves bandwidth to put whatever you can in there. Since you're asking about things involving templating, though, I imagine caching isn't desirable. To that, I say you should try to minimize your use of templating in JS. Sometimes it makes sense, but be careful.
(FYI: this is where the core of the relevant functionality is defined.)

Related

How/when/where to include external javascript

I'm looking for some advice on the best way to hold my JavaScript (jQuery) functions.
I am developing in MVC/razor and therefore have a layout page. I include my jQuery library and an external JavaScript file in here so it's available in every single page.
This is working well, but I am now becoming very aware of the fact that I am adding almost 300 lines of JS to EVERY page, where maybe half of that is used in any one of these pages.
One function is not in the external file and instead sits inside the HTML because I need to use variables set in my razor code.
I have a couple of questions around this arrangement:
Is placing JS inside the HTML generally acceptable when variables set using razor are used? There does not appear to be a clean way of passing a variable into an external js file
Should I split my functions down in to individual JS files and just include what is needed for each page in the site?
If I were to split them into multiple files, how would that work with jQuery's (document).ready ? Do I need to use that if all the JavaScript I am including is to be used?
I'm sure this will more a matter of opinion than a black and white answer, but I want to consider all my options before moving on. Even though it works fine as is, I can't help but feel there is a better/cleaner way.
Remember once a user lands on your homepage and loads the javascript file it will be cached in their browser so subsequent pages will not download the Javascript again.
I would definitely keep the js separate, you could have a snippet on each page that initialise the JS that that particurlar view needs. Put something like the below in the views that need to run JS
$(document).ready(function() {
mysite.mypage();
});
Then the function mysite.mypage() can be defined in the external JS file.
300 lines isnt the end of the world, I would say its probably too early to be worryign about optimisation.
You could always look at minifying that JS file to decrease the size. A quick and easy way to do this is here:
http://www.minifyjavascript.com/
Have you ever heard of require.js? http://requirejs.org/ I find it really useful.
It's a module loader so you are able to split all of your JS code into individual files and load only the ones you need on each page.
I don't know about passing a variable to an external JS file, I don't think its possible / the 'right' way.
You can make each external JS file into a function that accepts and returns parameters. Then in the page you need to use it:
- include the file dependancy
- call the function
Thats what I do, seems like your 2nd suggestion.
for the $(document.ready) question its really up to you. You don't have to use it but its useful for some things , check out this overview:
http://docs.jquery.com/Tutorials:Introducing_$(document).ready()

Javascript .js File Guidelines - How do I use a function outside of this file?

So two part question here. Basically, what is the proper practise for javascript function locations? I assumed it would be to have several MyScriptFile.js files, each with a few functions instead of one huge AllMyScripts.js file, as not every page needs every function.
However I'm not sure how to reference another function from outside of this file...
My situation: I'm using an AJAX request in many of my pages. Each request response is different (drawn from different files, etc) and is very hard to make dynamic (one-script-fits-all would be difficult). However, I do have my MakeAJAXRequest() function which creates the request object, which is standard to all DoSomethingWithRequest() functions.
How do I include MakeAJAXRequest() in the other files which contain the DoSomethingWithRequest() functions? It seems as though I should have been able to find this.. but I havn't come across it.
tl;dr I have MakeObject.js and UseObject.js. How does UseObject() reference MakeObject()?
EDIT: Found that if you include MakeObject BEFORE UseObject in your HTML <script> tags, UseObject will be able to reference MakeObject. Seems a little dirty still, as anybody who wants to use the UseObject script will have to be aware of the MakeObject dependency...
If you want to ensure your dependencies are loaded, you could use a function such as this: http://phpjs.org/functions/include:433 There is also include_once(), require(), and require_once()

One JavaScript File Per Page or Combine when using Jquery and Document Ready Function

Ok So I know it always depends on the situation but I have, thus far, combined my jquery files/plugins into a single compressed file.
Now I am wondering what I should do with my page specific js/jQuery code. Should I have a single file with one Document.Ready function and my entires sites js code inside of it? Or split it up into seperate js files per page with a document ready call in each?
These files will inclide things such as .Click handlers and other jquery code specific to certain pages.
Whats the best practice here to optimize load times and maintainabilty?
One way to do it would be to use require.js and then have an array with files and page types. Give each body tag an ID and use it to reference what files should be loaded in.
<body id="pageName">
Keep your global files everything you need for the core functionality to work and then lazy load in the features that aren't required for your site to run faster. I've seen huge speed improvements from this technique.
http://requirejs.org/
We can do this in multiple ways , i did in the following way.
Aggregate your files broadylyas following
1) Aggregate all the files required for all the pages
2) aggregate the pages specific to the page.
Include all the common aggregated file for all the pages , and include other aggregated files conditionally on the page
1) jquery and other plugins common to all pages so // it will go to all files
2) homepage-aggregation /// for homepage
3) gallerypage-aggregation // for gallery page.
If you include the same file for all the pages ,it may not necessary for all the files.
I did it recently , let me know if you need anything else
Because you're almost certain to want to have different things executed in the Document.Ready function depending on what page you're on I don't think that having one function that is executed on every page is helpful.
Personally I mix my $.ready calls in with my HTML. These are simple calls to functions stored in a single, minimizing javascript file so don't take up too many bytes, and prevent the need for a separate Javascript file per page. It also allows me to initiate the Javascript where I create the markup, so it's all in one place.
If you're minimizing your javascript and serving it with the correct headers you've got most of the benefits already, don't compromise readability more than you have to.
It also depends on the server side technology you are using. You may find tools to assist you on this task. If you are coding a Java server side, you may try JAWR. It allows the creation of separated JS/CSS files, merging and compressing them server-side, turning all the separate files into a single file.
About Document.Ready, I prefer to keep specific code page in separate files, avoiding incorrect code execution and behavior. It is also cleaner and easier to maintain.

What benefits are there to storing Javascript in external files vs in the <head>?

I have an Ajax-enabled CRUD application. If I display a record from my database it shows that record's values for each column, including its primary key.
For the Ajax actions tied to buttons on the page I am able to set up their calls by printing the ID directly into their onclick functions when rendering the HTML server-side. For example, to save changes to the record I may have a button as follows, with '123' being the primary key of the record.
<button type="button" onclick="saveRecord('123')">Save</button>
Sometimes I have pages with Javascript generating HTML and Javascript. In some of these cases the primary key is not naturally available at that place in the code. In these cases I took a shortcut and generate buttons like so, taking the primary key from a place it happens to be displayed on screen for visual consumption:
...
<td>Primary Key: </td>
<td><span id="PRIM_KEY">123</span></td>
...
<button type="button" onclick="saveRecord(jQuery('#PRIM_KEY').text())">DoSomething</button>
This definitely works, but it seems wrong to drive database queries based on the value of text whose purpose was user consumption rather than method consumption. I could solve this by adding a series of additional parameters to various methods to usher the primary key along until it is eventually needed, but that also seems clunky.
The most natural way for me to solve this problem would be to simply situate all the Javascript which currently lives in external files, in the <head> of the page. In that way I could generate custom Javascript methods without having to pass around as many parameters.
Other than readability, I'm struggling to see what benefit there is to storing Javascript externally. It seems like it makes the already weak marriage between HTML/DOM and Javascript all the more distant.
I've seen some people suggest that I leave the Javascript external, but do set various "custom" variables on the page itself, for example, in PHP:
<script type="text/javascript">
var primaryKey = <?php print $primaryKey; ?>;
</script>
<script type="text/javascript" src="my-external-js-file-depending-on-primaryKey-being-set.js"></script>
How is this any better than just putting all the Javascript on the page in the first place? There HTML and Javascript are still strongly dependent on each other.
one point: an external file can be cached by the browser, a js-block in the head is loaded every time the file loads.
Performance (due to browser caching)
Separation of concerns - HTML/CSS/JavaScript should be separate. It makes working with them easier. You know exactly where to locate certain areas, plus other developers can work on the likes of HTML, CSS and JavaScript independently.
Reuse - you can include a source file in multiple locations/projects without duplicating code.
You can YUICompress your javascript (at build/integration time) if it's in separate files. I smash all my Javascript together (lots of separate little jQuery plugins etc) at build time so that there's just one file to fetch/cache.
It depends on how much Javascript are you dynamically generating on the server-side versus how much of it is static. If all of it is dynamically generated, then it doesn't matter where you put them as every request will pull a new file without any caching. Putting it in the head has the advantage of one lesser HTTP request which is hardly any benefit unless you're primary concern is performance and bandwidth is a non-issue.
But if most of the Javascript is static, keeping it in separate files at development time keeps things organized.
Dynamically generated Javascript can be served as separate files instead of being part of the page itself. It will add an extra HTTP call.
<script src="myServerSideScript.php" type="text/javascript"></script>

Where to put JavaScript configuration functions?

What is the general developer opinion on including javascript code on the file instead of including it on the script tag.
So we all agree that jquery needs to be included with a script file, like below:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"
type="text/javascript"></script>
My question is, in order to get functions on a page that is not on all pages of a site. Do we include the functions like below in the same page or in a global include file like above called mysite.js.
$(document).ready(function(){
$(".clickme").click(function(event){
alert("Thanks for visiting!");
});
});
ok. So the question is: if the code above is going to be called in every class="clickme" on a specific pages, and you have the ability to call it either from an include separate file called mysite.js or in the content of the page. Which way will you go?
Arguments are:
If you include it on the page you will only call it from those specific pages that the js functionality is needed.
Or you include it as a file, which the browser cached, but then jquery will have to spend x ms to know that that function is not trigger on a page without "clickme" class in it.
EDIT 1:
Ok. One point that I want to make sure people address is what is the effect of having the document.ready function called things that does not exist in the page, will that trigger any type of delay on the browser? Is that a significant impact?
First of all - $("#clickme") will find the id="clickme" not class="clickme". You'd want $(".clickme") if you were looking for classes.
I (try to) never put any actual JavaScript code inside my XHTML documents, unless I'm working on testing something on a page quickly. I always link to an external JS file to load the functionality I want. Browsers without JS (like web crawlers) will not load these files, and it makes your code look much cleaner to the "view source".
If I need a bit of functionality only on one page - it sometimes gets its own include file. It all depends on how much functionality / slow selectors it uses. Just because you put your JS in an external JS file doesn't mean you need to include it on every page.
The main reason I use this practice - if I need to change some JavaScript code, it will all be in the same place, and change site wide.
As far as the question about performance goes- Some selectors take a lot of time, but most of them (especially those that deal with ID) are very quick. Searching for a selector that doesn't exist is a waste of time, but when you put that up against the wasted time of a second script HTTP request (which blocks the DOM from being ready btw), searching for an empty selector will generally win as being the lesser of the two evils. jQuery 1.3 Performace Notes and SlickSpeed will hopefully help you decide on how many MS you really are losing to searching for a class.
I tend to use an external file so if a change is needed it is done in one place for all pages, rather than x changes on x pages.
Also if you leave the project and someone else has to take over, it can be a massive pain to dig around the project trying to find some inline js.
My personal preference is
completely global functions, plugins and utilities - in a separate JavaScript file and referenced in each page (much like the jQuery file)
specific page functionality - in a separate JavaScript file and only referenced in the page it is needed for
Remember that you can also minify and gzip the files too.
I'm a firm believer of Unobtrusive JavaScript and therefore try to avoid having any JavaScript code in with the markup, even if the JavaScript is in it's own script block.
I agreed to never have code in your HTML page. In ASP.net I programmatically have added a check for each page to see if it has a same name javascript file.
Eg. MyPage.aspx will look for a MyPage.aspx.js
For my MVC master page I have this code to add a javascript link:
// Add Each page's javascript file
if (Page.ViewContext.View is WebFormView)
{
WebFormView view = Page.ViewContext.View as WebFormView;
string shortUrl = view.ViewPath + ".js";
if (File.Exists(Server.MapPath(shortUrl)))
{
_clientScriptIncludes["PageJavascript"] = Page.ResolveUrl(shortUrl);
}
}
This works well because:
It is automagically included in my files
The .js file lives alongside the page itself
Sorry if this doesn't apply to your language/coding style.

Categories

Resources