summaryrefslogtreecommitdiff
path: root/lib/grappelli/media/js/grappelli.timepicker.js
blob: 05bedcc5b7dc127f24ab95389e6b68271e4956c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
 * this is grappellis timepicker.
 * works pretty similar to ui.datepicker:
 *  - adds a button to the element
 *  - creates a node (div) at the bottom called ui-timepicker
 *  - element.onClick fills the ui-timepicker node with the time_list (all times you can select)
 */

(function( $ ) {
$.widget("ui.timepicker", {
    // default options
    options: {
        // template for the container of the timepicker
        template: '<div id="ui-timepicker" class="module" style="position: absolute; display: none;"></div>',
        // selector to get the ui-timepicker once it's added to the dom
        timepicker_selector: "#ui-timepicker",
        // needed offset of the container from the element
        offset: {
            top: 0
        },
        // if time_list wasn't sent when calling the timepicker we use this
        default_time_list: [
            'now',
            '00:00',
            '01:00',
            '02:00',
            '03:00',
            '04:00',
            '05:00',
            '06:00',
            '07:00',
            '08:00',
            '09:00',
            '10:00',
            '11:00',
            '12:00',
            '13:00',
            '14:00',
            '15:00',
            '16:00',
            '17:00',
            '18:00',
            '19:00',
            '20:00',
            '21:00',
            '22:00',
            '23:00'
        ],
        // leave this empty!!!
        // NOTE: you can't set a default for time_list because if you call:
        // $("node").timepicker({time_list: ["01:00", "02:00"]})
        // ui.widget will extend/merge the options.time_list whith the one you sent.
        time_list: []
    },
    
    /**
     * init timepicker for a specific element
     */
    _create: function() {
        // for the events
        var self = this;
        
        // to close timpicker if you click somewhere in the document
        $(document).mousedown(function(evt) {
            if (self.timepicker.is(":visible")) {
                var $target = $(evt.target);
                if ($target[0].id != self.timepicker[0].id && $target.parents(self.options.timepicker_selector).length == 0 && !$target.hasClass('hasTimepicker') && !$target.hasClass('ui-timepicker-trigger')) {
                    self.timepicker.hide();
                }
            }
        });
        
        // get/create timepicker's container
        if ($(this.options.timepicker_selector).size() == 0) {
            $(this.options.template).appendTo('body');
        }
        this.timepicker = $(this.options.timepicker_selector);
        this.timepicker.hide();
        
        // modify the element and create the button
        this.element.addClass("hasTimepicker");
        this.button = $('<button type="button" class="ui-timepicker-trigger"></button>');
        this.element.after(this.button);
        
        // disable button if element is disabled
        if (this.element.attr("disabled")) {
            this.button.attr("disabled", true);
        }
        // register event
        else {
            this.button.click(function() {
                self._toggleTimepicker();
            });
        }
    },
    
    /**
     * called when button is clicked
     */
    _toggleTimepicker: function() {
        if (this.timepicker.is(":visible")) {
            this.timepicker.hide();
        } else {
            this.element.focus();
            this._generateTimepickerContents();
            this._showTimepicker();
        }
    },
    
    /**
     * fills timepicker with time_list of element and shows it.
     *
     * called by _toggleTimepicker
     */
    _generateTimepickerContents: function() {
        var self = this,
            template_str = "<ul>";
        
        // there is no time_list for this instance so use the default one
        if (this.options.time_list.length == 0) {
            this.options.time_list = this.options.default_time_list;
        }
        
        for (var i = 0; i < this.options.time_list.length; i++) {
            if (this.options.time_list[i] == "now") {
                var now = new Date(),
                    hours = now.getHours(), 
                    minutes = now.getMinutes();
                    
                hours = ((hours < 10) ? "0" + hours : hours);
                minutes = ((minutes < 10) ? "0" + minutes : minutes);
                
                template_str += '<li class="ui-state-active row">' + hours + ":" + minutes + '</li>';
            } else {
                template_str += '<li class="ui-state-default row">' + this.options.time_list[i] + '</li>';
            }
        }
        template_str += "</ul>";
        
        // fill timepicker container
        this.timepicker.html(template_str);
        
        // click handler for items (times) in timepicker
        this.timepicker.find('li').click(function() {
            // remove active class from all items
            $(this).parent().children('li').removeClass("ui-state-active");
            // mark clicked item as active
            $(this).addClass("ui-state-active");
            
            // set the new value and hide the timepicker
            self.element.val($(this).html());
            self.timepicker.hide();
        });
    },
    
    /**
     * sets offset and shows timepicker containter
     */
    _showTimepicker: function() {
        this.timepicker_offset = this.element.offset();
        this.timepicker_offset.top += this.element.outerHeight() + this.options.offset.top;
        this.timepicker.css(this.timepicker_offset);
        this.timepicker.show();
    },
    
    destroy: function() {
        $.Widget.prototype.destroy.apply(this, arguments); // default destroy
        // now do other stuff particular to this widget
    }
});
})(django.jQuery);