diff options
Diffstat (limited to 'static/recurrence/js/recurrence-widget.js')
-rw-r--r-- | static/recurrence/js/recurrence-widget.js | 1795 |
1 files changed, 0 insertions, 1795 deletions
diff --git a/static/recurrence/js/recurrence-widget.js b/static/recurrence/js/recurrence-widget.js deleted file mode 100644 index f63e3b7..0000000 --- a/static/recurrence/js/recurrence-widget.js +++ /dev/null @@ -1,1795 +0,0 @@ -if (!recurrence) - var recurrence = {}; - -recurrence.widget = {}; - - -recurrence.widget.Grid = function(cols, rows) { - this.init(cols, rows); -}; -recurrence.widget.Grid.prototype = { - init: function(cols, rows) { - this.disabled = false; - this.cells = []; - this.cols = cols; - this.rows = rows; - - this.init_dom(); - }, - - init_dom: function() { - var tbody = recurrence.widget.e('tbody'); - for (var y=0; y < this.rows; y++) { - var tr = recurrence.widget.e('tr'); - tbody.appendChild(tr); - for (var x=0; x < this.cols; x++) { - var td = recurrence.widget.e('td'); - tr.appendChild(td); - this.cells.push(td); - } - } - var table = recurrence.widget.e( - 'table', { - 'class': 'grid', 'cellpadding': 0, - 'cellspacing': 0, 'border': 0}, - [tbody]); - - this.elements = {'root': table, 'table': table, 'tbody': tbody}; - }, - - cell: function(col, row) { - return this.elements.tbody.childNodes[row].childNodes[col]; - }, - - enable: function () { - recurrence.widget.remove_class('disabled'); - this.disabled = false; - }, - - disable: function () { - recurrence.widget.add_class('disabled'); - this.disabled = true; - } -}; - - -recurrence.widget.Calendar = function(date, options) { - this.init(date, options); -}; -recurrence.widget.Calendar.prototype = { - init: function(date, options) { - this.date = date || recurrence.widget.date_today(); - this.month = this.date.getMonth(); - this.year = this.date.getFullYear(); - this.options = options || {}; - - if (this.options.onchange) - this.onchange = this.options.onchange; - if (this.options.onclose) - this.onclose = this.options.onclose; - - this.init_dom(); - this.show_month(this.year, this.month); - }, - - init_dom: function() { - var calendar = this; - - // navigation - - var remove = recurrence.widget.e('a', { - 'class': 'remove', - 'href': 'javascript:void(0)', - 'title': recurrence.display.labels.remove, - 'onclick': function() { - calendar.close(); - } - }, '×'); - var year_prev = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'prev-year', - 'onclick': function() {calendar.show_prev_year();}}, - '<<'); - var year_next = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'next-year', - 'onclick': function() {calendar.show_next_year();}}, - '>>'); - var month_prev = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'prev-month', - 'onclick': function() {calendar.show_prev_month();}}, - '<'); - var month_next = recurrence.widget.e( - 'a', { - 'href': 'javascript:void(0)', 'class': 'next-month', - 'onclick': function() {calendar.show_next_month();}}, - '>'); - var month_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.months[this.month]); - - var header_elements = [ - year_prev, month_prev, month_label, month_next, year_next]; - var header_grid = new recurrence.widget.Grid(header_elements.length, 1); - recurrence.array.foreach(header_elements, function(item, i) { - header_grid.cells[i].appendChild(item); - recurrence.widget.add_class( - header_grid.cells[i], item.className); - }); - recurrence.widget.add_class(header_grid.elements.root, 'navigation'); - - // core - - var calendar_year = recurrence.widget.e( - 'div', {'class': 'year'}, this.year); - var calendar_navigation = header_grid.elements.root; - // var calendar_week = week_grid.elements.root; - var calendar_body = recurrence.widget.e('div', {'class': 'body'}); - var calendar_footer = recurrence.widget.e('div', {'class': 'footer'}); - - var td = recurrence.widget.e( - 'td', {}, - [remove, calendar_year, calendar_navigation, - calendar_body, calendar_footer]); - var tr = recurrence.widget.e('tr', {}, [td]); - var tbody = recurrence.widget.e('tbody', {}, [tr]); - var root = recurrence.widget.e( - 'table', {'class': 'recurrence-calendar'}, [tbody]); - root.style.display = 'none'; - - this.elements = { - 'root': root, - 'year': calendar_year, - 'year_prev': year_prev, - 'year_next': year_next, - 'month_prev': month_prev, - 'month_next': month_next, - 'month_label': month_label, - 'calendar_body': calendar_body - }; - }, - - get_month_grid: function(year, month) { - var calendar = this; - - var dt = new Date(year, month, 1); - var start = dt.getDay(); - var days = recurrence.date.days_in_month(dt); - var rows = Math.ceil((days + start) / 7) + 1; - var grid = new recurrence.widget.Grid(7, rows); - - var number = 1; - recurrence.array.foreach( - grid.cells, function(cell, i) { - var cell = grid.cells[i]; - if (i < 7) { - var weekday_number = i - 1; - if (weekday_number < 0) - weekday_number = 6; - else if (weekday_number > 6) - weekday_number = 0; - cell.innerHTML = recurrence.display.weekdays_oneletter[ - weekday_number]; - recurrence.widget.add_class(cell, 'header'); - } else if (i - 7 < start || number > days) { - recurrence.widget.add_class(cell, 'empty'); - } else { - recurrence.widget.add_class(cell, 'day'); - if (this.date.getDate() == number && - this.date.getFullYear() == dt.getFullYear() && - this.date.getMonth() == dt.getMonth()) - recurrence.widget.add_class(cell, 'active'); - cell.innerHTML = number; - number = number + 1; - cell.onclick = function () { - calendar.set_date( - calendar.year, calendar.month, - parseInt(this.innerHTML, 10)); - }; - } - }, this); - - return grid; - }, - - show_month: function(year, month) { - if (this.elements.calendar_body.childNodes.length) - this.elements.calendar_body.removeChild( - this.elements.calendar_body.childNodes[0]); - this.elements.month_grid = this.get_month_grid(year, month); - this.elements.calendar_body.appendChild( - this.elements.month_grid.elements.root); - this.elements.month_label.firstChild.nodeValue = ( - recurrence.display.months[this.month]); - this.elements.year.firstChild.nodeValue = this.year; - }, - - show_prev_year: function() { - this.year = this.year - 1; - this.show_month(this.year, this.month); - }, - - show_next_year: function() { - this.year = this.year + 1; - this.show_month(this.year, this.month); - }, - - show_prev_month: function() { - this.month = this.month - 1; - if (this.month < 0) { - this.month = 11; - this.year = this.year - 1; - } - this.show_month(this.year, this.month); - }, - - show_next_month: function() { - this.month = this.month + 1; - if (this.month > 11) { - this.month = 0; - this.year = this.year + 1; - } - this.show_month(this.year, this.month); - }, - - set_date: function(year, month, day) { - if (year != this.date.getFullYear() || - month != this.date.getMonth() || - day != this.date.getDate()) { - - this.date.setFullYear(year); - this.date.setMonth(month); - this.date.setDate(day); - - recurrence.array.foreach( - this.elements.month_grid.cells, function(cell) { - if (recurrence.widget.has_class(cell, 'day')) { - var number = parseInt(cell.innerHTML, 10); - if (number == day) { - recurrence.widget.add_class(cell, 'active'); - } else { - recurrence.widget.remove_class(cell, 'active'); - } - } - }); - - if (this.onchange) - this.onchange(this.date); - } - }, - - set_position: function(x, y) { - this.elements.root.style.left = x + 'px'; - this.elements.root.style.top = y + 'px'; - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - }, - - close: function() { - if (this.elements.root.parentNode) { - this.elements.root.parentNode.removeChild(this.elements.root); - if (this.onclose) - this.onclose(); - } - } -}; - - -recurrence.widget.DateSelector = function(date, options) { - this.init(date, options); -}; -recurrence.widget.DateSelector.prototype = { - init: function(date, options) { - this.disabled = false; - this.date = date; - this.calendar = null; - this.options = options || {}; - - if (this.options.onchange) - this.onchange = this.options.onchange; - - this.init_dom(); - }, - - init_dom: function() { - var dateselector = this; - - if (this.date) - var date_value = recurrence.date.format(this.date, '%Y-%m-%d'); - else - var date_value = ''; - var date_field = recurrence.widget.e( - 'input', { - 'class': 'date-field', 'size': 10, - 'value': date_value, - 'onchange': function() {dateselector.set_date(this.value);}}); - var calendar_button = recurrence.widget.e( - 'a', { - 'class': 'calendar-button', - 'href': 'javascript:void(0)', - 'title': recurrence.display.labels.calendar, - 'onclick': function() { - if (!dateselector.disabled) - dateselector.show_calendar(); - } - }, - ' '); - var root = recurrence.widget.e( - 'span', {'class': 'date-selector'}, - [date_field, calendar_button]); - - this.elements = { - 'root': root, - 'date_field': date_field, - 'calendar_button': calendar_button - }; - }, - - show_calendar: function() { - var dateselector = this; - - var calendar_blur = function(event) { - var element = event.target; - var is_in_dom = recurrence.widget.element_in_dom( - element, dateselector.calendar.elements.root); - if (!is_in_dom && - element != dateselector.elements.calendar_button) { - // clicked outside of calendar - dateselector.calendar.close(); - if (window.detachEvent) - window.detachEvent('onclick', calendar_blur); - else - window.removeEventListener('click', calendar_blur, false); - } - }; - - if (!this.calendar) { - this.calendar = new recurrence.widget.Calendar( - new Date((this.date || recurrence.widget.date_today()).valueOf()), { - 'onchange': function() { - dateselector.set_date( - recurrence.date.format(this.date, '%Y-%m-%d')); - dateselector.calendar.close(); - }, - 'onclose': function() { - if (window.detachEvent) - window.detachEvent('onclick', calendar_blur); - else - window.removeEventListener( - 'click', calendar_blur, false); - dateselector.hide_calendar(); - } - }); - document.body.appendChild(this.calendar.elements.root); - - this.calendar.show(); - this.set_calendar_position(); - - if (window.attachEvent) - window.attachEvent('onclick', calendar_blur); - else - window.addEventListener('click', calendar_blur, false); - } - }, - - set_date: function(datestring) { - var tokens = datestring.split('-'); - var year = parseInt(tokens[0], 10); - var month = parseInt(tokens[1], 10) - 1; - var day = parseInt(tokens[2], 10); - var dt = new Date(year, month, day); - - if (String(dt) == 'Invalid Date' || String(dt) == 'NaN') { - if (this.date && !this.options.allow_null) { - this.elements.date_field.value = recurrence.date.format( - this.date, '%Y-%m-%d'); - } else { - if (this.elements.date_field.value != '') { - if (this.onchange) - this.onchange(null); - } - this.elements.date_field.value = ''; - } - } else { - if (!this.date || - (year != this.date.getFullYear() || - month != this.date.getMonth() || - day != this.date.getDate())) { - - if (!this.date) - this.date = recurrence.widget.date_today(); - this.date.setFullYear(year); - this.date.setMonth(month); - this.date.setDate(day); - - this.elements.date_field.value = datestring; - - if (this.onchange) - this.onchange(this.date); - } - } - }, - - set_calendar_position: function() { - var loc = recurrence.widget.cumulative_offset( - this.elements.calendar_button); - - var calendar_x = loc[0]; - var calendar_y = loc[1]; - var calendar_right = ( - loc[0] + this.calendar.elements.root.clientWidth); - var calendar_bottom = ( - loc[1] + this.calendar.elements.root.clientHeight); - - if (calendar_right > document.scrollWidth) - calendar_x = calendar_x - ( - calendar_right - document.scrollWidth); - if (calendar_bottom > document.scrollHeight) - calendar_y = calendar_y - ( - calendar_bottom - document.scrollHeight); - - this.calendar.set_position(calendar_x, calendar_y); - }, - - hide_calendar: function() { - this.calendar = null; - }, - - enable: function () { - this.disabled = false; - this.elements.date_field.disabled = false; - }, - - disable: function () { - this.disabled = true; - this.elements.date_field.disabled = true; - if (this.calendar) - this.calendar.close(); - } -}; - - -recurrence.widget.Widget = function(textarea, options) { - this.init(textarea, options); -}; -recurrence.widget.Widget.prototype = { - init: function(textarea, options) { - if (textarea.toLowerCase) - textarea = document.getElementById(textarea); - this.selected_panel = null; - this.panels = []; - this.data = recurrence.deserialize(textarea.value); - this.textarea = textarea; - this.options = options; - - this.default_freq = options.default_freq || recurrence.WEEKLY; - - this.init_dom(); - this.init_panels(); - }, - - init_dom: function() { - var widget = this; - - var panels = recurrence.widget.e('div', {'class': 'panels'}); - var control = recurrence.widget.e('div', {'class': 'control'}); - var root = recurrence.widget.e( - 'div', {'class': this.textarea.className}, [panels, control]); - - var add_rule = new recurrence.widget.AddButton( - recurrence.display.labels.add_rule, { - 'onclick': function () {widget.add_rule();} - }); - recurrence.widget.add_class(add_rule.elements.root, 'add-rule'); - control.appendChild(add_rule.elements.root); - - var add_date = new recurrence.widget.AddButton( - recurrence.display.labels.add_date, { - 'onclick': function () {widget.add_date();} - }); - recurrence.widget.add_class(add_date.elements.root, 'add-date'); - control.appendChild(add_date.elements.root); - - this.elements = { - 'root': root, - 'panels': panels, - 'control': control - }; - - // attach immediately - this.textarea.style.display = 'none'; - this.textarea.parentNode.insertBefore( - this.elements.root, this.textarea); - }, - - init_panels: function() { - recurrence.array.foreach( - this.data.rrules, function(item) { - this.add_rule_panel(recurrence.widget.INCLUSION, item); - }, this); - recurrence.array.foreach( - this.data.exrules, function(item) { - this.add_rule_panel(recurrence.widget.EXCLUSION, item); - }, this); - recurrence.array.foreach( - this.data.rdates, function(item) { - this.add_date_panel(recurrence.widget.INCLUSION, item); - }, this); - recurrence.array.foreach( - this.data.exdates, function(item) { - this.add_date_panel(recurrence.widget.EXCLUSION, item); - }, this); - }, - - add_rule_panel: function(mode, rule) { - var panel = new recurrence.widget.Panel(this); - var form = new recurrence.widget.RuleForm(panel, mode, rule); - - panel.onexpand = function() { - if (panel.widget.selected_panel) - if (panel.widget.selected_panel != this) - panel.widget.selected_panel.collapse(); - panel.widget.selected_panel = this; - }; - panel.onremove = function() { - form.remove(); - }; - - this.elements.panels.appendChild(panel.elements.root); - this.panels.push(panel); - this.update(); - return panel; - }, - - add_date_panel: function(mode, date) { - var panel = new recurrence.widget.Panel(this); - var form = new recurrence.widget.DateForm(panel, mode, date); - - panel.onexpand = function() { - if (panel.widget.selected_panel) - if (panel.widget.selected_panel != this) - panel.widget.selected_panel.collapse(); - panel.widget.selected_panel = this; - }; - panel.onremove = function() { - form.remove(); - }; - - this.elements.panels.appendChild(panel.elements.root); - this.panels.push(panel); - this.update(); - return panel; - }, - - add_rule: function(rule) { - var rule = rule || new recurrence.Rule(this.default_freq); - this.data.rrules.push(rule); - this.add_rule_panel(recurrence.widget.INCLUSION, rule).expand(); - }, - - add_date: function(date) { - var date = date || recurrence.widget.date_today(); - this.data.rdates.push(date); - this.add_date_panel(recurrence.widget.INCLUSION, date).expand(); - }, - - update: function() { - this.textarea.value = this.data.serialize(); - } -}; - - -recurrence.widget.AddButton = function(label, options) { - this.init(label, options); -}; -recurrence.widget.AddButton.prototype = { - init: function(label, options) { - this.label = label; - this.options = options || {}; - - this.init_dom(); - }, - - init_dom: function() { - var addbutton = this; - - var plus = recurrence.widget.e( - 'span', {'class': 'plus'}, '+'); - var label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, this.label); - var root = recurrence.widget.e( - 'a', {'class': 'add-button', 'href': 'javascript:void(0)'}, - [plus, label]); - - root.onclick = function() { - addbutton.options.onclick(); - }; - - this.elements = {'root': root, 'plus': plus, 'label': label}; - } -}; - - -recurrence.widget.Panel = function(widget, options) { - this.init(widget, options); -}; -recurrence.widget.Panel.prototype = { - init: function(widget, options) { - this.collapsed = false; - this.widget = widget; - this.options = options || {}; - - if (this.options.onremove) - this.onremove = this.options.onremove; - if (this.options.onexpand) - this.onexpand = this.options.onexpand; - if (this.options.oncollapse) - this.oncollapse = this.options.oncollapse; - - this.init_dom(); - }, - - init_dom: function() { - var panel = this; - - var remove = recurrence.widget.e('a', { - 'class': 'remove', - 'href': 'javascript:void(0)', - 'title': recurrence.display.labels.remove, - 'onclick': function() { - panel.remove(); - } - }, '×'); - var label = recurrence.widget.e('a', { - 'class': 'recurrence-label', - 'href': 'javascript:void(0)', - 'onclick': function() { - if (panel.collapsed) - panel.expand(); - else - panel.collapse(); - } - }, ' '); - var header = recurrence.widget.e( - 'div', {'class': 'header'}, [remove, label]); - var body = recurrence.widget.e( - 'div', {'class': 'body'}); - var root = recurrence.widget.e( - 'div', {'class': 'panel'}, [header, body]); - - this.elements = { - 'root': root, 'remove': remove, 'label': label, - 'header': header, 'body': body - }; - - this.collapse(); - }, - - set_label: function(label) { - this.elements.label.innerHTML = label; - }, - - set_body: function(element) { - if (this.elements.body.childNodes.length) - this.elements.body.removeChild(this.elements.body.childNodes[0]); - this.elements.body.appendChild(element); - }, - - expand: function() { - this.collapsed = false; - this.elements.body.style.display = ''; - if (this.onexpand) - this.onexpand(this); - }, - - collapse: function() { - this.collapsed = true; - this.elements.body.style.display = 'none'; - if (this.oncollapse) - this.oncollapse(this); - }, - - remove: function() { - var parent = this.elements.root.parentNode; - if (parent) - parent.removeChild(this.elements.root); - if (this.onremove) - this.onremove(parent); - } -}; - - -recurrence.widget.RuleForm = function(panel, mode, rule, options) { - this.init(panel, mode, rule, options); -}; -recurrence.widget.RuleForm.prototype = { - init: function(panel, mode, rule, options) { - this.selected_freq = rule.freq; - this.panel = panel; - this.mode = mode; - this.rule = rule; - this.options = options || {}; - - var rule_options = { - interval: rule.interval, until: rule.until, count: rule.count - }; - - this.freq_rules = [ - new recurrence.Rule(recurrence.YEARLY, rule_options), - new recurrence.Rule(recurrence.MONTHLY, rule_options), - new recurrence.Rule(recurrence.WEEKLY, rule_options), - new recurrence.Rule(recurrence.DAILY, rule_options) - ]; - this.freq_rules[this.rule.freq].update(this.rule); - - this.init_dom(); - - this.set_freq(this.selected_freq); - }, - - init_dom: function() { - var form = this; - - // mode - - var mode_checkbox = recurrence.widget.e( - 'input', {'class': 'checkbox', 'type': 'checkbox', 'name': 'mode'}); - var mode_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.exclude_occurrences); - var mode_container = recurrence.widget.e( - 'div', {'class': 'mode'}, - [mode_checkbox, mode_label]); - if (this.mode == recurrence.widget.EXCLUSION) - // delay for ie6 compatibility - setTimeout(function() { - mode_checkbox.checked = true; - recurrence.widget.add_class(form.panel, 'exclusion'); - }, 10); - - // freq - - var freq_choices = recurrence.display.frequencies.slice(0, 4); - var freq_options = recurrence.array.foreach( - freq_choices, function(item, i) { - var option = recurrence.widget.e( - 'option', {'value': i}, - recurrence.string.capitalize(item)); - return option; - }); - var freq_select = recurrence.widget.e( - 'select', {'name': 'freq'}, freq_options); - var freq_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.frequency + ':'); - var freq_container = recurrence.widget.e( - 'div', {'class': 'freq'}, - [freq_label, freq_select]); - - // interval - - var interval_field = recurrence.widget.e( - 'input', { - 'name': 'interval', 'size': 1, 'value': this.rule.interval}); - var interval_label1 = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.every); - var interval_label2 = recurrence.widget.e( - 'span', {'class': 'laebl'}, - recurrence.display.timeintervals_plural[this.rule.freq]); - var interval_container = recurrence.widget.e( - 'div', {'class': 'interval'}, - [interval_label1, interval_field, interval_label2]); - - // until - - if (this.rule.until) - until_value = recurrence.date.format(this.rule.until, '%Y-%m-%d'); - else - until_value = ''; - var until_radio = recurrence.widget.e( - 'input', {'class': 'radio', 'type': 'radio', - 'name': 'until_count', 'value': 'until'}); - var until_date_selector = new recurrence.widget.DateSelector( - this.rule.until, { - 'onchange': function(date) {form.set_until(date);}, - 'allow_null': true - }); - var until_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.date + ':'); - var until_container = recurrence.widget.e( - 'li', {'class': 'until'}, - [until_radio, until_label, until_date_selector.elements.root]); - - // count - - if (this.rule.count) - count_value = this.rule.count; - else - count_value = 1; - var count_radio = recurrence.widget.e( - 'input', { - 'class': 'radio', 'type': 'radio', - 'name': 'until_count', 'value': 'count'}); - var count_field = recurrence.widget.e( - 'input', {'name': 'count', 'size': 1, 'value': count_value}); - if (this.rule.count && this.rule.count < 2) - var token = recurrence.string.capitalize( - recurrence.display.labels.count); - else - var token = recurrence.string.capitalize( - recurrence.display.labels.count_plural); - var count_label1 = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, token.split('%(number)s')[0]); - var count_label2 = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, token.split('%(number)s')[1]); - var count_container = recurrence.widget.e( - 'li', {'class': 'count'}, - [count_radio, count_label1, count_field, count_label2]); - - // limit container - - var until_count_container = recurrence.widget.e( - 'ul', {'class': 'until-count'}, - [until_container, count_container]); - var limit_checkbox = recurrence.widget.e( - 'input', { - 'class': 'checkbox', 'type': 'checkbox', - 'name': 'limit'}); - var limit_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.repeat_until + ':'); - var limit_container = recurrence.widget.e( - 'div', {'class': 'limit'}, - [limit_checkbox, limit_label, until_count_container]); - if (this.rule.until || this.rule.count) { - // compatibility with ie, we delay - setTimeout(function() {limit_checkbox.checked = true;}, 10); - } else { - until_radio.disabled = true; - count_radio.disabled = true; - until_date_selector.disable(); - recurrence.widget.add_class(until_count_container, 'disabled'); - } - - // core - - var freq_form_container = recurrence.widget.e( - 'div', {'class': 'form'}); - var root = recurrence.widget.e( - 'form', {}, [ - mode_container, freq_container, interval_container, - freq_form_container, limit_container]); - - // events - - mode_checkbox.onclick = function() { - if (this.checked) - form.set_mode(recurrence.widget.EXCLUSION); - else - form.set_mode(recurrence.widget.INCLUSION); - }; - - freq_select.onchange = function() { - form.set_freq(parseInt(this.value), 10); - }; - - interval_field.onchange = function() { - form.set_interval(parseInt(this.value), 10); - }; - - limit_checkbox.onclick = function () { - if (this.checked) { - recurrence.widget.remove_class( - until_count_container, 'disabled'); - until_radio.disabled = false; - count_radio.disabled = false; - if (until_radio.checked) { - until_date_selector.enable(); - form.set_until(until_date_selector.date); - } - if (count_radio.checked) { - count_field.disabled = false; - form.set_count(parseInt(count_field.value)); - } - } else { - recurrence.widget.add_class( - until_count_container, 'disabled'); - until_radio.disabled = true; - count_radio.disabled = true; - until_date_selector.disable(); - count_field.disabled = true; - recurrence.array.foreach( - form.freq_rules, function(rule) { - rule.until = null; - rule.count = null; - }); - form.update(); - } - } - - // for compatibility with ie, use timeout - setTimeout(function () { - if (form.rule.count) { - count_radio.checked = true; - until_date_selector.disable(); - } else { - until_radio.checked = true; - count_field.disabled = true; - } - }, 1); - - until_radio.onclick = function () { - this.checked = true; - until_date_selector.enable(); - count_radio.checked = false; - count_field.disabled = true; - form.set_until(until_date_selector.date); - }; - - count_radio.onclick = function () { - this.checked = true; - count_field.disabled = false; - until_radio.checked = false; - until_date_selector.disable(); - form.set_count(parseInt(count_field.value), 10); - }; - - count_field.onchange = function () { - form.set_count(parseInt(this.value), 10); - }; - - // freq forms - - var forms = [ - recurrence.widget.RuleYearlyForm, - recurrence.widget.RuleMonthlyForm, - recurrence.widget.RuleWeeklyForm, - recurrence.widget.RuleDailyForm - ]; - var freq_forms = recurrence.array.foreach( - forms, function(form, i) { - var rule = this.freq_rules[i]; - var f = new form(this, rule); - freq_form_container.appendChild(f.elements.root); - return f; - }, this); - - this.freq_forms = freq_forms; - - // install dom - - this.panel.set_label(this.get_display_text()); - this.panel.set_body(root); - - this.elements = { - 'root': root, - 'mode_checkbox': mode_checkbox, - 'freq_select': freq_select, - 'interval_field': interval_field, - 'freq_form_container': freq_form_container, - 'until_radio': until_radio, - 'count_field': count_field, - 'count_radio': count_radio, - 'limit_checkbox': limit_checkbox - }; - }, - - get_display_text: function() { - var text = this.freq_rules[this.selected_freq].get_display_text(); - if (this.mode == recurrence.widget.EXCLUSION) - text = recurrence.display.mode.exclusion + ' ' + text; - return recurrence.string.capitalize(text); - }, - - set_until: function(until) { - recurrence.array.foreach( - this.freq_rules, function(rule) { - rule.count = null; - rule.until = until; - }); - this.update(); - }, - - set_count: function(count) { - if (count < 2) - var token = recurrence.string.capitalize( - recurrence.display.labels.count); - else - var token = recurrence.string.capitalize( - recurrence.display.labels.count_plural); - var label1 = this.elements.count_field.previousSibling; - var label2 = this.elements.count_field.nextSibling; - label1.firstChild.nodeValue = token.split('%(number)s')[0]; - label2.firstChild.nodeValue = token.split('%(number)s')[1]; - recurrence.array.foreach( - this.freq_rules, function(rule) { - rule.until = null; - rule.count = count; - }); - this.update(); - }, - - set_interval: function(interval) { - interval = parseInt(interval, 10); - if (String(interval) == 'NaN') { - // invalid value, reset to previous value - this.elements.interval_field.value = ( - this.freq_rules[this.selected_freq].interval); - return; - } - - var label = this.elements.interval_field.nextSibling; - - if (interval < 2) - label.firstChild.nodeValue = ( - recurrence.display.timeintervals[this.selected_freq]); - else - label.firstChild.nodeValue = ( - recurrence.display.timeintervals_plural[this.selected_freq]); - recurrence.array.foreach( - this.freq_rules, function(rule) { - rule.interval = interval; - }); - - this.elements.interval_field.value = interval; - this.update(); - }, - - set_freq: function(freq) { - this.freq_forms[this.selected_freq].hide(); - this.freq_forms[freq].show(); - this.elements.freq_select.value = freq; - this.selected_freq = freq; - // need to update interval to display different label - this.set_interval(parseInt(this.elements.interval_field.value), 10); - this.update(); - }, - - set_mode: function(mode) { - if (this.mode != mode) { - if (this.mode == recurrence.widget.INCLUSION) { - recurrence.array.remove( - this.panel.widget.data.rrules, this.rule); - this.panel.widget.data.exrules.push(this.rule); - recurrence.widget.remove_class( - this.panel.elements.root, 'inclusion'); - recurrence.widget.add_class( - this.panel.elements.root, 'exclusion'); - } else { - recurrence.array.remove( - this.panel.widget.data.exrules, this.rule); - this.panel.widget.data.rrules.push(this.rule); - recurrence.widget.remove_class( - this.panel.elements.root, 'exclusion'); - recurrence.widget.add_class( - this.panel.elements.root, 'inclusion'); - } - this.mode = mode; - } - this.update(); - }, - - update: function() { - this.panel.set_label(this.get_display_text()); - this.rule.update(this.freq_rules[this.selected_freq]); - this.panel.widget.update(); - }, - - remove: function() { - var parent = this.elements.root.parentNode; - if (parent) - parent.removeChild(this.elements.root); - if (this.mode == recurrence.widget.INCLUSION) - recurrence.array.remove(this.panel.widget.data.rrules, this.rule); - else - recurrence.array.remove(this.panel.widget.data.exrules, this.rule); - this.panel.widget.update(); - } -}; - - -recurrence.widget.RuleYearlyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleYearlyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - var grid = new recurrence.widget.Grid(4, 3); - var number = 0; - for (var y=0; y < 3; y++) { - for (var x=0; x < 4; x++) { - var cell = grid.cell(x, y); - if (this.rule.bymonth.indexOf(number + 1) > -1) - recurrence.widget.add_class(cell, 'active'); - cell.value = number + 1; - cell.innerHTML = recurrence.display.months_short[number]; - cell.onclick = function () { - if (recurrence.widget.has_class(this, 'active')) - recurrence.widget.remove_class(this, 'active'); - else - recurrence.widget.add_class(this, 'active'); - form.set_bymonth(); - }; - number += 1; - } - } - - // by weekday checkbox - - var byday_checkbox = recurrence.widget.e( - 'input', { - 'class': 'checkbox', 'type': 'checkbox', - 'name': 'byday'}); - var byday_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.string.capitalize( - recurrence.display.labels.on_the) + ':'); - var byday_container = recurrence.widget.e( - 'div', {'class': 'byday'}, - [byday_checkbox, byday_label]); - - // weekday-position - - var position_options = recurrence.array.foreach( - [1, 2, 3, 4, -1, -2, -3], function(value) { - var option = recurrence.widget.e( - 'option', {'value': value}, - recurrence.string.strip(recurrence.display.weekdays_position[ - String(value)].split('%(weekday)s')[0])); - return option; - }); - var position_select = recurrence.widget.e( - 'select', {'name': 'position'}, position_options); - var weekday_options = recurrence.array.foreach( - recurrence.display.weekdays, function(weekday, i) { - var option = recurrence.widget.e( - 'option', {'value': i}, weekday); - return option; - }); - var weekday_select = recurrence.widget.e( - 'select', {'name': 'weekday'}, weekday_options); - var weekday_position_container = recurrence.widget.e( - 'div', {'class': 'section'}, [position_select, weekday_select]); - - // core - - var year = recurrence.widget.e('div'); - year.appendChild(grid.elements.root); - - var root = recurrence.widget.e( - 'div', {'class': 'yearly'}, - [year, byday_container, weekday_position_container]); - root.style.display = 'none'; - - if (this.rule.byday.length) { - if (form.rule.bysetpos.length) { - position_select.value = String(form.rule.bysetpos[0]); - } else { - position_select.value = String(form.rule.byday[0].index); - } - weekday_select.value = String(form.rule.byday[0].number); - byday_checkbox.checked = true; - } else { - position_select.disabled = true; - weekday_select.disabled = true; - } - - // events - - byday_checkbox.onclick = function () { - if (this.checked) { - position_select.disabled = false; - weekday_select.disabled = false; - form.set_byday(); - } else { - position_select.disabled = true; - weekday_select.disabled = true; - form.rule.byday = []; - form.panel.update(); - } - }; - - position_select.onchange = function () { - form.set_byday(); - }; - - weekday_select.onchange = function () { - form.set_byday(); - }; - - this.elements = { - 'root': root, - 'grid': grid, - 'byday_checkbox': byday_checkbox, - 'position_select': position_select, - 'weekday_select': weekday_select - }; - }, - - get_weekday: function() { - var number = parseInt(this.elements.weekday_select.value, 10); - var index = parseInt(this.elements.position_select.value, 10); - return new recurrence.Weekday(number, index); - }, - - set_bymonth: function() { - var bymonth = []; - recurrence.array.foreach( - this.elements.grid.cells, function(cell) { - if (recurrence.widget.has_class(cell, 'active')) - bymonth.push(cell.value); - }) - this.rule.bymonth = bymonth; - this.panel.update(); - }, - - set_byday: function() { - this.rule.byday = [this.get_weekday()]; - this.panel.update(); - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.RuleMonthlyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleMonthlyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - // monthday - - var monthday_grid = new recurrence.widget.Grid(7, Math.ceil(31 / 7)); - var number = 0; - for (var y=0; y < Math.ceil(31 / 7); y++) { - for (var x=0; x < 7; x++) { - number += 1; - var cell = monthday_grid.cell(x, y); - if (number > 31) { - recurrence.widget.add_class(cell, 'empty'); - continue; - } else { - cell.innerHTML = number; - if (this.rule.bymonthday.indexOf(number) > -1) - recurrence.widget.add_class(cell, 'active'); - cell.onclick = function () { - if (monthday_grid.disabled) - return; - var day = parseInt(this.innerHTML, 10) || null; - if (day) { - if (recurrence.widget.has_class(this, 'active')) - recurrence.widget.remove_class(this, 'active'); - else - recurrence.widget.add_class(this, 'active'); - form.set_bymonthday(); - } - } - } - } - } - var monthday_grid_container = recurrence.widget.e( - 'div', {'class': 'section'}); - monthday_grid_container.appendChild(monthday_grid.elements.root); - var monthday_radio = recurrence.widget.e( - 'input', { - 'class': 'radio', 'type': 'radio', - 'name': 'monthly', 'value': 'monthday'}); - var monthday_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.each + ':'); - var monthday_container = recurrence.widget.e( - 'li', {'class': 'monthday'}, - [monthday_radio, monthday_label, monthday_grid_container]); - - // weekday-position - - var position_options = recurrence.array.foreach( - [1, 2, 3, 4, -1, -2, -3], function(value) { - var option = recurrence.widget.e( - 'option', {'value': value}, - recurrence.string.strip( - recurrence.display.weekdays_position[ - String(value)].split('%(weekday)s')[0])); - return option; - }); - var position_select = recurrence.widget.e( - 'select', {'name': 'position'}, position_options); - - var weekday_options = recurrence.array.foreach( - recurrence.display.weekdays, function(weekday, i) { - var option = recurrence.widget.e( - 'option', {'value': i}, weekday); - return option; - }); - var weekday_select = recurrence.widget.e( - 'select', {'name': 'weekday'}, weekday_options); - var weekday_position_container = recurrence.widget.e( - 'div', {'class': 'section'}, [position_select, weekday_select]); - var weekday_radio = recurrence.widget.e( - 'input', { - 'class': 'radio', 'type': 'radio', - 'name': 'monthly', 'value': 'weekday'}); - var weekday_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.on_the + ':'); - var weekday_container = recurrence.widget.e( - 'li', {'class': 'weekday'}, - [weekday_radio, weekday_label, weekday_position_container]); - - // core - - var monthday_weekday_container = recurrence.widget.e( - 'ul', {'class': 'monthly'}, - [monthday_container, weekday_container]); - - var root = recurrence.widget.e( - 'div', {'class': 'monthly'}, [monthday_weekday_container]); - root.style.display = 'none'; - - // events - - // for compatibility with ie, use timeout - setTimeout(function () { - if (form.rule.byday.length) { - weekday_radio.checked = true; - if (form.rule.bysetpos.length) { - position_select.value = String(form.rule.bysetpos[0]); - } else { - position_select.value = String(form.rule.byday[0].index); - } - weekday_select.value = String(form.rule.byday[0].number); - monthday_grid.disable(); - } else { - monthday_radio.checked = true; - position_select.disabled = true; - weekday_select.disabled = true; - } - }, 1); - - monthday_radio.onclick = function () { - this.checked = true; - weekday_radio.checked = false; - position_select.disabled = true; - weekday_select.disabled = true; - monthday_grid.enable(); - form.set_bymonthday(); - }; - - weekday_radio.onclick = function () { - this.checked = true; - monthday_radio.checked = false; - position_select.disabled = false; - weekday_select.disabled = false; - monthday_grid.disable(); - form.set_byday(); - }; - - position_select.onchange = function () { - form.set_byday(); - }; - - weekday_select.onchange = function () { - form.set_byday(); - }; - - this.elements = { - 'root': root, - 'monthday_grid': monthday_grid, - 'monthday_radio': monthday_radio, - 'weekday_radio': weekday_radio, - 'position_select': position_select, - 'weekday_select': weekday_select - }; - }, - - get_weekday: function() { - var number = parseInt(this.elements.weekday_select.value, 10); - var index = parseInt(this.elements.position_select.value, 10); - return new recurrence.Weekday(number, index); - }, - - set_byday: function() { - this.rule.bymonthday = []; - this.rule.bysetpos = []; - this.rule.byday = [this.get_weekday()]; - this.panel.update(); - }, - - set_bymonthday: function() { - this.rule.bysetpos = []; - this.rule.byday = []; - var monthdays = []; - recurrence.array.foreach( - this.elements.monthday_grid.cells, function(cell) { - var day = parseInt(cell.innerHTML, 10) || null; - if (day && recurrence.widget.has_class(cell, 'active')) - monthdays.push(day); - }); - this.rule.bymonthday = monthdays; - this.panel.update(); - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.RuleWeeklyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleWeeklyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - var weekday_grid = new recurrence.widget.Grid(7, 1); - var days = []; - var days = recurrence.array.foreach( - this.rule.byday, function(day) { - return recurrence.to_weekday(day).number; - }); - for (var x=0; x < 7; x++) { - var cell = weekday_grid.cell(x, 0); - if (days.indexOf(x) > -1) - recurrence.widget.add_class(cell, 'active'); - cell.value = x; - cell.innerHTML = recurrence.display.weekdays_short[x]; - cell.onclick = function () { - if (weekday_grid.disabled) - return; - if (recurrence.widget.has_class(this, 'active')) - recurrence.widget.remove_class(this, 'active'); - else - recurrence.widget.add_class(this, 'active'); - form.set_byday(); - }; - } - - var weekday_container = recurrence.widget.e( - 'div', {'class': 'section'}); - weekday_container.appendChild(weekday_grid.elements.root); - var root = recurrence.widget.e( - 'div', {'class': 'weekly'}, [weekday_container]); - root.style.display = 'none'; - - this.elements = { - 'root': root, - 'weekday_grid': weekday_grid - }; - }, - - set_byday: function() { - var byday = []; - recurrence.array.foreach( - this.elements.weekday_grid.cells, function(cell) { - if (recurrence.widget.has_class(cell, 'active')) - byday.push(new recurrence.Weekday(cell.value)); - }); - this.rule.byday = byday; - this.panel.update(); - }, - - show: function() { - this.elements.root.style.display = ''; - }, - - hide: function() { - this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.RuleDailyForm = function(panel, rule) { - this.init(panel, rule); -}; -recurrence.widget.RuleDailyForm.prototype = { - init: function(panel, rule) { - this.panel = panel; - this.rule = rule; - - this.init_dom(); - }, - - init_dom: function() { - var root = recurrence.widget.e('div', {'class': 'daily'}); - root.style.display = 'none'; - this.elements = {'root': root}; - }, - - show: function() { - // this.elements.root.style.display = ''; - }, - - hide: function() { - // this.elements.root.style.display = 'none'; - } -}; - - -recurrence.widget.DateForm = function(panel, mode, date) { - this.init(panel, mode, date); -}; -recurrence.widget.DateForm.prototype = { - init: function(panel, mode, date) { - this.collapsed = true; - this.panel = panel; - this.mode = mode; - this.date = date; - - this.init_dom(); - }, - - init_dom: function() { - var form = this; - - // mode - - var mode_checkbox = recurrence.widget.e( - 'input', { - 'class': 'checkbox', 'type': 'checkbox', 'name': 'mode', - 'onclick': function() { - if (this.checked) - form.set_mode(recurrence.widget.EXCLUSION); - else - form.set_mode(recurrence.widget.INCLUSION); - } - }); - if (this.mode == recurrence.widget.EXCLUSION) - mode_checkbox.checked = true; - var mode_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, - recurrence.display.labels.exclude_date); - var mode_container = recurrence.widget.e( - 'div', {'class': 'mode'}, [mode_checkbox, mode_label]); - - // date - - var date_label = recurrence.widget.e( - 'span', {'class': 'recurrence-label'}, recurrence.display.labels.date + ':'); - var date_selector = new recurrence.widget.DateSelector( - this.date, {'onchange': function() {form.update();}}); - var date_container = recurrence.widget.e( - 'div', {'class': 'date'}, [date_label, date_selector.elements.root]); - - // core - - var root = recurrence.widget.e( - 'form', {'class': 'date'}, [mode_container, date_container]); - - // init dom - - this.panel.set_label(this.get_display_text()); - this.panel.set_body(root); - this.elements = {'root': root}; - }, - - get_display_text: function() { - var text = recurrence.date.format(this.date, pgettext('date', '%l, %F %j, %Y')); - if (this.mode == recurrence.widget.EXCLUSION) - text = recurrence.display.mode.exclusion + ' ' + text; - return recurrence.string.capitalize(text); - }, - - set_mode: function(mode) { - if (this.mode != mode) { - if (this.mode == recurrence.widget.INCLUSION) { - recurrence.array.remove( - this.panel.widget.data.rdates, this.date); - this.panel.widget.data.exdates.push(this.date); - recurrence.widget.remove_class( - this.elements.root, 'inclusion'); - recurrence.widget.add_class( - this.elements.root, 'exclusion'); - this.update(); - } else { - recurrence.array.remove( - this.panel.widget.data.exdates, this.date); - this.panel.widget.data.rdates.push(this.date); - recurrence.widget.remove_class( - this.elements.root, 'exclusion'); - recurrence.widget.add_class( - this.elements.root, 'inclusion'); - this.update(); - } - this.mode = mode; - } - this.update(); - }, - - update: function() { - this.panel.set_label(this.get_display_text()); - this.panel.widget.update(); - }, - - remove: function() { - var parent = this.elements.root.parentNode; - if (parent) - parent.removeChild(this.elements.root); - if (this.mode == recurrence.widget.INCLUSION) - recurrence.array.remove(this.panel.widget.data.rdates, this.date); - else - recurrence.array.remove(this.panel.widget.data.exdates, this.date); - this.panel.widget.update(); - } -}; - - -recurrence.widget.e = function(tag_name, attrs, inner) { - var element = document.createElement(tag_name); - if (attrs) - recurrence.widget.set_attrs(element, attrs); - if (inner) { - if (!inner.toLowerCase && inner.length) - recurrence.array.foreach( - inner, function(e) {element.appendChild(e);}); - else - element.innerHTML = inner; - } - return element; -}; - - -recurrence.widget.set_attrs = function(element, attrs) { - for (var attname in attrs) - if (attname.match(/^on/g)) - element[attname] = attrs[attname]; - else if (attname == 'class') - element.className = attrs[attname]; - else - element.setAttribute(attname, attrs[attname]); -}; - - -recurrence.widget.add_class = function(element, class_name) { - var names = (element.className || '').split(/[ \r\n\t]+/g); - if (names.indexOf(class_name) == -1) { - names.push(class_name); - element.className = names.join(' '); - } -}; - - -recurrence.widget.remove_class = function(element, class_name) { - var names = (element.className || '').split(/[ \r\n\t]+/g); - if (names.indexOf(class_name) > -1) { - recurrence.array.remove(names, class_name); - element.className = names.join(' '); - } -}; - - -recurrence.widget.has_class = function(element, class_name) { - var names = (element.className || '').split(/[ \r\n\t]+/g); - if (names.indexOf(class_name) > -1) - return true; - else - return false; -}; - - -recurrence.widget.element_in_dom = function(element, dom) { - if (element == dom) { - return true; - } else { - for (var i=0; i < dom.childNodes.length; i++) - if (recurrence.widget.element_in_dom(element, dom.childNodes[i])) - return true; - } - return false; -}; - - -recurrence.widget.cumulative_offset = function(element) { - var y = 0, x = 0; - do { - y += element.offsetTop || 0; - x += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return [x, y]; -}; - - -recurrence.widget.textareas_to_widgets = function(token) { - var elements = []; - if (!token) - token = 'recurrence-widget'; - if (token.toLowerCase) { - var textareas = document.getElementsByTagName('textarea'); - recurrence.array.foreach( - textareas, function(textarea) { - if (recurrence.widget.has_class(textarea, token)) - elements.push(textarea); - }); - } - recurrence.array.foreach( - elements, function(e) { - new recurrence.widget.Widget(e, window[e.id] || {}); - }); -}; - - -recurrence.widget.date_today = function() { - var date = new Date(); - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - return date; -}; - - -recurrence.widget.INCLUSION = true; -recurrence.widget.EXCLUSION = false; - - -// display - - -if (!recurrence.display) - recurrence.display = {}; - -recurrence.display.mode = { - 'inclusion': gettext('including'), 'exclusion': gettext('excluding') -}; - -recurrence.display.labels = { - 'frequency': gettext('Frequency'), - 'on_the': gettext('On the'), - 'each': gettext('Each'), - 'every': gettext('Every'), - 'until': gettext('Until'), - 'count': gettext('Occurs %(number)s time'), - 'count_plural': gettext('Occurs %(number)s times'), - 'date': gettext('Date'), - 'time': gettext('Time'), - 'repeat_until': gettext('Repeat until'), - 'exclude_occurrences': gettext('Exclude these occurences'), - 'exclude_date': gettext('Exclude this date'), - 'add_rule': gettext('Add rule'), - 'add_date': gettext('Add date'), - 'remove': gettext('Remove'), - 'calendar': gettext('Calendar') -}; |