Switch to unified view

a/static/jdpicker.js b/static/jdpicker.js
...
...
26
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29
OTHER DEALINGS IN THE SOFTWARE.
29
OTHER DEALINGS IN THE SOFTWARE.
30
*/
30
*/
31
jdPicker = (function($) { 
31
jdPicker = (function($) {
32
32
33
function jdPicker(el, opts) {
33
function jdPicker(el, opts) {
34
  if (typeof(opts) != "object") opts = {};
34
  if (typeof(opts) != "object") opts = {};
35
  $.extend(this, jdPicker.DEFAULT_OPTS, opts);
35
  $.extend(this, jdPicker.DEFAULT_OPTS, opts);
36
  
36
37
  this.input = $(el);
37
  this.input = $(el);
38
  this.bindMethodsToObj("show", "hide", "hideIfClickOutside", "keydownHandler", "selectDate");
38
  this.bindMethodsToObj("show", "hide", "hideIfClickOutside", "keydownHandler", "selectDate");
39
  
39
40
  this.build();
40
  this.build();
41
  this.selectDate();
41
  this.selectDate();
42
  
42
43
  this.hide();
43
  this.hide();
44
};
44
};
45
jdPicker.DEFAULT_OPTS = {
45
jdPicker.DEFAULT_OPTS = {
46
  month_names: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
46
  month_names: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
47
  short_month_names: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
47
  short_month_names: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
...
...
58
  date_max: "",
58
  date_max: "",
59
  date_format: "YYYY/mm/dd"
59
  date_format: "YYYY/mm/dd"
60
};
60
};
61
jdPicker.prototype = {
61
jdPicker.prototype = {
62
  build: function() {
62
  build: function() {
63
  
63
64
    this.wrapp = this.input.wrap('<div class="jdpicker_w">');
64
    this.wrapp = this.input.wrap('<div class="jdpicker_w">');
65
  
65
66
    switch (this.date_format){
66
    switch (this.date_format){
67
        case "dd/mm/YYYY": 
67
        case "dd/mm/YYYY":
68
            this.reg = new RegExp(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/); 
68
            this.reg = new RegExp(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
69
            this.date_decode = "new Date(matches[3], parseInt(matches[2]-1), matches[1]);";
69
            this.date_decode = "new Date(matches[3], parseInt(matches[2]-1), matches[1]);";
70
            this.date_encode = 'this.strpad(date.getDate()) + "/" + this.strpad(date.getMonth()+1) + "/" + date.getFullYear();';
70
            this.date_encode = 'this.strpad(date.getDate()) + "/" + this.strpad(date.getMonth()+1) + "/" + date.getFullYear();';
71
            this.date_encode_s = 'this.strpad(date.getDate()) + "/" + this.strpad(date.getMonth()+1)';
71
            this.date_encode_s = 'this.strpad(date.getDate()) + "/" + this.strpad(date.getMonth()+1)';
72
        break;
72
        break;
73
        case "FF dd YYYY": 
73
        case "FF dd YYYY":
74
            this.reg = new RegExp(/^([a-zA-Z]+) (\d{1,2}) (\d{4})$/); 
74
            this.reg = new RegExp(/^([a-zA-Z]+) (\d{1,2}) (\d{4})$/);
75
            this.date_decode = "new Date(matches[3], this.indexFor(this.month_names, matches[1]), matches[2]);"; 
75
            this.date_decode = "new Date(matches[3], this.indexFor(this.month_names, matches[1]), matches[2]);";
76
            this.date_encode = 'this.month_names[date.getMonth()] + " " + this.strpad(date.getDate()) + " " + date.getFullYear();';
76
            this.date_encode = 'this.month_names[date.getMonth()] + " " + this.strpad(date.getDate()) + " " + date.getFullYear();';
77
            this.date_encode_s = 'this.month_names[date.getMonth()] + " " + this.strpad(date.getDate());';
77
            this.date_encode_s = 'this.month_names[date.getMonth()] + " " + this.strpad(date.getDate());';
78
        break;
78
        break;
79
        case "dd MM YYYY": 
79
        case "dd MM YYYY":
80
            this.reg = new RegExp(/^(\d{1,2}) ([a-zA-Z]{3}) (\d{4})$/); 
80
            this.reg = new RegExp(/^(\d{1,2}) ([a-zA-Z]{3}) (\d{4})$/);
81
            this.date_decode = "new Date(matches[3], this.indexFor(this.short_month_names, matches[2]), matches[1]);"; 
81
            this.date_decode = "new Date(matches[3], this.indexFor(this.short_month_names, matches[2]), matches[1]);";
82
            this.date_encode = 'this.strpad(date.getDate()) + " " + this.short_month_names[date.getMonth()] + " " + date.getFullYear();'; 
82
            this.date_encode = 'this.strpad(date.getDate()) + " " + this.short_month_names[date.getMonth()] + " " + date.getFullYear();';
83
            this.date_encode_s = 'this.strpad(date.getDate()) + " " + this.short_month_names[date.getMonth()];'; 
83
            this.date_encode_s = 'this.strpad(date.getDate()) + " " + this.short_month_names[date.getMonth()];';
84
        break;
84
        break;
85
        case "MM dd YYYY": 
85
        case "MM dd YYYY":
86
            this.reg = new RegExp(/^([a-zA-Z]{3}) (\d{1,2}) (\d{4})$/); 
86
            this.reg = new RegExp(/^([a-zA-Z]{3}) (\d{1,2}) (\d{4})$/);
87
            this.date_decode = "new Date(matches[3], this.indexFor(this.short_month_names, matches[1]), matches[2]);"; 
87
            this.date_decode = "new Date(matches[3], this.indexFor(this.short_month_names, matches[1]), matches[2]);";
88
            this.date_encode = 'this.short_month_names[date.getMonth()] + " " + this.strpad(date.getDate()) + " " + date.getFullYear();'; 
88
            this.date_encode = 'this.short_month_names[date.getMonth()] + " " + this.strpad(date.getDate()) + " " + date.getFullYear();';
89
            this.date_encode_s = 'this.short_month_names[date.getMonth()] + " " + this.strpad(date.getDate());'; 
89
            this.date_encode_s = 'this.short_month_names[date.getMonth()] + " " + this.strpad(date.getDate());';
90
        break;
90
        break;
91
        case "dd FF YYYY": 
91
        case "dd FF YYYY":
92
            this.reg = new RegExp(/^(\d{1,2}) ([a-zA-Z]+) (\d{4})$/); 
92
            this.reg = new RegExp(/^(\d{1,2}) ([a-zA-Z]+) (\d{4})$/);
93
            this.date_decode = "new Date(matches[3], this.indexFor(this.month_names, matches[2]), matches[1]);"; 
93
            this.date_decode = "new Date(matches[3], this.indexFor(this.month_names, matches[2]), matches[1]);";
94
            this.date_encode = 'this.strpad(date.getDate()) + " " + this.month_names[date.getMonth()] + " " + date.getFullYear();'; 
94
            this.date_encode = 'this.strpad(date.getDate()) + " " + this.month_names[date.getMonth()] + " " + date.getFullYear();';
95
            this.date_encode_s = 'this.strpad(date.getDate()) + " " + this.month_names[date.getMonth()];'; 
95
            this.date_encode_s = 'this.strpad(date.getDate()) + " " + this.month_names[date.getMonth()];';
96
        break;
96
        break;
97
        case "YYYY-mm-dd": 
97
        case "YYYY-mm-dd":
98
        default: 
98
        default:
99
            this.reg = new RegExp(/^(\d{4})\-(\d{1,2})\-(\d{1,2})$/); 
99
            this.reg = new RegExp(/^(\d{4})\-(\d{1,2})\-(\d{1,2})$/);
100
            this.date_decode = "new Date(matches[1], parseInt(matches[2]-1), matches[3]);"; 
100
            this.date_decode = "new Date(matches[1], parseInt(matches[2]-1), matches[3]);";
101
            this.date_encode = 'date.getFullYear() + "-" + this.strpad(date.getMonth()+1) + "-" + this.strpad(date.getDate());'; 
101
            this.date_encode = 'date.getFullYear() + "-" + this.strpad(date.getMonth()+1) + "-" + this.strpad(date.getDate());';
102
            this.date_encode_s = 'this.strpad(date.getMonth()+1) + "-" + this.strpad(date.getDate());'; 
102
            this.date_encode_s = 'this.strpad(date.getMonth()+1) + "-" + this.strpad(date.getDate());';
103
        break;
103
        break;
104
    }
104
    }
105
  
105
106
    if(this.date_max != "" && this.date_max.match(this.reg)){
106
    if(this.date_max != "" && this.date_max.match(this.reg)){
107
        var matches = this.date_max.match(this.reg);
107
        var matches = this.date_max.match(this.reg);
108
        this.date_max = eval(this.date_decode);
108
        this.date_max = eval(this.date_decode);
109
    }else
109
    }else
110
        this.date_max = "";
110
        this.date_max = "";
111
  
111
112
    if(this.date_min != "" && this.date_min.match(this.reg)){
112
    if(this.date_min != "" && this.date_min.match(this.reg)){
113
        var matches = this.date_min.match(this.reg);
113
        var matches = this.date_min.match(this.reg);
114
        this.date_min = eval(this.date_decode);
114
        this.date_min = eval(this.date_decode);
115
    }else
115
    }else
116
        this.date_min = "";
116
        this.date_min = "";
117
  
117
118
    var monthNav = $('<p class="month_nav">' +
118
    var monthNav = $('<p class="month_nav">' +
119
      '<span class="button prev" title="[PageUp]">&#171;</span>' +
119
      '<span class="button prev" title="[PageUp]">&#171;</span>' +
120
      ' <span class="month_name"></span> ' +
120
      ' <span class="month_name"></span> ' +
121
      '<span class="button next" title="[PageDown]">&#187;</span>' +
121
      '<span class="button next" title="[PageDown]">&#187;</span>' +
122
      '</p>');
122
      '</p>');
123
    
123
124
    this.monthNameSpan = $(".month_name", monthNav);
124
    this.monthNameSpan = $(".month_name", monthNav);
125
    $(".prev", monthNav).click(this.bindToObj(function() { this.moveMonthBy(-1); }));
125
    $(".prev", monthNav).click(this.bindToObj(function() { this.moveMonthBy(-1); }));
126
    $(".next", monthNav).click(this.bindToObj(function() { this.moveMonthBy(1); }));
126
    $(".next", monthNav).click(this.bindToObj(function() { this.moveMonthBy(1); }));
127
    
127
128
    this.monthNameSpan.dblclick(this.bindToObj(function(){
128
    this.monthNameSpan.dblclick(this.bindToObj(function(){
129
        this.monthNameSpan.empty().append(this.getMonthSelect());
129
        this.monthNameSpan.empty().append(this.getMonthSelect());
130
        $('select', this.monthNameSpan).change(this.bindToObj(function(){
130
        $('select', this.monthNameSpan).change(this.bindToObj(function(){
131
            this.moveMonthBy(parseInt($('select :selected', this.monthNameSpan).val()) - this.currentMonth.getMonth());
131
            this.moveMonthBy(parseInt($('select :selected', this.monthNameSpan).val()) - this.currentMonth.getMonth());
132
        }));
132
        }));
133
    }));
133
    }));
134
  
134
135
    var yearNav = $('<p class="year_nav">' +
135
    var yearNav = $('<p class="year_nav">' +
136
      '<span class="button prev" title="[Shift+PageUp]">&#171;</span>' +
136
      '<span class="button prev" title="[Shift+PageUp]">&#171;</span>' +
137
      ' <span class="year_name" id="year_name"></span> ' +
137
      ' <span class="year_name" id="year_name"></span> ' +
138
      '<span class="button next" title="[Shift+PageDown]">&#187;</span>' +
138
      '<span class="button next" title="[Shift+PageDown]">&#187;</span>' +
139
      '</p>');
139
      '</p>');
140
    
140
141
    this.yearNameSpan = $(".year_name", yearNav);
141
    this.yearNameSpan = $(".year_name", yearNav);
142
    $(".prev", yearNav).click(this.bindToObj(function() { this.moveMonthBy(-12); }));
142
    $(".prev", yearNav).click(this.bindToObj(function() { this.moveMonthBy(-12); }));
143
    $(".next", yearNav).click(this.bindToObj(function() { this.moveMonthBy(12); }));
143
    $(".next", yearNav).click(this.bindToObj(function() { this.moveMonthBy(12); }));
144
    
144
145
    this.yearNameSpan.dblclick(this.bindToObj(function(){
145
    this.yearNameSpan.dblclick(this.bindToObj(function(){
146
      
146
147
        if($('.year_name input', this.rootLayers).length==0){
147
        if($('.year_name input', this.rootLayers).length==0){
148
            var initialDate = this.yearNameSpan.html();
148
            var initialDate = this.yearNameSpan.html();
149
          
149
150
            var yearNameInput = $('<input type="text" class="text year_input" value="'+initialDate+'" />');
150
            var yearNameInput = $('<input type="text" class="text year_input" value="'+initialDate+'" />');
151
            this.yearNameSpan.empty().append(yearNameInput);
151
            this.yearNameSpan.empty().append(yearNameInput);
152
          
152
153
            $(".year_input", yearNav).keyup(this.bindToObj(function(){
153
            $(".year_input", yearNav).keyup(this.bindToObj(function(){
154
                if($('input',this.yearNameSpan).val().length == 4 && $('input',this.yearNameSpan).val() != initialDate && parseInt($('input',this.yearNameSpan).val()) == $('input',this.yearNameSpan).val()){
154
                if($('input',this.yearNameSpan).val().length == 4 && $('input',this.yearNameSpan).val() != initialDate && parseInt($('input',this.yearNameSpan).val()) == $('input',this.yearNameSpan).val()){
155
                    this.moveMonthBy(parseInt(parseInt(parseInt($('input',this.yearNameSpan).val()) - initialDate)*12));
155
                    this.moveMonthBy(parseInt(parseInt(parseInt($('input',this.yearNameSpan).val()) - initialDate)*12));
156
                }else if($('input',this.yearNameSpan).val().length>4)
156
                }else if($('input',this.yearNameSpan).val().length>4)
157
                    $('input',this.yearNameSpan).val($('input',this.yearNameSpan).val().substr(0, 4));
157
                    $('input',this.yearNameSpan).val($('input',this.yearNameSpan).val().substr(0, 4));
158
            }));
158
            }));
159
          
159
160
            $('input',this.yearNameSpan).focus();
160
            $('input',this.yearNameSpan).focus();
161
            $('input',this.yearNameSpan).select();
161
            $('input',this.yearNameSpan).select();
162
        }
162
        }
163
      
163
164
    }));
164
    }));
165
165
166
    var error_msg = $('<div class="error_msg"></div>');
166
    var error_msg = $('<div class="error_msg"></div>');
167
  
167
168
    var nav = $('<div class="nav"></div>').append(error_msg, monthNav, yearNav);
168
    var nav = $('<div class="nav"></div>').append(error_msg, monthNav, yearNav);
169
    
169
170
    var tableShell = "<table><thead><tr>";
170
    var tableShell = "<table><thead><tr>";
171
  
171
172
    if(this.show_week == 1) tableShell +='<th class="week_label">'+(this.week_label)+'</th>';
172
    if(this.show_week == 1) tableShell +='<th class="week_label">'+(this.week_label)+'</th>';
173
  
173
174
    $(this.adjustDays(this.short_day_names)).each(function() {
174
    $(this.adjustDays(this.short_day_names)).each(function() {
175
      tableShell += "<th>" + this + "</th>";
175
      tableShell += "<th>" + this + "</th>";
176
    });
176
    });
177
  
177
178
    tableShell += "</tr></thead><tbody></tbody></table>";
178
    tableShell += "</tr></thead><tbody></tbody></table>";
179
179
180
    var style = (this.input.context.type=="hidden")?' style="display:block; position:static; margin:0 auto"':'';    
180
    var style = (this.input.context.type=="hidden")?' style="display:block; position:static; margin:0 auto"':'';
181
181
182
    this.dateSelector = this.rootLayers = $('<div class="date_selector" '+style+'></div>').append(nav, tableShell).insertAfter(this.input);
182
    this.dateSelector = this.rootLayers = $('<div class="date_selector" '+style+'></div>').append(nav, tableShell).insertAfter(this.input);
183
    
183
184
    if ($.browser.msie && $.browser.version < 7) {
184
    if ($.browser.msie && $.browser.version < 7) {
185
      
185
186
      this.ieframe = $('<iframe class="date_selector_ieframe" frameborder="0" src="#"></iframe>').insertBefore(this.dateSelector);
186
      this.ieframe = $('<iframe class="date_selector_ieframe" frameborder="0" src="#"></iframe>').insertBefore(this.dateSelector);
187
      this.rootLayers = this.rootLayers.add(this.ieframe);
187
      this.rootLayers = this.rootLayers.add(this.ieframe);
188
      
188
189
      $(".button", nav).mouseover(function() { $(this).addClass("hover"); });
189
      $(".button", nav).mouseover(function() { $(this).addClass("hover"); });
190
      $(".button", nav).mouseout(function() { $(this).removeClass("hover"); });
190
      $(".button", nav).mouseout(function() { $(this).removeClass("hover"); });
191
    };
191
    };
192
    
192
193
    this.tbody = $("tbody", this.dateSelector);
193
    this.tbody = $("tbody", this.dateSelector);
194
194
195
    this.input.change(this.bindToObj(function() { this.selectDate(); }));
195
    this.input.change(this.bindToObj(function() { this.selectDate(); }));
196
196
197
    this.selectDate();
197
    this.selectDate();
198
  
198
199
  },
200
  
199
  },
200
201
  selectMonth: function(date) {
201
  selectMonth: function(date) {
202
    var newMonth = new Date(date.getFullYear(), date.getMonth(), date.getDate());
202
    var newMonth = new Date(date.getFullYear(), date.getMonth(), date.getDate());
203
    if(this.isNewDateAllowed(newMonth)){
203
    if(this.isNewDateAllowed(newMonth)){
204
        if (!this.currentMonth || !(this.currentMonth.getFullYear() == newMonth.getFullYear() &&
204
        if (!this.currentMonth || !(this.currentMonth.getFullYear() == newMonth.getFullYear() &&
205
                                    this.currentMonth.getMonth() == newMonth.getMonth())) {
205
                                    this.currentMonth.getMonth() == newMonth.getMonth())) {
206
        
206
207
          this.currentMonth = newMonth;
207
          this.currentMonth = newMonth;
208
        
208
209
          var rangeStart = this.rangeStart(date), rangeEnd = this.rangeEnd(date);
209
          var rangeStart = this.rangeStart(date), rangeEnd = this.rangeEnd(date);
210
          var numDays = this.daysBetween(rangeStart, rangeEnd);
210
          var numDays = this.daysBetween(rangeStart, rangeEnd);
211
          var dayCells = "";
211
          var dayCells = "";
212
        
212
213
          for (var i = 0; i <= numDays; i++) {
213
          for (var i = 0; i <= numDays; i++) {
214
            var currentDay = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + i, 12, 00);
214
            var currentDay = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + i, 12, 00);
215
          
215
216
            if (this.isFirstDayOfWeek(currentDay)){
216
            if (this.isFirstDayOfWeek(currentDay)){
217
          
217
218
                var firstDayOfWeek = currentDay;
218
                var firstDayOfWeek = currentDay;
219
                var lastDayOfWeek = new Date(currentDay.getFullYear(), currentDay.getMonth(), currentDay.getDate()+6, 12, 00);
219
                var lastDayOfWeek = new Date(currentDay.getFullYear(), currentDay.getMonth(), currentDay.getDate()+6, 12, 00);
220
          
220
221
                if(this.select_week && this.isNewDateAllowed(firstDayOfWeek))
221
                if(this.select_week && this.isNewDateAllowed(firstDayOfWeek))
222
                    dayCells += "<tr date='" + this.dateToString(currentDay) + "' class='selectable_week'>";
222
                    dayCells += "<tr date='" + this.dateToString(currentDay) + "' class='selectable_week'>";
223
                else
223
                else
224
                    dayCells += "<tr>";
224
                    dayCells += "<tr>";
225
                  
225
226
                if(this.show_week==1)
226
                if(this.show_week==1)
227
                    dayCells += '<td class="week_num">'+this.getWeekNum(currentDay)+'</td>';
227
                    dayCells += '<td class="week_num">'+this.getWeekNum(currentDay)+'</td>';
228
            }
228
            }
229
            if ((this.select_week == 0 && currentDay.getMonth() == date.getMonth() && this.isNewDateAllowed(currentDay) && !this.isHoliday(currentDay)) || (this.select_week==1 && currentDay.getMonth() == date.getMonth() && this.isNewDateAllowed(firstDayOfWeek))) {
229
            if ((this.select_week == 0 && currentDay.getMonth() == date.getMonth() && this.isNewDateAllowed(currentDay) && !this.isHoliday(currentDay)) || (this.select_week==1 && currentDay.getMonth() == date.getMonth() && this.isNewDateAllowed(firstDayOfWeek))) {
230
              dayCells += '<td class="selectable_day" date="' + this.dateToString(currentDay) + '">' + currentDay.getDate() + '</td>';
230
              dayCells += '<td class="selectable_day" date="' + this.dateToString(currentDay) + '">' + currentDay.getDate() + '</td>';
231
            } else {
231
            } else {
232
              dayCells += '<td class="unselected_month" date="' + this.dateToString(currentDay) + '">' + currentDay.getDate() + '</td>';
232
              dayCells += '<td class="unselected_month" date="' + this.dateToString(currentDay) + '">' + currentDay.getDate() + '</td>';
233
            };
233
            };
234
          
234
235
            if (this.isLastDayOfWeek(currentDay)) dayCells += "</tr>";
235
            if (this.isLastDayOfWeek(currentDay)) dayCells += "</tr>";
236
          };
236
          };
237
          this.tbody.empty().append(dayCells);
237
          this.tbody.empty().append(dayCells);
238
        
238
239
          this.monthNameSpan.empty().append(this.monthName(date));
239
          this.monthNameSpan.empty().append(this.monthName(date));
240
          this.yearNameSpan.empty().append(this.currentMonth.getFullYear());
240
          this.yearNameSpan.empty().append(this.currentMonth.getFullYear());
241
        
241
242
          if(this.select_week == 0){
242
          if(this.select_week == 0){
243
              $(".selectable_day", this.tbody).click(this.bindToObj(function(event) {
243
              $(".selectable_day", this.tbody).click(this.bindToObj(function(event) {
244
                this.changeInput($(event.target).attr("date"));if(this.input.context.type!="hidden") this.hide();
244
                this.changeInput($(event.target).attr("date"));if(this.input.context.type!="hidden") this.hide();
245
              }));
245
              }));
246
          }else{
246
          }else{
247
              $(".selectable_week", this.tbody).click(this.bindToObj(function(event) {
247
              $(".selectable_week", this.tbody).click(this.bindToObj(function(event) {
248
                this.changeInput($(event.target.parentNode).attr("date"));if(this.input.context.type!="hidden") this.hide();
248
                this.changeInput($(event.target.parentNode).attr("date"));if(this.input.context.type!="hidden") this.hide();
249
              }));
249
              }));
250
          }
250
          }
251
        
251
252
          $("td[date='" + this.dateToString(new Date()) + "']", this.tbody).addClass("today");
252
          $("td[date='" + this.dateToString(new Date()) + "']", this.tbody).addClass("today");
253
          if(this.select_week == 1){
253
          if(this.select_week == 1){
254
              $("tr", this.tbody).mouseover(function() { $(this).addClass("hover"); });
254
              $("tr", this.tbody).mouseover(function() { $(this).addClass("hover"); });
255
              $("tr", this.tbody).mouseout(function() { $(this).removeClass("hover"); });
255
              $("tr", this.tbody).mouseout(function() { $(this).removeClass("hover"); });
256
          }else{
256
          }else{
257
              $("td.selectable_day", this.tbody).mouseover(function() { $(this).addClass("hover"); });
257
              $("td.selectable_day", this.tbody).mouseover(function() { $(this).addClass("hover"); });
258
              $("td.selectable_day", this.tbody).mouseout(function() { $(this).removeClass("hover"); });
258
              $("td.selectable_day", this.tbody).mouseout(function() { $(this).removeClass("hover"); });
259
          }
259
          }
260
        };
260
        };
261
      
261
262
        $('.selected', this.tbody).removeClass("selected");
262
        $('.selected', this.tbody).removeClass("selected");
263
        $('td[date="' + this.selectedDateString + '"], tr[date="' + this.selectedDateString + '"]', this.tbody).addClass("selected");
263
        $('td[date="' + this.selectedDateString + '"], tr[date="' + this.selectedDateString + '"]', this.tbody).addClass("selected");
264
    }else
264
    }else
265
        this.show_error(this.error_out_of_range);
265
        this.show_error(this.error_out_of_range);
266
  },
266
  },
267
  
267
268
  selectDate: function(date) {
268
  selectDate: function(date) {
269
    if (typeof(date) == "undefined") {
269
    if (typeof(date) == "undefined") {
270
      date = this.stringToDate(this.input.val());
270
      date = this.stringToDate(this.input.val());
271
    };
271
    };
272
    if (!date) date = new Date();
272
    if (!date) date = new Date();
273
    
273
274
    if(this.select_week == 1 && !this.isFirstDayOfWeek(date))
274
    if(this.select_week == 1 && !this.isFirstDayOfWeek(date))
275
        date = new Date(date.getFullYear(), date.getMonth(), (date.getDate() - date.getDay() + this.start_of_week), 12, 00);  
275
        date = new Date(date.getFullYear(), date.getMonth(), (date.getDate() - date.getDay() + this.start_of_week), 12, 00);
276
  
276
277
    if(this.isNewDateAllowed(date)){
277
    if(this.isNewDateAllowed(date)){
278
        this.selectedDate = date;
278
        this.selectedDate = date;
279
        this.selectedDateString = this.dateToString(this.selectedDate);
279
        this.selectedDateString = this.dateToString(this.selectedDate);
280
        this.selectMonth(this.selectedDate);
280
        this.selectMonth(this.selectedDate);
281
    }else if((this.date_min) && this.daysBetween(this.date_min, date)<0){
281
    }else if((this.date_min) && this.daysBetween(this.date_min, date)<0){
...
...
285
    }else{
285
    }else{
286
            this.selectMonth(this.date_max);
286
            this.selectMonth(this.date_max);
287
            this.input.val(" ");
287
            this.input.val(" ");
288
    }
288
    }
289
  },
289
  },
290
  
290
291
  isNewDateAllowed: function(date){
291
  isNewDateAllowed: function(date){
292
    return ((!this.date_min) || this.daysBetween(this.date_min, date)>=0) && ((!this.date_max) || this.daysBetween(date, this.date_max)>=0);
292
    return ((!this.date_min) || this.daysBetween(this.date_min, date)>=0) && ((!this.date_max) || this.daysBetween(date, this.date_max)>=0);
293
  },
293
  },
294
294
295
  isHoliday: function(date){
295
  isHoliday: function(date){
296
    return ((this.indexFor(this.selectable_days, date.getDay())===false || this.indexFor(this.non_selectable, this.dateToString(date))!==false) || this.indexFor(this.rec_non_selectable, this.dateToShortString(date))!==false);
296
    return ((this.indexFor(this.selectable_days, date.getDay())===false || this.indexFor(this.non_selectable, this.dateToString(date))!==false) || this.indexFor(this.rec_non_selectable, this.dateToShortString(date))!==false);
297
  },
297
  },
298
  
298
299
  changeInput: function(dateString) {
299
  changeInput: function(dateString) {
300
    this.input.val(dateString).change();
300
    this.input.val(dateString).change();
301
  },
301
  },
302
  
302
303
  show: function() {
303
  show: function() {
304
    $('.error_msg', this.rootLayers).css('display', 'none');
304
    $('.error_msg', this.rootLayers).css('display', 'none');
305
    this.rootLayers.slideDown("fast");
305
    this.rootLayers.slideDown("fast");
306
    $([window, document.body]).click(this.hideIfClickOutside);
306
    $([window, document.body]).click(this.hideIfClickOutside);
307
    this.input.unbind("focus", this.show);
307
    this.input.unbind("focus", this.show);
308
    $(document.body).keydown(this.keydownHandler);
308
    $(document.body).keydown(this.keydownHandler);
309
    this.setPosition();
309
    this.setPosition();
310
    this.orig_date = this.input.val()
310
    this.orig_date = this.input.val()
311
    
311
312
  },
313
  
312
  },
313
314
  hide: function() {
314
  hide: function() {
315
    if(this.input.context.type!="hidden"){
315
    if(this.input.context.type!="hidden"){
316
        this.rootLayers.slideUp("fast");
316
        this.rootLayers.slideUp("fast");
317
        $([window, document.body]).unbind("click", this.hideIfClickOutside);
317
        $([window, document.body]).unbind("click", this.hideIfClickOutside);
318
        this.input.focus(this.show);
318
        this.input.focus(this.show);
319
        $(document.body).unbind("keydown", this.keydownHandler);
319
        $(document.body).unbind("keydown", this.keydownHandler);
320
    }
320
    }
321
  },
321
  },
322
  
322
323
  hideIfClickOutside: function(event) {
323
  hideIfClickOutside: function(event) {
324
    if (event.target != this.input[0] && !this.insideSelector(event)) {
324
    if (event.target != this.input[0] && !this.insideSelector(event)) {
325
      this.hide();
325
      this.hide();
326
    };
326
    };
327
  },
327
  },
328
  
328
329
  insideSelector: function(event) {
329
  insideSelector: function(event) {
330
    var offset = this.dateSelector.position();
330
    var offset = this.dateSelector.position();
331
    offset.right = offset.left + this.dateSelector.outerWidth();
331
    offset.right = offset.left + this.dateSelector.outerWidth();
332
    offset.bottom = offset.top + this.dateSelector.outerHeight();
332
    offset.bottom = offset.top + this.dateSelector.outerHeight();
333
    
333
334
    return event.pageY < offset.bottom &&
334
    return event.pageY < offset.bottom &&
335
           event.pageY > offset.top &&
335
           event.pageY > offset.top &&
336
           event.pageX < offset.right &&
336
           event.pageX < offset.right &&
337
           event.pageX > offset.left;
337
           event.pageX > offset.left;
338
  },
338
  },
339
  
339
340
  keydownHandler: function(event) {
340
  keydownHandler: function(event) {
341
    switch (event.keyCode)
341
    switch (event.keyCode)
342
    {
342
    {
343
      case 9: 
343
      case 9:
344
    this.hide()
344
    this.hide()
345
    return;
345
    return;
346
      break;
346
      break;
347
      case 27:
347
      case 27:
348
    this.input.val(this.orig_date)
348
    this.input.val(this.orig_date)
...
...
386
      default:
386
      default:
387
        return;
387
        return;
388
    }
388
    }
389
    event.preventDefault();
389
    event.preventDefault();
390
  },
390
  },
391
  
391
392
  stringToDate: function(string) {
392
  stringToDate: function(string) {
393
    var matches;
393
    var matches;
394
  
394
395
    if (matches = string.match(this.reg)) {
395
    if (matches = string.match(this.reg)) {
396
      if(matches[3]==0 && matches[2]==0 && matches[1]==0)
396
      if(matches[3]==0 && matches[2]==0 && matches[1]==0)
397
        return null;
397
        return null;
398
      else
398
      else
399
        return eval(this.date_decode);
399
        return eval(this.date_decode);
400
    } else {
400
    } else {
401
      return null;
401
      return null;
402
    };
402
    };
403
  },
403
  },
404
  
404
405
  dateToString: function(date) {
405
  dateToString: function(date) {
406
    return eval(this.date_encode);
406
    return eval(this.date_encode);
407
  },
407
  },
408
408
409
  dateToShortString: function(date){
409
  dateToShortString: function(date){
410
    return eval(this.date_encode_s);
410
    return eval(this.date_encode_s);
411
  },
411
  },
412
  
412
413
  setPosition: function() {
413
  setPosition: function() {
414
    var offset = this.input.offset();
414
    var offset = this.input.offset();
415
    this.rootLayers.css({
415
    this.rootLayers.css({
416
      top: offset.top + this.input.outerHeight(),
416
      top: offset.top + this.input.outerHeight(),
417
      left: offset.left
417
      left: offset.left
418
    });
418
    });
419
    
419
420
    if (this.ieframe) {
420
    if (this.ieframe) {
421
      this.ieframe.css({
421
      this.ieframe.css({
422
        width: this.dateSelector.outerWidth(),
422
        width: this.dateSelector.outerWidth(),
423
        height: this.dateSelector.outerHeight()
423
        height: this.dateSelector.outerHeight()
424
      });
424
      });
425
    };
425
    };
426
  },
426
  },
427
  
427
428
  moveDateBy: function(amount) {
428
  moveDateBy: function(amount) {
429
    var newDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate() + amount);
429
    var newDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate() + amount);
430
    this.selectDate(newDate);
430
    this.selectDate(newDate);
431
  },
431
  },
432
  
432
433
  moveDateMonthBy: function(amount) {
433
  moveDateMonthBy: function(amount) {
434
    var newDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth() + amount, this.selectedDate.getDate());
434
    var newDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth() + amount, this.selectedDate.getDate());
435
    if (newDate.getMonth() == this.selectedDate.getMonth() + amount + 1) {
435
    if (newDate.getMonth() == this.selectedDate.getMonth() + amount + 1) {
436
      newDate.setDate(0);
436
      newDate.setDate(0);
437
    };
437
    };
438
    this.selectDate(newDate);
438
    this.selectDate(newDate);
439
  },
439
  },
440
  
440
441
  moveMonthBy: function(amount) {
441
  moveMonthBy: function(amount) {
442
    if(amount<0)
442
    if(amount<0)
443
        var newMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + amount+1, -1);
443
        var newMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + amount+1, -1);
444
    else
444
    else
445
        var newMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + amount, 1);
445
        var newMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + amount, 1);
446
    this.selectMonth(newMonth);
446
    this.selectMonth(newMonth);
447
  },
447
  },
448
  
448
449
  monthName: function(date) {
449
  monthName: function(date) {
450
    return this.month_names[date.getMonth()];
450
    return this.month_names[date.getMonth()];
451
  },
451
  },
452
  
452
453
  getMonthSelect:function(){
453
  getMonthSelect:function(){
454
    var month_select = '<select>';
454
    var month_select = '<select>';
455
    for(var i = 0; i<this.month_names.length; i++){
455
    for(var i = 0; i<this.month_names.length; i++){
456
        if(i==this.currentMonth.getMonth())
456
        if(i==this.currentMonth.getMonth())
457
            month_select += '<option value="'+(i)+'" selected="selected">'+this.month_names[i]+'</option>';
457
            month_select += '<option value="'+(i)+'" selected="selected">'+this.month_names[i]+'</option>';
458
        else
458
        else
459
            month_select += '<option value="'+(i)+'">'+this.month_names[i]+'</option>';
459
            month_select += '<option value="'+(i)+'">'+this.month_names[i]+'</option>';
460
    }
460
    }
461
    month_select += '</select>';
461
    month_select += '</select>';
462
  
462
463
    return month_select;
463
    return month_select;
464
  },
464
  },
465
  
465
466
  bindToObj: function(fn) {
466
  bindToObj: function(fn) {
467
    var self = this;
467
    var self = this;
468
    return function() { return fn.apply(self, arguments) };
468
    return function() { return fn.apply(self, arguments) };
469
  },
469
  },
470
  
470
471
  bindMethodsToObj: function() {
471
  bindMethodsToObj: function() {
472
    for (var i = 0; i < arguments.length; i++) {
472
    for (var i = 0; i < arguments.length; i++) {
473
      this[arguments[i]] = this.bindToObj(this[arguments[i]]);
473
      this[arguments[i]] = this.bindToObj(this[arguments[i]]);
474
    };
474
    };
475
  },
475
  },
476
  
476
477
  indexFor: function(array, value) {
477
  indexFor: function(array, value) {
478
    for (var i = 0; i < array.length; i++) {
478
    for (var i = 0; i < array.length; i++) {
479
      if (value == array[i]) return i;
479
      if (value == array[i]) return i;
480
    };
480
    };
481
    return false;
481
    return false;
482
  },
482
  },
483
  
483
484
  monthNum: function(month_name) {
484
  monthNum: function(month_name) {
485
    return this.indexFor(this.month_names, month_name);
485
    return this.indexFor(this.month_names, month_name);
486
  },
486
  },
487
  
487
488
  shortMonthNum: function(month_name) {
488
  shortMonthNum: function(month_name) {
489
    return this.indexFor(this.short_month_names, month_name);
489
    return this.indexFor(this.short_month_names, month_name);
490
  },
490
  },
491
  
491
492
  shortDayNum: function(day_name) {
492
  shortDayNum: function(day_name) {
493
    return this.indexFor(this.short_day_names, day_name);
493
    return this.indexFor(this.short_day_names, day_name);
494
  },
494
  },
495
  
495
496
  daysBetween: function(start, end) {
496
  daysBetween: function(start, end) {
497
    start = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
497
    start = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
498
    end = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
498
    end = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
499
    return (end - start) / 86400000;
499
    return (end - start) / 86400000;
500
  },
500
  },
501
  
501
502
  changeDayTo: function(dayOfWeek, date, direction) {
502
  changeDayTo: function(dayOfWeek, date, direction) {
503
    var difference = direction * (Math.abs(date.getDay() - dayOfWeek - (direction * 7)) % 7);
503
    var difference = direction * (Math.abs(date.getDay() - dayOfWeek - (direction * 7)) % 7);
504
    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + difference);
504
    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + difference);
505
  },
505
  },
506
  
506
507
  rangeStart: function(date) {
507
  rangeStart: function(date) {
508
    return this.changeDayTo(this.start_of_week, new Date(date.getFullYear(), date.getMonth()), -1);
508
    return this.changeDayTo(this.start_of_week, new Date(date.getFullYear(), date.getMonth()), -1);
509
  },
509
  },
510
  
510
511
  rangeEnd: function(date) {
511
  rangeEnd: function(date) {
512
    return this.changeDayTo((this.start_of_week - 1) % 7, new Date(date.getFullYear(), date.getMonth() + 1, 0), 1);
512
    return this.changeDayTo((this.start_of_week - 1) % 7, new Date(date.getFullYear(), date.getMonth() + 1, 0), 1);
513
  },
513
  },
514
  
514
515
  isFirstDayOfWeek: function(date) {
515
  isFirstDayOfWeek: function(date) {
516
    return date.getDay() == this.start_of_week;
516
    return date.getDay() == this.start_of_week;
517
  },
517
  },
518
  
518
519
  getWeekNum:function(date){
519
  getWeekNum:function(date){
520
    date_week= new Date(date.getFullYear(), date.getMonth(), date.getDate()+6);
520
    date_week= new Date(date.getFullYear(), date.getMonth(), date.getDate()+6);
521
    var firstDayOfYear = new Date(date_week.getFullYear(), 0, 1, 12, 00);
521
    var firstDayOfYear = new Date(date_week.getFullYear(), 0, 1, 12, 00);
522
    var n = parseInt(this.daysBetween(firstDayOfYear, date_week)) + 1;
522
    var n = parseInt(this.daysBetween(firstDayOfYear, date_week)) + 1;
523
    return Math.floor((date_week.getDay() + n + 5)/7) - Math.floor(date_week.getDay() / 5);
523
    return Math.floor((date_week.getDay() + n + 5)/7) - Math.floor(date_week.getDay() / 5);
524
  },
524
  },
525
  
525
526
  isLastDayOfWeek: function(date) {
526
  isLastDayOfWeek: function(date) {
527
    return date.getDay() == (this.start_of_week - 1) % 7;
527
    return date.getDay() == (this.start_of_week - 1) % 7;
528
  },
528
  },
529
  
529
530
  show_error: function(error){
530
  show_error: function(error){
531
    $('.error_msg', this.rootLayers).html(error);
531
    $('.error_msg', this.rootLayers).html(error);
532
    $('.error_msg', this.rootLayers).slideDown(400, function(){
532
    $('.error_msg', this.rootLayers).slideDown(400, function(){
533
        setTimeout("$('.error_msg', this.rootLayers).slideUp(200);", 2000);
533
        setTimeout("$('.error_msg', this.rootLayers).slideUp(200);", 2000);
534
    });
534
    });
535
  },
535
  },
536
  
536
537
  adjustDays: function(days) {
537
  adjustDays: function(days) {
538
    var newDays = [];
538
    var newDays = [];
539
    for (var i = 0; i < days.length; i++) {
539
    for (var i = 0; i < days.length; i++) {
540
      newDays[i] = days[(i + this.start_of_week) % 7];
540
      newDays[i] = days[(i + this.start_of_week) % 7];
541
    };
541
    };
542
    return newDays;
542
    return newDays;
543
  },
543
  },
544
  
544
545
  strpad: function(num){
545
  strpad: function(num){
546
    if(parseInt(num)<10)    return "0"+parseInt(num);
546
    if(parseInt(num)<10)    return "0"+parseInt(num);
547
    else    return parseInt(num);
547
    else    return parseInt(num);
548
  }
548
  }
549
  
549
550
};
550
};
551
551
552
$.fn.jdPicker = function(opts) {
552
$.fn.jdPicker = function(opts) {
553
  return this.each(function() { new jdPicker(this, opts); });
553
  return this.each(function() { new jdPicker(this, opts); });
554
};
554
};
555
$.jdPicker = { initialize: function(opts) {
555
$.jdPicker = { initialize: function(opts) {
556
  $("input.jdpicker").jdPicker(opts);
556
  $("input.jdpicker").jdPicker(opts);
557
} };
557
} };
558
558
559
return jdPicker;
559
return jdPicker;
560
})(jQuery); 
560
})(jQuery);
561
561
562
$($.jdPicker.initialize);
562
$($.jdPicker.initialize);