How to emulate ScriptManager.RegisterStartupScript() in ASP.NET MVC project - asp.net

I am using ASP.NET MVC project and jQuery to handle async requests. Sometimes for an async request I need an initialization JavaScript snippet to be returned and executed together with an HTML snippet (I want this JavaScript to be rendered on server).
For now I am using my own ScriptsHelper class with a RegisterStartupScript() method (adds data to HttpContext.Current.Items). Then in global.asax HttpApplication.EndRequest() for async requests I append all registered scripts to the output (enclosed in tags). jQuery.fn.load() successfully executes them when the received HTML is appended to the DOM - this is exactly what I need. Do you think it is "correct" (good) solution, or maybe you can suggest something better? Thanks.

I encountered a similar situation in a project before I started using jquery and wound up resorting to using eval(). I was returning a javascript text snippet as part of the value of a non-visible DOM element along with the rest of the HTML I was inserting into the DOM.
I had a lot of trouble debugging this type of dynamically generated javascript in IE6 so this solution worked out decently for me because I could inspect the value of the DOM element that was getting eval'd. However, I've always been leery of using eval.
It sounds like your solution has a reasonable architecture for the server-side rendering as opposed to my spaghetti-code and this technique looks like it fits right in with the spirit of jQuery.fn.load so I wouldn't worry too much.

Yeah I think that jQuery is calling eval() internally for you - are you using append? I think that this technique works pretty good most of the time. If the data returned from the server is in a list that is repeated you may want to look at using the live function added to jQuery 1.3 It allows you to attach an event to all current and future elements matching your selector. Checkout these articles:
Live
jQuery Live Events
Also as something else to consider is a tool to help manage scripts and css for asp.net mvc. I have been using this and I love it as it combines files as well as compresses them. You can configure it all from you web config too.

Related

Rendering javascript at the server side level. A good or bad idea?

Now a community wiki!
I want to make it clear first: This isn't a question in relation to server-side Javascript or running Javascript server side. This is a question regarding rendering of Javascript code (which will be executed on the client-side) from server-side code.
Having said that, take a look at below ASP.net code for example:
hlRemoveCategory.Attributes.Add("onclick", "return confirm('Are you sure you want to delete this?');")
This is prescribing the client-side onclick event on the server-side.
As oppose to writing Javascript on the client-side:
$('a[rel=remove]').bind('click', function(event) {
return confirm('Are you sure you want to delete this?');
}
Now the question I want to ask is: What is the benefit of rendering javascript from the server-side code? Or the vice-versa?
I personally prefer the second way of hooking up client-side UI/behaviour to HTML elements for the following reasons:
Server-side does what ever it needs to already, including data-validation, event delegation and etc; and
What server-side sees as an event is not necessarily the same process on the client-side. i.e., there are plenty more events on client-side (just look at custom events); and
What happens on client-side and on server-side, during an event, could be completely irrelevant and decoupled; and
What ever happens on client-side happens on client-side, there is no need for the server to know. Server should process and run what is given to them, how the process comes to life is not really up to them to decide in the event of the client-side events; and so on and so forth.
These are my thoughts obviously. I want to know what others think and if there has been any discussions on this topic.
Topics branching from this argument can reach:
Code management: is it easier to render everything from server-side?
Separation of concern: is it easier if client-side logic is separated to server-side logic?
Efficiency: which is more efficient both in terms of coding and running?
At the end of the day, I am trying to move my team to go towards the second approach. There are lot of old guys in this team who are afraid of this change. I just wish to convince them with the right facts and stats.
Let me know your thoughts.
UPDATE1: It looks like all of us who have participated in this post have common thought; Good to know that there are others who think alike. Now to go convince the guys ;) Thanks everyone.
Your second example is vastly superior to the first example. Javascript is your behaviour layer and should be separate from your semantic markup (content) and CSS (presentation). There are a number of reasons this is better architecture:
Encourages progressive enhancement. As you mentioned, the backend code should work correctly in the absence of JS. You cannot rely on your clients having JS available. This way you build it once without JS and then can enhance the experience for those with JS (e.g. by adding clientside validation as well as serverside validation so that the client can get instant feedback)
Cleaner markup. Normally reduced download size. One reusable selector in a separate JS file that can be cached and shared between pages vs. a handler on each element.
All of your JS in one re-used place. e.g. if your code was opening a popup window and you decided to change the dimensions of the window you would change it once in the code in the JS file vs. having to change it on every individual inline handler.
There are lots of other arguments and reasons but they should get you started...
Also, from your example it appears that you have a normal link in your document which can delete content. This would also be a bad practice. Anything that deletes or updates content should be done on a POST (not GET) request. So it should be the result of submitting a form. Otherwise e.g. googlebot could accidentally delete all of your content by just crawling your page (and search engine robots don't execute JS so your alert wouldn't help there)
The two biggest differences i can think of up front are:
you lose the client side caching you would get if the javascript was in a separate js file
if you need to change your javascript, you have to recompile (extrapolate this to what happens after you have released your product: if you have to recompile then you need to redistribute binaries instead of just a modified js file)
it is easier to use the VS debugger if the javascript is in a separate file; you can just set a break point in that file, if you are generating the code server side then you have to use the running documents feature, find your generated code and then add the breakpoint, and that breakpoint has to be manually added everytime you re-run your app. Following on from that, if the code is in a separate file, then you can just make your tweak to the javascript code, F5 your browser page, and keep on debugging without having to stop and restart the debugger.
It should be mentioned that sometimes you have to insert js code from the server - for example if the bulk of your code is in a separate js file and you need to insert control identities in to the page for that code to work with. Just try to avoid that situation if possible.
Looks like you already know what to do. Rendering it on the server side is a bad idea.
The simple reasoning being you're Javascript lives both on the server side pages as well as in separate Javascript files (assuming you are using Javascript at all). It can become a debugging nightmare to fix things when everything is everywhere.
Were you not using any other Javascript besides what the server side scripts generate, it would probably be fine and manageable (forget what the unobtrusive movement says).
Secondly, if you have 100 links on the page, you will be repeating that same code in 100 places. Repetition is another maintenance and debugging nightmare. You can handle all links on all pages with one event handler and one attribute. That doesn't even need a second thought.
<Rant>
It's not easy to separate HTML and Javascript, and even CSS especially if you want some AJAX or UI goodness. To have total separation we would have to move to a desktop application model where all the front-end code is generated on the client side programmatically using Javascript, and all interaction with the server gets limited to pure data exchange.
Most upstream communication (client to server) is already just data exchange, but not the downstream communications. Many server-side scripts generate HTML, merge it with data and spit it back. That is fine as long as the server stays in command of generating the HTML views. But when fancy Javascript comes onboard and starts appending rows to tables, and div's for comments by replicating the existing HTML structure exactly, then we have created two points at which the markup gets generated.
$(".comments").append($("<div>", {
"id": "123",
"class": "comment",
"html": "I would argue this is still bad practice..."
}));
Maybe this is not as big a nightmare (depending on the scale), but it can be a serious problem too. Now if we change the structure of the comments, the change needs to be done at two places - the server side script and templates where content is initially generated, and the Javascript side which dynamically adds comments after page load.
A second example is about applications that use drag and drag. If you can drag div's around the page, they would need to be taken off the regular page flow, and positioned absolutely or relatively with precise coordinates. Now since we cannot create classes beforehand for all possible coordinates (and that would be stupid to attempt), we basically inject styles directly in the element. Our HTML then looks like:
<div style="position: absolute; top: 100px; left: 250px;">..</div>
We have screwed up our beautiful semantic pages, but it had to be done.
</Rant>
Semantic, and behavioral separation aside, I would say is basically boils down to repetition. Are you repeating the code unnecessarily. Are multiple layers handling the same logic. Is it possible to shove all of it into a single layer, or cut down on all repetition.
You and the other people answering the question have already listed reasons why it is better not to having the server side code spit intrinsic event attributes into documents.
The flip side of the coin is that doing so is quick and simple (at least in the short term).
IMO, this doesn't come close to outweighing the cons of the approach, but it is a reason.
For the code in your example it doesn't really matter. The code isn't using any information that is only available at the server side, so it's just as easy to bind the event in client side code.
Sometimes you want to use some information that is available at the server side to decide whether the event should be added or not, or to create the code for the event, for example:
if (categoryCanBeDeleted) {
hlRemoveCategory.Attributes.Add(
"onclick",
"return confirm('Are you sure you want to delete the " + categoryType + "?');"
);
}
If you would do this at the client side, you have to put this information into the page somehow so that the client side code also has access to it.

Placing jQuery Refernce at the bottom of HTML Document breaks User Control

Walter Rumsby provided a great answer to Where to place JavaScript in an HTML file. He references the work done by the Yahoo Exceptional Performance team and their recommendation to place scripts at the bottom of the page. Which is a hard and fast rule that I've been following for quite sometime now. In the same thread Levi Rosol pointed out "the best place for it [JavaScript] is just before you need it an no sooner." That is the predicament that I now find myself in.
I've added my reference to jQuery at the end of my page but have run into an issue with how to structure a user control that I'd like to add client side functionality to. Specifically, I am having a hard time working out the best way to accommodate dependencies. The user control has a span tag containing a numeric value that I'd like to update based on the number of check boxes the user has checked in the user control. I am using jQuery to find the span tag and update its text property.
Unfortunately, unless my reference to jQuery appears prior to the user control I receive JavaScript errors. This makes sense because the control is referencing functions that have not yet been added. I can think of several solutions to the issue but am looking for a best practice option.
Placing a reference to the jQuery library inside of the user control.
Downside: if the user control was placed into a repeater multiple references to the jQuery library would be made.
Put no JavaScript in the user control and write all code to update the span tag for the user control in the containing page.
Downside: I'd end up with the same code in multiple places creating a potential maintenance nightmare.
Place the jQuery reference in the head section of the page.
Downside: I've violated the recommendation to place scripts at the bottom of the page and have created an unusable user control if the page does not include a reference to jQuery.
Those are the options and downsides I came up with when thinking about solutions to this problem. I am certainly open to suggestions for better solutions and barring none looking for a recommendation of which of the three I should choose.
There's a Google project that aims to solve these pains you may want to look at called Jingo:
http://code.google.com/p/jingo/
Another solution I'd recommend is a loader like YUI Loader Utility.
http://developer.yahoo.com/yui/yuiloader/
It will allow you to manage dependencies etc. and it's not just useful when you're using their UI components. It can be used for anything; just look at the docs around addModule.
If you're using ASP.NET the ScriptManager is another good solution.
Another option would be to dynamically generate the script reference by registering a startup script from your usercontrol that wrote a script reference to the document head.
The javascript function could check for an existing jQuery reference, and if none was found, write the reference out. This would solve the multiple references. A basic example was discussed in this thread.
The simplest solution to this I've found is to use a helper to accumulate Javascript fragments to be included at the page body while rendering other page elements. Then, you can include jQuery first, followed by any deferred literal Javascript fragments.
It does require maintaining some extra state during page generation, which can complicate your rendering pipeline just a bit. However, it allows you to get deferred Javascript inclusion, without requiring complex DOM manipulation after the page is loaded to pick out any existing references to jQuery.

Tips for developing an ASP.NET application that doesn't depend on JavaScript

Not sure if this belongs in community wiki...
Can somebody give some general guidelines on how to successfully build an ASP.NET site that isn't dependent on JavaScript? My understanding is that I should build a functional site initially without JavaScript, and use it to enhance the user experience. That is easier said than done... how can I make sure my site works without JavaScript short of disabling JavaScript and trying it? Or is this something that comes with experience?
Try ASP.NET MVC! sure most of the examples use JavaScript for the AJAX functionality, but it's easy to build a fully functioning site that doesn't use JavaScript.
Since ASP.NET MVC doesn't use server controls with all their embedded JavaScript, it's a great way to build a site with very minimal and lightweight HTML, while still writting your data access and business logic in C#, VB.NET, or any other .NET language.
I've built working ASP.Net sites with little or no JavaScript, so it's definitely possible (just a royal pain.) The trick, and this sounds silly, is to use as few <ASP:> type tags as possible. Those all spawn various levels of JavaScript. Regular old-school HTML elements work just fine with no scripting.
So, on the extreme end, you write, say, your form using all plain-vanilla HTML elements, and then you have that form submit point at another page that accepts the form submit and hands it off to your server-side scripting.
To put it another way, pretend that all you get with ASP.NET is a snazzy server-side programming language and you're writing HTML in 1998.
Now, having done this, I can tell you that what this ends up as is a classic ASP webpage with cleaner programming syntax. ;) Most of the features that make ASP.NET "better" than classic ASP hang on JavaScript, so writing a JavaScript-free ASP.NET system is an exercise in shooting oneself in the foot repeatedly.
However, the one thing you should absolutely do is make sure the first page or two do work without JavaScript. Unlike 10 years ago you can safely assume that any browser hitting your page has JavaScript, and unlike about 8 years ago, your visitors probably don't have JavaScript turned off for speed reasons, but they very well might have something like the NoScript plugin for Firefox dialed all the way to 11. So, your first couple of pages need to work well enough to a) tell the new visitor that they need JavaScript, and b) still look and work good enough to make it look like adding your site to the white list is worth it. (In my experience, most people get the first one done, but in such as way as to totally drop the ball on the second. To put it another way - if your super fancy web 2.0 mega site starts looking like craigslist if noScript is fired up, I'm probably not going to bother letting you run scripts on my machine.)
If you want to use many of the ASP.NET controls (i.e. the DataGridView), ASP.NET pages are generated with lots of JavaScript in order to handle the events on the controls (i.e. selecting a row in the DataGridView). I think you're going to lose so much of ASP.NET that trying to have ASP.NET work without JavaScript enabled is impractical.
Disabling Javascript is the best way to test how a web site performs with out it. Good news, IE8's developer tools provide a quick and easy way to do just that. Now, having said that, often times the only thing that you can do is put up a message with a noscript tag to the effect that your site requires javascript for best function.
Many ASP.NET functionalities & controls won't work when JavaScript has been disabled. Think of LinkButton's onclick event which contains a call to a JavaScript function.
LinkButton is just an example. But there are many other things too.
If your concern is with JavaScript being disabled in user's browser then you can check for that and handle your site accordingly.
If you do decide to build the site without JavaScript then you will end up building a somewhat static web site. If your need is just to build a static website then you can go on with this approach.
Write everything with basic html forms and css, and then you will know that it works without javascript.
Once you are happy with it, then look at unobtrusive javascript, so you can modify the way the application works when javascript is enabled.
Last time I looked at some stats about this around 1% disable JavaScript, so why spend hours and hours on this when what you should do is show a message telling the user that your site requires javascript.
Use your time to be productive instead of trying to write around perceived limitations.

jQuery and Asp.Net compatibility

I am trying to use jQuery and Asp.net Ajax library. The jQuery code is solid, I have it working on a separate page. When I incorporate the jQuery code into an existing page that using Asp.net Ajax, the jQuery code does not work.
I think this has something to do with name mangling.
How can I stop asp.net from name mangling or whatever else is going on?
If you're running into major naming issues then leverage QJuery's ability to use almost anything as a selector, including classes. Sure, class lookup isn't as fast as id lookup, but it is far less prone to being mangled by auto-generated code.
Here is a good article detailing How To Work With JQuery in ASP.NET.
Generally, the two frameworks do not interfere with each other. You can run into issues though, since asp.net ajax adds a hole bunch of extra functions to some of the base types like string, int or data.
But usually that is not a problem when only using jquery, but I have had issues with a few plugins that was not written probably, so that might be where your problem is.
With that said, it is hard to give you any concrete help without more information or/and code.
Maybe the two frameworks (jQuery and ASP.Net AJAX) collide in defining some operators like the $.
This old forum post is made by someone facing similar situation.

Which Javascript history back implementation is the best?

There are implementations for history.back in Micrososft AJAX and jQuery (http://www.asual.com/jquery/address/).
I already have jQuery and asp.net ajax included in my project but I am not sure which implementation of history.back is better.
Better for me is:
Already used by some large projects
Wide browser support
Easy to implement
Little footprint
Does anybody know which one is better?
EDIT:
Another jquery plugin is http://plugins.jquery.com/project/history It is recommmended in the book JQuery Cookbook. This one worked well so far.
One alternative to jQuery Address is the nice jQuery history plugin. There are also URL Utils.
Reference: AJAX History and Bookmarks.
If you are building an ASP.NET application then using ASP.NET Ajax Framework gives you many advantages and a nice-simple API to use server-side.
Below you can find an example that uses Browser History with ASP.NET Ajax
Create a Facebook-like AJAX image gallery
Both have a wide range support in browsers.
For me is easier to integrate Microsoft AJAX Framework in an ASP.NET page so again if you have an .aspx page it might be easier to work with ASP.NET AJAX
If you don't need exactly AJAX, i.e. updating only parts of the site on request is sufficient for you, then you can use invisible iframe as target for loading generated HTML file containing only JS script that updates/resets "updateable" parts of the site. This is cross-browser solution and doesn't need address polling.
Example, but not in ASP: kociszkowo.pl (Polish site)
When you click there in the section icon and your browser supports javascript, link is modified before being fetched - target is changed to iframe and href is suffixed with .dhtml to inform server, that we're interested in a special version of the page. If you press Back in your js-equipped browser, then previously fetched iframe page is loaded from the cache. Simple, but requires some decisions at architectural level.
This link modification is irrelevant here, it's just the result of combining JS/non-JS world.
In my experience, your best bet is using the same one that you have doing most (if not all) of your ajax calls. For instance, if you're using asp:UpdatePanel's, use the MS one - if you're using jQuery.ajax, use the jQuery history plugin. If you're doing a mix (which I've tried to avoid in my projects), I'd personally test with both and see which behaves better - if they both test fine, then it's a bit of preference. Some may argue the Microsoft one would have better support, but jQuery's history plugin may get more use and more mature.
http://msdn.microsoft.com/en-us/library/system.web.ui.updatepanel.aspx
http://docs.jquery.com/Ajax/jQuery.ajax#options

Resources