Tigraine

Daniel Hoelbling-Inzko talks about programming

jQuery.validate and multiple forms on one page

I like generic, convention based approaches to infrastructure so in most of my projects you'll find something like this in the main javascript file:

$('form').validate();
There is only one slight problem: jQuery validate doesn't work like most jQuery plugins and won't operate on the matched set, but rather only on the first element.

So if you want to validate multiple forms you have to call each form individually through each

$('form').each(function () {
    $(this).validate();
});

jQuery.validate and Microsofts unobtrusive validation don't play well together

I was banging my head against the wall for more than three hours, reading jQuery.validate's code, trying to figure out why my supplied errorPlacement or highlight callbacks where not called.

The code in question looked perfectly fine and came pretty much straight out of the docs:

$('form').validate({
    debug: true,
    errorPlacement: function () {
        console.log("errorPlacement", this, arguments);
    },
    highlight: function () {
        console.log("highlight", this, arguments);
    },
    success: function () {
        console.log("success", this, arguments);
    }
});

As you can see I was still stuck in the "let's see what we can do from these callbacks" phase of implementing my own automatic validation scheme for a project. Guess what the above did? Nothing! And I mean really nothing. The validation worked as expected with my validation classes, but none of my callbacks got ever called (meanwhile supplied arguments like messages etc worked like a charm).

After 3 hours I finally came onto something when I couldn't find the validation classnames that where put on my elements inside the jQuery.validation code I was looking at. Turns out: Microsoft's jquery.validation.unobtrusive.js cripples jQuery.validation so that most of it's configuration options simply don't work any more. Neither with the $.validate.setDefaults() nor with the $('#element').validate() methods.

Needless to say that I almost broke into tears when my stuff was working fine once I removed the unobtrusive script from the page.

I do like the unobtrusive stuff - it serves it's purpose inside the MS MVC niche. But in this case I was not using unobtrusive on that form at all! So I simply did not expect the library to mess with jQuery.validate in any way as there was no unobtrusive validation stuff going on.

Localized Fullcalendar options

I usually try to avoid using too many jQuery plugins, especially for rather simple stuff like this. But displaying a calendar is pretty tricky (believe me - I wrote one using GDI+) and Fullcalendar has saved me countless hours so far.

One issue that cropped up now is that we needed our Fullcalendar to be localized in German. As with most things I came across so far, Fullcalendar already supports it - but the documentation is a bit cryptic on the issue so here is my localized options hash:

var localOptions = {
	buttonText: {
		today: 'Heute',
		month: 'Monat',
		day: 'Tag',
		week: 'Woche'
	},
	monthNames: ['Jänner','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'],
	monthNamesShort: ['Jän','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sept','Okt','Nov','Dez'],
	dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
	dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa']
}

$('#calendar').fullCalendar($.extend({ ... your options ... }, localOptions));

jQuery: Execute once animation finished

Good JavaScript almost forces you into learning async programming and jQuery animations is no different. Everything in jQuery supports callbacks because the stuff you do is in most cases done on the background while your script continues to run.

But as with most stuff, there are many ways of going about this:

Completed Callbacks

    $('#item').fadeOut('slow', function () {
        console.log('animation finished');
    });

The problem with this approach is that it gets rather tedious to queue stuff together if you want to do say three things in order.

Let's say you want to a fadeOut animation then add a cssClass, start another animation and once that one is finished remove the cssClass again. Using callbacks this looks rather ugly:

    $('#item').fadeOut('slow', function () {
        var foo = $('#foo');
        foo.addClass('myclass');
        $('#item2').fadeIn('slow', function () {
          foo.removeClasS('myclass');
        }
    });

As you can see, two nested callbacks is really not that readable and almost confusing.. That's why there is a better way to do this:

The fx Queue

jQuery uses a queue for all it's animations. That's the magic behind this nice syntax:

    $('#item').fadeIn().fadeOut();

If you run this code it will first fade the item in and only once it's completely visible it will start the fadeOut animation.

Problem with this is that it looks nice in it's syntax, but can't be mixed with the regular jQuery methods. Something like

$('#item').fadeIn().removeClass('active').fadeOut();
will not work simply because you removeClass will be executed instantly while fadeIn and fadeOut will be queued for later execution by the effects (fx) queue.

In that case you can hook into the queue yourself by using the .queue() method:

    $('#item').fadeIn().queue(function (next) {
        $(this).removeClass('active');
        next(); //Important to continue running the queue
    }).fadeOut();

Hope this helps!

Filed under javascript, jquery

dotless v1.2.1 released

Remember dotless, the awesome little framework that makes writing CSS a enjoyable and nice experience? Well, it's time to announce a new major/minor version!

Major? Yes - James in all secrecy tagged a v1.2 without me putting out a formal NuGet package. So v1.2 has been available for quite some time but only to the few interested souls that follow us on GitHub and those who got it to compile.

So it's been about time we formally push out v1.2 (and me writing about it). But, as with all software 1.2 had some open issues that got patched by the community and that's why we are calling it 1.2.1 :)

The binaries are now available through NuGet with a simple:

PM> Install-Package dotless

Or you can simply grab the binaries from GitHub . If you care to build the code yourself from source: knock yourself out

Hope you enjoy writing lesscss - I for sure do.

Filed under dotless, projects

Don't commit when you rebase

One common mistake and my team seem to be doing at times with Git is that we routinely commit after resolving a merge conflict during a rebase.

The idea is simple: Instead of doing thousands of merges (thus cluttering the timeline of the project) whenever someone wants to check something into the central repository he fetches the remote changes and applies his local changes onto the remote ones.

Thanks to Visual Studio and it's way of having every source file referenced from the .csproj files (I hate that btw), we routinely get merge conflicts on the project files that need to be manually resolved. During a rebase this means the rebase will stop on the commit that caused the conflict and you have to fix it.

After you are done with fixing the conflict (usually it's just removing the conflict markers Git inserted) you then have to add the now merged file to the index (aka staging area) and hit git rebase --continue. Problem is: Since it's just a special state of a repository you can just as easily do the following:

git add -A git commit

Good job you just put your repository into limbo mode and your merge is gone .. You recorded a commit onto your rebase-HEAD and you can't continue the rebase because the rebase head is no longer where it belongs to.. So once you try to do git rebase --continue git will tell you: "No changes - did you forget to use 'git add'?" And when you run git status you'll see: "Not currently on any branch. nothing to commit"

Your only avenue here is:

git rebase --abort git checkout master git rebase origin/master ... redo the merge git rebase --continue

Filed under programmierung, git

jQuery.Stepy select callback

I just stumbled upon a little issue while using jQuery.Stepy wizard plugin: There are callbacks for navigating, but there is simply no callback that gets fired when the current step is actually displayed. As it happens there are a number of things you may want to do once a wizard  step is shown like start animations or maybe initialize something. (And next/back get fired before validation happens so they don't actually work in case validation fails)

Thank god JavaScript is almost by definition open-source so I fixed this with the following pull request.

The select callback works just like the back/next callbacks:

$('#wizard').stepy({
  select: function (index) {
     //your code goes here
     //index is 1 based - not zero based
  }
});

Filed under programmierung, jquery

My Photography business

Projects

dynamic css for .NET

Archives

more