Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

jQuery Intellisense in Visual Studio


:P
On this page:

Jeff King, who's one of the program managers in the Web Tool Division and who focuses on the JavaScript editor, has posted about another byproduct of the Visual Studio hotfix I mentioned a few days ago. Jeff's post talks about how you can make Visual Studio's JavaScript Intellisense work better with jQuery. Previously working with jQuery got you - well, nothing because the the Intellisense parser didn't properly parse the jQuery source file and so failed to produce any Intellisense for anything in the jQuery library. The problem is that jQuery is basically one big function and since it failed to parse - you got nothing <g>.

The hotfix apparently works around the problem parsing jQuery and so you can get some Intellisense out of the box and with a wee bit of marking up the jQuery code you can now get some pretty useful Intellisense from jQuery in the JavaScript and ASP.NET Html editor. Jeff shows a small example of how to fix up jQuery functions by adding Visual Studio documentation with a suggestion of marking up the full jQuery library.

While I don't think I'd want to add VS specific comments to all of jQuery's functions and keep up with it for each of the frequent new releases of jQuery, I think adding a single single comment to the main jQuery function itself is probably worth it and it provides a pretty good payback for little effort.

If you don't do anything and leave jQuery.js as is you only get some limited supoport. What's new is that the parsing doesn't fail and because of it doesn't break parsing of other JavaScript files. In addition you can now do the following slightly non-standard jQuery activation and get Intellisense:

newJquery

Note that the new operator is required to make this work. Generally the jQuery function is called through its static function  (ie. without new) but that doesn't work by default.

In addition you also get Intellisense on the static object instance (not the function of jQuery) so the following also gives you Intellisense:

$.ajax( {
       url: "callbackPage.aspx", 
success: function(result){alert(result);}
} );

and you get Intellisense on the $ (same as jQuery) instance.

To get the static function to work you can make at least one small modification to jQuery.js. If you modify jQuery.js and only change the jQuery function definition (at the top of jQuery.js) like this:

var jQuery = window.jQuery = function( selector, context ) {    
    /// <summary>The jQuery object is actually just the init constructor 'enhanced'</summary>
    /// <param name="selector" type="var">Document selector. 
    /// (examples: "Element","#Id",".cssClass","#divMessage,#divError",DomElement,jQueryObject)
    ///  </param>
    /// <param name="context" type="object">Object scope of any code executed with jQuery functions</param>
    /// <returns type="jQuery" />
    return new jQuery.prototype.init( selector, context );
};

You get this Intellisense at the first level of jQuery usage which is the most common usage scenario:

 jqueryIntellisense[5]

Note that the single change addresses both jQuery and $ function usage.

You also get the comment information:

jQueryFunctionDocs

Most jQuery functions also return a jQuery object as a return value so you can chain operations, but even though those functions return jQuery objects that Intellisense now understands, it has no way of knowing what the return value type is and so chaining does not work unless you modify each of the functions with the same small hack by adding a return type as Jeff suggests in his post. It's simple enough to do if you find yourself chaining certain functions all the time. Just add the <return /> comment and you're done.

Note that as you drill into functions, parameter info is often not all that useful - unless you annotate - because jQuery mostly takes object map parameters that allow optional parameters to be passed and those only show up as a single object parameter. For example:

JsIntellisenseSyntax

is not terribly useful given that you can specify 15 or so optional parameters in the 's' map... you'll still need to consult the documentation to find all of the ajax() function flags, but this is certainly not Visual Studio's fault. Thankfully jQuery is well documented with easy to find documentation and examples.

Note that in order to get the basic VS Intellisense to work on any function you only need to add this below the function declaration:

    /// <returns type="jQuery" />

So if you want to be sly about this just cut and paste this line into a few of the core functions you use a lot (like filter, find, each etc.)  and that return a jQuery object for chaining and you're a long way to getting useful Intellisense functionality for a few minutes worth of work.

It'd be better if this was more automatic, but even so this is a welcome fix that improves usability with jQuery quite a bit especially if you're new to it and its many function parameters. At the very least adding the above to the jQuery function itself brings a sufficient payback during development.  In production you probably deploy the packed version anyway so this doesn't affect production code in any way anyway.

A few thoughts on JavaScript Intellisense in Visual Studio

I just wish a little more work could be done to make consumption of JavaScript easier. Intellisense in Visual Studio is severely hampered by the fact that once you assign a function value to a variable you lose all use of Intellisense with the variable. Sticking with the jQuery theme here, the following doesn't do well:

var jCtl = jQuery("#divMessage");
var text = jCtl.text();
var val = jCtl.value();

In this code I'm reusing the jQuery instance rather than making calls to the function repeatedly, but as soon as I assign to jCtl all Intellisense goodness is gone even though the parser inheritently understands what jQuery() is and what it returns.

The parser understands this though:

var jCtl = new jQuery("#divMessage");    
var text = jCtl.text();

and WILL provide Intellisense for jCtl in this scenario. While this works here and it's functionally equivalent (although non-conventional), it's not always practical to declare a new object. In other situations you have no choice at all because results may simply be returned from a function and there's no way to fake the type with an explicit object declaration.

If I really need this functionality I've often temporarily added a type declaration to get Intellisense to work

// Temporary declaration - remove when done
var date = new Date();
 
// 'real' code in your script
dateString = date.toLocaleTime();

and while that works it's a hassle to add vars like that and remember to remove them. So much so that most of the time I don't bother unless there's lots of code against a complex type.

It sure would be nice if one could place a comment into the code to give a hint as to the type of the var with something like this:

/// <declare var="jCtl" type="jQuery" />
var jCtl = jQuery("#divMessage");    
var text = jCtl.text();

Better yet I would love to see the Intellisense parser figure out that the call to jQuery() returns a jQuery object and work off that. It seems given that Intellisense works on the function itself that this should be possible to associate the variable with the return type.

ASPX pages and Scripts loaded via Resources

One scenario that bugs me is that I can't force Intellisense to recognize script files that are loaded via Resources. If I have a control that loads its own resources the only way I can get Intellisense to recognize the script file is by adding a <script src="" /> reference into the page. Doing so however breaks my page potentially because the script file is now loaded twice.

I don't have a problem with having script files available in the design environment even if scripts will serve from resources, but I need some way to load the script for Intellisense.

JavaScript (.js) files have an option to include a comment that forces loading of files:

/// <reference path="../scripts/jquery.js" />

but unfortunately that doesn't work in an ASPX page, or at least I haven't figured out to make this work.

The only way to get this to work is to add the ASP.NET AJAX ScriptManager to the page, but I'd like to avoid that given that it requires the whole configuration of Atlas as well as ASP.NET AJAX client libraries loading which I don't need.

There really should be some other mechanism to allow letting Intellisense work with resource based javascript files in an ASPX page.

Posted in ASP.NET  jQuery  

The Voices of Reason


 

Josh Bush
February 11, 2008

# re: jQuery Intellisense in Visual Studio

Thanks for the heads up. When vs2008 was still in beta I gave it a go with their new javascript intellisense only to find out that it didn't play too nice with jQuery. I'll have to give it another go and see if that helps out with my masked input plugin. I code in studio all day long, it'd be nice to be able to use it for my jQuery projects as well.

Josh

Kevin Dente
February 11, 2008

# re: jQuery Intellisense in Visual Studio

Overall I've been very disappointed with Visual Studio's Javascript support (both intellisense and debugging), especially for non-MS frameworks. Aptana kicks it's butt in this area.

Mike
February 11, 2008

# re: jQuery Intellisense in Visual Studio

I can hardly imagine what the Microsoft developers had to do to get javascript intellisense working at all. They basically run the script as far as I understand, but there are so many clever ways of writing javascript (such as using closures to create private fields) that I don't know if it ever going to be possible to get intellisense for each and every toolkit just by checking the scripts.

Aptana also offers support for several javascript toolkit. I'm not sure, but I think they go the other way, adding specific info to the IDE to give intellisense and showing comments.

About the resources: why doesn't VS just load everything it can find, files and referenced libraries? Too much overhead?

Ben
February 11, 2008

# re: jQuery Intellisense in Visual Studio

I was able to get IntelliSense to work for some resourced js files by adding a non-visible placehoder containing the js references in a master page (see below). I'm guessing this would work in an aspx page as well. It's a hack but adds nothing to the rendered page output. Hope this works for you.

<asp:PlaceHolder id="referencePH" Visible="false" runat="server">
<script type="text/javascript" src="my.js"></script>
<script type="text/javascript" src="more.js"></script>
</asp:PlaceHolder>

Bertrand Le Roy
February 11, 2008

# re: jQuery Intellisense in Visual Studio

Nononono :) . There's a perfectly supported way of getting IntelliSense on a resource-based script. Just add a script reference to your script manager that points to it. When the control registers it, it will just get ignored because the script manager already has it in its list, and the IDE will still be able to use it for IntelliSense. It won't make a difference at runtime.
<scriptreference assembly="yourassembly" name="resourcename.js"/>

Rick Strahl
February 11, 2008

# re: jQuery Intellisense in Visual Studio

@Bertrand - only if you use ScriptManager and System.Web.Extensions. Chances are if you are using jQuery that you won't, right? <g>

What I'd like to see is a way to do the same without ScriptManager as you can in .js files which already have this capability via <reference />.

Rick Strahl
February 11, 2008

# re: jQuery Intellisense in Visual Studio

@Ben - yeah good point about using an invisible placeholder. Actually that should do the trick.

Bertrand Le Roy
February 11, 2008

# re: jQuery Intellisense in Visual Studio

Right, but then you probably also shouldn't use resource-based scripts: the only advantage in that case is packaging and deployment but you'll need the jQuery script anyway as a path based script.

Rick Strahl
February 11, 2008

# re: jQuery Intellisense in Visual Studio

Right - Actually I do load jQuery and a few other scripts (optionally) from resources in a few controls. Each of the controls has options that allows to set the script location, but the default is to use WebResources. The advantage is that everything is self contained and - as in ASP.NET AJAX - I can compress script code and cache it.

IAC, in this scenario Ben's approach might work - putting hte scripts into a dev folder and using an invisible placeholder. I have to see if that does indeed work. It would be nice though if the editor would also understand the same script reference syntax that standalone .js files get for consistency's sake.

Stephen
February 12, 2008

# re: jQuery Intellisense in Visual Studio

Is the place holder "trick" to get around MasterPages getting all confused?

For instance, in my MasterPage i have:

<script language="javascript" type="text/javascript" src="/ScriptLibrary/jQuery/1.2.3/jquery.pack.js"></script>
<script type="text/javascript" src="/common/code.js"></script>
<link href="/common/Styles.css" rel="stylesheet" type="text/css" />


with src/href attributes leading off with "/" so that no matter where my aspx page is, on the root, 1 folder deep, 4 folders deeps, wherever, that it will properly "start at root" and go find the js file

But like that, Intellisense doesn't work (and this goes for any js or css files)

Changing it to use ".." and the like lights intellisense back up for everything (including jQuery since the update) but now i can't have aspx pages in folders (or at different levels of folders) because the src/href's don't properly resolve

Lance Fisher
February 12, 2008

# re: jQuery Intellisense in Visual Studio

Hi Rick,

I went through and added xml comments to almost all of the functions in jQuery. Some don't work, but most do. The annotated jQuery file is on my newly launched blog here:
http://lancefisher.net/blog/archive/2008/02/12/intellisense-for-jquery-in-visual-studio-2008.aspx

Lance

James Hart
February 22, 2008

# re: jQuery Intellisense in Visual Studio

I've found similar issues with regard to getting external JS files to be available as an intellisense source in ASPX and (particularly) ASCX contexts, but I've found the invisible placeholder to be the best trick. And since you're using a pretend scriptfile reference, why not reference a pretend scriptfile (one with helpful intellisense comments in it...)

More on how I've gone about it here: http://blogs.ipona.com/james/archive/2008/02/15/JQuery-IntelliSense-in-Visual-Studio-2008.aspx

Agreed, though - the failure of type inference to flow to variables is annoying - although given how hard it must be to come up with any kind of intellisense in JavaScript it feels a bit harsh to go moaning about it. Also, if I comment at the top of a function that a parameter variable will be of type jQuery, shouldn't intellisense kick in whenever I type that parameter name followed by a dot?

function foo(bar) {
  /// <param name="bar" type="jQuery">
  
  bar.[Show me what I can do here!]
}

Peter Bromberg
February 23, 2008

# re: jQuery Intellisense in Visual Studio

I think it is interesting to note how many developers are deliberately abandoning the overhead of the Microsoft AJAX thingy and implementing their own cool JQuery and other scripts which are much more lightweight. At least, I've always felt that way - having avoided using the MS tools in this particular area.

Rick Strahl
February 23, 2008

# re: jQuery Intellisense in Visual Studio

Peter - I think part of the reason for this this also is that with the client stuff you do have a choice - you're not locked into using MS Ajax. Personally for me it's the value of it - size vs. functionality. The MS Ajax client library doesn't offer much useful stuff IMHO to make the part that's usually the most difficult - the client side coding - easier. The all server approach - UpdatePanel etc. - for me has proven to be too leaky of an abstraction with lots of little problems that when they crop up are next to impossible to debug let alone work around. So from that angle it seems easier to go with a custom solution.

On the other hand the comments here certainly don't rule anybody out from using MS Ajax. jQuery and most other frameworks should cooperate just fine with MS Ajax. Once you're using it adding hte overhead of jQuery doesn't add much weight <g>...

David R
January 23, 2009

# re: jQuery Intellisense in Visual Studio

Great Post!
you probably know, but google are hosting JQuery amongst other JS libraries which you can access using the google AJAX Libraries API:

http://web2asp.net/2009/01/google-hosts-jquery-scriptaculous.html
http://http://code.google.com/apis/ajaxlibs/

Matt
April 30, 2009

# re: jQuery Intellisense in Visual Studio

Well, it works with HTML, but not XHTML. Valid XHTML uses CDATA sections inside script tags, which stop JavaScript intellisense from working.

Of course, this isn't a problem for most Microsofties, who don't care about valid HTML or XHTML, and still use language="JavaScript" in script tags as if it's 1998.

Robert Werner
May 02, 2009

# re: jQuery Intellisense in Visual Studio

I've gone through some frustrations getting jQuery Intellisense working. But I've now resolved those problems and published this to hopefully help others: http://mwtech.blogspot.com/2009/05/how-to-get-jquery-intellisense-working.html

LLC IRA
May 21, 2009

# re: jQuery Intellisense in Visual Studio

My preference is always with xhtml because it is more likely readable in every instance.

Rick Strahl
May 21, 2009

# re: jQuery Intellisense in Visual Studio

@LLC - maybe so but you can miss out on optimizations like swapping in compressed files and still be able to debug your script code. Lots of things you can do with resources (or a custom script manager) that you can't with a hardcoded script reference.

Praveen
March 24, 2010

# re: jQuery Intellisense in Visual Studio


magang jepang
October 19, 2010

# re: jQuery Intellisense in Visual Studio

My absolute favorite feature of Visual Studio 2010, so far, is the javascript Intellisense support via the <reference> tag. Add the following line to your .js file and you get jQuery Intellisense.

/// <reference path="/scripts/jquery-1.4.1.js" />

My second favorite feature, so far, was just added with the Visual Studio 2010 Pro Power Tools just released by Microsoft the other day. It is the Add Reference Search feature.
<a href="http://www.kougas.co.id/">magang jepang</a>

Silah
March 11, 2011

# re: jQuery Intellisense in Visual Studio

Nononono :) . There's a perfectly supported way of getting IntelliSense on a resource-based script. Just add a script reference to your script manager that points to it. When the control registers it, it will just get ignored because the script manager already has it in its list, and the IDE will still be able to use it for IntelliSense. It won't make a difference at runtime.

mynet sohbet
January 13, 2012

# re: jQuery Intellisense in Visual Studio

maybe so but you can miss out on optimizations like swapping in compressed files and still be able to debug your script code. Lots of things you can do with resources (or a custom script manager) that you can't with a hardcoded script reference.

Rick Strahl
January 13, 2012

# re: jQuery Intellisense in Visual Studio

@Silah - perfectly supported and perfectly heavy weight in what it pulls in. ScriptManager is a pain in the butt and I avoid it like the plague.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024