MVC3 Move Validation Blocks - javascript

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!

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>
}

Best way to refer to javascript in UserControl(ascx)

I usually create usercontrol which is referring javascript file/block. For example, I have a cascading Nation/City selection which is based on AJAX in my Register.ascx(a usercontrol), certainly I need add the javascript file into page. I have 3 ways at present:
1.Writing <Script> element in .ascx file directly, but it will bring nonstandard HTML structure due to many <Script> elements would appear in <Body>.
2.Writing <Script> element in aspx page which will use the usercontrol, but the father(aspx) rely on child(ascx), it's listening too bad.
3.Using ScriptManager or HtmlGenericControl to register file/block in head, but I'm worrying about performance of them, and it's a bit weird that I bring javascript to c# file.
Well I don't feel there is really anything wrong with having your scripts inside the body tag. In fact placing scripts at the bottom of the page is fairly common practice.
However if that concerns you, you may try putting all your scripts into a separate .js file and then call those functions from your control.
As far as the script manage, your probably right... I am sure that comes with some overhead.

Multiple pages on a single page

I am using backbone.js and building a single page application, inspired by trello.com ..
I want to know how you show many pages on top of the original page. As in how you architect it.
How do you use Backbone routers to achieve this?
For example in trello
Basepage
And then now on top of the base page you have dynamic content
like a cards detail
like a boards details
How could i architecture something like this?
I've done a couple of approaches so far in projects with 50+ pages and they both scaled well. I did not use backbone.js but the approaches are straight forward and do not require a framework to learn other than I used jQuery for selectors.
Both of them have in common creating a single overlay window that you can pull in content into the window. I wrote mine from scratch but you could easily use jQuery UI dialog. The two approaches only differ in how the content is pulled. Also, using the information on the link is all you should need to pull in the "module" or overlay content as your rule. Do not need tons of scripts loaded in to start your app. Have the modules pull in the behavior for you.
Option 1) Use the jQuery load method to pull content from stand-alone web pages by using a placeholder variable like so:
var $ph = $('<div />');
$ph.load(URL); // loads gui of remote URL + executes any script that URL has
The $ph var now contains all the GUI loaded in from the external URL so you can use selector on it to extract the particular HTML and place it into your DOM or overlay as you need.
Here is an example of the stand-alone HTML output:
<div class="module">
<a class="link">click me</a>
</div>
<script>
(function(){
// put any private vars here
$('.module .link').click(function(){
// do something
});
})();
</script>
If you remove() or destroy the dom inside the overlay through jQuery, it will automatically remove all the events directly assigned aka "bind" and "unbind" them but using "live" or "delegate" you will need to worry about "die" and "undelegate" etc. just doing die('.namespace').live('click.namespace') will ensure is cleaned.
Here is an example of this on one of my websites -> http://www.kitgui.com/docs
But the better example is within the customer section as the docs is fairly simple using hash history.
2) Using an iframe inside your overlay and assigning it a URL.
This is the easiest option but is a little slower because each page called has to have a full standalone behavior and dependencies with the iframe. Also you must worry about sizing the frame etc. unless you have a fixed overlay window.
You must have a loader overlay your iframe while its loading then have the iframe talk the parent to tell it its done loading and hide the loader.
I did this for several sites but one of them is a site in development you can see here to get the code ->
http://dev.zipstory.com (sign in and go to my zipstory and click "group" settings etc to see this, just view source to see how I did this as its all there)
The thing about iframes is you should write some code on the parent that accepts standard messages from the iframe that you agree on as a typical set of behavior such as notifying its done loading or passing messages to update something on the parent etc. This can be added on the fly and refactored as you need as long as your aim is KISS approach.
Each of the 'dynamic content' pages should be a template (underscore.js gives you _.template()) rendered by a backbone view. The main page needs to have events that initialize new views and render the templates. Look at the todos app (http://documentcloud.github.com/backbone/docs/todos.html) to get a basic idea about the flow of a backbone app.

How Jammit handle view specific 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é

Categories

Resources