Skip to main content

7 posts tagged with "jquery"

View All Tags

The Mysterious Case of Webpack, Angular and jQuery

You may know that Angular ships with a cutdown version of jQuery called jQLite. It's still possible to use the full-fat jQuery; to quote the docs:

To use jQuery, simply ensure it is loaded before the angular.js file.

Now the wording rather implies that you're not using any module loader / bundler. Rather that all files are being loaded via script tags and relies on the global variables that result from that. True enough, if you take a look at the Angular source you can see how this works:

// bind to jQuery if present;
var jqName = jq();
jQuery = isUndefined(jqName) ? window.jQuery : // use jQuery (if present)
!jqName ? undefined : // use jqLite
window[jqName]; // use jQuery specified by `ngJq`

Amongst other things it looks for a jQuery variable which has been placed onto the window object. If it is found then jQuery is used; if it is not then it's jqLite all the way.

But wait! I'm using webpack#

Me too! And one of the reasons is that we get to move away from reliance upon the global scope and towards proper modularisation. So how do we get Angular to use jQuery given the code we've seen above? Well, your first thought might be to npm install yourself some jQuery and then make sure you've got something like this in your entry file:

import "jquery"; // This'll fix it... Right?
import * as angular from "angular";

Wrong.

You need the ProvidePlugin#

In your webpack.config.js you need to add the following entry to your plugins:

new webpack.ProvidePlugin({
"window.jQuery": "jquery"
}),

This uses the webpack <a href="https://github.com/webpack/docs/wiki/list-of-plugins#provideplugin">ProvidePlugin</a> and, at the point of webpackification (© 2016 John Reilly) all references in the code to window.jQuery will be replaced with a reference to the webpack module that contains jQuery. So when you look at the bundled file you'll see that the code that checks the window object for jQuery has become this:

jQuery = isUndefined(jqName) ? __webpack_provided_window_dot_jQuery : // use jQuery (if present)
!jqName ? undefined : // use jqLite
window[jqName]; // use jQuery specified by `ngJq`

That's right; webpack is providing Angular with jQuery whilst still not placing a jQuery variable onto the window. Neat huh?

TypeScript, JSDoc and Intellisense

Days of Yore#

It was my first job. The web was alive and well at this point but still very much in it's infancy. Newspapers had only recently moved on from calling it "the information superhighway". No-one was doing real programming for the web - the desktop was where it was at.

As for me, I was writing call centre software. It was all very exciting. Here was the idea: the phone on your desk would start ringing and through the magic of TAPI our app would be presented with the telephone number of the dialer. It would then look up that telephone number in the appropriate CRM application and pop the callers details on the screen. You'd pick up the phone and bellow "why hello Mr Jones!" and either impress the caller with your incredible fore-knowledge of who had rung you or perhaps terrify them with our Brave New Orwellian World.

My job was to work out how to call into the APIs of the various CRM applications / databases being used and extract the relevant information. So it goes without saying that I have spent a lot of time with badly documented APIs. Or in fact undocumented APIs. I know pain my friend...

Hours and days were spent debugging and walking APIs just to find out what they could do and what information they exposed. This, I need hardly say, was dull and tedious work. Having spent longer than I care to remember with no more information on an API than method names has left its mark on me. I am consequently keener than your average dev on documentation and intellisense. When you've stared at the coalface of the Lotus Notes API for 2 weeks with only Dephi 3 as your constant companion you'd feel the same way too. (This was before the days of Google and actually being able to find stuff on the internet.)

If you can convey information about the API that you're building then I'd say you're duty-bound to do so. Or at least that it's good manners.

Definitely Intellisensed#

When I started getting involved with the Definitely Typed project my focus was on giving good Intellisense. Where there was documentation for an API I wanted to get that popping in front of users when they hit the "." key:

As the above screenshot demonstrates TypeScript supports Intellisense through a slightly tweaked implementation of JSDoc:

With 0.8.2, the TypeScript compiler and tools now support JSDoc comments.

In the TypeScript implementation, because types are already part of the system, we allow the JSDoc type annotation to be elided, as in the example above.

You can now document a variety of language constructs (including classes, modules, interfaces, and functions) with comments that become part of the information displayed to the user. We’ve also started extending lib.d.ts, the default JS and DOM API library, with JSDoc comments.

Partly as an exercise in getting better acquainted with TypeScript and partly responding to my instinctive need to have nicely documented APIs I decided to start adding JSDoc comments to the world's most popular typings file <a href="https://github.com/borisyankov/DefinitelyTyped/blob/master/jquery/jquery.d.ts">jquery.d.ts</a>.

Why jquery.d.ts?

Well a number of reasons:

  1. I used jquery.d.ts already myself and I'm a firm believer in eating your own dogfood
  2. jQuery is well documented. I needed a source of information to power my JSDoc and api.jquery.com had my back.
  3. jquery.d.ts was widely used. Given how ubiquitous jQuery has become this typing file was unsurprisingly the most popular in the world. That was key for me as I wanted feedback - if I was making a mess of the typings I wanted someone to pitch in and tell me.

Just to digress once more, points #2 and #3 turned out to be of particular note.

Concerning point #2, I did find the occasional error or inconsistency in the jQuery API documentation. These were definitely the exception rather than the rule though. And thanks to the very helpful Dave Methvin these actually lead to minor improvements to the jQuery API documentation.

Concerning point #3 I did indeed get feedback. As well as enriching jquery.d.ts with JSDoc goodness I also found myself fixing slight errors in the typings. Here and there I would find examples where jquery.d.ts was out of line the with API documentation. Where this was the case I would amend the typings to bring them into line - trying to make jquery.d.ts entirely API-compliant. This was not always popular. But despite the heat it generated I think it ended up leading to a better typing file. I'm again grateful for Dave Methvin's thoughtful contributions.

Turning API documentation into JSDoc#

I wanted to take an example of API documentation and demonstrate how that can be applied to a typing file with particular focus on how JSDoc comments can be created to drive Intellisense. So let's take everyone's favourite jQuery method: val. The documentation of val can be found here: api.jquery.com/val

By the way, check out the *entirely* intuitive URL. Now you've clocked just how straightforward that is you've probably a fair idea how you could find pretty much any jQuery documentation you might need without recourse to Google. Brilliant!

Let's take a look at what val looked like before JSDoc in the first version of the typing available on GitHub. (By the way, remember the original jquery.d.ts came out of the TypeScript team):

val(): any;
val(value: string[]): JQuery;
val(value: string): JQuery;
val(value: number): JQuery;
val(func: (index: any, value: any) => any): JQuery;

And now let's look at jquery.d.tsafter JSDoc:

/**
* Get the current value of the first element in the set of matched elements.
*/
val(): any;
/**
* Set the value of each element in the set of matched elements.
*
* @param value A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked.
*/
val(value: string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param value A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked.
*/
val(value: string[]): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string) => string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string[]) => string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: number) => string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string) => string[]): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string[]) => string[]): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: number) => string[]): JQuery;

Many changes yes? Let's break it down a little.

1. You have 20 seconds to comply (with the API)#

The first thing to note is the number setter method:

val(value: number): JQuery;

Let's have a look at the jQuery documentation for the simple setter:

.val( value )#

value
Type: String or Array
A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked.

See the problem? There is *no* number setter. The typings are wrong. So let's remedy this:

<strike>val(value: number): JQuery;</strike>

2. String and Array of String setters#

The documentation states that we have setters which accept String and Array of String. These are already modeled in the existing typings by the string and string[] overloads:

val(value: string[]): JQuery;
val(value: string): JQuery;

So let's enrich these typings with some JSDoc:

/**
* Set the value of each element in the set of matched elements.
*
* @param value A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked.
*/
val(value: string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param value A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked.
*/
val(value: string[]): JQuery;

If you look you can see we've added a related JSDoc style comment block prior to each overload. The first part of the comment ("Set the value of...") is the overarching Intellisense that is displayed. Each of the @param statements represents each of the parameters and it's associated comment. By comparing the API documentation to the JSDoc it's pretty clear how the API has been transformed into useful JSDoc.

It's worth noting that I could have taken the choice to customise the @param value comments based on the overload I was JSDoc-ing. Arguably it would have been more useful to have something like this instead:

/**
* Set the value of each element in the set of matched elements.
*
* @param value A string of text <strike>or an array of strings</strike> corresponding to the value of each matched element to set as selected/checked.
*/
val(value: string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param value <strike>A string of text or</strike> an array of strings corresponding to the value of each matched element to set as selected/checked.
*/
val(value: string[]): JQuery;

After some pondering I decided not to take this approach, just to maintain that close relationship between jquery.d.ts and api.jquery.com. It's open to debate how useful that relationship actually is so I thought I'd just highlight this as a choice I made.

3. Getter#

The jQuery documentation for the getter looks like this:

[

.val()

](http://api.jquery.com/val/#val)Returns: String or Number or Array

Description: Get the current value of the first element in the set of matched elements.

So the val() overload can return a string, a number or a string[]. Unfortunately there is no real way to model that in TypeScript at present due to the absence of "union types". Union types are being discussed at present but in TypeScript v1.0 world the only viable approach is returning the any type. This implies val() returns any possible JavaScript value from boolean to Function and straight on 'til morning. So clearly this isn't accurate but importantly it also allows for the possibility of val() returning string, number or string[].

The final getter typing with JSDoc applied ends up looking like this:

/**
* Get the current value of the first element in the set of matched elements.
*/
val(): any;

As you can see the "Get the current value..." from the API docs has been used as the overarching Intellisense that is displayed for the getter.

4. The Function setter#

Finally we're going to take a look at the Function setter which is documented as follows:

[#

.val( function(index, value) )](http://api.jquery.com/val/#val-functionindex--value)

function(index, value)
Type: Function()
A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.

If you cast your eyes back to the original typings for the Function setter you'll see they look like this:

val(func: (index: any, value: any) => any): JQuery;

This is a good start but it's less accurate than it could be in a number of ways:

  1. index is a number - we needn't keep it as an any
  2. value is the old value - we know from our getter that this can be a string, number or string[]. So we can lose the any in favour of overloads which specify different types for value in each.
  3. The return value of the function is the value that should be set. We know from our other setters that the possible types allowed here are string and string[]. (And yes I'm as puzzled as you are that the getter can return a number but the setter can't set one.) That being the case it makes sense for us to have overloads with functions that return both string and string[]

So, we've got a little tidy up to do for #1 and extra overloads to add for #2 and #3. We're going to replace the single Function setter with 3 overloads to cater for #2. Then for #3 we're going to take each of the 3 overloads we've just created and make 2 overloads place of each to handle the different return types. This will lead us with the grand total of 6 overloads to model our Function setter!

/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string) => string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string[]) => string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: number) => string): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string) => string[]): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: string[]) => string[]): JQuery;
/**
* Set the value of each element in the set of matched elements.
*
* @param func A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.
*/
val(func: (index: number, value: number) => string[]): JQuery;

A cursory glance shows that each of the overloads above shares the same JSDoc. Each has the "Set the value..." from the API docs as the overarching Intellisense that is displayed for the Function setter. And each has the same @param func comment as well.

It could be you...#

This post is much longer than I ever intended it to be. But I wanted to show how easy it is to create typings with JSDoc to drive Intellisense. For no obvious reason people generally don't make a great deal of use of JSDoc when creating typings. Perhaps the creators have no good source of documentation (a common problem). Or perhaps people are not even aware it's a possibility - they don't know about the TypeScript support of JSDoc. In case it's the latter I think this post was worth writing.

NuGet and WebMatrix: How to install a specific version of a package

I've recently been experimenting with WebMatrix. If you haven't heard of it, WebMatrix is Microsoft's "free, lightweight, cloud-connected web development tool". All marketing aside, it's pretty cool. You can whip up a site in next to no time, it has source control, publishing abilities, intellisense. Much good stuff. And one thing it has, that I genuinely hadn't expected is NuGet. Brilliant!

But like any free product there are disadvantages. As a long time Visual Studio user I've become very used to the power of the NuGet command line. I've been spoiled. You don't have this in WebMatrix. You have a nice UI that looks like this:

Looks great right? However, if you want to install a specific version of a NuGet package... well let's see what happens...

As you're probably aware jQuery currently exists in 2 branches; the 1.10.x branch which supports IE 6-8 and the 2.0.x branch which doesn't. However there is only 1 jQuery inside NuGet. Let's click on install and see if we can select a specific version:

Hmmm.... As you can see it's 2.0.3 or bust. We can't select a specific version; we're forced to go with the latest and greatest which is a problem if you need to support IE 6-8. So the obvious strategy if you're in this particular camp is to forego NuGet entirely. Go old school. And we could. But let's say we want to keep using NuGet, mindful that a little while down the road we'll be ready to do that upgrade. Can it be done? Let's find out.

NuGet, by hook or by crook#

I've created a new site in WebMatrix using the Empty Site template. Looks like this:

Lovely.

Now to get me some jQuery 1.10.2 goodness. To the console Batman! We've already got the NuGet command line installed (if you haven't you could get it from here) and so we follow these steps:

  • At the C:\ prompt we enter nuget install jQuery -Version 1.10.2 and down comes jQuery 1.10.2.
  • We move C:\jQuery.1.10.2 to C:\Users\me\Documents\My Web Sites\Empty Site\App_Data\packages\jQuery.1.10.2.
  • Then we delete the C:\Users\me\Documents\My Web Sites\Empty Site\App_Data\packages\jQuery.1.10.2\Tools subfolder.
  • We move C:\Users\me\Documents\My Web Sites\Empty Site\App_Data\packages\jQuery.1.10.2\Content\Scripts to C:\Users\me\Documents\My Web Sites\Empty Site\Scripts.
  • And finally we delete the C:\Users\me\Documents\My Web Sites\Empty Site\App_Data\packages\jQuery.1.10.2\Content folder.

We hit refresh back in WebMatrix and now we get this:

If we go to NuGet and select updates you'll see that jQuery is now considered "installed" and an update is available. So, in short, our plan worked - yay!

Now for bonus points#

Just to prove that you can upgrade using the WebMatrix tooling following our manual install let's do it. Click "Update", then "Yes" and finally "I Accept" to the EULA. You'll now see we're now on jQuery 2.0.3:

Rounding off#

In my example I'm only looking at a simple JavaScript library. But the same principal should be able to be applied to any NuGet package as far as I'm aware. Hope that helps!

jQuery Unobtrusive Remote Validation

Just recently I have been particularly needing to make use of remote / server-side validation in my ASP.NET MVC application and found that the unobtrusive way of using this seemed to be rather inadequately documented (of course it's possible that it's well documented and I just didn't find the resources). Anyway I've rambled on much longer than I intended to in this post so here's the TL;DR:

  • You *can* use remote validation driven by unobtrusive data attributes
  • Using remote validation you can supply *multiple* parameters to be evaluated
  • It is possible to block validation and force it to be re-evaluted - although using a slightly hacky method which I document here. For what it's worth I acknowledge up front that this is *not* an ideal solution but it does seem to work. I really hope there is a better solution out there and if anyone knows about it then please get in contact and let me know.

Off we go... So, jQuery unobtrusive validation; clearly the new cool right?

I'd never been particularly happy with the validation that I had traditionally been using with ASP.NET classic. It worked... but it always seemed a little... clunky? I realise that's not the most well expressed concern. For basic scenarios it seemed fine, but I have recollections of going through some pain as soon as I stepped outside of the basic form validation. Certainly when it came to validating custom controls that we had developed it never seemed entirely straightforward to get validation to play nice.

Based on this I was keen to try something new and the opportunity presented itself when we started integrating MVC into our classic WebForms app. (By the way if you didn't know that MVC and ASP.NET could live together in perfect harmony, well, they can! And a good explanation on how to achieve it is offered by Colin Farr here.)

Jörn Zaefferer came out with the jQuery validation plug-in way back in 2006. And mighty fine it is too. Microsoft (gor' bless 'em) really brought something new to the jQuery validation party when they came out with their unobtrusive javascript validation library along with MVC 3. What this library does, in short, is allows for jQuery validation to be driven by data-val-* attributes alone as long as the jquery.validate.js and jquery.validate.unobtrusive.js libraries are included in the screen (I have assumed you are already including jQuery). I know; powerful stuff!

A good explanation of unobtrusive validation is given by Brad Wilson here.

Anyway, to my point: what about remote validation? That is to say, what about validation which needs to go back to the server to perform the necessary tests? Well I struggled to find decent examples of how to use this. Those that I did find seemed to universally be php examples; not so useful for an ASP.NET user. Also, when I did root out an ASP.NET example there seemed to be a fundamental flaw. Namely, if remote validation hadn't been triggered and completed successfully then the submit could fire anyway. This seems to be down to the asynchronous nature of the test; ie because it is *not* synchronous there is no "block" to the submit. And out of the box with unobtrusive validation there seems no way to make this synchronous. I could of course wire this up manually and simply side-step the restrictions of unobtrusive validation but that wasn't what I wanted.

***Your mission John, should you decide to accept it, is this: block the submit until remote validation has completed successfully

. As always, should you or any of your I.M. Force be caught or killed, the Secretary will disavow any knowledge of your actions.***

So that's what I wanted to do. Make it act like it's synchronous even though it's asynchronous. Bit horrible but I had a deadline to meet and so this is my pragmatic solution. There may be better alternatives but this worked for me.

First of all the HTML:

<form action="/Dummy/ValidationDemo.mvc/SaveUser"
id="ValidationForm" method="post">
First name:
<input data-val="true" data-val-required="First Name required"
id="FirstName" name="FirstName" type="text" value="" />
Last name:
<input data-val="true" data-val-required="Last Name required"
id="LastName" name="LastName" type="text" value="" />
User name:
<input id="UserName" name="UserName" type="text" value=""
data-val="true"
data-val-required="You must enter a user name before we can validate it remotely"
data-val-remote="&amp;#39;UserNameInput&amp;#39; is invalid."
data-val-remote-additionalfields="*.FirstName,*.LastName"
data-val-remote-url="/Dummy/ValidationDemo/IsUserNameValid" />
<input id="SaveMyDataButton" name="SaveMyDataButton"
type="button" value="Click to Save" />
</form>

I should mention that on my actual page (a cshtml partial view) the HTML for the inputs is generated by the use of the InputExtensions.TextBoxFor method which is lovely. It takes your model and using the validation attributes that decorate your models properties it generates the relevant jQuery unobtrusive validation data attributes so you don't have to do it manually.

But for the purposes of seeing what's "under the bonnet" I thought it would be more useful to post the raw HTML so it's entirely clear what is being used. Also there doesn't appear to be a good way (that I've yet seen) for automatically generating Remote validation data attributes in the way that I've found works. So I'm manually specifying the data-val-remote-* attributes using the htmlAttributes parameter of the TextBoxFor (using "_" to replace "-" obviously).

Next the JavaScript that performs the validation:

$(document).ready(function () {
var intervalId = null,
//
// DECLARE FUNCTION EXPRESSIONS
//
//======================================================
// function that triggers update when remote validation
// completes successfully
//======================================================
pendingValidationComplete = function () {
var i, errorList, errorListForUsers;
var $ValidationForm = $("#ValidationForm");
if ($ValidationForm.data("validator").pendingRequest === 0) {
clearInterval(intervalId);
//Force validation to present to user
//(this will *not* retrigger remote validation)
if ($ValidationForm.valid()) {
alert("Validation has succeeded - you can now submit");
}
else {
//Validation failed!
errorList = $ValidationForm.data("validator").errorList;
errorListForUsers = [];
for (i = 0; i < errorList.length; i++) {
errorListForUsers.push(errorList[i].message);
}
alert(errorListForUsers.join("\r\n"));
}
}
},
//======================================================
// Trigger validation
//======================================================
triggerValidation = function (evt) {
//Removed cached values where remote is concerned
// so remote validation is retriggered
$("#UserName").removeData("previousValue");
//Trigger validation
$("#ValidationForm").valid();
//Setup interval which will evaluate validation
//(this approach because of remote validation)
intervalId = setInterval(pendingValidationComplete, 50);
};
//
//ASSIGN EVENT HANDLERS
//
$("#SaveMyDataButton").click(triggerValidation);
});

And finally the Controller:

public JsonResult IsUserNameValid(string UserName,
string FirstName,
string LastName)
{
var userNameIsUnique = IsUserNameUnique(UserName);
if (userNameIsUnique)
return Json(true, JsonRequestBehavior.AllowGet);
else
return Json(string.Format(
"{0} is already taken I'm afraid {1} {2}",
UserName, FirstName, LastName),
JsonRequestBehavior.AllowGet);
}
private bool IsUserNameUnique(string potentialUserName)
{
return false;
}

So what happens here exactly? Well it's like this:

  1. The user enters their first name, last name and desired user name and hits the "Click to Save" button.
  2. This forces validation by first removing any cached validation values stored in previousValue data attribute and then triggering the valid method. Disclaimer: I KNOW THIS IS A LITTLE HACKY. I would have expected there would be some way in the API to manually re-force validation. Unless I've missed something there doesn't appear to be. (And the good citizens of Stack Overflow would seem to concur.) I would guess that the underlying assumption is that if nothing has changed on the client then that's all that matters. Clearly that's invalid for our remote example given that a username could be "claimed" at any time; eg in between people first entering their username (when validation should have fired automatically) and actually submitting the form. Anyway - this approach seems to get us round the problem.
  3. When validation takes place the IsUserNameValid action / method on our controller will be called. It's important to note that I have set up a method that takes 3 inputs; UserName, which is supplied by default as the UserName input is the one which is decorated with remote validation attributes as well as the 2 extra inputs of FirstName and LastName. In the example I've given I don't actually need these extra attributes. I'm doing this because I know that I have situations in remote validation where I *need* to supply multiple inputs and so essentially I did it here as a proof of concept. The addition of these 2 extra inputs was achieved through the use of the data-val-remote-additionalfields attribute. When searching for documentation about this I found absolutely none

. I assume there is some out there - if anyone knows then I'd very pleased to learn about it. I only learned about it in the end by finding an example of someone using this out in the great wide world and understanding how to use it based on their example. To understand how the data-val-remote-additionalfields attribute works you can look at jquery.validate.unobtrusive.js. If you're just looking to get up and running then I found that the following works: data-val-remote-additionalfields="*.FirstName,*.LastName" You will notice that: - Each parameter is supplied in the format *.[InputName] and inputs are delimited by ","'s - Name is a required

attribute for an input if you wish it to be evaluated with unobtrusive validation. (Completely obvious statement I realise; I'm writing that sentence more for my benefit than yours) - Finally, our validation always fails. That's deliberate - I just wanted to be clear on the approach used to get remote unobtrusive validation with extra parameters up and running. 4. Using setInterval we intend to trigger the pendingValidationComplete function to check if remote validation has completed every 50ms - again I try to avoid setInterval wherever possible but this seems to be the most sensible solution in this case. 5. When the remote request finally completes (ie when pendingRequest has a value of 0) then we can safely proceed on the basis of our validation results. In the example above I'm simply alerting to the screen based on my results; this is *not* advised for any finished work; I'm just using this mechanism here to demonstrate the principle.

Validation in action:

Well I've gone on for far too long but I am happy to have an approach that does what I need. It does feel like a slightly hacky solution and I expect that there is a better approach for this that I'm not aware of. As much as anything else I've written this post in the hope that someone who knows this better approach will set me straight. In summary, this works. But if you're aware of a better solution then please do get in contact - I'd love to know!

PS:Just in case you're in the process of initially getting up and running with unobtrusive validation I've listed below a couple of general helpful bits of config etc:

The following setting is essential for Application_Start in Global.asax.cs:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

The following settings should be used in your Web.Config:

<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true "/>
</appSettings>

My example used the following scripts:

<script src="Scripts/jquery-1.7.1.js"></script>
<script src="Scripts/jquery.validate.js"></script>
<script src="Scripts/jquery.validate.unobtrusive.js"></script>
<script src="Scripts/ValidationDemo.js"></script>

A Potted History of using Ajax (on the Microsoft Stack of Love)

This post originally started out as an explanation of JSON. However as I wrote this quickly got abandoned in favour of writing about how I came to use JSON in the first place - which was through the use of Ajax. Having written a goodly amount I've now decided to move the actual JSON stuff into another post since I think Ajax is probably worth thinking about by itself rather than as an aside. So let me start at the beginning and explain how I came to use Ajax in the first place (this may take some time so please bear with me). In late 2004 I first started working on a project which I was to remain involved with (on and off) for a very long time indeed. The project was part financial reporting system and part sales incentivisation tool; it was used internally in the investment bank in which I was working. The project had been in existence for a number of years and had a web front end which at that point would been built in a combination of HTML, JavaScript, classic ASP and with a Visual Basic 6.0 back end. One of the reasons I had been brought on to the project was to help ".Net-ify" the thing and migrate it to ASP.NET and C#. I digress. The interesting thing about this app was that there were actually some quite advanced things being done with it (despite the classic ASP / VB). The users could enter trades into the system which represented actual trades that had been entered into a trading system elsewhere in the organisation. These trades would be assigned a reporting value which would be based on their various attributes. (Stay with me people this will get more interesting I *promise*.) The calculation of the reporting value was quite an in depth process and needed to be performed server-side. However, the users had decreed that it wasn't acceptable to do a full postback to the server to perform this calculation; they wanted it done "on-the-fly". Now if you asked me at the time I'd have said "can't be done". Fortunately the other people working on the project then weren't nearly so defeatist. Instead they went away and found Microsoft's webservice.htc library. For those of you that don't know this was a JavaScript library that Microsoft came up with to enable the access of Web Services on the client. Given that it was designed to work with IE 5 I suspect it was created between 1999-2001 (but I'm not certain about that). Now it came as a revelation to me but this was a JavaScript library that talked to our web services through the medium of XML. In short it was my first encounter with anything remotely Ajax-y. It was exciting! However, the possibilities of what we could do didn't actually become apparent to me for some years. It's worth saying that the way we were using webservice.htc was exceedingly simplistic and rather than investigating further I took the limited ways we were using it as indications of the limitations of Ajax and / or webservice.htc. So for a long time I thought the following: - The only way to pass multiple arguments to a web service was to package up arguments into a single string with delimiters which you could split and unpackage as your first step on the server.

  • The only valid return type was a single string. And so if you wanted to return a number of numeric values (as we did) the only way to do this was to package up return values into a very long string with delimiters in and (you guessed it!) split and unpackage as your first step on the client.
  • The only thing that you could (or would want to) send back and forth between client and server was XML

So to recap, I'm now aware that it's possible for JavaScript to interact with the server through the use of web services. It's possible, but ugly, not that quick and requires an awful lot of manual serialization / deserialization operations. It's clearly powerful but not much fun at all. And that's where I left it for a number of years. Let's fade to black... It's now 2007 and Microsoft have released ASP.NET Ajax, the details of which are well explained in this article (which I have only recently discovered). Now I'm always interested in "the new" and so I was naturally interested in this. Just to be completely upfront about this I should confess that when I first discovered ASP.NET Ajax I didn't clock the power of it at all. Initially I just switched over from using webservice.htc to ASP.NET Ajax. This alone gave us a *massive* performance improvement (I know it was massive since we actually received a "well done" email from our users which is testament to the difference it was making to their experience of the system). But we were still performing our manual serialisation / deserialisation of values on the client and the server. ie. Using Ajax was now much faster but still not too much fun. Let's jump forward in time again to around 2010 to the point in time when I was discovering jQuery and that JavaScript wasn't actually evil. It's not unusual for me to play around with "what if" scenarios in my code, just to see what might might be possible. Sometimes I discover things. So it was with JSON. We had a web service in the system that allowed us to look up a counterparty (ie a bank account) with an identifier. Once we looked it up we packaged up the counterparty details (eg name, location etc) into a big long string with delimiters and sent it back to client. One day I decided to change the return type on the web service from a string to the actual counterparty class. So we went from something like this: ```cs [WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class CounterpartyWebService : System.Web.Services.WebService { [WebMethod] public string GetCounterparty(string parameters) { string[] aParameters = parameters.Split("|"); int counterpartyId = int.Parse(aParameters[0]); bool includeLocation = (aParameters[1] == "1"); Counterparty counterparty = _counterpartyDb .GetCounterparty(counterpartyId);

string returnValue = counterparty.Id +
"|" + counterparty.Name +
(includeLocation
? "|" + counterparty.Location
: "");
return returnValue;

} }

To something like this: ```cs
[WebMethod]
public Counterparty GetCounterparty(string parameters)
{
string[] aParameters = parameters.Split("|");
int counterpartyId = int.Parse(aParameters[0]);
bool includeLocation = (aParameters[1] == "1");
Counterparty counterparty = _counterpartyDb
.GetCounterparty(counterpartyId);
return counterparty;
}

I genuinely expected that this was just going to break. It didn't. Suddenly on the client I'm sat there with a full blown object that looks just like the object I had on the server. WHAT BLACK MAGIC COULD THIS BE?????????? Certain that I'd discovered witchcraft I decided to try something else. What would happen if I changed the signature on the method so it received individual parameters and passed my individual parameters to the web service instead of packaging them up into a string? I tried this: ```cs [WebMethod] public Counterparty GetCounterparty(int counterpartyId, bool includeLocation) { Counterparty counterparty = _counterpartyDb .GetCounterparty(counterpartyId);

return counterparty; }

And it worked! **[IT WORKED!!!!!!!!!!!!!!!!!!!!!](<http://www.youtube.com/watch?v=N_dWpCy8rdc&feature=related>)** (And yes I know I wasn't actually using the includeLocation parameter - but the point was it was being passed to the server and I could have used it if I'd wanted to.) I couldn't believe it. For **years** I'd been using Ajax and without **any** idea of the power available to me. The ignorance! The stupidity of the man! To my complete surprise it turned out that: - Ajax could be quick! ASP.NET Ajax was lightening fast when compared to webservice.htc
- You could send multiple arguments to a web service without all that packaging nonsense
- You could return complex objects without the need for packaging it all up yourself.
<!-- -->
Essentially the source of all this goodness was the magic of JSON. I wouldn't really come to comprehend this until I moved away from using the ASP.NET Ajax client libraries in favour of using the [jQuery.ajax](<http://api.jquery.com/jQuery.ajax/>) functionality. (Yes, having mostly rattled on about using webservice.htc and ASP.NET Ajax I should clarify that I have now forsaken both for jQuery as I find it more powerful and more configurable - but it's the journey that counts I guess!) It's abysmal that I didn't discover the power of Ajax sooner but the difference this discovery made to me was immense. Approaches that I would have dismissed or shied away from previously because of the amount of "plumbing" involved now became easy. This massively contributed to my [programmer joy](<http://www.hanselman.com/blog/HanselminutesPodcast260NETAPIDesignThatOptimizesForProgrammerJoyWithJonathanCarter.aspx>)! Next time I promise I'll aim to actually get onto JSON.

What on earth is jQuery? And why should I care?

What on earth is jQuery? What's a jQuery plugin?

These were the questions I was asking myself shortly after discovering that jqGrid was a "jQuery plugin". I'd been vaguely aware of the phrase "jQuery" being increasingly mentioned on various techical websites since about 2009. But for some reason I'd felt no urge to find out what it was. I seem to remember that I read the name "jQuery" and jumped to the perfectly logical (in my head) conclusion that this must be a Java SQL engine of some sort. (After all "j" as a prefix to anything so far had generally been Java and "Query" just rang of databases to me.) Clearly I was wrong - life's full of surprises.

I soon discovered that, contrary to expectations, jQuery had nothing to do with Java *and* nothing to do with databases either. It was in fact a JavaScript library written by the amazing John Resig. At the time I had no love for JavaScript. I now realise I knew nearly nothing about it but my feeling was that JavaScript was awful - evil even. However, given JavaScripts ubiquity in the world of web it seemed to be a necessary evil.

I took a look at the jQuery website and after reading round a bit I noticed that it could be used for Ajax operations. This lead to me reaching the (incorrect) conclusion that jQuery was basically an alternative to the Microsoft Ajax library which we were already using to call various Web Services. But I remained frankly suspicious of jQuery. What was the point of this library? Why did it exist?

I read the the blog by Scott Gu announcing Microsoft was going to start shipping jQuery with Visual Studio. The Great Gu trusted it. Therefore, I figured, it must be okay... Right?

The thing was, I was quite happy with the Microsoft Ajax library. I was familiar with it. It worked. Why switch? I saw the various operations Scott Gu was doing to divs on the screen using jQuery. I didn't want to do anything like that at all. As I said; I had no love for JavaScript - I viewed it as C#'s simple-minded idiot cousin. My unofficial motto when doing web stuff was "wherever possible, do it on the server".

I think I would have ignored jQuery entirely but for the fact of jqGrid. If I wanted to use jqGrid I had to use jQuery as well. In the end I decided I'd allow it house room just for the sake of jqGrid and I'd just ignore it apart from that. And that's how it was for a while.

Then I had an epiphany. Okay - that's overplaying it. What actually happened was I realised that something we were doing elsewhere could be done faster and easier with jQuery. It's something so ridiculously feeble that I feel vaguely embarrassed sharing it. Anyway.

So, you know the css hover behaviour is only implemented for anchor tags in IE6? No? Well read this Stack Overflow entry - it'll clarify. Well, the app that I was working on was an internal web application only used by people with the corporate installation of IE 6 on their desktops. And it was "terribly important" that buttons had hover behaviour. For reasons that now escape me we were doing this by manually adding inline onmouseover / onmouseout event handlers to each input button on the screen in turn in every page in the Page_Load event server side. I think we were aware it wasn't fantastic to have to wire up each button in turn. But it worked and as with so many development situations we had other pressures, other requirements to fulfil and other fish to fry - so we left it at that.

And then it occurred to me... What about using the jQuery class selector in conjunction with the jQuery hover event? I could have one method that I called on a page which would wire up all of my hover behaviours in one fell swoop. I wouldn't need to do input-by-input wireups anymore! Hallelujah! This is what I did:

The buttons I would like to style:

<input type="button" value="I am a button" class="itIsAButton" />
<input type="button" value="So am I" class="itIsAButton" />
<input type="button" value="Me too" class="itIsAButton" />

My CSS (filter, by the way, is just linear gradients in IE 6-9):

.itIsAButton
{
filter:progid:DXImageTransform.Microsoft.Gradient (GradientType=0,StartColorStr='#ededed',EndColorStr='#cdcdcd');
}
.itIsAButton:hover, .itIsAButton_hover /* "_hover" is for IE6 */
{
filter:progid:DXImageTransform.Microsoft.Gradient (GradientType=0,StartColorStr='#f6f6f6',EndColorStr='#efefef');
}

My jQuery:

$(document).ready(function () {
//Add hover behaviour on picker buttons for IE6
if (($.browser.msie) &&
(parseInt($.browser.version, 10) < 7)) {
var fnButtonHover = function (handlerInOut) {
var $btn = $(this);
var sOriginalClass = $btn.prop("class");
if (handlerInOut.type === "mouseenter") {
//If not already hovering class then apply it
if (sOriginalClass.indexOf("_hover") === -1) {
$btn.prop("class", sOriginalClass + "_hover");
}
}
else if (handlerInOut.type === "mouseleave") {
//If not already non-hovering class then apply it
if (sOriginalClass.indexOf("_hover") !== -1) {
$btn.prop("class", sOriginalClass.split("_")[0]);
}
}
};
$(".itIsAButton").hover(fnButtonHover);
}
});

And it worked. I didn't really understand this much about this jQuery "thing" at that point but I could now see that it clearly had at least one use. I've come to appreciate that jQuery is one of the best pieces of software I've ever encountered. Over time I may go further into some of the good stuff of jQuery. It is, quite simply, brilliant.

jqGrid - it's just a far better grid

The year was 2010 (not really that long ago I know) and the project that I was working on was sorely in need of a new grid component. It was an ASP.NET WebForms project and for some time we'd been using what was essentially a glorified datagrid which had a few extra features implemented to allow us to change column order / columns displayed / copy contents to clipboard etc. Our grid worked perfectly fine - it gave us the functionality we needed. However, it looked pretty terrible, and had some "quirky" approaches in place for supporting IE and Firefox side by side. Also, at the time we were attempting to make our app seem new and exciting again for the users. The surprising truth is that users seem to be more impressed with a visual revamp than with new or amended functionality. So I was looking for something which would make them sit up and say "oooh - isn't it pretty!". Unfortunately the nature of the organisation I was working for was not one that lended itself to paying for components. They were occasionally willing to do that but the hoops that would have to be jumped through first, the forms that would need to be signed in triplicate by people that had nearly nothing to do with the project made that an unattractive prospect. So I began my search initially looking at the various open source offerings that were around. As a minimum I was looking for something that would do what our home-grown component did already (change column order / columns displayed / copy contents to clipboard etc) but hopefully in a "nicer" way. Also, I had long been unhappy with the fact that to get our current grid to render results we did a *full postback* to the server and re-rendered the whole page. Pointless! Why should you need to do all this each time when you only wanted to refresh the data? Instead I was thinking about using an Ajax approach; a grid that could just get the data that it needed and render it to the client. This seemed to me a vastly "cleaner" solution - why update a whole screen when you only want to update a small part of it? Why not save yourself the trouble of having to ensure that all other screen controls are persisted just as you'd like them after the postback? I also thought it was probably something that would scale better as it would massively reduce the amount of data moving backwards and forwards between client and server. No need for a full page life cycle on the server each time the grid refreshes. Just simple data travelling down the pipes of web. With the above criteria in mind I set out on my Google quest for a grid. Quite soon I found that there was a component out there which seemed to do all that I wanted and far more besides. It was called jqGrid:

Oooh look at the goodness! It had both column re-ordering and column choosing built in!: This was a *very promising sign*! Now it's time for me to demonstrate my ignorance. According to the website this grid component was a "jQuery plugin". At the time I read this I had no idea what jQuery was at all - let alone what a plugin for it was. Anyway, I don't want to get diverted so let's just say that reading this lead to me getting an urgent education about some of the client side aspects of the modern web that I had been previously unaware of. I digress. This component did exactly what I wanted in terms of just sending data down the pipe. jqGrid worked with a whole number of possible data sources; XML, Array but the most exciting for me was obviously JSON. Take a look a the grid rendered below and the JSON that powered it (all from a simple GET request):

As you can see from the above screenshot, the grid has populated itself using the results of a web request. The only information that has gone to the server are the relevant criteria to drive the search results. The only information that has come back from the server is the data needed to drive the grid. Simple. Beautiful. I loved it and I wanted to use it. So I did! I had to take a few steps that most people thinking about using a grid component probably wont need to. First of all I had to write an ASP.Net WebForms wrapper for jqGrid which could be implemented in a similar way to our current custom datagrid. This was because, until the users were convinced that the new grid was better than the old both had to co-exist in the project and the user would have the option to switch between the two. This WebForms wrapper plugged into our old school XML column definition files and translated them into JSON for the grid. It also took datasets (which drove our old grid) and translated them into jqGrid-friendly JSON. I wanted to power the jqGrid using WebMethods on ASPX's. After a little digging I found Dave Ward of Encosia's post which made it very simple (and in line with this I switched over from GET requests to POSTs). Finally I wrote some custom javascript which added a button to jqGrid which, if clicked, would copy the contents of the jqGrid to the clipboard (this was the only bit of functionality that didn't appear to be implemented out of the box with jqGrid). I think I'm going to leave it there for now but I just wanted to say that I think jqGrid is a fantastic component and it's certainly made my life better! It's: - well supported, there is lots on StackOverflow and the like about it

I think Tony Tomov (the man behind jqGrid) has come up with something truly brilliant. It's worth saying that the equally brilliant jQueryUI team are in the process of writing an official jQuery UI grid component which uses jqGrid as one of its inspirations. However, this is still a long way from even a "zero feature" release. In the meantime jqGrid is continuing to go from strength to strength and as such I heartily recommend it. Finally, you can take a look at jqGrid's source on GitHub.