wcm
wcm

Reputation: 9281

Replicating Google Analytics DateRange picker

I need to replicate the Google Analytics date picker (plus a few new options). Can anyone tell me how to highlight all the cells on a calendar between two dates. My basic JavaScript is OK but I think I'm getting a bit out of my depth.

I'm using JQuery 1.5.1 and JQuery UI 1.8.14.

Upvotes: 3

Views: 3877

Answers (3)

petrkotek
petrkotek

Reputation: 4761

In needed to replicate Google Analytics date picker as well. I know you were asking just about highlighting cells, but if someone else would prefer complete solution, you can see my answer from another question: jquery google analytics datepicker

Date Ranges Widget

Upvotes: 4

pete
pete

Reputation: 25081

Here's a solution using the built-in 'onSelect' event (jsFiddle):

$(document).ready(function() {
    'use strict';
    var range = {
        'start': null,
        'stop': null
    };
    $('#picker').datepicker({
        'onSelect': function(dateText, inst) {
            var d, ds, i, sel, $this = $(this);
            if (range.start === null || range.stop === null) {
                if (range.start === null) {
                    range.start = new Date(dateText);
                } else {
                    range.stop = new Date(dateText);
                }
            }
            if (range.start !== null && range.stop !== null) {
                if ($this.find('td').hasClass('selected')) {
                    //clear selected range
                    $this.children().removeClass('selected');
                    range.start = new Date(dateText);
                    range.stop = null;
                    //call internal method '_updateDatepicker'.
                    inst.inline = true;
                } else {
                    //prevent internal method '_updateDatepicker' from being called.
                    inst.inline = false;
                    if (range.start > range.stop) {
                        d = range.stop;
                        range.stop = range.start;
                        range.start = d;
                    }
                    sel = (range.start.toString() === range.stop.toString()) ? 0 : (new Date(range.stop - range.start)).getDate();
                    for (i = 0; i <= sel; i += 1) {
                        ds = (range.start.getMonth() + 1).toString() + '/' + (range.start.getDate() + i).toString() + '/' + (range.start.getFullYear()).toString();
                        d = new Date(ds);
                        $this.find('td a').filter(function(index) {
                            return $(this).text() === d.getDate().toString();
                        }).parents('td').addClass('selected');
                    }
                }
            }
        }
    });
});

Upvotes: 2

wcm
wcm

Reputation: 9281

I became desperate and came up with a solution on my own. It wasn't pretty but I'll detail it.

I was able to construct a div that had the text boxes, buttons and the datepicker that looked like the Google Analytics control but I couldn't make the datepicker work properly. Eventually, I came up with the idea of creating a toggle variable that kept track of which date you were selecting (start date or end date). Using that variable in a custom onSelect event handler worked well but I still couldn't figure out how to get the cells between dates to highlight.

It took a while, but I slowly came to the realization that I couldn't do it with the datepicker as it existed out of the box. Once I figured that out, I was able to come up with a solution.

My solution was to add a new event call afterSelect. This is code that would run after all the internal adjustments and formatting were complete. I then wrote a function that, given a cell in the datepicker calendar, would return the date that it represented. I identified the calendar date cells by using jQuery to find all the elements that had the "ui-state-default" class. Once I had the date function and a list of all the calendar cells, I just needed to iterate over all of them and, if the date was in the correct range, add a new class to the parent.

It was extremely tedious but I was able to make it work.

Upvotes: 1

Related Questions