How Jammit handle view specific JavaScript - javascript

I'm trying to adopt Jammit in my Rails application.
Default config provided in documentation grabs all js files including view specific javascript:
embed_assets: on
javascripts:
workspace:
- public/javascripts/vendor/jquery.js
- public/javascripts/lib/*.js
- public/javascripts/views/**/*.js
- app/views/workspace/*.jst
stylesheets:
common:
- public/stylesheets/reset.css
- public/stylesheets/widgets/*.css
workspace:
- public/stylesheets/pages/workspace.css
empty:
- public/stylesheets/pages/empty.css
Let's consider a case when view specific javascript should be executed only on certain view:
$(function(){
alert("View specific message here!");
}
How can I avoid such effect?
Regards,
Alexey Zakharov

My preference is to wrap up that "view-specific-javascript" in a function. And then call that function depending on the page you actually load. In this way, all of your JavaScripts can be cached by browsers as a single file, and you can execute the portions of the JS that you need.
So I'd add a <script> tag to the particular html.erb template that calls your view-specific function on page load.
Hope that helps...

I'm digging this up to point out an alternative to jashkenas approach, which is to link behaviour just to specific tags.
$(function() {
$('#my-view-object').someBehaviour();
}
So, what's the catch? The main difference is that JS code tends to be linked to certain objects, not pages. In case you reorganize your views, you will to have to change your JS too. The other problem is that JS needs to be at the bottom of the page to squeeze the most out of the browser. If you are putting script entries in your views, then most likely they will end up being all over the page's html markup and slowing the rendering.
BR,
-- José

Related

Where to put script references for widgets (partial page)

Working on MVC5 asp.net website.
I have a "dashboard" page that allows the user to place pre-defined "widgets" on the page. These widgets are simply MVC 5 partial pages (Razor). I really wanted each widget to be "self-contained" so all references, scripts, etc... are within the widget's cshtml file. BUT, the main "dashboard" page also needs certain references to jQuery, bootstrap, etc...
Of course, doing this, I could encounter conflicts, duplicate references (one from main page, one from widget), etc....
Question: What is the preferred method for this scenario? Should references like jQuery and bootstrap be JUST on the main "dashboard" page? What about javascript or jQuery code that is in the widget itself? Should this remain in the widget? If so, will I encounter the issue where it doesn't have jQuery defined (because it's in the parent page), etc...?
Any thoughts on this would be appreciated?
Thanks!
**** UPDATE ****
TO further clarify: If I put the scripts, references, etc (specific to the widget) at the bottom of the widget, then when the partial page is rendered on the main page, the scripts, etc.. are not rendered at the bottom of the main page. This causes my code to act funny because of the order that things are rendered. This is one reason I ask this question. Hope this makes sense. Thanks.
Put the script code and references that are global to the application , that are used everywhere and that are not specific to a widget in the most outer page.
What i would do, is i would bundle all my script references in one place and add that bundle link to the dashboard page, this makes your code cleaner and your page will have less external references thus a better client side performance.

Run javascript code that is specific to the view

In my ASP.NET MVC4 application I got 1 javascript file for my functions across the site.
This works pretty good - however I want to run certain code in certain views.
Usually I would solve this by simply putting a short script tag in the view calling the desired function.
However I load my js files at the bottom of the body tag so this script tag would call a function before it being loaded which would obviously not work.
How can I call individual parts of my js file from different views while keeping my js files at the bottom of the body?
There are a few things going on here.
I would not be putting JavaScript directly in the page. Many reasons for this, and is not the focus of your question, but something I wanted to bring up.
You can have a separate JS file that gets loaded after your main JS file that actually does the call to the functions from "main".
My approach is to tag said views with an id:
<div id="specific-page-name"></div>
Then in my javascript simply do:
if ($('#specific-page-name').length) {
// Run code
}
This way you can still separate your views from js code.
Finally, if I have to use model data in js I can do something like:
<div data-model-data="#Model.Data"></div>
And simply read it as:
$('div').data('model-data');
I'm detailing the answer given by Matt in his comment : in your layout, you can specify that you want some additional HTML content (in your case, that will be your JS). You'll want to add it after your main JS block.
#RenderSection("AddScripts", required: false)
Then in your view, you can add a section and it won't be rendered in the view, but in the corresponding section in the layout (after your main JS block).
#section AddScripts {
<script type="text/javascript">
...
</script>
}

MVC3 Move Validation Blocks

I'm attempting to place all JavaScript at the bottom of a page. If I move jquery to the bottom it breaks validation on the page. Is there a way to move validation to the bottom of the page.
No, jQuery must be at the top of the page, but most everything else can come after it.
The best practice is to put all of your styles at the top of the page and all of your scripts at the bottom of the page. You will need to put the references to your JavaScript files above your page specific JavaScript.
Its easy to do in MVC3 if you use helper methods.
The process goes like this:
Create helper methods for storing the scripts in the ViewContext
Add scripts and references to JavaScript files in the ViewContext in any of your views and partial views
Render the scripts at the bottom of the page in the order you need them
If this seems like a lot, take a look at this post:
MVC executing view code before layout code and ruining my script order
The helper methods simplify what would otherwise be very messy code. Good luck!

Debug a script that sits in a partial view

Why I can't debug scripts that reside in a partial view, that gets created in runtime?
To see the script in the list of scripts (in Chrome for example) and debug it, I have to move it to the "regular" view on the upper level or I have to move it to a separate .js file.
But what, if the script so small that I don't want to move it anywhere, and still want to be able to debug it?
If you do not load the partial view via ajax (the view is in place at the initial page rendering) you can use 'debugger'. If the code you want to run is added to the dom IE will not know where the actual code is located that you want to debug. So:
// javascript
var foo = 2;
debugger;
// more javascript
There's a much better way to do this now, just use the syntax
//## sourceURL=someValue
immediately after opening your script tag. Example:
<script type="text/javascript">
//## sourceURL=_fooPartialView.cshtml
function foo() {}
</script>
--edit--
Apparently due to some IE compatibility issue javascript source mapping has been changed from the above to:
//# sourceURL=_fooPartialView.cshtml
Also note, although not mentioned earlier, the ## was only necessary for source mapping in razor views since "#" had other significance.
It's generally considered poor practice to include a script inside of a partial view. You could run into all kinds of issues with multiple script references and performance. The better approach here is to ensure the script gets moved up to a placeholder in your head tag. For a few examples on this, check out:
Linking JavaScript Libraries in User Controls
and
Include JavaScript file in partial views
If you insist on loading the script from the partial, the 'debugger' approach above is very effective.

Programmatically remove <script src="/unwanted.js".. /> reference

I have partial control of a web page where by I can enter snippets of code at various places, but I cannot remove any preexisting code.
There is a script reference midway through the page
<script src="/unwanted.js" type="text/javascript"></script>
but I do not want the script to load. I cannot access the unwanted.js file. Is there anyway I can use javascript executing above this refernce to cause the unwanted.js file not to load?
Edit: To answer the comments asking what and why:
I'm setting up a Stack Exchange site and the WMD* js file loads halfway down the page. SE will allow you to insert HTML in various parts of the page - so you can have your custom header and footer etc. I want to override the standard WMD code with my own version of it.
I can get around the problem by just loading javascript after the original WMD script loads and replacing the functions with my own - but it would be nice not to have such a large chunk of JS load needlessly.
*WMD = the mark down editor used here at SO, and on the SE sites.
In short, you can't. Even if there is a hack, it would heavily depend on the way browsers parse the HTML and load the scripts and hence wouldn't be compatible with all browsers.
Please tell us exactly what you can and cannot do, and (preferably; this sounds fascinating) why.
If you can, try inserting <!-- before the script include and --> afterwards to comment it out.
Alternatively, look through the script file and see if there's any way that you could break it or nullify its effects. (this would depend entirely on the script itself; if you want more specific advice, please post more details, or preferably, the script itself.
Could you start an HTML comment above it and end below it in another block?
What does the contents of unwanted.js look like?
You can remove a script from the DOM after it is called by using something simple such as:
s = document.getElementById ("my_script");
s.parentNode.removeChild(s);
This will stop all functions of the script but will not take it out of user's cache. However like you wanted it can't be used.
Basically you can't unless you have access to the page content before you render it.
If you can manipulate the HTML before you send it off to the browser, you can write a regular expression that will match the desired piece of code, and remove it.

Categories

Resources