I use some Facebook JS scripts for user authentification, etc. I want to place them in the properly unobtrusive way as application-wide scripts.
Currently I have the script as a partial and call it from my application header:
<%# render 'layouts/facebook_app_scripts' %>
The script works but is extremely obtrusive. I want to make it unobtrusive. This is especially important since I tap into all sorts of APIs and it's getting messy.
You don't need to see it in its entirety (if you need to see the script to answer this question, I don't think you'll be any help as this is a general question not script-specific)
You should know that it contains dynamically created links such as this one:
window.top.location = "<%= Facebook::SITE_URL.to_s %>/logout";
That means that putting this in a .js file in the assets/javascript folder isn't going to work, since .js files can't access rails-generated variables.
So how can I shift my javascript with dynamically-generated links from the rails view to an unobtrusive javascript file?
Take a look on this project to include all the Facebook JS SDK as a gem
Related
I have a ASP.NET MVC project which adopts lots of JavaScript (jQuery and d3). I am new to web development, so I want to ask for some help on how to organize front end script code.
My current way is, each folder under 'Views', has only one corresponding .js file (which means all partial views (.cshtml) under that folder, share that .js file), and I explicitly initialize all .js files of my project in $(document).ready() of _Layout.cshtml.
This introduces 2 issues:
Because all partial views puts there codes in one .js file, so it makes each .js file huge and complex.
Because I hardcoded initialize all .js files when _Layout.cshtml is loaded, so even when one view is not loaded, its behind .js is executed, sounds not flexible.
So here are my questions:
How to make each partial view has its own .js file (split current .js into small pieces).
How can I load and run a partial view's .js file only when that partial view is loaded.
If I use TypeScript and KnockoutJS, do they provide any benefits on organizing front end script code?
Thanks in advance.
Split up your javascript code into multiple file such that each js file corresponds to the partial views.
Then load the corresponding js in partial view in partial view instead _Layout.cshtml file. In this way, the corresponding js will execute only when the partial view is loaded.
TypeScript is a class-based object-oriented programming style applied to basic javascript, which is developed and maintained by Microsoft. This does not help to organized the files but do help to maintain the js code in an OOP style.(link here)
KnockoutJS is Model-View-ViewModel(MVVM) pattern applied to javascript. You can modularized each js files in KnockoutJS, ie, separate js for Model, View and ViewModel but they will have dependency each other.(see documentaion)
There are multiple ways to skin a cat. If you have javascript code specific to a partial view it's entirely fine to just skip the step of including a file and embedding JavaScript directly in there by means of the <script> tag. This solves problem 1 and 2 you posted because razor partial views boil down to just arbitrary HTML inserted into the DOM when they are loaded.
As for TypeScript and KnockoutJS the benefits they provide are highly subjective to yourself and the project you are working on. I would suggest reading up on the features they provide and see if that's an avenue you want to pursue -- There is no right or wrong answer to this, at least not with a lot of specific context as to what you're working on.
I am tinkering around with jQuery and am finding it very useful and almost exciting.
As of now, I am referencing the jQuery script via Google's CDN and I store plugins I use locally in a static/scripts directory.
Naturally, each page has its own individual implementation of components that are required for the features it currently offers. I.E. the main page has the Twitter plugin whereas the login page has form validation logic and password strength metering. However, certain components (navigation bar) for example use the same script across multiple pages.
Admittedly so, I am not a fan of putting javascript code in the header of a page, but I rather prefer to have it in an external file (for caching, re-usability, and optimization purposes).
My question is, what is the preferred route for organizing the external files. I wanted to try and keep it to one javascript file for the entire site to reduce IO requests. However, I am not sure how to implement document ready functions on a conditional per page bases.
$(document).ready(function () { ... }
Is there some way to reference a page by some method (preferably id based and not a url conditional).
Thank you in advance for your time!
You should try REQUIRE JS.
This will allow you to load only those plugins the pages where you need them, and unload them again if they are not needed anymore.
Then again, it might be overkill. It really depends on the size of your project.
Paul Irish:
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
This will allow you to block your scripts by body class/ID and execute them automatically.
First you might want to use YUI Compressor or some other JS compressing tool. Then perhaps creating a resource file (resx) for your JavaScript is the way to go. Then just reference the resource within your code. This is the approach Telerik took for their RadControl ASP.NET AJAX control framework.
I'd like to separate my JS code from HTML as much as possible and I can see several patterns for that.
1) I can use
$(document).ready(function() {...})
just before closing body tag
2) I can just put js code like
new FormValidationHandler()
in script tag just before closing body tag
3) I can point external js file containing initialization like $(document)ready or new FormValidationHandler in script tag
4) there is also a way to use self-invoking function but don't know if it maps to this problem
My question is which way is preferred?
Second one is that there are two places I can put my external scripts into the web page:
in the head tag
in the body tag (usually at the end)
Should head contain only code that doesn't have to run on page load? Then that code should be placed in body?
there is how I like to do. It's probably not perfect, but I like it this way :
Script location in the HTML document :
Every script loaded at the end of the HTML doc, just before the closing body.
There's one exception : the script that handles the FOUC (modernizr for example). This script must be in the head.
I don't see any other reasonable exceptions.
Scripts organization :
Their's two cases for this, in my opinion : If you work with an Hypertext document, or a web app (Maybe this could need some more explanations, but it would be long :p ). I rarely worked for web apps, so I don't yet have a validated organization for this. But I think in a web app you can probably use some script loading libraries like requirejs and it will probably be more useful than for simple web pages.
For a Hypertext document (most web pages), I like to distinguish two kind of scripts : libraries and what I call in french "script d'interfaçage" ("linking script" could probably be a good translation...).
Libraries are, as the name says, scripts that loads libraries in the javascript environment, but doesn't DO anything.
linking script is made to link those libraries to the specific HTML doc.
For me, in a perfect world, there should be as much library scripts as you which but only one linking script for each HTML doc. In this script you'll find the $(document).ready call if you're using jQuery, and all the content of this script should be very very very simple. Ideally there should be, in the document ready function, only instructions like :
$('my selector').MyPlugin({
option1:'value',
option2: 'value'
});
This type of instruction is really a simple link between the HTML doc and the JS library, and it's very simple to read and understand.
Over this organization, you can than do any kind of packaging to reduce the number of js files to be loaded. This packaging have to be optimized for client caching and limiting HTTP requests etc...
External files or inline scripts ?
Personally, I prefer to use external files for all scripts, but generally I use one inline script tag to declare some variables needed for some libraries (your key for your ad service etc...).
Loading of external libraries
One last specific case : When you have to load a script from another host. Generally, you can't tell if the script will load or not, because you can't tell if the other server is up or not, and if it will be slow or fast... You can't tell exactly what this script will do, so it could break your page...
Loading scripts from other hosts can really create problems, and this is why I recommend loading them asynchronously, once your page is fully loaded, with as much controls as you can.
To do this, I personally developed a library dedicated to loading libraries (maybe one day I'll publish it on gitHub, when I have some time).
For example, I use this script to load Facebook google+ ou twitter APIs, or any other external libs like stat counter or ads services.
I am trying to get inline C# to work in my JavaScript files using the MVC Framework. I made this little test code up.
$(document).ready(function() {
alert(<%= ViewData["Message"] %>);
});
When this code is used inside of the view it works perfectly. When I get outside of my aspx view and try this in a JavaScript file I get illegal XML character. I figure this is by design in the MVC Framework but I haven't been able to find any material on this on the web.
Has anyone gotten inline C# to work in JavaScript files using the MVC Framework?
As others have said, the C# is not being processed by the server.
A possible solution would be to have a separate view that uses the same model and outputs the JavaScript, then reference that view in your <script type="text/javascript" src="yourJSview.aspx"></script>.
Added as per SLaks' answer:
Set the content-type to text/javascript, and put your JavaScript source directly below the <%# Page directive (without a <script> tag).
Beware that you won't get any IntelliSense for it in VS.
You could make an ASPX view that renders JavaScript.
Set the content-type to text/javascript, and put your JavaScript source directly below the <%# Page directive (without a <script> tag).
Beware that you won't get any IntelliSense for it in VS.
To add to Grant Wagner's answer and SLaks's answer, you can actually fool Visual Studio into giving you IntelliSense in his solution like so:
<%if (false) {%><script type="text/javascript"><%} %>
// your javascript here
<%if (false) {%></script><%} %>
In his solution it is required that when it renders to the page that there be no <script> tags, but that has a side effect that turns off JavaScript IntelliSense in Visual Studio. With the above, Visual Studio will give you IntelliSense, and at the same time not render the <script> tags when executed.
.aspx files are the view files of MVC framework. The framework only renders the views and partial views. I do not think there would exist a way to use server-side code inside javascript files.
You can include your message in a hidden field
<%-- This goes into a view in an .aspx --%>
<%= Html.Hidden("MyMessage", ViewData["Message"]) %>
and use that inside your javascript file:
// This is the js file
$(document).ready(function() {
alert($("#MyMessage").attr("value"));
});
That inline C# has to be processed by the server in order to make sense. Naturally, it won't work with a just-plain-JavaScript file.
Your web server does not process .js files, it only serves them to the client. This is in contrast to .aspx or other ASP.NET file types. These files are interpreted by your server before they are served up to the client.
This is an old question, but for those who stumble upon in through google in the future, the best solution is to use data-* attributes to pass in the variables. A hidden element could be used, but you might as well use the <script> tag itself, and give it a unique ID.
A full example is answered here: https://stackoverflow.com/a/18993844/1445356
when you have C# code in a separate file and include it in your View the Server does not process the code, the script file will be called by the browser and the inline script would be treated as plain string
alternatively you can try script runat=server when including you script file but I am not sure about the effects of this
I agree with Serhat. It's best to render an HTML Hidden field, or, as Al mentioned, go to a URL for it. This can be done through a Web Service or even an IHttpHandler implementation. Then you could use a url such as "messages.axd?id=17".
I have some javascript code that has in it localized messages that i pull from my resource files. My problem is that if i include my javascript files like...
<script scr="..." type="text/javascript"/>
in my masterpage for example, then the <%= Resources... %> code is not running on view rendering. My current way of resolving this problem is by including the full code inside script tags in my masterpage, but i don't like it.
Any better suggestions?
You need to close out all script tags as such for IE to accept the JavaScript:
<script>....</script>
Not
<script .... />
Understanding the problem
Inline asp.net tags (e.g. '<%= %>' are parsed at runtime when the server renders your page.
In order for ASP.Net to be able to parse documents it needs to be specified by the webserver that the extension is handled by the aspnet_isapi ISAPI extension.
The regular JavaScript files, to which you are adding asp.net code, will never run through this extension and thus will never be 'compiled' properly.
Now is there a solution?
Mads Kristensen has written a blogpost about this problem in 2008. It is still valid afaik and should do exactly what you need.
See http://madskristensen.net/post/Localize-text-in-JavaScript-files-in-ASPNET.aspx
He uses the .axd extension which is also handled by the aspnet_isapi ISAPI extension.
Another very good post which addresses the problem more specifically for asp.net mvc can be found here: http://afana.me/post/aspnet-mvc-internationalization.aspx
Hope this helps.