37

I want to highlight the dates on jquery datepicker where there are events attached to it (i'm not talking about js event, but real life events :D).

  1. How to pass the event dates to the calendar?
  2. How to make it clickable, either to display the event(s) with their url in a small popup tip, either to go to the event page?

Are there already available plugins or ressources (like tutorials) to help me achieve that please?

Thanks.

PS: I'm not using the datepicker to pick a date, only to access the events attached to a date

PS2: I'll use it on a multilingual website (fr and english), that's why I thought of datepicker

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
sf_tristanb
  • 8,725
  • 17
  • 74
  • 118
  • 2
    I wouldn't think making the events clickable is a good idea. How would you choose that date then? _Also_, are you using this to pick a date? If not, some [calendar plugin](http://arshaw.com/fullcalendar/) might suit you better. – StackExchange saddens dancek Apr 07 '11 at 08:56
  • @dancek No i'm not using this to pick a date. Only to access to events. Ok, thanks i'll take a look at the calendar plugin. – sf_tristanb Apr 07 '11 at 09:01

2 Answers2

65

This is definitely possible, and in my opinion not too much of an abuse of the datepicker widget. There is an option to initialize the widget in-line, which can be used for exactly the scenario you describe above.

There are a couple of steps you'll have to take:

  1. Initialize the datepicker in-line. Attach the datepicker widget to a <div> so that it will always appear and you won't have to attach it to an input:

    $("div").datepicker({...});
    
  2. Tap into the beforeShowDay event to highlight dates with specific events. Also, define your events in an array that you can populate and send down to the client:

    Events array:

    var events = [ 
        { Title: "Five K for charity", Date: new Date("02/13/2011") }, 
        { Title: "Dinner", Date: new Date("02/25/2011") }, 
        { Title: "Meeting with manager", Date: new Date("03/01/2011") }
    ];
    

    Event handler:

    beforeShowDay: function(date) {
        var result = [true, '', null];
        var matching = $.grep(events, function(event) {
            return event.Date.valueOf() === date.valueOf();
        });
    
        if (matching.length) {
            result = [true, 'highlight', null];
        }
        return result;
    },
    

    This might look a bit complex, but all it's doing is highlighting dates in the datepicker that have entries in the events array defined above.

  3. Define an onSelect event handler where you can tell the datepicker what to do when a day is clicked:

    onSelect: function(dateText) {
        var date,
            selectedDate = new Date(dateText),
            i = 0,
            event = null;
    
        /* Determine if the user clicked an event: */
        while (i < events.length && !event) {
            date = events[i].Date;
    
            if (selectedDate.valueOf() === date.valueOf()) {
                event = events[i];
            }
            i++;
        }
        if (event) {
            /* If the event is defined, perform some action here; show a tooltip, navigate to a URL, etc. */
            alert(event.Title);
        }
    }
    

    Again, it looks like a lot of code, but all that's happening is that we're finding the event associated with the date clicked. After we find that event, you can take whatever action you want (show a tooltip, for example)

Here's a complete working example: http://jsfiddle.net/Zrz9t/1151/. Make sure to navigate to February/March to see the events.

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • Andrew, the above works for all dates that are formatted like : mm/dd/yyyy , is there any way to make it work in dd/mm/yyyy ? – Michael Schinis Aug 13 '11 at 15:57
  • Did you try using the `dateFormat` option? – Andrew Whitaker Aug 14 '11 at 14:49
  • Nice man! just a question how do i alert if there are multiple event for a date? – SVS Jun 12 '12 at 07:59
  • Thanks for this code! Really awesome. It wasn't working for me at first and then I realised there is an invalid (invisible) character at the last }); (or maybe it was already on my page). http://stackoverflow.com/questions/9955242/syntaxerror-invalid-character-u8203 –  Jul 21 '12 at 14:16
  • @KatiePatrick: You're right, there was an invisible character at the end of the code in the fiddle. Thanks for the heads up! – Andrew Whitaker Jul 21 '12 at 15:06
  • What if there are multiple Events we have on the same date what could we do then ? – Seeker Apr 10 '13 at 07:31
  • @PHPSeeker: You should be able to perform any actions you need in the `onSelect` handler. – Andrew Whitaker Apr 10 '13 at 12:55
  • Amazing, sleek,intuitive...all in all life-saver :) – abhijit Jul 15 '13 at 11:26
  • How about if you want to display a tooltip, not an alert. I have tried: var day = new Date(event.Date).getDate().toString(); $("a.ui-state-active:contains("+day+")").tooltip({content:'yay'}); – codecowboy Sep 22 '13 at 10:25
  • re: dateFormat, having been caught by this, be aware that entering `yyyy` actually gives you the year twice - e.g. 20132013 - it's `y` for a two-digit year and `yy` for a four-digit one. Just in case anyone sees any invalid date messages during debugging. – William Turrell Nov 04 '13 at 18:10
4

in addition to Andrew Whitaker solution there is another way to do it (actually its a hack but actually its maybe perfect for someone else because maybe the title or date is not always a good identifier)

Note: please read Andrew Whitaker solution first and see the changes here

// date picker
$("div").datepicker({
    // hook handler
    beforeShowDay: function(tdate) {
        var mydata = $(this).data("mydata");
        var enabled = false;
        var classes = "";
        var title = date;
        $.each(mydata, function() {
            if (this.date.valueOf() === tdate.valueOf()){
                enabled = true;
                classes = "highlight";
                title = title + '" data-id ="'+this.id;// my hack to add additional attributes ;)
            }
        });        
        return [enabled,classes,title];
    },
    // event handler
    onSelect: function() {
        var id = $(this).find(".ui-datepicker-current-day").attr("data-id");
        mydata = $(this).data("mydata"),
        selectedData = null;        
        /* search for data id */
        $.each(mydata,function(){
            if (this.id == id){
                selectedData = this;
            }
        });
        if (selectedData) {
            /* If the event is defined, perform some action here; show a tooltip, navigate to a URL, etc. */
            alert(selectedData);
        }
    }
}).data("mydata",
    // your data
    [{
        id:1,
        title: "Five K for charity", 
        date: new Date("02/13/2011")
    }, 
    {
        id:2,
        title: "Dinner", 
        date: new Date("02/25/2011")
    }, 
    {
        id:3,
        title: "Meeting with manager", 
        date: new Date("03/01/2011")
    }]);
Fareed Alnamrouti
  • 30,771
  • 4
  • 85
  • 76