jQuery datepicker improved

I like jQuery’s datepicker a lot, but I miss two things – one is some kind of mask on the input field so I can write date directly without worrying about the correct date format, and the second is customisable trigger (the thing you click on to toggle the calendar widget 🙂 )

Masked input

This is a screenshot taken directly from jqueryui.com. As you see you can write anything to the input field.  Then you have to validate it, display error message, prevent form from submit… etc. It’s not nice.  Luckily there is a nice solution, a jQuery plugin called maskedinput. (and yes, I use it in durationPicker plugin). I definitely recommend you to use it, it’s very handy, saves lot of work.

I typed a date, right? ... or didn't I?

This is what I wanted!

So, that’s the first thing. Masked input is great, but there is a conflict with the new jQueryUI datepicker. Both of them listen on keypress event. Masked input in order to position entered digit in front of or behind given delimiter and datepicker listens in order to automatically update selected date in a widget as you type.  It works fine until you type the first digit indicating year – maskedinput will insert delimiter in front of your digit, which is perfectly fine, but datepicker expects number, and as a result you get year 1900 (or something else same crazy).

Custom trigger

To prevent this conflict you need to toggle datepicker not when user enters input field, which is the default behaviour, but when she clicks on some trigger, in most cases icon or a button.  Datepicker has an option for it

$( "#datepicker" ).datepicker({
   showOn: "button",
   buttonImage: "images/calendar.gif",
   buttonImageOnly: true
});

Do you see the path to image file embedded in js code? It should not be there, it’s not flexible and makes it very difficult to style.  Not mentioning that you can’t use themeroller. Wouldn’t it be nice if you could use any DOM element as an trigger with themeroller-ready classes, and not just an image? Well…. You can 🙂 Use something like this:

var el = $('.datepicker');
el.parent().addClass('hideCalImage calImgWrapper'); //add class to hide 'native' image triggers
//add themeroller ui classes
	var calImgController = $('<div class="calImg ui-icon-calendar ui-icon"></div>').click(function () {
	if (el.attr('data-hasDPVisible') == 'true') {
		el.attr('data-hasDPVisible', 'false');
		el.datepicker('hide');
	}
	else {
		el.attr('data-hasDPVisible', 'true');
		el.datepicker('show');
	}
}).appendTo(el.parent());

I add some css class to hide the <img>, and then replace it with my own <div> element with attached click listeners.  Notice the use of data- attribute hasDpVisible. I have to use some kind of indication whether datepicker is on or off to be able to show / close it as needed.  And that’s basically it. For the full source code see the DEMO.

Why I love my work

I consider myself lucky to have work that I love. I work as Javascript / C# developer for a company where I can be creative, I can try new technologies and constantly learn new stuff. In short: I grow, I develop myself. That’s great. I left my previous post not just because of low salary, but mostly because it just sucked. I did not trust my boss, as nobody did, he was that kind of person who tries to avoid responsibility. He had a gift to demotivate people by randomly checking what they are doing, peeking over their shoulders and so on.  Everyone hates that. No wonder people started to leave the company…

But back to topic: in my current company nobody checks how long I am at work, what sites I am visiting, I can go to town if I need to. If I need anything, like better keyboard, books to study, it’s not a problem I can just ask for it and I will probably get it.  I feel free and welcomed, and I feel that my work is appreciated (not just by money but by respect of my peers). That’s very motivating.  Another big motivating factor is enthusiasm of my co-workers.  It creates great atmosphere, so it’s pleasant to work with them. And not just to work, but to go to pub, get stoned and have fun… that’s part of team building 🙂

PS: I know that I probably suck at writing because English is not my native tongue, but it is an exercise for me, a part of kind of self development plan.

I’m going to IPO48 Prague

I have just learned about IPO48 and I am very excited about it. It is a 48 (!) hours long hackaton where people gather to form teams and deliver functional app prototypes.  It is a great opportunity to meet creative innovative people, make contacts with investors and start something new.

This is my startup idea – HistoryGraph. Check it out:)

Educational web-app displaying graph of historical timelines.

It gives you visual comparison of historical developement of chosen topics

(countries, churches, science, etc...)

so that you can spot not-so-obvious relations between various events.


I am currently looking for developers to join my team.  I need front-end, back-end developers, database specialist and graphic.  I am looking forward what will come out of it… who knows?

console.log() problem solved

console.log(),  console.debug()..  my two favourite helpers. If I need check whether my jquery selector returns what I expect it to or just to check how some variable changes its value during script execution I often use console.  It’s great tool. Google Chrome provides it by default, Firefox only when you have Firebug turned on and IE likewise. If there is no console object available, then Javascript throws an Error and stops execution. Console should be used in developement enviroment only, where you can be sure that console is turned on. But sometimes it is good to keep it, at least for error messages. I don’t know about any tool which would walk thru javascript code and remove calls to console when it is deployed in production. If you know about any, please let me know in comments.  As a workaround I wrote simple script which mocks console to prevent errors:

Consolecheck.js

// if console is not available -> mock it to prevent errors
try {
    var c = console;
}
catch (e) {
    console = {};
    console.log = function () { };
    console.debug = function () { };
    console.warn = function () { };
    console.error = function () { };
    console.dir = function () { };
}

Fun with Dojo animation

Best way to learn is by doing. About a year ago when I needed to learn Dojo I created this simple animation. It is also my tribute to Avatar movie.  Click the image to see it in action. It looks really cool on full screen [press F11] 🙂

Avatar - dojo.js animation

Tribute to Avatar - animation build in dojo.js

How it works

When page loads dojo.addOnLoad() fires callback function. First it calculates dimension of the <img> used as background. In this case Avatar wallpaper.  Then it creates overlay <div> with same dimension as background image and insert grid of tiles. Number of tiles is calculated dependending on their width and height set in config object.

var config = {
 cellHeight : 80, //px
 cellWidth : 80, //px
 timerTick: 750, //ms
 fadeOutDurr: 400, //ms
 fadeInDurr: 2200 //ms
};

Each tile has unique ID based on its position in the grid, ID is used for easy referencing of tiles for fading effects. Random tiles  fade in and out revealing portions of the image underneath.  To get next random cell I simply generate two random numbers (max is the number of cols/rows in the grid), compose the ID as x-y and then call dojo.byId(). Each cells also have mouseenter event listener which triggers the same fading effect. When you swift mouse over screen you will see some beautiful ‘waves’ 🙂

//create grid of tiles with StringBuilder

var str = new StringBuilder();
for(var i=0; i<rows; i++) {
	str.append('<div class="row" id="row'+ i + '">');
	for(var j=0; j<cols; j++) {
		str.append('<div class="cell" id="' + i + '-' + j +'" style="height:'+config.cellHeight+'px; width: '+(config.cellWidth-2)+'px"> </div>');
	}
	config.maxY = j;
	str.append('</div>');
}
config.maxX = i;
cellContainer.innerHTML = str.toString();

I use Javascript implementation of StringBuilder for faster string manipulation. It really pays off when building large portions of html in javascript, so I definitely recommend using it.

_fader function takes care of the fadeIn/fadeOut effect. Well, actually it is fadeOut/fadeIn but whatever…Notice the onEnd callback.

function _fader(item) {
	dojo.fadeOut({
		node: item,
		duration: config.fadeOutDurr,
		onEnd: function() {
			dojo.fadeIn({
				node: item,
				duration: config.fadeInDurr
			}).play();
		}
	}).play();
} //_fader()

Now add the event listener for mouseenter. In dojo this is done with the dojo.connect function. You can connect basically almost any object’s method to any listener or other object’s method. It’s very usefull.

dojo.forEach(dojo.query('div.cell'), function(item) {
	dojo.connect(item, 'mouseenter', function () { _fader(item)});
});

And that’s all. For the full source code see the demo.

jQuery.datepicker – issue with duplicate ID

I have discovered (minor) issue with jQuery Datepicker plugin:

It’s not actually datepicker’s fault, but it might be difficult to find it in a complex web page, so I decided to share it with you. Imagine that your application relies heavily on javascript, ajax, widgets etc… Widgets are created on the fly, and it happens is that two datepicker instances share the same ID. They might be generated from the same template (as was my case), or they dont have any ID at all, but were initaliazed in a certain way, more on this in future post.

Here is a sample code:

<div class="someWidget">
<input id="myId" class="datepicker"/>
</div>
....
<div class="someOtherWidget">
<input id="myId" class="datepicker"/>
</div>

and the javascript:

$('.datepicker').datepicker();

This will add datepickers on both input fields, and when they gain focus, widget will be displayed (that’s default behaviour). So far so good. But if you click on any date, it will be passed set in the first field and the first field only. Even if datepicker is displayed below the second field, the value will never be passed to it.

Why does this happen? Because of id. Datepicker uses it internally to know to which input field the date should be passed to.  If you don’t supply the id in html, then datepicker will come up with its own unique id. But it will never overwrite id, if it is already set.

Hope this will help someone, it took me some time to find out what was happening.

PS:

If your datepickers share same id, and one of them is hidden, you may even get this exception: “cannot set property ‘currentDay’ of undefined”. I wanted to show it in a demo, but for some reason I was not able to reproduce it, probably there was something more involved than just ids.

Buffer
GetSocial