diff --git a/libraries.txt b/libraries.txt index 968a487cd..3fc8feb7a 100644 --- a/libraries.txt +++ b/libraries.txt @@ -15,5 +15,7 @@ Require.js 2.1.18 BSD/MIT http://requirejs.org/ Underscore.js 1.8.3 MIT http://underscorejs.org/ Underscore.string 387ab72d49 MIT http://epeli.github.io/underscore.string/ Backform.js 5859b4f9db MIT https://github.com/AmiliaApp/backform +Backbone 1.1.2 MIT http://backbonejs.org font-Awesome 4.3 SIL OFL http://fortawesome.github.io/Font-Awesome/ font-mfizz 1.2 MIT http://fizzed.com/oss/font-mfizz +backgrid.js 0.3.5 MIT http://backgridjs.com/ diff --git a/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js b/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js index 1632d79a1..7600fbf5a 100644 --- a/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js +++ b/web/pgadmin/browser/server_groups/templates/server_groups/server_groups.js @@ -32,8 +32,13 @@ function($, _, pgAdmin, Backbone) { name: null }, schema: [ - {id: 'id', label: 'ID', type: 'int', group: null, mode: ['properties']}, - {id: 'name', label:'Name', type: 'text', group: null, mode: ['properties', 'edit', 'create']} + { + id: 'id', label: 'ID', type: 'int', group: null, + mode: ['properties'] + },{ + id: 'name', label:'Name', type: 'text', group: null, + mode: ['properties', 'edit', 'create'] + } ], validate: function(attrs, options) { if (!this.isNew() && 'id' in this.changed) { diff --git a/web/pgadmin/browser/templates/browser/js/browser.js b/web/pgadmin/browser/templates/browser/js/browser.js index 85ec212d5..38822bd5a 100644 --- a/web/pgadmin/browser/templates/browser/js/browser.js +++ b/web/pgadmin/browser/templates/browser/js/browser.js @@ -52,8 +52,7 @@ OWNER TO helpdesk;\n'; if (d && obj.Nodes[d._type].callbacks['selected'] && _.isFunction(obj.Nodes[d._type].callbacks['selected'])) { return obj.Nodes[d._type].callbacks['selected'].apply( - obj.Nodes[d._type], - [{ data: d, browser: obj, item: i }]); + obj.Nodes[d._type], [i]); } } }; @@ -442,10 +441,8 @@ OWNER TO helpdesk;\n'; typeof obj.Nodes[d._type].callbacks[eventName] == 'function') { return obj.Nodes[d._type].callbacks[eventName].apply( - obj.Nodes[d._type], [{ - data: d, browser: obj, item: item, - eventName: eventName, options: options - }]); + obj.Nodes[d._type], [item, eventName, options] + ); } } switch (eventName) { @@ -618,7 +615,8 @@ OWNER TO helpdesk;\n'; }, messages: { 'server_lost': '{{ _('Connection to the server has been lost!') }}', - 'click_for_detailed_msg': '{{ _('%s

click here for details!') }}' + 'click_for_detailed_msg': '{{ _('%s

click here for details!') }}', + 'general_cateogty': '{{ _('General') }}' } }); diff --git a/web/pgadmin/browser/templates/browser/js/node.js b/web/pgadmin/browser/templates/browser/js/node.js index 61b22fcbc..0e1f2c7ce 100644 --- a/web/pgadmin/browser/templates/browser/js/node.js +++ b/web/pgadmin/browser/templates/browser/js/node.js @@ -46,38 +46,6 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { return child; }; - // Defines - which control needs to be instantiated in different modes. - // i.e. Node properties, create, edit, etc. - var controlType = { - 'properties': { - 'int': 'uneditable-input', - 'text': 'uneditable-input', - 'numeric': 'uneditable-input', - 'date': 'date', - 'boolean': 'bool-text', - 'options': Backform.ReadonlyOptionControl, - 'multiline': 'textarea' - }, - 'edit': { - 'int': 'input', - 'text': 'input', - 'numeric': 'input', - 'date': 'date', - 'boolean': 'boolean', - 'options': 'select', - 'multiline': 'textarea' - }, - 'create': { - 'int': 'input', - 'text': 'input', - 'numeric': 'input', - 'date': 'date', - 'boolean': 'boolean', - 'options': 'select', - 'multiline': 'textarea' - } - }; - _.extend(pgAdmin.Browser.Node, { // Node type type: undefined, @@ -115,9 +83,9 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { // // Used to generate view for the particular node properties, edit, // creation. - getView: function(type, el, node, formType, callback) { + getView: function(type, el, node, formType, callback, data) { - if (!this.type || this.type == '' || !type in controlType) + if (!this.type || this.type == '') // We have no information, how to generate view for this type. return null; @@ -131,62 +99,25 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { // node. return null; - var opts = {}; + var attrs = {}; // In order to get the object data from the server, we must set // object-id in the model (except in the create mode). if (type !== 'create') { - opts[this.model.idAttribute || 'id'] = node._id; + attrs[this.model.idAttribute || 'id'] = node._id; } // We know - which data model to be used for this object. - var newModel = new (this.model.extend({urlRoot: urlBase}))(opts); + var newModel = new (this.model.extend({urlRoot: urlBase}))(attrs, { + onChangeData: data, + onChangeCallback: callback + }), + groups = Backform.generateViewSchema(newModel, type); // 'schema' has the information about how to generate the form. - if (newModel.schema && _.isArray(newModel.schema)) { - var groups = {}; - - _.each(newModel.schema, function(f) { - // Do we understand - what control, we're creating - // here? - if (f && f.mode && _.isObject(f.mode) && - _.indexOf(f.mode, type) != -1 && - type in controlType) { - // Each field is kept in specified group, or in - // 'General' category. - var group = f.group || '{{ _("General") }}'; - - // Generate the empty group list (if not exists) - if (!groups[group]) { - groups[group] = []; - } - - // Temporarily store in dictionaly format for - // utilizing it later. - groups[group].push({ - name: f.id, label: f.label, - control: controlType[type][f.type], - // Do we need to show this control in this mode? - visible: f.show && newModel[f.show] && - typeof newModel[f.show] == "function" ? - newModel[f.show] : f.show, - // This can be disabled in some cases (if not hidden) - disabled: (type == 'properties' ? true : ( - f.disabled && newModel[f.disabled] && - typeof newModel[f.disabled] == "function" ? - newModel[f.disabled] : undefined)), - options: f.options - }); - } - }); - - // Do we have fields to genreate controls, which we - // understand? - if (_.isEmpty(groups)) { - return null; - } - + if (groups) { var fields = []; + // This will contain the actual view var view; @@ -214,34 +145,24 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { // This is definetely not in create mode newModel.fetch() .success(function(res, msg, xhr) { - if (res) { - // We got the latest attributes of the - // object. Render the view now. - view.render(); - if (typeof(callback) != "undefined") { - callback(view); - } - } + // We got the latest attributes of the + // object. Render the view now. + view.render(); }) - .error(function(m, jqxhr) { + .error(function(jqxhr, error, message) { // TODO:: We may not want to continue from here - console.log(arguments); Alertify.pgNotifier( - "error", jqxhr, + error, jqxhr, S( "{{ _("Error fetching the properties - %%s!") }}" - ).sprintf(jqxhr.statusText).value() + ).sprintf(message).value() ); }); } else { // Yay - render the view now! view.render(); - if (typeof(callback) != "undefined") { - callback(view); - } } } - return view; } @@ -475,7 +396,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { null).show() }, // Callback called - when a node is selected in browser tree. - selected: function(o) { + selected: function(item) { // Show the information about the selected node in the below panels, // which are visible at this time: // + Properties @@ -483,53 +404,54 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { // + Dependents // + Dependencies // + Statistics + var b = pgBrowser, + t = b.tree, + d = t.itemData(item); // Update the menu items - pgAdmin.Browser.enable_disable_menus.apply(o.browser, [o.item]); + pgAdmin.Browser.enable_disable_menus.apply(b, [item]); - if (o && o.data && o.browser) { - var br = o.browser; - if ('properties' in br.panels && - br.panels['properties'] && - br.panels['properties'].panel && - br.panels['properties'].panel.isVisible()) { + if (d && b) { + if ('properties' in b.panels && + b.panels['properties'] && + b.panels['properties'].panel && + b.panels['properties'].panel.isVisible()) { // Show object properties (only when the 'properties' tab // is active). - this.showProperties(o.item, o.data, - pgBrowser.panels['properties'].panel); + this.showProperties(item, d, b.panels['properties'].panel); } - if ('sql' in br.panels && - br.panels['sql'] && - br.panels['sql'].panel && - br.panels['sql'].panel.isVisible()) { + if ('sql' in b.panels && + b.panels['sql'] && + b.panels['sql'].panel && + b.panels['sql'].panel.isVisible()) { // TODO:: Show reverse engineered query for this object (when 'sql' // tab is active.) } - if ('statistics' in br.panels && - br.panels['statistics'] && - br.panels['statistics'].panel && - br.panels['statistics'].panel.isVisible()) { + if ('statistics' in b.panels && + b.panels['statistics'] && + b.panels['statistics'].panel && + b.panels['statistics'].panel.isVisible()) { // TODO:: Show statistics for this object (when the 'statistics' // tab is active.) } - if ('dependencies' in br.panels && - br.panels['dependencies'] && - br.panels['dependencies'].panel && - br.panels['dependencies'].panel.isVisible()) { + if ('dependencies' in b.panels && + b.panels['dependencies'] && + b.panels['dependencies'].panel && + b.panels['dependencies'].panel.isVisible()) { // TODO:: Show dependencies for this object (when the // 'dependencies' tab is active.) } - if ('dependents' in br.panels && - br.panels['dependents'] && - br.panels['dependents'].panel && - br.panels['dependents'].panel.isVisible()) { + if ('dependents' in b.panels && + b.panels['dependents'] && + b.panels['dependents'].panel && + b.panels['dependents'].panel.isVisible()) { // TODO:: Show dependents for this object (when the 'dependents' // tab is active.) } } }, - refresh_node: function(args) { - this.callbacks.selected(); + refresh_node: function(item) { + this.callbacks.selected(undefined, item); } }, /********************************************************************** @@ -544,7 +466,7 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { tree = pgAdmin.Browser.tree, j = panel.$container.find('.obj_properties').first(), view = j.data('obj-view'), - content = $('
') + content = $('
') .addClass('pg-prop-content col-xs-12'), // Template function to create the button-group createButtons = function(buttons, extraClasses) { @@ -644,9 +566,27 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { } // Make sure the HTML element is empty. j.empty(); - // Create a view to edit/create the properties in fieldsets - view = that.getView(action, content, data, 'dialog'); + var modelChanged = function(m, o) { + var btnGroup = o.find('.pg-prop-btn-group'), + btnSave = btnGroup.find('button[type="save"]'), + btnReset = btnGroup.find('button[type="reset"]'); + + if (m.sessChanged()) { + btnSave.prop('disabled', false); + btnSave.removeAttr('disabled'); + btnReset.prop('disabled', false); + btnReset.removeAttr('disabled'); + } else { + btnSave.prop('disabled', true); + btnSave.attr('disabled', 'disabled'); + btnReset.prop('disabled', true); + btnReset.attr('disabled', 'disabled'); + } + }; + + // Create a view to edit/create the properties in fieldsets + view = that.getView(action, content, data, 'dialog', modelChanged, j); if (view) { // Save it to release it later j.data('obj-view', view); @@ -659,14 +599,13 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { register: function(btn) { // Save the changes btn.click(function() { - var m = view.model, - c = m.isNew() ? m.attributes : - m.changedAttributes(); + d = m.toJSON(true); - if (c && !_.isEmpty(c)) { - m.save({} ,{ - attrs: m.attributes, + if (d && !_.isEmpty(d)) { + m.save({}, { + attrs: d, + validate: false, success: function() { onSaveFunc.call(); }, @@ -858,14 +797,70 @@ function($, _, S, pgAdmin, Menu, Backbone, Alertify, Backform) { return args[arg]; }); }, + Collection: Backbone.Collection.extend({ + }), // Base class for Node Model Model: Backbone.Model.extend({ parse: function(res) { + var self = this; if ('node' in res && res['node']) { - this.tnode = _.extend({}, res.node); + self.tnode = _.extend({}, res.node); delete res.node; } + if (self.schema && _.isArray(self.schema)) { + _.each(self.schema, function(s) { + if (s.id in res) { + var o; + switch(s.type) { + case 'collection': + o = self.get(s.id) + o.reset(res[s.id], [{silent: true}]); + res[s.id] = o; + break; + case 'model': + o = self.get(s.id); + o.set(res[s.id], [{silent: true}]); + res[s.id] = o; + break; + default: + break; + } + } + }); + } return res; + }, + initialize: function(attributes, options) { + var self = this; + + if (this.schema && _.isArray(this.schema)) { + _.each(this.schema, function(s) { + var obj = null; + switch(s.type) { + case 'collection': + if (_.isString(s.model) && + s.model in pgBrowser.Nodes) { + var node = pgBrowser.Nodes[s.model]; + obj = new (node.Collection)(null, {model: node.model}); + } else { + obj = new (pgBrowser.Node.Collection)(null, {model: s.model}); + } + break; + case 'model': + if (_.isString(s.model) && + s.model in pgBrowser.Nodes[s.model]) { + obj = new (pgBrowser.Nodes[s.model].Model)(null); + } else { + obj = new (s.model)(null); + } + break; + default: + return; + } + obj.name = s.id; + self.set(s.id, obj, {silent: true}); + }); + } } }) }); diff --git a/web/pgadmin/static/css/backgrid/backgrid.css b/web/pgadmin/static/css/backgrid/backgrid.css new file mode 100644 index 000000000..7eb59697f --- /dev/null +++ b/web/pgadmin/static/css/backgrid/backgrid.css @@ -0,0 +1,240 @@ +/* + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. +*/ + +.backgrid-container { + position: relative; + display: block; + width: 100%; + height: 465px; + padding: 0; + overflow: auto; + border: 0; +} + +.backgrid { + width: 100%; + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.backgrid th, +.backgrid td { + display: none; + height: 20px; + max-width: 250px; + padding: 4px 5px; + overflow: hidden; + line-height: 20px; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; + vertical-align: middle; + border-bottom: 1px solid #DDD; +} + +.backgrid th.renderable, +.backgrid td.renderable { + display: table-cell; +} + +.backgrid th { + font-weight: bold; + text-align: center; +} + +.backgrid th.sortable a { + text-decoration: none; + white-space: nowrap; + cursor: pointer; +} + +.backgrid thead th { + vertical-align: bottom; + background-color: #f9f9f9; +} + +.backgrid thead th a { + display: block; +} + +.backgrid.backgrid-striped tbody tr:nth-child(even) { + background-color: #f9f9f9; +} + +.backgrid tbody tr.empty { + font-style: italic; + color: gray; +} + +.backgrid tbody tr.empty td { + display: inherit; + text-align: center; +} + +.backgrid td.editor { + padding: 0; +} + +.backgrid td.editor, +.backgrid tbody tr:nth-child(odd) td.editor { + background-color: rgba(82, 168, 236, 0.1); + outline: 1px solid rgba(82, 168, 236, 0.8); + outline-offset: -1px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition-duration: 200ms; + -moz-transition-duration: 200ms; + -o-transition-duration: 200ms; + transition-duration: 200ms; + -webkit-transition-property: width, outline, background-color; + -moz-transition-property: width, outline, background-color; + -o-transition-property: width, outline, background-color; + transition-property: width, outline, background-color; + -webkit-transition-timing-function: ease-in-out; + -moz-transition-timing-function: ease-in-out; + -o-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; +} + +.backgrid td.editor input[type=text] { + display: block; + width: 100%; + height: 100%; + padding: 0 5px; + margin: 0; + background-color: transparent; + border: 0; + outline: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; +} + +.backgrid td.editor input[type=text]::-ms-clear { + display: none; +} + +.backgrid td.error, +.backgrid tbody tr:nth-child(odd) td.error { + background-color: rgba(255, 210, 77, 0.1); + outline: 1px solid #ffd24d; +} + +.backgrid td.editor :focus, +.backgrid th.editor :focus { + outline: 0; +} + +.backgrid .sort-caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.3em; + border: 0; + content: ""; +} + +.backgrid .ascending .sort-caret { + vertical-align: baseline; + border-top: none; + border-right: 4px solid transparent; + border-bottom: 4px solid #000000; + border-left: 4px solid transparent; +} + +.backgrid .descending .sort-caret { + vertical-align: super; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-bottom: none; + border-left: 4px solid transparent; +} + +.backgrid .string-cell, +.backgrid .uri-cell, +.backgrid .email-cell, +.backgrid .string-cell.editor input[type=text], +.backgrid .uri-cell.editor input[type=text], +.backgrid .email-cell.editor input[type=text] { + text-align: left; +} + +.backgrid .date-cell, +.backgrid .time-cell, +.backgrid .datetime-cell, +.backgrid .number-cell, +.backgrid .integer-cell, +.backgrid .percent-cell, +.backgrid .date-cell.editor input[type=text], +.backgrid .time-cell.editor input[type=text], +.backgrid .datetime-cell.editor input[type=text], +.backgrid .number-cell.editor input[type=text], +.backgrid .integer-cell.editor input[type=text], +.backgrid .percent-cell.editor input[type=text] { + text-align: right; +} + +.backgrid .boolean-cell, +.backgrid .boolean-cell.editor input[type=checkbox] { + text-align: center; +} + +.backgrid .select-cell { + text-align: center; +} + +.backgrid .select-cell.editor { + padding: 0; +} + +.backgrid .select-cell.editor select { + display: block; + width: 100%; + height: 28px; + padding: 4px 5px; + margin: 0; + line-height: 28px; + vertical-align: middle; + background-color: white; + border: 0; + outline: 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.backgrid .select-cell.editor select[multiple] { + height: auto; +} + +.backgrid .select-cell.editor :focus { + border: 0; + outline: 0; +} + +.backgrid .select-cell.editor select::-moz-focus-inner, +.backgrid .select-cell.editor optgroup::-moz-focus-inner, +.backgrid .select-cell.editor option::-moz-focus-inner, +.backgrid .select-cell.editor select::-o-focus-inner, +.backgrid .select-cell.editor optgroup::-o-focus-inner, +.backgrid .select-cell.editor option::-o-focus-inner { + border: 0; +} \ No newline at end of file diff --git a/web/pgadmin/static/css/backgrid/backgrid.min.css b/web/pgadmin/static/css/backgrid/backgrid.min.css new file mode 100644 index 000000000..764e79997 --- /dev/null +++ b/web/pgadmin/static/css/backgrid/backgrid.min.css @@ -0,0 +1 @@ +.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{display:none;height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;border-bottom:1px solid #DDD}.backgrid th.renderable,.backgrid td.renderable{display:table-cell}.backgrid th{font-weight:bold;text-align:center}.backgrid th.sortable a{text-decoration:none;white-space:nowrap;cursor:pointer}.backgrid thead th{vertical-align:bottom;background-color:#f9f9f9}.backgrid thead th a{display:block}.backgrid.backgrid-striped tbody tr:nth-child(even){background-color:#f9f9f9}.backgrid tbody tr.empty{font-style:italic;color:gray}.backgrid tbody tr.empty td{display:inherit;text-align:center}.backgrid td.editor{padding:0}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0 5px;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.editor input[type=text]::-ms-clear{display:none}.backgrid td.error,.backgrid tbody tr:nth-child(odd) td.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}.backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .percent-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text],.backgrid .percent-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor select[multiple]{height:auto}.backgrid .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0} \ No newline at end of file diff --git a/web/pgadmin/static/css/bootstrap-datepicker3.css b/web/pgadmin/static/css/bootstrap-datepicker3.css index fa369ca95..1540d0b68 100644 --- a/web/pgadmin/static/css/bootstrap-datepicker3.css +++ b/web/pgadmin/static/css/bootstrap-datepicker3.css @@ -1,5 +1,5 @@ /*! - * Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker) + * Datepicker for Bootstrap v1.5.0 (https://github.com/eternicode/bootstrap-datepicker) * * Copyright 2012 Stefan Petre * Improvements by Andrew Rowls @@ -21,13 +21,14 @@ .datepicker-dropdown { top: 0; left: 0; + padding: 4px; } .datepicker-dropdown:before { content: ''; display: inline-block; border-left: 7px solid transparent; border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; + border-bottom: 7px solid rgba(0, 0, 0, 0.15); border-top: 0; border-bottom-color: rgba(0, 0, 0, 0.2); position: absolute; @@ -37,7 +38,7 @@ display: inline-block; border-left: 6px solid transparent; border-right: 6px solid transparent; - border-bottom: 6px solid #fff; + border-bottom: 6px solid #ffffff; border-top: 0; position: absolute; } @@ -53,30 +54,25 @@ .datepicker-dropdown.datepicker-orient-right:after { right: 7px; } -.datepicker-dropdown.datepicker-orient-top:before { +.datepicker-dropdown.datepicker-orient-bottom:before { top: -7px; } -.datepicker-dropdown.datepicker-orient-top:after { +.datepicker-dropdown.datepicker-orient-bottom:after { top: -6px; } -.datepicker-dropdown.datepicker-orient-bottom:before { +.datepicker-dropdown.datepicker-orient-top:before { bottom: -7px; border-bottom: 0; - border-top: 7px solid #999; + border-top: 7px solid rgba(0, 0, 0, 0.15); } -.datepicker-dropdown.datepicker-orient-bottom:after { +.datepicker-dropdown.datepicker-orient-top:after { bottom: -6px; border-bottom: 0; - border-top: 6px solid #fff; + border-top: 6px solid #ffffff; } .datepicker > div { display: none; } -.datepicker.days .datepicker-days, -.datepicker.months .datepicker-months, -.datepicker.years .datepicker-years { - display: block; -} .datepicker table { margin: 0; -webkit-touch-callout: none; @@ -98,470 +94,486 @@ .table-striped .datepicker table tr th { background-color: transparent; } -.datepicker table tr td.day:hover, -.datepicker table tr td.day.focused { - background: #eeeeee; - cursor: pointer; -} .datepicker table tr td.old, .datepicker table tr td.new { color: #999999; } +.datepicker table tr td.day:hover, +.datepicker table tr td.focused { + background: #eeeeee; + cursor: pointer; +} .datepicker table tr td.disabled, .datepicker table tr td.disabled:hover { background: none; color: #999999; cursor: default; } -.datepicker table tr td.today, -.datepicker table tr td.today:hover, -.datepicker table tr td.today.disabled, -.datepicker table tr td.today.disabled:hover { +.datepicker table tr td.highlighted { + color: #000000; + background-color: #d9edf7; + border-color: #85c5e5; + border-radius: 0; +} +.datepicker table tr td.highlighted:focus, +.datepicker table tr td.highlighted.focus { + color: #000000; + background-color: #afd9ee; + border-color: #298fc2; +} +.datepicker table tr td.highlighted:hover { + color: #000000; + background-color: #afd9ee; + border-color: #52addb; +} +.datepicker table tr td.highlighted:active, +.datepicker table tr td.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.highlighted { + color: #000000; + background-color: #afd9ee; + border-color: #52addb; +} +.datepicker table tr td.highlighted:active:hover, +.datepicker table tr td.highlighted.active:hover, +.open > .dropdown-toggle.datepicker table tr td.highlighted:hover, +.datepicker table tr td.highlighted:active:focus, +.datepicker table tr td.highlighted.active:focus, +.open > .dropdown-toggle.datepicker table tr td.highlighted:focus, +.datepicker table tr td.highlighted:active.focus, +.datepicker table tr td.highlighted.active.focus, +.open > .dropdown-toggle.datepicker table tr td.highlighted.focus { + color: #000000; + background-color: #91cbe8; + border-color: #298fc2; +} +.datepicker table tr td.highlighted:active, +.datepicker table tr td.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.highlighted { + background-image: none; +} +.datepicker table tr td.highlighted.disabled:hover, +.datepicker table tr td.highlighted[disabled]:hover, +fieldset[disabled] .datepicker table tr td.highlighted:hover, +.datepicker table tr td.highlighted.disabled:focus, +.datepicker table tr td.highlighted[disabled]:focus, +fieldset[disabled] .datepicker table tr td.highlighted:focus, +.datepicker table tr td.highlighted.disabled.focus, +.datepicker table tr td.highlighted[disabled].focus, +fieldset[disabled] .datepicker table tr td.highlighted.focus { + background-color: #d9edf7; + border-color: #85c5e5; +} +.datepicker table tr td.highlighted.focused { + background: #afd9ee; +} +.datepicker table tr td.highlighted.disabled, +.datepicker table tr td.highlighted.disabled:active { + background: #d9edf7; + color: #999999; +} +.datepicker table tr td.today { color: #000000; background-color: #ffdb99; border-color: #ffb733; } -.datepicker table tr td.today:hover, -.datepicker table tr td.today:hover:hover, -.datepicker table tr td.today.disabled:hover, -.datepicker table tr td.today.disabled:hover:hover, .datepicker table tr td.today:focus, -.datepicker table tr td.today:hover:focus, -.datepicker table tr td.today.disabled:focus, -.datepicker table tr td.today.disabled:hover:focus, -.datepicker table tr td.today:active, -.datepicker table tr td.today:hover:active, -.datepicker table tr td.today.disabled:active, -.datepicker table tr td.today.disabled:hover:active, -.datepicker table tr td.today.active, -.datepicker table tr td.today:hover.active, -.datepicker table tr td.today.disabled.active, -.datepicker table tr td.today.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.today, -.open .dropdown-toggle.datepicker table tr td.today:hover, -.open .dropdown-toggle.datepicker table tr td.today.disabled, -.open .dropdown-toggle.datepicker table tr td.today.disabled:hover { +.datepicker table tr td.today.focus { color: #000000; - background-color: #ffcd70; + background-color: #ffc966; + border-color: #b37400; +} +.datepicker table tr td.today:hover { + color: #000000; + background-color: #ffc966; border-color: #f59e00; } .datepicker table tr td.today:active, -.datepicker table tr td.today:hover:active, -.datepicker table tr td.today.disabled:active, -.datepicker table tr td.today.disabled:hover:active, .datepicker table tr td.today.active, -.datepicker table tr td.today:hover.active, -.datepicker table tr td.today.disabled.active, -.datepicker table tr td.today.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.today, -.open .dropdown-toggle.datepicker table tr td.today:hover, -.open .dropdown-toggle.datepicker table tr td.today.disabled, -.open .dropdown-toggle.datepicker table tr td.today.disabled:hover { +.open > .dropdown-toggle.datepicker table tr td.today { + color: #000000; + background-color: #ffc966; + border-color: #f59e00; +} +.datepicker table tr td.today:active:hover, +.datepicker table tr td.today.active:hover, +.open > .dropdown-toggle.datepicker table tr td.today:hover, +.datepicker table tr td.today:active:focus, +.datepicker table tr td.today.active:focus, +.open > .dropdown-toggle.datepicker table tr td.today:focus, +.datepicker table tr td.today:active.focus, +.datepicker table tr td.today.active.focus, +.open > .dropdown-toggle.datepicker table tr td.today.focus { + color: #000000; + background-color: #ffbc42; + border-color: #b37400; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today.active, +.open > .dropdown-toggle.datepicker table tr td.today { background-image: none; } -.datepicker table tr td.today.disabled, -.datepicker table tr td.today:hover.disabled, -.datepicker table tr td.today.disabled.disabled, -.datepicker table tr td.today.disabled:hover.disabled, -.datepicker table tr td.today[disabled], -.datepicker table tr td.today:hover[disabled], -.datepicker table tr td.today.disabled[disabled], -.datepicker table tr td.today.disabled:hover[disabled], -fieldset[disabled] .datepicker table tr td.today, -fieldset[disabled] .datepicker table tr td.today:hover, -fieldset[disabled] .datepicker table tr td.today.disabled, -fieldset[disabled] .datepicker table tr td.today.disabled:hover, .datepicker table tr td.today.disabled:hover, -.datepicker table tr td.today:hover.disabled:hover, -.datepicker table tr td.today.disabled.disabled:hover, -.datepicker table tr td.today.disabled:hover.disabled:hover, .datepicker table tr td.today[disabled]:hover, -.datepicker table tr td.today:hover[disabled]:hover, -.datepicker table tr td.today.disabled[disabled]:hover, -.datepicker table tr td.today.disabled:hover[disabled]:hover, fieldset[disabled] .datepicker table tr td.today:hover, -fieldset[disabled] .datepicker table tr td.today:hover:hover, -fieldset[disabled] .datepicker table tr td.today.disabled:hover, -fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover, .datepicker table tr td.today.disabled:focus, -.datepicker table tr td.today:hover.disabled:focus, -.datepicker table tr td.today.disabled.disabled:focus, -.datepicker table tr td.today.disabled:hover.disabled:focus, .datepicker table tr td.today[disabled]:focus, -.datepicker table tr td.today:hover[disabled]:focus, -.datepicker table tr td.today.disabled[disabled]:focus, -.datepicker table tr td.today.disabled:hover[disabled]:focus, fieldset[disabled] .datepicker table tr td.today:focus, -fieldset[disabled] .datepicker table tr td.today:hover:focus, -fieldset[disabled] .datepicker table tr td.today.disabled:focus, -fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus, -.datepicker table tr td.today.disabled:active, -.datepicker table tr td.today:hover.disabled:active, -.datepicker table tr td.today.disabled.disabled:active, -.datepicker table tr td.today.disabled:hover.disabled:active, -.datepicker table tr td.today[disabled]:active, -.datepicker table tr td.today:hover[disabled]:active, -.datepicker table tr td.today.disabled[disabled]:active, -.datepicker table tr td.today.disabled:hover[disabled]:active, -fieldset[disabled] .datepicker table tr td.today:active, -fieldset[disabled] .datepicker table tr td.today:hover:active, -fieldset[disabled] .datepicker table tr td.today.disabled:active, -fieldset[disabled] .datepicker table tr td.today.disabled:hover:active, -.datepicker table tr td.today.disabled.active, -.datepicker table tr td.today:hover.disabled.active, -.datepicker table tr td.today.disabled.disabled.active, -.datepicker table tr td.today.disabled:hover.disabled.active, -.datepicker table tr td.today[disabled].active, -.datepicker table tr td.today:hover[disabled].active, -.datepicker table tr td.today.disabled[disabled].active, -.datepicker table tr td.today.disabled:hover[disabled].active, -fieldset[disabled] .datepicker table tr td.today.active, -fieldset[disabled] .datepicker table tr td.today:hover.active, -fieldset[disabled] .datepicker table tr td.today.disabled.active, -fieldset[disabled] .datepicker table tr td.today.disabled:hover.active { +.datepicker table tr td.today.disabled.focus, +.datepicker table tr td.today[disabled].focus, +fieldset[disabled] .datepicker table tr td.today.focus { background-color: #ffdb99; border-color: #ffb733; } -.datepicker table tr td.today:hover:hover { - color: #000; +.datepicker table tr td.today.focused { + background: #ffc966; } -.datepicker table tr td.today.active:hover { - color: #fff; +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:active { + background: #ffdb99; + color: #999999; } -.datepicker table tr td.range, -.datepicker table tr td.range:hover, -.datepicker table tr td.range.disabled, -.datepicker table tr td.range.disabled:hover { - background: #eeeeee; +.datepicker table tr td.range { + color: #000000; + background-color: #eeeeee; + border-color: #bbbbbb; border-radius: 0; } -.datepicker table tr td.range.today, -.datepicker table tr td.range.today:hover, -.datepicker table tr td.range.today.disabled, -.datepicker table tr td.range.today.disabled:hover { +.datepicker table tr td.range:focus, +.datepicker table tr td.range.focus { + color: #000000; + background-color: #d5d5d5; + border-color: #7c7c7c; +} +.datepicker table tr td.range:hover { + color: #000000; + background-color: #d5d5d5; + border-color: #9d9d9d; +} +.datepicker table tr td.range:active, +.datepicker table tr td.range.active, +.open > .dropdown-toggle.datepicker table tr td.range { + color: #000000; + background-color: #d5d5d5; + border-color: #9d9d9d; +} +.datepicker table tr td.range:active:hover, +.datepicker table tr td.range.active:hover, +.open > .dropdown-toggle.datepicker table tr td.range:hover, +.datepicker table tr td.range:active:focus, +.datepicker table tr td.range.active:focus, +.open > .dropdown-toggle.datepicker table tr td.range:focus, +.datepicker table tr td.range:active.focus, +.datepicker table tr td.range.active.focus, +.open > .dropdown-toggle.datepicker table tr td.range.focus { + color: #000000; + background-color: #c3c3c3; + border-color: #7c7c7c; +} +.datepicker table tr td.range:active, +.datepicker table tr td.range.active, +.open > .dropdown-toggle.datepicker table tr td.range { + background-image: none; +} +.datepicker table tr td.range.disabled:hover, +.datepicker table tr td.range[disabled]:hover, +fieldset[disabled] .datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled:focus, +.datepicker table tr td.range[disabled]:focus, +fieldset[disabled] .datepicker table tr td.range:focus, +.datepicker table tr td.range.disabled.focus, +.datepicker table tr td.range[disabled].focus, +fieldset[disabled] .datepicker table tr td.range.focus { + background-color: #eeeeee; + border-color: #bbbbbb; +} +.datepicker table tr td.range.focused { + background: #d5d5d5; +} +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:active { + background: #eeeeee; + color: #999999; +} +.datepicker table tr td.range.highlighted { + color: #000000; + background-color: #e4eef3; + border-color: #9dc1d3; +} +.datepicker table tr td.range.highlighted:focus, +.datepicker table tr td.range.highlighted.focus { + color: #000000; + background-color: #c1d7e3; + border-color: #4b88a6; +} +.datepicker table tr td.range.highlighted:hover { + color: #000000; + background-color: #c1d7e3; + border-color: #73a6c0; +} +.datepicker table tr td.range.highlighted:active, +.datepicker table tr td.range.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.range.highlighted { + color: #000000; + background-color: #c1d7e3; + border-color: #73a6c0; +} +.datepicker table tr td.range.highlighted:active:hover, +.datepicker table tr td.range.highlighted.active:hover, +.open > .dropdown-toggle.datepicker table tr td.range.highlighted:hover, +.datepicker table tr td.range.highlighted:active:focus, +.datepicker table tr td.range.highlighted.active:focus, +.open > .dropdown-toggle.datepicker table tr td.range.highlighted:focus, +.datepicker table tr td.range.highlighted:active.focus, +.datepicker table tr td.range.highlighted.active.focus, +.open > .dropdown-toggle.datepicker table tr td.range.highlighted.focus { + color: #000000; + background-color: #a8c8d8; + border-color: #4b88a6; +} +.datepicker table tr td.range.highlighted:active, +.datepicker table tr td.range.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.range.highlighted { + background-image: none; +} +.datepicker table tr td.range.highlighted.disabled:hover, +.datepicker table tr td.range.highlighted[disabled]:hover, +fieldset[disabled] .datepicker table tr td.range.highlighted:hover, +.datepicker table tr td.range.highlighted.disabled:focus, +.datepicker table tr td.range.highlighted[disabled]:focus, +fieldset[disabled] .datepicker table tr td.range.highlighted:focus, +.datepicker table tr td.range.highlighted.disabled.focus, +.datepicker table tr td.range.highlighted[disabled].focus, +fieldset[disabled] .datepicker table tr td.range.highlighted.focus { + background-color: #e4eef3; + border-color: #9dc1d3; +} +.datepicker table tr td.range.highlighted.focused { + background: #c1d7e3; +} +.datepicker table tr td.range.highlighted.disabled, +.datepicker table tr td.range.highlighted.disabled:active { + background: #e4eef3; + color: #999999; +} +.datepicker table tr td.range.today { color: #000000; background-color: #f7ca77; border-color: #f1a417; - border-radius: 0; } -.datepicker table tr td.range.today:hover, -.datepicker table tr td.range.today:hover:hover, -.datepicker table tr td.range.today.disabled:hover, -.datepicker table tr td.range.today.disabled:hover:hover, .datepicker table tr td.range.today:focus, -.datepicker table tr td.range.today:hover:focus, -.datepicker table tr td.range.today.disabled:focus, -.datepicker table tr td.range.today.disabled:hover:focus, -.datepicker table tr td.range.today:active, -.datepicker table tr td.range.today:hover:active, -.datepicker table tr td.range.today.disabled:active, -.datepicker table tr td.range.today.disabled:hover:active, -.datepicker table tr td.range.today.active, -.datepicker table tr td.range.today:hover.active, -.datepicker table tr td.range.today.disabled.active, -.datepicker table tr td.range.today.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.range.today, -.open .dropdown-toggle.datepicker table tr td.range.today:hover, -.open .dropdown-toggle.datepicker table tr td.range.today.disabled, -.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { +.datepicker table tr td.range.today.focus { color: #000000; - background-color: #f4bb51; + background-color: #f4b747; + border-color: #815608; +} +.datepicker table tr td.range.today:hover { + color: #000000; + background-color: #f4b747; border-color: #bf800c; } .datepicker table tr td.range.today:active, -.datepicker table tr td.range.today:hover:active, -.datepicker table tr td.range.today.disabled:active, -.datepicker table tr td.range.today.disabled:hover:active, .datepicker table tr td.range.today.active, -.datepicker table tr td.range.today:hover.active, -.datepicker table tr td.range.today.disabled.active, -.datepicker table tr td.range.today.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.range.today, -.open .dropdown-toggle.datepicker table tr td.range.today:hover, -.open .dropdown-toggle.datepicker table tr td.range.today.disabled, -.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { +.open > .dropdown-toggle.datepicker table tr td.range.today { + color: #000000; + background-color: #f4b747; + border-color: #bf800c; +} +.datepicker table tr td.range.today:active:hover, +.datepicker table tr td.range.today.active:hover, +.open > .dropdown-toggle.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:active:focus, +.datepicker table tr td.range.today.active:focus, +.open > .dropdown-toggle.datepicker table tr td.range.today:focus, +.datepicker table tr td.range.today:active.focus, +.datepicker table tr td.range.today.active.focus, +.open > .dropdown-toggle.datepicker table tr td.range.today.focus { + color: #000000; + background-color: #f2aa25; + border-color: #815608; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today.active, +.open > .dropdown-toggle.datepicker table tr td.range.today { background-image: none; } -.datepicker table tr td.range.today.disabled, -.datepicker table tr td.range.today:hover.disabled, -.datepicker table tr td.range.today.disabled.disabled, -.datepicker table tr td.range.today.disabled:hover.disabled, -.datepicker table tr td.range.today[disabled], -.datepicker table tr td.range.today:hover[disabled], -.datepicker table tr td.range.today.disabled[disabled], -.datepicker table tr td.range.today.disabled:hover[disabled], -fieldset[disabled] .datepicker table tr td.range.today, -fieldset[disabled] .datepicker table tr td.range.today:hover, -fieldset[disabled] .datepicker table tr td.range.today.disabled, -fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today.disabled:hover, -.datepicker table tr td.range.today:hover.disabled:hover, -.datepicker table tr td.range.today.disabled.disabled:hover, -.datepicker table tr td.range.today.disabled:hover.disabled:hover, .datepicker table tr td.range.today[disabled]:hover, -.datepicker table tr td.range.today:hover[disabled]:hover, -.datepicker table tr td.range.today.disabled[disabled]:hover, -.datepicker table tr td.range.today.disabled:hover[disabled]:hover, fieldset[disabled] .datepicker table tr td.range.today:hover, -fieldset[disabled] .datepicker table tr td.range.today:hover:hover, -fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, -fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover, .datepicker table tr td.range.today.disabled:focus, -.datepicker table tr td.range.today:hover.disabled:focus, -.datepicker table tr td.range.today.disabled.disabled:focus, -.datepicker table tr td.range.today.disabled:hover.disabled:focus, .datepicker table tr td.range.today[disabled]:focus, -.datepicker table tr td.range.today:hover[disabled]:focus, -.datepicker table tr td.range.today.disabled[disabled]:focus, -.datepicker table tr td.range.today.disabled:hover[disabled]:focus, fieldset[disabled] .datepicker table tr td.range.today:focus, -fieldset[disabled] .datepicker table tr td.range.today:hover:focus, -fieldset[disabled] .datepicker table tr td.range.today.disabled:focus, -fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus, -.datepicker table tr td.range.today.disabled:active, -.datepicker table tr td.range.today:hover.disabled:active, -.datepicker table tr td.range.today.disabled.disabled:active, -.datepicker table tr td.range.today.disabled:hover.disabled:active, -.datepicker table tr td.range.today[disabled]:active, -.datepicker table tr td.range.today:hover[disabled]:active, -.datepicker table tr td.range.today.disabled[disabled]:active, -.datepicker table tr td.range.today.disabled:hover[disabled]:active, -fieldset[disabled] .datepicker table tr td.range.today:active, -fieldset[disabled] .datepicker table tr td.range.today:hover:active, -fieldset[disabled] .datepicker table tr td.range.today.disabled:active, -fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active, -.datepicker table tr td.range.today.disabled.active, -.datepicker table tr td.range.today:hover.disabled.active, -.datepicker table tr td.range.today.disabled.disabled.active, -.datepicker table tr td.range.today.disabled:hover.disabled.active, -.datepicker table tr td.range.today[disabled].active, -.datepicker table tr td.range.today:hover[disabled].active, -.datepicker table tr td.range.today.disabled[disabled].active, -.datepicker table tr td.range.today.disabled:hover[disabled].active, -fieldset[disabled] .datepicker table tr td.range.today.active, -fieldset[disabled] .datepicker table tr td.range.today:hover.active, -fieldset[disabled] .datepicker table tr td.range.today.disabled.active, -fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active { +.datepicker table tr td.range.today.disabled.focus, +.datepicker table tr td.range.today[disabled].focus, +fieldset[disabled] .datepicker table tr td.range.today.focus { background-color: #f7ca77; border-color: #f1a417; } +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:active { + background: #f7ca77; + color: #999999; +} .datepicker table tr td.selected, -.datepicker table tr td.selected:hover, -.datepicker table tr td.selected.disabled, -.datepicker table tr td.selected.disabled:hover { +.datepicker table tr td.selected.highlighted { color: #ffffff; background-color: #999999; border-color: #555555; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } -.datepicker table tr td.selected:hover, -.datepicker table tr td.selected:hover:hover, -.datepicker table tr td.selected.disabled:hover, -.datepicker table tr td.selected.disabled:hover:hover, .datepicker table tr td.selected:focus, -.datepicker table tr td.selected:hover:focus, -.datepicker table tr td.selected.disabled:focus, -.datepicker table tr td.selected.disabled:hover:focus, -.datepicker table tr td.selected:active, -.datepicker table tr td.selected:hover:active, -.datepicker table tr td.selected.disabled:active, -.datepicker table tr td.selected.disabled:hover:active, -.datepicker table tr td.selected.active, -.datepicker table tr td.selected:hover.active, -.datepicker table tr td.selected.disabled.active, -.datepicker table tr td.selected.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.selected, -.open .dropdown-toggle.datepicker table tr td.selected:hover, -.open .dropdown-toggle.datepicker table tr td.selected.disabled, -.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { +.datepicker table tr td.selected.highlighted:focus, +.datepicker table tr td.selected.focus, +.datepicker table tr td.selected.highlighted.focus { color: #ffffff; - background-color: #858585; + background-color: #808080; + border-color: #161616; +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.highlighted:hover { + color: #ffffff; + background-color: #808080; border-color: #373737; } .datepicker table tr td.selected:active, -.datepicker table tr td.selected:hover:active, -.datepicker table tr td.selected.disabled:active, -.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.highlighted:active, .datepicker table tr td.selected.active, -.datepicker table tr td.selected:hover.active, -.datepicker table tr td.selected.disabled.active, -.datepicker table tr td.selected.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.selected, -.open .dropdown-toggle.datepicker table tr td.selected:hover, -.open .dropdown-toggle.datepicker table tr td.selected.disabled, -.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { +.datepicker table tr td.selected.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.selected, +.open > .dropdown-toggle.datepicker table tr td.selected.highlighted { + color: #ffffff; + background-color: #808080; + border-color: #373737; +} +.datepicker table tr td.selected:active:hover, +.datepicker table tr td.selected.highlighted:active:hover, +.datepicker table tr td.selected.active:hover, +.datepicker table tr td.selected.highlighted.active:hover, +.open > .dropdown-toggle.datepicker table tr td.selected:hover, +.open > .dropdown-toggle.datepicker table tr td.selected.highlighted:hover, +.datepicker table tr td.selected:active:focus, +.datepicker table tr td.selected.highlighted:active:focus, +.datepicker table tr td.selected.active:focus, +.datepicker table tr td.selected.highlighted.active:focus, +.open > .dropdown-toggle.datepicker table tr td.selected:focus, +.open > .dropdown-toggle.datepicker table tr td.selected.highlighted:focus, +.datepicker table tr td.selected:active.focus, +.datepicker table tr td.selected.highlighted:active.focus, +.datepicker table tr td.selected.active.focus, +.datepicker table tr td.selected.highlighted.active.focus, +.open > .dropdown-toggle.datepicker table tr td.selected.focus, +.open > .dropdown-toggle.datepicker table tr td.selected.highlighted.focus { + color: #ffffff; + background-color: #6e6e6e; + border-color: #161616; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected.highlighted:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.selected, +.open > .dropdown-toggle.datepicker table tr td.selected.highlighted { background-image: none; } -.datepicker table tr td.selected.disabled, -.datepicker table tr td.selected:hover.disabled, -.datepicker table tr td.selected.disabled.disabled, -.datepicker table tr td.selected.disabled:hover.disabled, -.datepicker table tr td.selected[disabled], -.datepicker table tr td.selected:hover[disabled], -.datepicker table tr td.selected.disabled[disabled], -.datepicker table tr td.selected.disabled:hover[disabled], -fieldset[disabled] .datepicker table tr td.selected, -fieldset[disabled] .datepicker table tr td.selected:hover, -fieldset[disabled] .datepicker table tr td.selected.disabled, -fieldset[disabled] .datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected.disabled:hover, -.datepicker table tr td.selected:hover.disabled:hover, -.datepicker table tr td.selected.disabled.disabled:hover, -.datepicker table tr td.selected.disabled:hover.disabled:hover, +.datepicker table tr td.selected.highlighted.disabled:hover, .datepicker table tr td.selected[disabled]:hover, -.datepicker table tr td.selected:hover[disabled]:hover, -.datepicker table tr td.selected.disabled[disabled]:hover, -.datepicker table tr td.selected.disabled:hover[disabled]:hover, +.datepicker table tr td.selected.highlighted[disabled]:hover, fieldset[disabled] .datepicker table tr td.selected:hover, -fieldset[disabled] .datepicker table tr td.selected:hover:hover, -fieldset[disabled] .datepicker table tr td.selected.disabled:hover, -fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover, +fieldset[disabled] .datepicker table tr td.selected.highlighted:hover, .datepicker table tr td.selected.disabled:focus, -.datepicker table tr td.selected:hover.disabled:focus, -.datepicker table tr td.selected.disabled.disabled:focus, -.datepicker table tr td.selected.disabled:hover.disabled:focus, +.datepicker table tr td.selected.highlighted.disabled:focus, .datepicker table tr td.selected[disabled]:focus, -.datepicker table tr td.selected:hover[disabled]:focus, -.datepicker table tr td.selected.disabled[disabled]:focus, -.datepicker table tr td.selected.disabled:hover[disabled]:focus, +.datepicker table tr td.selected.highlighted[disabled]:focus, fieldset[disabled] .datepicker table tr td.selected:focus, -fieldset[disabled] .datepicker table tr td.selected:hover:focus, -fieldset[disabled] .datepicker table tr td.selected.disabled:focus, -fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus, -.datepicker table tr td.selected.disabled:active, -.datepicker table tr td.selected:hover.disabled:active, -.datepicker table tr td.selected.disabled.disabled:active, -.datepicker table tr td.selected.disabled:hover.disabled:active, -.datepicker table tr td.selected[disabled]:active, -.datepicker table tr td.selected:hover[disabled]:active, -.datepicker table tr td.selected.disabled[disabled]:active, -.datepicker table tr td.selected.disabled:hover[disabled]:active, -fieldset[disabled] .datepicker table tr td.selected:active, -fieldset[disabled] .datepicker table tr td.selected:hover:active, -fieldset[disabled] .datepicker table tr td.selected.disabled:active, -fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active, -.datepicker table tr td.selected.disabled.active, -.datepicker table tr td.selected:hover.disabled.active, -.datepicker table tr td.selected.disabled.disabled.active, -.datepicker table tr td.selected.disabled:hover.disabled.active, -.datepicker table tr td.selected[disabled].active, -.datepicker table tr td.selected:hover[disabled].active, -.datepicker table tr td.selected.disabled[disabled].active, -.datepicker table tr td.selected.disabled:hover[disabled].active, -fieldset[disabled] .datepicker table tr td.selected.active, -fieldset[disabled] .datepicker table tr td.selected:hover.active, -fieldset[disabled] .datepicker table tr td.selected.disabled.active, -fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active { +fieldset[disabled] .datepicker table tr td.selected.highlighted:focus, +.datepicker table tr td.selected.disabled.focus, +.datepicker table tr td.selected.highlighted.disabled.focus, +.datepicker table tr td.selected[disabled].focus, +.datepicker table tr td.selected.highlighted[disabled].focus, +fieldset[disabled] .datepicker table tr td.selected.focus, +fieldset[disabled] .datepicker table tr td.selected.highlighted.focus { background-color: #999999; border-color: #555555; } .datepicker table tr td.active, -.datepicker table tr td.active:hover, -.datepicker table tr td.active.disabled, -.datepicker table tr td.active.disabled:hover { +.datepicker table tr td.active.highlighted { color: #ffffff; background-color: #428bca; border-color: #357ebd; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } -.datepicker table tr td.active:hover, -.datepicker table tr td.active:hover:hover, -.datepicker table tr td.active.disabled:hover, -.datepicker table tr td.active.disabled:hover:hover, .datepicker table tr td.active:focus, -.datepicker table tr td.active:hover:focus, -.datepicker table tr td.active.disabled:focus, -.datepicker table tr td.active.disabled:hover:focus, -.datepicker table tr td.active:active, -.datepicker table tr td.active:hover:active, -.datepicker table tr td.active.disabled:active, -.datepicker table tr td.active.disabled:hover:active, -.datepicker table tr td.active.active, -.datepicker table tr td.active:hover.active, -.datepicker table tr td.active.disabled.active, -.datepicker table tr td.active.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.active, -.open .dropdown-toggle.datepicker table tr td.active:hover, -.open .dropdown-toggle.datepicker table tr td.active.disabled, -.open .dropdown-toggle.datepicker table tr td.active.disabled:hover { +.datepicker table tr td.active.highlighted:focus, +.datepicker table tr td.active.focus, +.datepicker table tr td.active.highlighted.focus { color: #ffffff; - background-color: #3276b1; + background-color: #3071a9; + border-color: #193c5a; +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active.highlighted:hover { + color: #ffffff; + background-color: #3071a9; border-color: #285e8e; } .datepicker table tr td.active:active, -.datepicker table tr td.active:hover:active, -.datepicker table tr td.active.disabled:active, -.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.highlighted:active, .datepicker table tr td.active.active, -.datepicker table tr td.active:hover.active, -.datepicker table tr td.active.disabled.active, -.datepicker table tr td.active.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td.active, -.open .dropdown-toggle.datepicker table tr td.active:hover, -.open .dropdown-toggle.datepicker table tr td.active.disabled, -.open .dropdown-toggle.datepicker table tr td.active.disabled:hover { +.datepicker table tr td.active.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.active, +.open > .dropdown-toggle.datepicker table tr td.active.highlighted { + color: #ffffff; + background-color: #3071a9; + border-color: #285e8e; +} +.datepicker table tr td.active:active:hover, +.datepicker table tr td.active.highlighted:active:hover, +.datepicker table tr td.active.active:hover, +.datepicker table tr td.active.highlighted.active:hover, +.open > .dropdown-toggle.datepicker table tr td.active:hover, +.open > .dropdown-toggle.datepicker table tr td.active.highlighted:hover, +.datepicker table tr td.active:active:focus, +.datepicker table tr td.active.highlighted:active:focus, +.datepicker table tr td.active.active:focus, +.datepicker table tr td.active.highlighted.active:focus, +.open > .dropdown-toggle.datepicker table tr td.active:focus, +.open > .dropdown-toggle.datepicker table tr td.active.highlighted:focus, +.datepicker table tr td.active:active.focus, +.datepicker table tr td.active.highlighted:active.focus, +.datepicker table tr td.active.active.focus, +.datepicker table tr td.active.highlighted.active.focus, +.open > .dropdown-toggle.datepicker table tr td.active.focus, +.open > .dropdown-toggle.datepicker table tr td.active.highlighted.focus { + color: #ffffff; + background-color: #285e8e; + border-color: #193c5a; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active.highlighted:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active.highlighted.active, +.open > .dropdown-toggle.datepicker table tr td.active, +.open > .dropdown-toggle.datepicker table tr td.active.highlighted { background-image: none; } -.datepicker table tr td.active.disabled, -.datepicker table tr td.active:hover.disabled, -.datepicker table tr td.active.disabled.disabled, -.datepicker table tr td.active.disabled:hover.disabled, -.datepicker table tr td.active[disabled], -.datepicker table tr td.active:hover[disabled], -.datepicker table tr td.active.disabled[disabled], -.datepicker table tr td.active.disabled:hover[disabled], -fieldset[disabled] .datepicker table tr td.active, -fieldset[disabled] .datepicker table tr td.active:hover, -fieldset[disabled] .datepicker table tr td.active.disabled, -fieldset[disabled] .datepicker table tr td.active.disabled:hover, .datepicker table tr td.active.disabled:hover, -.datepicker table tr td.active:hover.disabled:hover, -.datepicker table tr td.active.disabled.disabled:hover, -.datepicker table tr td.active.disabled:hover.disabled:hover, +.datepicker table tr td.active.highlighted.disabled:hover, .datepicker table tr td.active[disabled]:hover, -.datepicker table tr td.active:hover[disabled]:hover, -.datepicker table tr td.active.disabled[disabled]:hover, -.datepicker table tr td.active.disabled:hover[disabled]:hover, +.datepicker table tr td.active.highlighted[disabled]:hover, fieldset[disabled] .datepicker table tr td.active:hover, -fieldset[disabled] .datepicker table tr td.active:hover:hover, -fieldset[disabled] .datepicker table tr td.active.disabled:hover, -fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover, +fieldset[disabled] .datepicker table tr td.active.highlighted:hover, .datepicker table tr td.active.disabled:focus, -.datepicker table tr td.active:hover.disabled:focus, -.datepicker table tr td.active.disabled.disabled:focus, -.datepicker table tr td.active.disabled:hover.disabled:focus, +.datepicker table tr td.active.highlighted.disabled:focus, .datepicker table tr td.active[disabled]:focus, -.datepicker table tr td.active:hover[disabled]:focus, -.datepicker table tr td.active.disabled[disabled]:focus, -.datepicker table tr td.active.disabled:hover[disabled]:focus, +.datepicker table tr td.active.highlighted[disabled]:focus, fieldset[disabled] .datepicker table tr td.active:focus, -fieldset[disabled] .datepicker table tr td.active:hover:focus, -fieldset[disabled] .datepicker table tr td.active.disabled:focus, -fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus, -.datepicker table tr td.active.disabled:active, -.datepicker table tr td.active:hover.disabled:active, -.datepicker table tr td.active.disabled.disabled:active, -.datepicker table tr td.active.disabled:hover.disabled:active, -.datepicker table tr td.active[disabled]:active, -.datepicker table tr td.active:hover[disabled]:active, -.datepicker table tr td.active.disabled[disabled]:active, -.datepicker table tr td.active.disabled:hover[disabled]:active, -fieldset[disabled] .datepicker table tr td.active:active, -fieldset[disabled] .datepicker table tr td.active:hover:active, -fieldset[disabled] .datepicker table tr td.active.disabled:active, -fieldset[disabled] .datepicker table tr td.active.disabled:hover:active, -.datepicker table tr td.active.disabled.active, -.datepicker table tr td.active:hover.disabled.active, -.datepicker table tr td.active.disabled.disabled.active, -.datepicker table tr td.active.disabled:hover.disabled.active, -.datepicker table tr td.active[disabled].active, -.datepicker table tr td.active:hover[disabled].active, -.datepicker table tr td.active.disabled[disabled].active, -.datepicker table tr td.active.disabled:hover[disabled].active, -fieldset[disabled] .datepicker table tr td.active.active, -fieldset[disabled] .datepicker table tr td.active:hover.active, -fieldset[disabled] .datepicker table tr td.active.disabled.active, -fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { +fieldset[disabled] .datepicker table tr td.active.highlighted:focus, +.datepicker table tr td.active.disabled.focus, +.datepicker table tr td.active.highlighted.disabled.focus, +.datepicker table tr td.active[disabled].focus, +.datepicker table tr td.active.highlighted[disabled].focus, +fieldset[disabled] .datepicker table tr td.active.focus, +fieldset[disabled] .datepicker table tr td.active.highlighted.focus { background-color: #428bca; border-color: #357ebd; } @@ -593,28 +605,24 @@ fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { border-color: #357ebd; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } -.datepicker table tr td span.active:hover, -.datepicker table tr td span.active:hover:hover, -.datepicker table tr td span.active.disabled:hover, -.datepicker table tr td span.active.disabled:hover:hover, .datepicker table tr td span.active:focus, .datepicker table tr td span.active:hover:focus, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled:hover:focus, -.datepicker table tr td span.active:active, -.datepicker table tr td span.active:hover:active, -.datepicker table tr td span.active.disabled:active, -.datepicker table tr td span.active.disabled:hover:active, -.datepicker table tr td span.active.active, -.datepicker table tr td span.active:hover.active, -.datepicker table tr td span.active.disabled.active, -.datepicker table tr td span.active.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td span.active, -.open .dropdown-toggle.datepicker table tr td span.active:hover, -.open .dropdown-toggle.datepicker table tr td span.active.disabled, -.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { +.datepicker table tr td span.active.focus, +.datepicker table tr td span.active:hover.focus, +.datepicker table tr td span.active.disabled.focus, +.datepicker table tr td span.active.disabled:hover.focus { color: #ffffff; - background-color: #3276b1; + background-color: #3071a9; + border-color: #193c5a; +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover { + color: #ffffff; + background-color: #3071a9; border-color: #285e8e; } .datepicker table tr td span.active:active, @@ -625,24 +633,68 @@ fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { .datepicker table tr td span.active:hover.active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:hover.active, -.open .dropdown-toggle.datepicker table tr td span.active, -.open .dropdown-toggle.datepicker table tr td span.active:hover, -.open .dropdown-toggle.datepicker table tr td span.active.disabled, -.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { +.open > .dropdown-toggle.datepicker table tr td span.active, +.open > .dropdown-toggle.datepicker table tr td span.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + color: #ffffff; + background-color: #3071a9; + border-color: #285e8e; +} +.datepicker table tr td span.active:active:hover, +.datepicker table tr td span.active:hover:active:hover, +.datepicker table tr td span.active.disabled:active:hover, +.datepicker table tr td span.active.disabled:hover:active:hover, +.datepicker table tr td span.active.active:hover, +.datepicker table tr td span.active:hover.active:hover, +.datepicker table tr td span.active.disabled.active:hover, +.datepicker table tr td span.active.disabled:hover.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active:hover:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:active:focus, +.datepicker table tr td span.active:hover:active:focus, +.datepicker table tr td span.active.disabled:active:focus, +.datepicker table tr td span.active.disabled:hover:active:focus, +.datepicker table tr td span.active.active:focus, +.datepicker table tr td span.active:hover.active:focus, +.datepicker table tr td span.active.disabled.active:focus, +.datepicker table tr td span.active.disabled:hover.active:focus, +.open > .dropdown-toggle.datepicker table tr td span.active:focus, +.open > .dropdown-toggle.datepicker table tr td span.active:hover:focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active:active.focus, +.datepicker table tr td span.active:hover:active.focus, +.datepicker table tr td span.active.disabled:active.focus, +.datepicker table tr td span.active.disabled:hover:active.focus, +.datepicker table tr td span.active.active.focus, +.datepicker table tr td span.active:hover.active.focus, +.datepicker table tr td span.active.disabled.active.focus, +.datepicker table tr td span.active.disabled:hover.active.focus, +.open > .dropdown-toggle.datepicker table tr td span.active.focus, +.open > .dropdown-toggle.datepicker table tr td span.active:hover.focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled.focus, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover.focus { + color: #ffffff; + background-color: #285e8e; + border-color: #193c5a; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open > .dropdown-toggle.datepicker table tr td span.active, +.open > .dropdown-toggle.datepicker table tr td span.active:hover, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled, +.open > .dropdown-toggle.datepicker table tr td span.active.disabled:hover { background-image: none; } -.datepicker table tr td span.active.disabled, -.datepicker table tr td span.active:hover.disabled, -.datepicker table tr td span.active.disabled.disabled, -.datepicker table tr td span.active.disabled:hover.disabled, -.datepicker table tr td span.active[disabled], -.datepicker table tr td span.active:hover[disabled], -.datepicker table tr td span.active.disabled[disabled], -.datepicker table tr td span.active.disabled:hover[disabled], -fieldset[disabled] .datepicker table tr td span.active, -fieldset[disabled] .datepicker table tr td span.active:hover, -fieldset[disabled] .datepicker table tr td span.active.disabled, -fieldset[disabled] .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active:hover.disabled:hover, .datepicker table tr td span.active.disabled.disabled:hover, @@ -667,30 +719,18 @@ fieldset[disabled] .datepicker table tr td span.active:focus, fieldset[disabled] .datepicker table tr td span.active:hover:focus, fieldset[disabled] .datepicker table tr td span.active.disabled:focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, -.datepicker table tr td span.active.disabled:active, -.datepicker table tr td span.active:hover.disabled:active, -.datepicker table tr td span.active.disabled.disabled:active, -.datepicker table tr td span.active.disabled:hover.disabled:active, -.datepicker table tr td span.active[disabled]:active, -.datepicker table tr td span.active:hover[disabled]:active, -.datepicker table tr td span.active.disabled[disabled]:active, -.datepicker table tr td span.active.disabled:hover[disabled]:active, -fieldset[disabled] .datepicker table tr td span.active:active, -fieldset[disabled] .datepicker table tr td span.active:hover:active, -fieldset[disabled] .datepicker table tr td span.active.disabled:active, -fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active, -.datepicker table tr td span.active.disabled.active, -.datepicker table tr td span.active:hover.disabled.active, -.datepicker table tr td span.active.disabled.disabled.active, -.datepicker table tr td span.active.disabled:hover.disabled.active, -.datepicker table tr td span.active[disabled].active, -.datepicker table tr td span.active:hover[disabled].active, -.datepicker table tr td span.active.disabled[disabled].active, -.datepicker table tr td span.active.disabled:hover[disabled].active, -fieldset[disabled] .datepicker table tr td span.active.active, -fieldset[disabled] .datepicker table tr td span.active:hover.active, -fieldset[disabled] .datepicker table tr td span.active.disabled.active, -fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { +.datepicker table tr td span.active.disabled.focus, +.datepicker table tr td span.active:hover.disabled.focus, +.datepicker table tr td span.active.disabled.disabled.focus, +.datepicker table tr td span.active.disabled:hover.disabled.focus, +.datepicker table tr td span.active[disabled].focus, +.datepicker table tr td span.active:hover[disabled].focus, +.datepicker table tr td span.active.disabled[disabled].focus, +.datepicker table tr td span.active.disabled:hover[disabled].focus, +fieldset[disabled] .datepicker table tr td span.active.focus, +fieldset[disabled] .datepicker table tr td span.active:hover.focus, +fieldset[disabled] .datepicker table tr td span.active.disabled.focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus { background-color: #428bca; border-color: #357ebd; } @@ -701,11 +741,15 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { .datepicker .datepicker-switch { width: 145px; } -.datepicker thead tr:first-child th, +.datepicker .datepicker-switch, +.datepicker .prev, +.datepicker .next, .datepicker tfoot tr th { cursor: pointer; } -.datepicker thead tr:first-child th:hover, +.datepicker .datepicker-switch:hover, +.datepicker .prev:hover, +.datepicker .next:hover, .datepicker tfoot tr th:hover { background: #eeeeee; } @@ -715,10 +759,6 @@ fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { padding: 0 2px 0 5px; vertical-align: middle; } -.datepicker thead tr:first-child .cw { - cursor: default; - background-color: transparent; -} .input-group.date .input-group-addon { cursor: pointer; } diff --git a/web/pgadmin/static/css/bootstrap-datepicker3.min.css b/web/pgadmin/static/css/bootstrap-datepicker3.min.css new file mode 100644 index 000000000..8a5102b7c --- /dev/null +++ b/web/pgadmin/static/css/bootstrap-datepicker3.min.css @@ -0,0 +1,8 @@ +/*! + * Datepicker for Bootstrap v1.5.0 (https://github.com/eternicode/bootstrap-datepicker) + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) + */ +.datepicker{border-radius:4px;direction:ltr}.datepicker-inline{width:220px}.datepicker.datepicker-rtl{direction:rtl}.datepicker.datepicker-rtl table tr td span{float:right}.datepicker-dropdown{top:0;left:0;padding:4px}.datepicker-dropdown:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(0,0,0,.15);border-top:0;border-bottom-color:rgba(0,0,0,.2);position:absolute}.datepicker-dropdown:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;border-top:0;position:absolute}.datepicker-dropdown.datepicker-orient-left:before{left:6px}.datepicker-dropdown.datepicker-orient-left:after{left:7px}.datepicker-dropdown.datepicker-orient-right:before{right:6px}.datepicker-dropdown.datepicker-orient-right:after{right:7px}.datepicker-dropdown.datepicker-orient-bottom:before{top:-7px}.datepicker-dropdown.datepicker-orient-bottom:after{top:-6px}.datepicker-dropdown.datepicker-orient-top:before{bottom:-7px;border-bottom:0;border-top:7px solid rgba(0,0,0,.15)}.datepicker-dropdown.datepicker-orient-top:after{bottom:-6px;border-bottom:0;border-top:6px solid #fff}.datepicker>div{display:none}.datepicker table{margin:0;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.datepicker table tr td,.datepicker table tr th{text-align:center;width:30px;height:30px;border-radius:4px;border:none}.table-striped .datepicker table tr td,.table-striped .datepicker table tr th{background-color:transparent}.datepicker table tr td.old,.datepicker table tr td.new{color:#999}.datepicker table tr td.day:hover,.datepicker table tr td.focused{background:#eee;cursor:pointer}.datepicker table tr td.disabled,.datepicker table tr td.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td.highlighted{color:#000;background-color:#d9edf7;border-color:#85c5e5;border-radius:0}.datepicker table tr td.highlighted:focus,.datepicker table tr td.highlighted.focus{color:#000;background-color:#afd9ee;border-color:#298fc2}.datepicker table tr td.highlighted:hover{color:#000;background-color:#afd9ee;border-color:#52addb}.datepicker table tr td.highlighted:active,.datepicker table tr td.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.highlighted{color:#000;background-color:#afd9ee;border-color:#52addb}.datepicker table tr td.highlighted:active:hover,.datepicker table tr td.highlighted.active:hover,.open>.dropdown-toggle.datepicker table tr td.highlighted:hover,.datepicker table tr td.highlighted:active:focus,.datepicker table tr td.highlighted.active:focus,.open>.dropdown-toggle.datepicker table tr td.highlighted:focus,.datepicker table tr td.highlighted:active.focus,.datepicker table tr td.highlighted.active.focus,.open>.dropdown-toggle.datepicker table tr td.highlighted.focus{color:#000;background-color:#91cbe8;border-color:#298fc2}.datepicker table tr td.highlighted:active,.datepicker table tr td.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.highlighted{background-image:none}.datepicker table tr td.highlighted.disabled:hover,.datepicker table tr td.highlighted[disabled]:hover,fieldset[disabled] .datepicker table tr td.highlighted:hover,.datepicker table tr td.highlighted.disabled:focus,.datepicker table tr td.highlighted[disabled]:focus,fieldset[disabled] .datepicker table tr td.highlighted:focus,.datepicker table tr td.highlighted.disabled.focus,.datepicker table tr td.highlighted[disabled].focus,fieldset[disabled] .datepicker table tr td.highlighted.focus{background-color:#d9edf7;border-color:#85c5e5}.datepicker table tr td.highlighted.focused{background:#afd9ee}.datepicker table tr td.highlighted.disabled,.datepicker table tr td.highlighted.disabled:active{background:#d9edf7;color:#999}.datepicker table tr td.today{color:#000;background-color:#ffdb99;border-color:#ffb733}.datepicker table tr td.today:focus,.datepicker table tr td.today.focus{color:#000;background-color:#ffc966;border-color:#b37400}.datepicker table tr td.today:hover{color:#000;background-color:#ffc966;border-color:#f59e00}.datepicker table tr td.today:active,.datepicker table tr td.today.active,.open>.dropdown-toggle.datepicker table tr td.today{color:#000;background-color:#ffc966;border-color:#f59e00}.datepicker table tr td.today:active:hover,.datepicker table tr td.today.active:hover,.open>.dropdown-toggle.datepicker table tr td.today:hover,.datepicker table tr td.today:active:focus,.datepicker table tr td.today.active:focus,.open>.dropdown-toggle.datepicker table tr td.today:focus,.datepicker table tr td.today:active.focus,.datepicker table tr td.today.active.focus,.open>.dropdown-toggle.datepicker table tr td.today.focus{color:#000;background-color:#ffbc42;border-color:#b37400}.datepicker table tr td.today:active,.datepicker table tr td.today.active,.open>.dropdown-toggle.datepicker table tr td.today{background-image:none}.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today[disabled]:hover,fieldset[disabled] .datepicker table tr td.today:hover,.datepicker table tr td.today.disabled:focus,.datepicker table tr td.today[disabled]:focus,fieldset[disabled] .datepicker table tr td.today:focus,.datepicker table tr td.today.disabled.focus,.datepicker table tr td.today[disabled].focus,fieldset[disabled] .datepicker table tr td.today.focus{background-color:#ffdb99;border-color:#ffb733}.datepicker table tr td.today.focused{background:#ffc966}.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled:active{background:#ffdb99;color:#999}.datepicker table tr td.range{color:#000;background-color:#eee;border-color:#bbb;border-radius:0}.datepicker table tr td.range:focus,.datepicker table tr td.range.focus{color:#000;background-color:#d5d5d5;border-color:#7c7c7c}.datepicker table tr td.range:hover{color:#000;background-color:#d5d5d5;border-color:#9d9d9d}.datepicker table tr td.range:active,.datepicker table tr td.range.active,.open>.dropdown-toggle.datepicker table tr td.range{color:#000;background-color:#d5d5d5;border-color:#9d9d9d}.datepicker table tr td.range:active:hover,.datepicker table tr td.range.active:hover,.open>.dropdown-toggle.datepicker table tr td.range:hover,.datepicker table tr td.range:active:focus,.datepicker table tr td.range.active:focus,.open>.dropdown-toggle.datepicker table tr td.range:focus,.datepicker table tr td.range:active.focus,.datepicker table tr td.range.active.focus,.open>.dropdown-toggle.datepicker table tr td.range.focus{color:#000;background-color:#c3c3c3;border-color:#7c7c7c}.datepicker table tr td.range:active,.datepicker table tr td.range.active,.open>.dropdown-toggle.datepicker table tr td.range{background-image:none}.datepicker table tr td.range.disabled:hover,.datepicker table tr td.range[disabled]:hover,fieldset[disabled] .datepicker table tr td.range:hover,.datepicker table tr td.range.disabled:focus,.datepicker table tr td.range[disabled]:focus,fieldset[disabled] .datepicker table tr td.range:focus,.datepicker table tr td.range.disabled.focus,.datepicker table tr td.range[disabled].focus,fieldset[disabled] .datepicker table tr td.range.focus{background-color:#eee;border-color:#bbb}.datepicker table tr td.range.focused{background:#d5d5d5}.datepicker table tr td.range.disabled,.datepicker table tr td.range.disabled:active{background:#eee;color:#999}.datepicker table tr td.range.highlighted{color:#000;background-color:#e4eef3;border-color:#9dc1d3}.datepicker table tr td.range.highlighted:focus,.datepicker table tr td.range.highlighted.focus{color:#000;background-color:#c1d7e3;border-color:#4b88a6}.datepicker table tr td.range.highlighted:hover{color:#000;background-color:#c1d7e3;border-color:#73a6c0}.datepicker table tr td.range.highlighted:active,.datepicker table tr td.range.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.range.highlighted{color:#000;background-color:#c1d7e3;border-color:#73a6c0}.datepicker table tr td.range.highlighted:active:hover,.datepicker table tr td.range.highlighted.active:hover,.open>.dropdown-toggle.datepicker table tr td.range.highlighted:hover,.datepicker table tr td.range.highlighted:active:focus,.datepicker table tr td.range.highlighted.active:focus,.open>.dropdown-toggle.datepicker table tr td.range.highlighted:focus,.datepicker table tr td.range.highlighted:active.focus,.datepicker table tr td.range.highlighted.active.focus,.open>.dropdown-toggle.datepicker table tr td.range.highlighted.focus{color:#000;background-color:#a8c8d8;border-color:#4b88a6}.datepicker table tr td.range.highlighted:active,.datepicker table tr td.range.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.range.highlighted{background-image:none}.datepicker table tr td.range.highlighted.disabled:hover,.datepicker table tr td.range.highlighted[disabled]:hover,fieldset[disabled] .datepicker table tr td.range.highlighted:hover,.datepicker table tr td.range.highlighted.disabled:focus,.datepicker table tr td.range.highlighted[disabled]:focus,fieldset[disabled] .datepicker table tr td.range.highlighted:focus,.datepicker table tr td.range.highlighted.disabled.focus,.datepicker table tr td.range.highlighted[disabled].focus,fieldset[disabled] .datepicker table tr td.range.highlighted.focus{background-color:#e4eef3;border-color:#9dc1d3}.datepicker table tr td.range.highlighted.focused{background:#c1d7e3}.datepicker table tr td.range.highlighted.disabled,.datepicker table tr td.range.highlighted.disabled:active{background:#e4eef3;color:#999}.datepicker table tr td.range.today{color:#000;background-color:#f7ca77;border-color:#f1a417}.datepicker table tr td.range.today:focus,.datepicker table tr td.range.today.focus{color:#000;background-color:#f4b747;border-color:#815608}.datepicker table tr td.range.today:hover{color:#000;background-color:#f4b747;border-color:#bf800c}.datepicker table tr td.range.today:active,.datepicker table tr td.range.today.active,.open>.dropdown-toggle.datepicker table tr td.range.today{color:#000;background-color:#f4b747;border-color:#bf800c}.datepicker table tr td.range.today:active:hover,.datepicker table tr td.range.today.active:hover,.open>.dropdown-toggle.datepicker table tr td.range.today:hover,.datepicker table tr td.range.today:active:focus,.datepicker table tr td.range.today.active:focus,.open>.dropdown-toggle.datepicker table tr td.range.today:focus,.datepicker table tr td.range.today:active.focus,.datepicker table tr td.range.today.active.focus,.open>.dropdown-toggle.datepicker table tr td.range.today.focus{color:#000;background-color:#f2aa25;border-color:#815608}.datepicker table tr td.range.today:active,.datepicker table tr td.range.today.active,.open>.dropdown-toggle.datepicker table tr td.range.today{background-image:none}.datepicker table tr td.range.today.disabled:hover,.datepicker table tr td.range.today[disabled]:hover,fieldset[disabled] .datepicker table tr td.range.today:hover,.datepicker table tr td.range.today.disabled:focus,.datepicker table tr td.range.today[disabled]:focus,fieldset[disabled] .datepicker table tr td.range.today:focus,.datepicker table tr td.range.today.disabled.focus,.datepicker table tr td.range.today[disabled].focus,fieldset[disabled] .datepicker table tr td.range.today.focus{background-color:#f7ca77;border-color:#f1a417}.datepicker table tr td.range.today.disabled,.datepicker table tr td.range.today.disabled:active{background:#f7ca77;color:#999}.datepicker table tr td.selected,.datepicker table tr td.selected.highlighted{color:#fff;background-color:#999;border-color:#555;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.selected:focus,.datepicker table tr td.selected.highlighted:focus,.datepicker table tr td.selected.focus,.datepicker table tr td.selected.highlighted.focus{color:#fff;background-color:gray;border-color:#161616}.datepicker table tr td.selected:hover,.datepicker table tr td.selected.highlighted:hover{color:#fff;background-color:gray;border-color:#373737}.datepicker table tr td.selected:active,.datepicker table tr td.selected.highlighted:active,.datepicker table tr td.selected.active,.datepicker table tr td.selected.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.selected,.open>.dropdown-toggle.datepicker table tr td.selected.highlighted{color:#fff;background-color:gray;border-color:#373737}.datepicker table tr td.selected:active:hover,.datepicker table tr td.selected.highlighted:active:hover,.datepicker table tr td.selected.active:hover,.datepicker table tr td.selected.highlighted.active:hover,.open>.dropdown-toggle.datepicker table tr td.selected:hover,.open>.dropdown-toggle.datepicker table tr td.selected.highlighted:hover,.datepicker table tr td.selected:active:focus,.datepicker table tr td.selected.highlighted:active:focus,.datepicker table tr td.selected.active:focus,.datepicker table tr td.selected.highlighted.active:focus,.open>.dropdown-toggle.datepicker table tr td.selected:focus,.open>.dropdown-toggle.datepicker table tr td.selected.highlighted:focus,.datepicker table tr td.selected:active.focus,.datepicker table tr td.selected.highlighted:active.focus,.datepicker table tr td.selected.active.focus,.datepicker table tr td.selected.highlighted.active.focus,.open>.dropdown-toggle.datepicker table tr td.selected.focus,.open>.dropdown-toggle.datepicker table tr td.selected.highlighted.focus{color:#fff;background-color:#6e6e6e;border-color:#161616}.datepicker table tr td.selected:active,.datepicker table tr td.selected.highlighted:active,.datepicker table tr td.selected.active,.datepicker table tr td.selected.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.selected,.open>.dropdown-toggle.datepicker table tr td.selected.highlighted{background-image:none}.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected.highlighted.disabled:hover,.datepicker table tr td.selected[disabled]:hover,.datepicker table tr td.selected.highlighted[disabled]:hover,fieldset[disabled] .datepicker table tr td.selected:hover,fieldset[disabled] .datepicker table tr td.selected.highlighted:hover,.datepicker table tr td.selected.disabled:focus,.datepicker table tr td.selected.highlighted.disabled:focus,.datepicker table tr td.selected[disabled]:focus,.datepicker table tr td.selected.highlighted[disabled]:focus,fieldset[disabled] .datepicker table tr td.selected:focus,fieldset[disabled] .datepicker table tr td.selected.highlighted:focus,.datepicker table tr td.selected.disabled.focus,.datepicker table tr td.selected.highlighted.disabled.focus,.datepicker table tr td.selected[disabled].focus,.datepicker table tr td.selected.highlighted[disabled].focus,fieldset[disabled] .datepicker table tr td.selected.focus,fieldset[disabled] .datepicker table tr td.selected.highlighted.focus{background-color:#999;border-color:#555}.datepicker table tr td.active,.datepicker table tr td.active.highlighted{color:#fff;background-color:#428bca;border-color:#357ebd;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td.active:focus,.datepicker table tr td.active.highlighted:focus,.datepicker table tr td.active.focus,.datepicker table tr td.active.highlighted.focus{color:#fff;background-color:#3071a9;border-color:#193c5a}.datepicker table tr td.active:hover,.datepicker table tr td.active.highlighted:hover{color:#fff;background-color:#3071a9;border-color:#285e8e}.datepicker table tr td.active:active,.datepicker table tr td.active.highlighted:active,.datepicker table tr td.active.active,.datepicker table tr td.active.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.active,.open>.dropdown-toggle.datepicker table tr td.active.highlighted{color:#fff;background-color:#3071a9;border-color:#285e8e}.datepicker table tr td.active:active:hover,.datepicker table tr td.active.highlighted:active:hover,.datepicker table tr td.active.active:hover,.datepicker table tr td.active.highlighted.active:hover,.open>.dropdown-toggle.datepicker table tr td.active:hover,.open>.dropdown-toggle.datepicker table tr td.active.highlighted:hover,.datepicker table tr td.active:active:focus,.datepicker table tr td.active.highlighted:active:focus,.datepicker table tr td.active.active:focus,.datepicker table tr td.active.highlighted.active:focus,.open>.dropdown-toggle.datepicker table tr td.active:focus,.open>.dropdown-toggle.datepicker table tr td.active.highlighted:focus,.datepicker table tr td.active:active.focus,.datepicker table tr td.active.highlighted:active.focus,.datepicker table tr td.active.active.focus,.datepicker table tr td.active.highlighted.active.focus,.open>.dropdown-toggle.datepicker table tr td.active.focus,.open>.dropdown-toggle.datepicker table tr td.active.highlighted.focus{color:#fff;background-color:#285e8e;border-color:#193c5a}.datepicker table tr td.active:active,.datepicker table tr td.active.highlighted:active,.datepicker table tr td.active.active,.datepicker table tr td.active.highlighted.active,.open>.dropdown-toggle.datepicker table tr td.active,.open>.dropdown-toggle.datepicker table tr td.active.highlighted{background-image:none}.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active.highlighted.disabled:hover,.datepicker table tr td.active[disabled]:hover,.datepicker table tr td.active.highlighted[disabled]:hover,fieldset[disabled] .datepicker table tr td.active:hover,fieldset[disabled] .datepicker table tr td.active.highlighted:hover,.datepicker table tr td.active.disabled:focus,.datepicker table tr td.active.highlighted.disabled:focus,.datepicker table tr td.active[disabled]:focus,.datepicker table tr td.active.highlighted[disabled]:focus,fieldset[disabled] .datepicker table tr td.active:focus,fieldset[disabled] .datepicker table tr td.active.highlighted:focus,.datepicker table tr td.active.disabled.focus,.datepicker table tr td.active.highlighted.disabled.focus,.datepicker table tr td.active[disabled].focus,.datepicker table tr td.active.highlighted[disabled].focus,fieldset[disabled] .datepicker table tr td.active.focus,fieldset[disabled] .datepicker table tr td.active.highlighted.focus{background-color:#428bca;border-color:#357ebd}.datepicker table tr td span{display:block;width:23%;height:54px;line-height:54px;float:left;margin:1%;cursor:pointer;border-radius:4px}.datepicker table tr td span:hover{background:#eee}.datepicker table tr td span.disabled,.datepicker table tr td span.disabled:hover{background:0 0;color:#999;cursor:default}.datepicker table tr td span.active,.datepicker table tr td span.active:hover,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled:hover{color:#fff;background-color:#428bca;border-color:#357ebd;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.datepicker table tr td span.active:focus,.datepicker table tr td span.active:hover:focus,.datepicker table tr td span.active.disabled:focus,.datepicker table tr td span.active.disabled:hover:focus,.datepicker table tr td span.active.focus,.datepicker table tr td span.active:hover.focus,.datepicker table tr td span.active.disabled.focus,.datepicker table tr td span.active.disabled:hover.focus{color:#fff;background-color:#3071a9;border-color:#193c5a}.datepicker table tr td span.active:hover,.datepicker table tr td span.active:hover:hover,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover:hover{color:#fff;background-color:#3071a9;border-color:#285e8e}.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.active,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:hover.active,.open>.dropdown-toggle.datepicker table tr td span.active,.open>.dropdown-toggle.datepicker table tr td span.active:hover,.open>.dropdown-toggle.datepicker table tr td span.active.disabled,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:hover{color:#fff;background-color:#3071a9;border-color:#285e8e}.datepicker table tr td span.active:active:hover,.datepicker table tr td span.active:hover:active:hover,.datepicker table tr td span.active.disabled:active:hover,.datepicker table tr td span.active.disabled:hover:active:hover,.datepicker table tr td span.active.active:hover,.datepicker table tr td span.active:hover.active:hover,.datepicker table tr td span.active.disabled.active:hover,.datepicker table tr td span.active.disabled:hover.active:hover,.open>.dropdown-toggle.datepicker table tr td span.active:hover,.open>.dropdown-toggle.datepicker table tr td span.active:hover:hover,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:hover,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active:active:focus,.datepicker table tr td span.active:hover:active:focus,.datepicker table tr td span.active.disabled:active:focus,.datepicker table tr td span.active.disabled:hover:active:focus,.datepicker table tr td span.active.active:focus,.datepicker table tr td span.active:hover.active:focus,.datepicker table tr td span.active.disabled.active:focus,.datepicker table tr td span.active.disabled:hover.active:focus,.open>.dropdown-toggle.datepicker table tr td span.active:focus,.open>.dropdown-toggle.datepicker table tr td span.active:hover:focus,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:focus,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:hover:focus,.datepicker table tr td span.active:active.focus,.datepicker table tr td span.active:hover:active.focus,.datepicker table tr td span.active.disabled:active.focus,.datepicker table tr td span.active.disabled:hover:active.focus,.datepicker table tr td span.active.active.focus,.datepicker table tr td span.active:hover.active.focus,.datepicker table tr td span.active.disabled.active.focus,.datepicker table tr td span.active.disabled:hover.active.focus,.open>.dropdown-toggle.datepicker table tr td span.active.focus,.open>.dropdown-toggle.datepicker table tr td span.active:hover.focus,.open>.dropdown-toggle.datepicker table tr td span.active.disabled.focus,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:hover.focus{color:#fff;background-color:#285e8e;border-color:#193c5a}.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.active,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled:hover.active,.open>.dropdown-toggle.datepicker table tr td span.active,.open>.dropdown-toggle.datepicker table tr td span.active:hover,.open>.dropdown-toggle.datepicker table tr td span.active.disabled,.open>.dropdown-toggle.datepicker table tr td span.active.disabled:hover{background-image:none}.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active:hover.disabled:hover,.datepicker table tr td span.active.disabled.disabled:hover,.datepicker table tr td span.active.disabled:hover.disabled:hover,.datepicker table tr td span.active[disabled]:hover,.datepicker table tr td span.active:hover[disabled]:hover,.datepicker table tr td span.active.disabled[disabled]:hover,.datepicker table tr td span.active.disabled:hover[disabled]:hover,fieldset[disabled] .datepicker table tr td span.active:hover,fieldset[disabled] .datepicker table tr td span.active:hover:hover,fieldset[disabled] .datepicker table tr td span.active.disabled:hover,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active.disabled:focus,.datepicker table tr td span.active:hover.disabled:focus,.datepicker table tr td span.active.disabled.disabled:focus,.datepicker table tr td span.active.disabled:hover.disabled:focus,.datepicker table tr td span.active[disabled]:focus,.datepicker table tr td span.active:hover[disabled]:focus,.datepicker table tr td span.active.disabled[disabled]:focus,.datepicker table tr td span.active.disabled:hover[disabled]:focus,fieldset[disabled] .datepicker table tr td span.active:focus,fieldset[disabled] .datepicker table tr td span.active:hover:focus,fieldset[disabled] .datepicker table tr td span.active.disabled:focus,fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,.datepicker table tr td span.active.disabled.focus,.datepicker table tr td span.active:hover.disabled.focus,.datepicker table tr td span.active.disabled.disabled.focus,.datepicker table tr td span.active.disabled:hover.disabled.focus,.datepicker table tr td span.active[disabled].focus,.datepicker table tr td span.active:hover[disabled].focus,.datepicker table tr td span.active.disabled[disabled].focus,.datepicker table tr td span.active.disabled:hover[disabled].focus,fieldset[disabled] .datepicker table tr td span.active.focus,fieldset[disabled] .datepicker table tr td span.active:hover.focus,fieldset[disabled] .datepicker table tr td span.active.disabled.focus,fieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus{background-color:#428bca;border-color:#357ebd}.datepicker table tr td span.old,.datepicker table tr td span.new{color:#999}.datepicker .datepicker-switch{width:145px}.datepicker .datepicker-switch,.datepicker .prev,.datepicker .next,.datepicker tfoot tr th{cursor:pointer}.datepicker .datepicker-switch:hover,.datepicker .prev:hover,.datepicker .next:hover,.datepicker tfoot tr th:hover{background:#eee}.datepicker .cw{font-size:10px;width:12px;padding:0 2px 0 5px;vertical-align:middle}.input-group.date .input-group-addon{cursor:pointer}.input-daterange{width:100%}.input-daterange input{text-align:center}.input-daterange input:first-child{border-radius:3px 0 0 3px}.input-daterange input:last-child{border-radius:0 3px 3px 0}.input-daterange .input-group-addon{width:auto;min-width:16px;padding:4px 5px;font-weight:400;line-height:1.42857143;text-align:center;text-shadow:0 1px 0 #fff;vertical-align:middle;background-color:#eee;border:solid #ccc;border-width:1px 0;margin-left:-5px;margin-right:-5px} \ No newline at end of file diff --git a/web/pgadmin/static/css/overrides.css b/web/pgadmin/static/css/overrides.css index fa148f69b..22a2dacee 100644 --- a/web/pgadmin/static/css/overrides.css +++ b/web/pgadmin/static/css/overrides.css @@ -382,7 +382,7 @@ iframe { } .pg-prop-btn-group button:not(:first-child):not(:last-child) { - margin: 0px; + margin-left: 0px; } .pg-prop-content { @@ -448,3 +448,116 @@ fieldset[disabled] .form-control { margin-left: -18px; margin-right: 9px; } + + +/* Sub-Node */ + +.table-bordered > thead > tr > td, .table-bordered > thead > tr > th { + border-bottom-width: 1px; +} + +.subnode > table.backgrid{ + width: 99%; + margin: 0.1% 0.49%; + padding: 0; +} + +.backgrid thead th{ + background-color: #2c76b4; +} + +.backgrid th, .backgrid td { + line-height: 18px; + font-size: 12px; +} + +.backgrid td { + padding-top: 0px; + padding-bottom: 0px; + padding-left: 2px; + padding-right: 2px; +} + +.backgrid thead th a { + color: #ffffff; +} + +.backgrid > th.object { + width: 30px; +} + +.edit-cell, .delete-cell { + text-align:center !important; + width:25px; +} + +.backgrid td.renderable:not(.editable):not(.delete-cell) { + background-color: #eee; +} + +.subnode-header { + background-color:#2c76b4; + height:35px; + color:#FFFFFF; + border-radius:5px 5px 0px 0px; + padding-top:3px; +} + +.subnode-header > button.add { + float:right; + margin-right:15px; +} + +.subnode { + margin-top:5px; + padding-top:0px; + border-left:1px solid #dadada; + border-bottom:1px solid #ddd; + border-right:1px solid #ddd; +} + +.subnode-dialog { + bottom: 0; + left: 0; + overflow-x: auto; + overflow-y: auto; + right: 0; + height:auto; + margin-left: 23px; + background-color: #dadada; + margin-top: 0px; + border: 1px solid #a9a9a9; +} +.subnode-body { + height:auto; + overflow:inherit; + +} +.subnode-footer { + height:38px;; + margin: 0px, 15px; + min-height:40px; + vertical-align: bottom; +} + +.sub-node-form { + height:auto; + padding: 1px; +} + +.sub-node-form > .nav-tabs { + background-color: #DADADA; +} + +.sub-node-form > ul.tab-content{ + background-color: #FFFFFF; + padding-left: 15px; + left: 1px; +} + +table.backgrid tr.new { + background-color: rgba(82, 168, 236, 0.1) !important; + box-sizing: border-box; + outline: 1px solid rgba(82, 168, 236, 0.8); + outline-offset: -1px; + } diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 7c9d6881f..17c54b6c1 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -10,10 +10,11 @@ // Set up Backform appropriately for the environment. Start with AMD. if (typeof define === 'function' && define.amd) { - define(['underscore', 'jquery', 'backbone', 'backform'], function(_, $, Backbone, Backform) { + define(['underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'pgadmin.backgrid'], + function(_, $, Backbone, Backform, Backgrid) { // Export global even in AMD case in case this script is loaded with // others that may still expect a global Backform. - return factory(root, _, $, Backbone, Backform); + return factory(root, _, $, Backbone, Backform, Backgrid); }); // Next for Node.js or CommonJS. jQuery may not be needed as a module. @@ -21,14 +22,16 @@ var _ = require('underscore') || root._, $ = root.jQuery || root.$ || root.Zepto || root.ender, Backbone = require('backbone') || root.Backbone, - Backform = require('backform') || root.Backform; - factory(root, _, $, Backbone, Backform); + Backform = require('backform') || root.Backform, + Backgrid = require('backgrid') || root.Backgrid; + pgAdminBackgrid = require('pgadmin.backgrid'); + factory(root, _, $, Backbone, Backform, Backgrid); // Finally, as a browser global. } else { - factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform); + factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform, root.Backgrid); } -}(this, function(root, _, $, Backbone, Backform) { +}(this, function(root, _, $, Backbone, Backform, Backgrid) { // HTML markup global class names. More can be added by individual controls // using _.extend. Look at RadioControl as an example. @@ -41,6 +44,51 @@ setGroupContentClassName: "fieldset-content col-xs-12" }); + var controlMapper = Backform.controlMapper = { + 'int': ['uneditable-input', 'input', 'integer'], + 'text': ['uneditable-input', 'input', 'string'], + 'numeric': ['uneditable-input', 'input', 'number'], + 'date': 'datepicker', + 'boolean': 'boolean', + 'options': ['readonly-option', 'select', Backgrid.Extension.PGSelectCell], + 'multiline': ['textarea', 'textarea', 'string'], + 'collection': ['sub-node-collection', 'sub-node-collection', 'string'] + }; + + var getMappedControl = Backform.getMappedControl = function(type, mode) { + if (type in Backform.controlMapper) { + var m = Backform.controlMapper[type]; + + if (!_.isArray(m)) { + return m; + } + + var idx = 1, len = _.size(m); + + switch (mode) { + case 'properties': + idx = 0; + break; + case 'edit': + case 'create': + case 'control': + idx = 1; + break; + case 'cell': + idx = 2; + break; + default: + idx = 0; + break; + } + + return m[idx > len ? 0 : idx]; + } + alert ("Developer: did you forget to put/implement the control type - '" + type + "' in mapper"); + return null; + } + + // Override the Backform.Control to allow to track changes in dependencies, // and rerender the View element var BackformControlInit = Backform.Control.prototype.initialize; @@ -72,7 +120,7 @@ '
', '<% for (var i=0; i < options.length; i++) { %>', ' <% var option = options[i]; %>', - ' <% if (option.value === rawValue) { %>', + ' <% if (option.value === rawValue) { %>', ' <%-option.label%>', ' <% } %>', '<% } %>', @@ -214,5 +262,196 @@ events: {} }); + var SubNodeCollectionControl = Backform.SubNodeCollectionControl = Backform.Control.extend({ + render: function() { + var field = _.defaults(this.field.toJSON(), this.defaults), + attributes = this.model.toJSON(), + attrArr = field.name.split('.'), + name = attrArr.shift(), + path = attrArr.join('.'), + rawValue = this.keyPathAccessor(attributes[name], path), + data = _.extend(field, { + rawValue: rawValue, + value: this.formatter.fromRaw(rawValue, this.model), + attributes: attributes, + formatter: this.formatter + }), + evalF = function(f, m) { + return (_.isFunction(f) ? !!f(m) : !!f); + }; + + // Evaluate the disabled, visible, required, canAdd, cannEdit & canDelete option + _.extend(data, { + disabled: evalF(data.disabled, this.model), + visible: evalF(data.visible, this.model), + required: evalF(data.required, this.model), + canAdd: evalF(data.canAdd, this.model), + canEdit: evalF(data.canEdit, this.model), + canDelete: evalF(data.canDelete, this.model) + }); + // Show Backgrid Control + grid = (data.subnode == undefined) ? "" : this.showGridControl(data); + + this.$el.html(grid).addClass(field.name); + this.updateInvalid(); + + return this; + }, + showGridControl: function(data) { + var gridHeader = ["
", + " " , + "
"].join("\n"); + gridBody = $("
").append(gridHeader); + + var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype, + columns = [], + gridColumns = [], + groups = Backform.generateViewSchema(subnode, this.field.get('mode')), + schema = []; + + // Prepare columns for backgrid + _.each(groups, function(fields, key) { + _.each(fields, function(f) { + if (!f.control && !f.cell) { + return; + } + f.cel_priority = _.indexOf(data.columns, f.name); + if (f.cel_priority != -1) { + columns.push(f); + } + }); + schema.push({label: key, fields: fields}); + }); + + // Set visibility of Add button + if (data.disabled || data.canAdd == false) { + $(gridBody).find("button.add").remove(); + } + + // Insert Delete Cell into Grid + if (data.disabled == false && data.canDelete) { + columns.unshift({ + name: "pg-backform-delete", label: "", + cell: Backgrid.Extension.DeleteCell, + editable: false, priority: -1 + }); + } + + // Insert Edit Cell into Grid + if (data.disabled == false && data.canEdit) { + var editCell = Backgrid.Extension.ObjectCell.extend({ + schema: schema + }); + + columns.unshift({ + name: "pg-backform-edit", label: "", cell : editCell, + priority: -2 + }); + } + + var collections = this.model.get(data.name); + + // Initialize a new Grid instance + var grid = new Backgrid.Grid({ + columns: _.sortBy(columns, function(c) { return c.cell_priority; }), + collection: collections, + className: "backgrid table-bordered" + }); + + // Render subNode grid + subNodeGrid = grid.render().$el; + + // Combine Edit and Delete Cell + if (data.canDelete && data.canEdit) { + $(subNodeGrid).find("th.pg-backform-delete").remove(); + $(subNodeGrid).find("th.pg-backform-edit").attr("colspan", "2"); + } + + $dialog = gridBody.append(subNodeGrid); + + // Add button callback + $dialog.find('button.add').click(function(e) { + e.preventDefault(); + grid.insertRow({}); + newRow = $(grid.body.rows[collections.length - 1].$el); + newRow.attr("class", "new").click(function(e) { + $(this).attr("class", ""); + }); + return false; + }); + + return $dialog; + } + }); + + /////// + // Generate a schema (as group members) based on the model's schema + // + // It will be used by the grid, properties, and dialog view generation + // functions. + var generateViewSchema = Backform.generateViewSchema = function(Model, mode) { + var proto = (Model && Model.prototype) || Model, + schema = (proto && proto.schema), + groups, pgBrowser = window.pgAdmin.Browser; + + // 'schema' has the information about how to generate the form. + if (schema && _.isArray(schema)) { + var evalASFunc = evalASFunc = function(prop) { + return ((prop && proto[prop] && + typeof proto[prop] == "function") ? proto[prop] : prop); + }; + groups = {}; + + _.each(schema, function(s) { + // Do we understand - what control, we're creating + // here? + if (!s.mode || (s && s.mode && _.isObject(s.mode) && + _.indexOf(s.mode, mode) != -1)) { + // Each field is kept in specified group, or in + // 'General' category. + var group = s.group || pgBrowser.messages.general_cateogty, + control = Backform.getMappedControl(s.type, mode), + cell = s.cell || Backform.getMappedControl(s.type, 'cell'); + + if (control == null) { + return; + } + + // Generate the empty group list (if not exists) + groups[group] = (groups[group] || []); + + var o = _.extend(_.clone(s), { + name: s.id, + // Do we need to show this control in this mode? + visible: evalASFunc(s.show), + // This can be disabled in some cases (if not hidden) + disabled: (mode == 'properties' ? true : evalASFunc(s.disabled)), + subnode: (_.isString(s.model) && s.model in pgBrowser.Nodes) ? + pgBrowser.Nodes[s.model].model : s.model, + canAdd: (mode == 'properties' ? false : evalASFunc(s.canAdd)), + canEdit: (mode == 'properties' ? false : evalASFunc(s.canEdit)), + canDelete: (mode == 'properties' ? false : evalASFunc(s.canDelete)), + mode: mode, + control: control, + cell: cell + }); + delete o.id; + + // Temporarily store in dictionaly format for + // utilizing it later. + groups[group].push(o); + } + }); + + // Do we have fields to genreate controls, which we + // understand? + if (_.isEmpty(groups)) { + return null; + } + } + return groups; + } + return Backform; })); diff --git a/web/pgadmin/static/js/backgrid/backgrid.js b/web/pgadmin/static/js/backgrid/backgrid.js new file mode 100644 index 000000000..6f8da79e5 --- /dev/null +++ b/web/pgadmin/static/js/backgrid/backgrid.js @@ -0,0 +1,2883 @@ +/*! + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2014 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. +*/ + +(function (factory) { + + // CommonJS + if (typeof exports == "object") { + module.exports = factory(module.exports, + require("underscore"), + require("backbone")); + } + // Browser + else factory(this, this._, this.Backbone); +}(function (root, _, Backbone) { + + "use strict"; + +/* + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. +*/ + +// Copyright 2009, 2010 Kristopher Michael Kowal +// https://github.com/kriskowal/es5-shim +// ES5 15.5.4.20 +// http://es5.github.com/#x15.5.4.20 +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + + "\u2029\uFEFF"; +if (!String.prototype.trim || ws.trim()) { + // http://blog.stevenlevithan.com/archives/faster-trim-javascript + // http://perfectionkills.com/whitespace-deviations/ + ws = "[" + ws + "]"; + var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), + trimEndRegexp = new RegExp(ws + ws + "*$"); + String.prototype.trim = function trim() { + if (this === undefined || this === null) { + throw new TypeError("can't convert " + this + " to object"); + } + return String(this) + .replace(trimBeginRegexp, "") + .replace(trimEndRegexp, ""); + }; +} + +function lpad(str, length, padstr) { + var paddingLen = length - (str + '').length; + paddingLen = paddingLen < 0 ? 0 : paddingLen; + var padding = ''; + for (var i = 0; i < paddingLen; i++) { + padding = padding + padstr; + } + return padding + str; +} + +var $ = Backbone.$; + +var Backgrid = root.Backgrid = { + + Extension: {}, + + resolveNameToClass: function (name, suffix) { + if (_.isString(name)) { + var key = _.map(name.split('-'), function (e) { + return e.slice(0, 1).toUpperCase() + e.slice(1); + }).join('') + suffix; + var klass = Backgrid[key] || Backgrid.Extension[key]; + if (_.isUndefined(klass)) { + throw new ReferenceError("Class '" + key + "' not found"); + } + return klass; + } + + return name; + }, + + callByNeed: function () { + var value = arguments[0]; + if (!_.isFunction(value)) return value; + + var context = arguments[1]; + var args = [].slice.call(arguments, 2); + return value.apply(context, !!(args + '') ? args : []); + } + +}; +_.extend(Backgrid, Backbone.Events); + +/** + Command translates a DOM Event into commands that Backgrid + recognizes. Interested parties can listen on selected Backgrid events that + come with an instance of this class and act on the commands. + + It is also possible to globally rebind the keyboard shortcuts by replacing + the methods in this class' prototype. + + @class Backgrid.Command + @constructor + */ +var Command = Backgrid.Command = function (evt) { + _.extend(this, { + altKey: !!evt.altKey, + "char": evt["char"], + charCode: evt.charCode, + ctrlKey: !!evt.ctrlKey, + key: evt.key, + keyCode: evt.keyCode, + locale: evt.locale, + location: evt.location, + metaKey: !!evt.metaKey, + repeat: !!evt.repeat, + shiftKey: !!evt.shiftKey, + which: evt.which + }); +}; +_.extend(Command.prototype, { + /** + Up Arrow + + @member Backgrid.Command + */ + moveUp: function () { return this.keyCode == 38; }, + /** + Down Arrow + + @member Backgrid.Command + */ + moveDown: function () { return this.keyCode === 40; }, + /** + Shift Tab + + @member Backgrid.Command + */ + moveLeft: function () { return this.shiftKey && this.keyCode === 9; }, + /** + Tab + + @member Backgrid.Command + */ + moveRight: function () { return !this.shiftKey && this.keyCode === 9; }, + /** + Enter + + @member Backgrid.Command + */ + save: function () { return this.keyCode === 13; }, + /** + Esc + + @member Backgrid.Command + */ + cancel: function () { return this.keyCode === 27; }, + /** + None of the above. + + @member Backgrid.Command + */ + passThru: function () { + return !(this.moveUp() || this.moveDown() || this.moveLeft() || + this.moveRight() || this.save() || this.cancel()); + } +}); + +/* + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. +*/ + +/** + Just a convenient class for interested parties to subclass. + + The default Cell classes don't require the formatter to be a subclass of + Formatter as long as the fromRaw(rawData) and toRaw(formattedData) methods + are defined. + + @abstract + @class Backgrid.CellFormatter + @constructor +*/ +var CellFormatter = Backgrid.CellFormatter = function () {}; +_.extend(CellFormatter.prototype, { + + /** + Takes a raw value from a model and returns an optionally formatted string + for display. The default implementation simply returns the supplied value + as is without any type conversion. + + @member Backgrid.CellFormatter + @param {*} rawData + @param {Backbone.Model} model Used for more complicated formatting + @return {*} + */ + fromRaw: function (rawData, model) { + return rawData; + }, + + /** + Takes a formatted string, usually from user input, and returns a + appropriately typed value for persistence in the model. + + If the user input is invalid or unable to be converted to a raw value + suitable for persistence in the model, toRaw must return `undefined`. + + @member Backgrid.CellFormatter + @param {string} formattedData + @param {Backbone.Model} model Used for more complicated formatting + @return {*|undefined} + */ + toRaw: function (formattedData, model) { + return formattedData; + } + +}); + +/** + A floating point number formatter. Doesn't understand scientific notation at + the moment. + + @class Backgrid.NumberFormatter + @extends Backgrid.CellFormatter + @constructor + @throws {RangeError} If decimals < 0 or > 20. +*/ +var NumberFormatter = Backgrid.NumberFormatter = function (options) { + _.extend(this, this.defaults, options || {}); + + if (this.decimals < 0 || this.decimals > 20) { + throw new RangeError("decimals must be between 0 and 20"); + } +}; +NumberFormatter.prototype = new CellFormatter(); +_.extend(NumberFormatter.prototype, { + + /** + @member Backgrid.NumberFormatter + @cfg {Object} options + + @cfg {number} [options.decimals=2] Number of decimals to display. Must be an integer. + + @cfg {string} [options.decimalSeparator='.'] The separator to use when + displaying decimals. + + @cfg {string} [options.orderSeparator=','] The separator to use to + separator thousands. May be an empty string. + */ + defaults: { + decimals: 2, + decimalSeparator: '.', + orderSeparator: ',' + }, + + HUMANIZED_NUM_RE: /(\d)(?=(?:\d{3})+$)/g, + + /** + Takes a floating point number and convert it to a formatted string where + every thousand is separated by `orderSeparator`, with a `decimal` number of + decimals separated by `decimalSeparator`. The number returned is rounded + the usual way. + + @member Backgrid.NumberFormatter + @param {number} number + @param {Backbone.Model} model Used for more complicated formatting + @return {string} + */ + fromRaw: function (number, model) { + if (_.isNull(number) || _.isUndefined(number)) return ''; + + number = number.toFixed(~~this.decimals); + + var parts = number.split('.'); + var integerPart = parts[0]; + var decimalPart = parts[1] ? (this.decimalSeparator || '.') + parts[1] : ''; + + return integerPart.replace(this.HUMANIZED_NUM_RE, '$1' + this.orderSeparator) + decimalPart; + }, + + /** + Takes a string, possibly formatted with `orderSeparator` and/or + `decimalSeparator`, and convert it back to a number. + + @member Backgrid.NumberFormatter + @param {string} formattedData + @param {Backbone.Model} model Used for more complicated formatting + @return {number|undefined} Undefined if the string cannot be converted to + a number. + */ + toRaw: function (formattedData, model) { + formattedData = formattedData.trim(); + + if (formattedData === '') return null; + + var rawData = ''; + + var thousands = formattedData.split(this.orderSeparator); + for (var i = 0; i < thousands.length; i++) { + rawData += thousands[i]; + } + + var decimalParts = rawData.split(this.decimalSeparator); + rawData = ''; + for (var i = 0; i < decimalParts.length; i++) { + rawData = rawData + decimalParts[i] + '.'; + } + + if (rawData[rawData.length - 1] === '.') { + rawData = rawData.slice(0, rawData.length - 1); + } + + var result = (rawData * 1).toFixed(~~this.decimals) * 1; + if (_.isNumber(result) && !_.isNaN(result)) return result; + } + +}); + +/** + A number formatter that converts a floating point number, optionally + multiplied by a multiplier, to a percentage string and vice versa. + + @class Backgrid.PercentFormatter + @extends Backgrid.NumberFormatter + @constructor + @throws {RangeError} If decimals < 0 or > 20. + */ +var PercentFormatter = Backgrid.PercentFormatter = function () { + Backgrid.NumberFormatter.apply(this, arguments); +}; + +PercentFormatter.prototype = new Backgrid.NumberFormatter(), + +_.extend(PercentFormatter.prototype, { + + /** + @member Backgrid.PercentFormatter + @cfg {Object} options + + @cfg {number} [options.multiplier=1] The number used to multiply the model + value for display. + + @cfg {string} [options.symbol='%'] The symbol to append to the percentage + string. + */ + defaults: _.extend({}, NumberFormatter.prototype.defaults, { + multiplier: 1, + symbol: "%" + }), + + /** + Takes a floating point number, where the number is first multiplied by + `multiplier`, then converted to a formatted string like + NumberFormatter#fromRaw, then finally append `symbol` to the end. + + @member Backgrid.PercentFormatter + @param {number} rawValue + @param {Backbone.Model} model Used for more complicated formatting + @return {string} + */ + fromRaw: function (number, model) { + var args = [].slice.call(arguments, 1); + args.unshift(number * this.multiplier); + return (NumberFormatter.prototype.fromRaw.apply(this, args) || "0") + this.symbol; + }, + + /** + Takes a string, possibly appended with `symbol` and/or `decimalSeparator`, + and convert it back to a number for the model like NumberFormatter#toRaw, + and then dividing it by `multiplier`. + + @member Backgrid.PercentFormatter + @param {string} formattedData + @param {Backbone.Model} model Used for more complicated formatting + @return {number|undefined} Undefined if the string cannot be converted to + a number. + */ + toRaw: function (formattedValue, model) { + var tokens = formattedValue.split(this.symbol); + if (tokens && tokens[0] && tokens[1] === "" || tokens[1] == null) { + var rawValue = NumberFormatter.prototype.toRaw.call(this, tokens[0]); + if (_.isUndefined(rawValue)) return rawValue; + return rawValue / this.multiplier; + } + } + +}); + +/** + Formatter to converts between various datetime formats. + + This class only understands ISO-8601 formatted datetime strings and UNIX + offset (number of milliseconds since UNIX Epoch). See + Backgrid.Extension.MomentFormatter if you need a much more flexible datetime + formatter. + + @class Backgrid.DatetimeFormatter + @extends Backgrid.CellFormatter + @constructor + @throws {Error} If both `includeDate` and `includeTime` are false. +*/ +var DatetimeFormatter = Backgrid.DatetimeFormatter = function (options) { + _.extend(this, this.defaults, options || {}); + + if (!this.includeDate && !this.includeTime) { + throw new Error("Either includeDate or includeTime must be true"); + } +}; +DatetimeFormatter.prototype = new CellFormatter(); +_.extend(DatetimeFormatter.prototype, { + + /** + @member Backgrid.DatetimeFormatter + + @cfg {Object} options + + @cfg {boolean} [options.includeDate=true] Whether the values include the + date part. + + @cfg {boolean} [options.includeTime=true] Whether the values include the + time part. + + @cfg {boolean} [options.includeMilli=false] If `includeTime` is true, + whether to include the millisecond part, if it exists. + */ + defaults: { + includeDate: true, + includeTime: true, + includeMilli: false + }, + + DATE_RE: /^([+\-]?\d{4})-(\d{2})-(\d{2})$/, + TIME_RE: /^(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?$/, + ISO_SPLITTER_RE: /T|Z| +/, + + _convert: function (data, validate) { + if ((data + '').trim() === '') return null; + + var date, time = null; + if (_.isNumber(data)) { + var jsDate = new Date(data); + date = lpad(jsDate.getUTCFullYear(), 4, 0) + '-' + lpad(jsDate.getUTCMonth() + 1, 2, 0) + '-' + lpad(jsDate.getUTCDate(), 2, 0); + time = lpad(jsDate.getUTCHours(), 2, 0) + ':' + lpad(jsDate.getUTCMinutes(), 2, 0) + ':' + lpad(jsDate.getUTCSeconds(), 2, 0); + } + else { + data = data.trim(); + var parts = data.split(this.ISO_SPLITTER_RE) || []; + date = this.DATE_RE.test(parts[0]) ? parts[0] : ''; + time = date && parts[1] ? parts[1] : this.TIME_RE.test(parts[0]) ? parts[0] : ''; + } + + var YYYYMMDD = this.DATE_RE.exec(date) || []; + var HHmmssSSS = this.TIME_RE.exec(time) || []; + + if (validate) { + if (this.includeDate && _.isUndefined(YYYYMMDD[0])) return; + if (this.includeTime && _.isUndefined(HHmmssSSS[0])) return; + if (!this.includeDate && date) return; + if (!this.includeTime && time) return; + } + + var jsDate = new Date(Date.UTC(YYYYMMDD[1] * 1 || 0, + YYYYMMDD[2] * 1 - 1 || 0, + YYYYMMDD[3] * 1 || 0, + HHmmssSSS[1] * 1 || null, + HHmmssSSS[2] * 1 || null, + HHmmssSSS[3] * 1 || null, + HHmmssSSS[5] * 1 || null)); + + var result = ''; + + if (this.includeDate) { + result = lpad(jsDate.getUTCFullYear(), 4, 0) + '-' + lpad(jsDate.getUTCMonth() + 1, 2, 0) + '-' + lpad(jsDate.getUTCDate(), 2, 0); + } + + if (this.includeTime) { + result = result + (this.includeDate ? 'T' : '') + lpad(jsDate.getUTCHours(), 2, 0) + ':' + lpad(jsDate.getUTCMinutes(), 2, 0) + ':' + lpad(jsDate.getUTCSeconds(), 2, 0); + + if (this.includeMilli) { + result = result + '.' + lpad(jsDate.getUTCMilliseconds(), 3, 0); + } + } + + if (this.includeDate && this.includeTime) { + result += "Z"; + } + + return result; + }, + + /** + Converts an ISO-8601 formatted datetime string to a datetime string, date + string or a time string. The timezone is ignored if supplied. + + @member Backgrid.DatetimeFormatter + @param {string} rawData + @param {Backbone.Model} model Used for more complicated formatting + @return {string|null|undefined} ISO-8601 string in UTC. Null and undefined + values are returned as is. + */ + fromRaw: function (rawData, model) { + if (_.isNull(rawData) || _.isUndefined(rawData)) return ''; + return this._convert(rawData); + }, + + /** + Converts an ISO-8601 formatted datetime string to a datetime string, date + string or a time string. The timezone is ignored if supplied. This method + parses the input values exactly the same way as + Backgrid.Extension.MomentFormatter#fromRaw(), in addition to doing some + sanity checks. + + @member Backgrid.DatetimeFormatter + @param {string} formattedData + @param {Backbone.Model} model Used for more complicated formatting + @return {string|undefined} ISO-8601 string in UTC. Undefined if a date is + found when `includeDate` is false, or a time is found when `includeTime` is + false, or if `includeDate` is true and a date is not found, or if + `includeTime` is true and a time is not found. + */ + toRaw: function (formattedData, model) { + return this._convert(formattedData, true); + } + +}); + +/** + Formatter to convert any value to string. + + @class Backgrid.StringFormatter + @extends Backgrid.CellFormatter + @constructor + */ +var StringFormatter = Backgrid.StringFormatter = function () {}; +StringFormatter.prototype = new CellFormatter(); +_.extend(StringFormatter.prototype, { + /** + Converts any value to a string using Ecmascript's implicit type + conversion. If the given value is `null` or `undefined`, an empty string is + returned instead. + + @member Backgrid.StringFormatter + @param {*} rawValue + @param {Backbone.Model} model Used for more complicated formatting + @return {string} + */ + fromRaw: function (rawValue, model) { + if (_.isUndefined(rawValue) || _.isNull(rawValue)) return ''; + return rawValue + ''; + } +}); + +/** + Simple email validation formatter. + + @class Backgrid.EmailFormatter + @extends Backgrid.CellFormatter + @constructor + */ +var EmailFormatter = Backgrid.EmailFormatter = function () {}; +EmailFormatter.prototype = new CellFormatter(); +_.extend(EmailFormatter.prototype, { + /** + Return the input if it is a string that contains an '@' character and if + the strings before and after '@' are non-empty. If the input does not + validate, `undefined` is returned. + + @member Backgrid.EmailFormatter + @param {*} formattedData + @param {Backbone.Model} model Used for more complicated formatting + @return {string|undefined} + */ + toRaw: function (formattedData, model) { + var parts = formattedData.trim().split("@"); + if (parts.length === 2 && _.all(parts)) { + return formattedData; + } + } +}); + +/** + Formatter for SelectCell. + + If the type of a model value is not a string, it is expected that a subclass + of this formatter is provided to the SelectCell, with #toRaw overridden to + convert the string value returned from the DOM back to whatever value is + expected in the model. + + @class Backgrid.SelectFormatter + @extends Backgrid.CellFormatter + @constructor +*/ +var SelectFormatter = Backgrid.SelectFormatter = function () {}; +SelectFormatter.prototype = new CellFormatter(); +_.extend(SelectFormatter.prototype, { + + /** + Normalizes raw scalar or array values to an array. + + @member Backgrid.SelectFormatter + @param {*} rawValue + @param {Backbone.Model} model Used for more complicated formatting + @return {Array.<*>} + */ + fromRaw: function (rawValue, model) { + return _.isArray(rawValue) ? rawValue : rawValue != null ? [rawValue] : []; + } +}); + +/* + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT license. +*/ + +/** + Generic cell editor base class. Only defines an initializer for a number of + required parameters. + + @abstract + @class Backgrid.CellEditor + @extends Backbone.View +*/ +var CellEditor = Backgrid.CellEditor = Backbone.View.extend({ + + /** + Initializer. + + @param {Object} options + @param {Backgrid.CellFormatter} options.formatter + @param {Backgrid.Column} options.column + @param {Backbone.Model} options.model + + @throws {TypeError} If `formatter` is not a formatter instance, or when + `model` or `column` are undefined. + */ + initialize: function (options) { + this.formatter = options.formatter; + this.column = options.column; + if (!(this.column instanceof Column)) { + this.column = new Column(this.column); + } + + this.listenTo(this.model, "backgrid:editing", this.postRender); + }, + + /** + Post-rendering setup and initialization. Focuses the cell editor's `el` in + this default implementation. **Should** be called by Cell classes after + calling Backgrid.CellEditor#render. + */ + postRender: function (model, column) { + if (column == null || column.get("name") == this.column.get("name")) { + this.$el.focus(); + } + return this; + } + +}); + +/** + InputCellEditor the cell editor type used by most core cell types. This cell + editor renders a text input box as its editor. The input will render a + placeholder if the value is empty on supported browsers. + + @class Backgrid.InputCellEditor + @extends Backgrid.CellEditor +*/ +var InputCellEditor = Backgrid.InputCellEditor = CellEditor.extend({ + + /** @property */ + tagName: "input", + + /** @property */ + attributes: { + type: "text" + }, + + /** @property */ + events: { + "blur": "saveOrCancel", + "keydown": "saveOrCancel" + }, + + /** + Initializer. Removes this `el` from the DOM when a `done` event is + triggered. + + @param {Object} options + @param {Backgrid.CellFormatter} options.formatter + @param {Backgrid.Column} options.column + @param {Backbone.Model} options.model + @param {string} [options.placeholder] + */ + initialize: function (options) { + InputCellEditor.__super__.initialize.apply(this, arguments); + + if (options.placeholder) { + this.$el.attr("placeholder", options.placeholder); + } + }, + + /** + Renders a text input with the cell value formatted for display, if it + exists. + */ + render: function () { + var model = this.model; + this.$el.val(this.formatter.fromRaw(model.get(this.column.get("name")), model)); + return this; + }, + + /** + If the key pressed is `enter`, `tab`, `up`, or `down`, converts the value + in the editor to a raw value for saving into the model using the formatter. + + If the key pressed is `esc` the changes are undone. + + If the editor goes out of focus (`blur`) but the value is invalid, the + event is intercepted and cancelled so the cell remains in focus pending for + further action. The changes are saved otherwise. + + Triggers a Backbone `backgrid:edited` event from the model when successful, + and `backgrid:error` if the value cannot be converted. Classes listening to + the `error` event, usually the Cell classes, should respond appropriately, + usually by rendering some kind of error feedback. + + @param {Event} e + */ + saveOrCancel: function (e) { + + var formatter = this.formatter; + var model = this.model; + var column = this.column; + + var command = new Command(e); + var blurred = e.type === "blur"; + + if (command.moveUp() || command.moveDown() || command.moveLeft() || command.moveRight() || + command.save() || blurred) { + + e.preventDefault(); + e.stopPropagation(); + + var val = this.$el.val(); + var newValue = formatter.toRaw(val, model); + if (_.isUndefined(newValue)) { + model.trigger("backgrid:error", model, column, val); + } + else { + model.set(column.get("name"), newValue); + model.trigger("backgrid:edited", model, column, command); + } + } + // esc + else if (command.cancel()) { + // undo + e.stopPropagation(); + model.trigger("backgrid:edited", model, column, command); + } + }, + + postRender: function (model, column) { + if (column == null || column.get("name") == this.column.get("name")) { + // move the cursor to the end on firefox if text is right aligned + if (this.$el.css("text-align") === "right") { + var val = this.$el.val(); + this.$el.focus().val(null).val(val); + } + else this.$el.focus(); + } + return this; + } + +}); + +/** + The super-class for all Cell types. By default, this class renders a plain + table cell with the model value converted to a string using the + formatter. The table cell is clickable, upon which the cell will go into + editor mode, which is rendered by a Backgrid.InputCellEditor instance by + default. Upon encountering any formatting errors, this class will add an + `error` CSS class to the table cell. + + @abstract + @class Backgrid.Cell + @extends Backbone.View +*/ +var Cell = Backgrid.Cell = Backbone.View.extend({ + + /** @property */ + tagName: "td", + + /** + @property {Backgrid.CellFormatter|Object|string} [formatter=CellFormatter] + */ + formatter: CellFormatter, + + /** + @property {Backgrid.CellEditor} [editor=Backgrid.InputCellEditor] The + default editor for all cell instances of this class. This value must be a + class, it will be automatically instantiated upon entering edit mode. + + See Backgrid.CellEditor + */ + editor: InputCellEditor, + + /** @property */ + events: { + "click": "enterEditMode" + }, + + /** + Initializer. + + @param {Object} options + @param {Backbone.Model} options.model + @param {Backgrid.Column} options.column + + @throws {ReferenceError} If formatter is a string but a formatter class of + said name cannot be found in the Backgrid module. + */ + initialize: function (options) { + this.column = options.column; + if (!(this.column instanceof Column)) { + this.column = new Column(this.column); + } + + var column = this.column, model = this.model, $el = this.$el; + + var formatter = Backgrid.resolveNameToClass(column.get("formatter") || + this.formatter, "Formatter"); + + if (!_.isFunction(formatter.fromRaw) && !_.isFunction(formatter.toRaw)) { + formatter = new formatter(); + } + + this.formatter = formatter; + + this.editor = Backgrid.resolveNameToClass(this.editor, "CellEditor"); + + this.listenTo(model, "change:" + column.get("name"), function () { + if (!$el.hasClass("editor")) this.render(); + }); + + this.listenTo(model, "backgrid:error", this.renderError); + + this.listenTo(column, "change:editable change:sortable change:renderable", + function (column) { + var changed = column.changedAttributes(); + for (var key in changed) { + if (changed.hasOwnProperty(key)) { + $el.toggleClass(key, changed[key]); + } + } + }); + + if (Backgrid.callByNeed(column.editable(), column, model)) $el.addClass("editable"); + if (Backgrid.callByNeed(column.sortable(), column, model)) $el.addClass("sortable"); + if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass("renderable"); + }, + + /** + Render a text string in a table cell. The text is converted from the + model's raw value for this cell's column. + */ + render: function () { + this.$el.empty(); + var model = this.model; + this.$el.text(this.formatter.fromRaw(model.get(this.column.get("name")), model)); + this.delegateEvents(); + return this; + }, + + /** + If this column is editable, a new CellEditor instance is instantiated with + its required parameters. An `editor` CSS class is added to the cell upon + entering edit mode. + + This method triggers a Backbone `backgrid:edit` event from the model when + the cell is entering edit mode and an editor instance has been constructed, + but before it is rendered and inserted into the DOM. The cell and the + constructed cell editor instance are sent as event parameters when this + event is triggered. + + When this cell has finished switching to edit mode, a Backbone + `backgrid:editing` event is triggered from the model. The cell and the + constructed cell instance are also sent as parameters in the event. + + When the model triggers a `backgrid:error` event, it means the editor is + unable to convert the current user input to an apprpriate value for the + model's column, and an `error` CSS class is added to the cell accordingly. + */ + enterEditMode: function () { + var model = this.model; + var column = this.column; + + var editable = Backgrid.callByNeed(column.editable(), column, model); + if (editable) { + + this.currentEditor = new this.editor({ + column: this.column, + model: this.model, + formatter: this.formatter + }); + + model.trigger("backgrid:edit", model, column, this, this.currentEditor); + + // Need to redundantly undelegate events for Firefox + this.undelegateEvents(); + this.$el.empty(); + this.$el.append(this.currentEditor.$el); + this.currentEditor.render(); + this.$el.addClass("editor"); + + model.trigger("backgrid:editing", model, column, this, this.currentEditor); + } + }, + + /** + Put an `error` CSS class on the table cell. + */ + renderError: function (model, column) { + if (column == null || column.get("name") == this.column.get("name")) { + this.$el.addClass("error"); + } + }, + + /** + Removes the editor and re-render in display mode. + */ + exitEditMode: function () { + this.$el.removeClass("error"); + this.currentEditor.remove(); + this.stopListening(this.currentEditor); + delete this.currentEditor; + this.$el.removeClass("editor"); + this.render(); + }, + + /** + Clean up this cell. + + @chainable + */ + remove: function () { + if (this.currentEditor) { + this.currentEditor.remove.apply(this.currentEditor, arguments); + delete this.currentEditor; + } + return Cell.__super__.remove.apply(this, arguments); + } + +}); + +/** + StringCell displays HTML escaped strings and accepts anything typed in. + + @class Backgrid.StringCell + @extends Backgrid.Cell +*/ +var StringCell = Backgrid.StringCell = Cell.extend({ + + /** @property */ + className: "string-cell", + + formatter: StringFormatter + +}); + +/** + UriCell renders an HTML `` anchor for the value and accepts URIs as user + input values. No type conversion or URL validation is done by the formatter + of this cell. Users who need URL validation are encourage to subclass UriCell + to take advantage of the parsing capabilities of the HTMLAnchorElement + available on HTML5-capable browsers or using a third-party library like + [URI.js](https://github.com/medialize/URI.js). + + @class Backgrid.UriCell + @extends Backgrid.Cell +*/ +var UriCell = Backgrid.UriCell = Cell.extend({ + + /** @property */ + className: "uri-cell", + + /** + @property {string} [title] The title attribute of the generated anchor. It + uses the display value formatted by the `formatter.fromRaw` by default. + */ + title: null, + + /** + @property {string} [target="_blank"] The target attribute of the generated + anchor. + */ + target: "_blank", + + initialize: function (options) { + UriCell.__super__.initialize.apply(this, arguments); + this.title = options.title || this.title; + this.target = options.target || this.target; + }, + + render: function () { + this.$el.empty(); + var rawValue = this.model.get(this.column.get("name")); + var formattedValue = this.formatter.fromRaw(rawValue, this.model); + this.$el.append($("", { + tabIndex: -1, + href: rawValue, + title: this.title || formattedValue, + target: this.target + }).text(formattedValue)); + this.delegateEvents(); + return this; + } + +}); + +/** + Like Backgrid.UriCell, EmailCell renders an HTML `` anchor for the + value. The `href` in the anchor is prefixed with `mailto:`. EmailCell will + complain if the user enters a string that doesn't contain the `@` sign. + + @class Backgrid.EmailCell + @extends Backgrid.StringCell +*/ +var EmailCell = Backgrid.EmailCell = StringCell.extend({ + + /** @property */ + className: "email-cell", + + formatter: EmailFormatter, + + render: function () { + this.$el.empty(); + var model = this.model; + var formattedValue = this.formatter.fromRaw(model.get(this.column.get("name")), model); + this.$el.append($("", { + tabIndex: -1, + href: "mailto:" + formattedValue, + title: formattedValue + }).text(formattedValue)); + this.delegateEvents(); + return this; + } + +}); + +/** + NumberCell is a generic cell that renders all numbers. Numbers are formatted + using a Backgrid.NumberFormatter. + + @class Backgrid.NumberCell + @extends Backgrid.Cell +*/ +var NumberCell = Backgrid.NumberCell = Cell.extend({ + + /** @property */ + className: "number-cell", + + /** + @property {number} [decimals=2] Must be an integer. + */ + decimals: NumberFormatter.prototype.defaults.decimals, + + /** @property {string} [decimalSeparator='.'] */ + decimalSeparator: NumberFormatter.prototype.defaults.decimalSeparator, + + /** @property {string} [orderSeparator=','] */ + orderSeparator: NumberFormatter.prototype.defaults.orderSeparator, + + /** @property {Backgrid.CellFormatter} [formatter=Backgrid.NumberFormatter] */ + formatter: NumberFormatter, + + /** + Initializes this cell and the number formatter. + + @param {Object} options + @param {Backbone.Model} options.model + @param {Backgrid.Column} options.column + */ + initialize: function (options) { + NumberCell.__super__.initialize.apply(this, arguments); + var formatter = this.formatter; + formatter.decimals = this.decimals; + formatter.decimalSeparator = this.decimalSeparator; + formatter.orderSeparator = this.orderSeparator; + } + +}); + +/** + An IntegerCell is just a Backgrid.NumberCell with 0 decimals. If a floating + point number is supplied, the number is simply rounded the usual way when + displayed. + + @class Backgrid.IntegerCell + @extends Backgrid.NumberCell +*/ +var IntegerCell = Backgrid.IntegerCell = NumberCell.extend({ + + /** @property */ + className: "integer-cell", + + /** + @property {number} decimals Must be an integer. + */ + decimals: 0 +}); + +/** + A PercentCell is another Backgrid.NumberCell that takes a floating number, + optionally multiplied by a multiplier and display it as a percentage. + + @class Backgrid.PercentCell + @extends Backgrid.NumberCell + */ +var PercentCell = Backgrid.PercentCell = NumberCell.extend({ + + /** @property */ + className: "percent-cell", + + /** @property {number} [multiplier=1] */ + multiplier: PercentFormatter.prototype.defaults.multiplier, + + /** @property {string} [symbol='%'] */ + symbol: PercentFormatter.prototype.defaults.symbol, + + /** @property {Backgrid.CellFormatter} [formatter=Backgrid.PercentFormatter] */ + formatter: PercentFormatter, + + /** + Initializes this cell and the percent formatter. + + @param {Object} options + @param {Backbone.Model} options.model + @param {Backgrid.Column} options.column + */ + initialize: function () { + PercentCell.__super__.initialize.apply(this, arguments); + var formatter = this.formatter; + formatter.multiplier = this.multiplier; + formatter.symbol = this.symbol; + } + +}); + +/** + DatetimeCell is a basic cell that accepts datetime string values in RFC-2822 + or W3C's subset of ISO-8601 and displays them in ISO-8601 format. For a much + more sophisticated date time cell with better datetime formatting, take a + look at the Backgrid.Extension.MomentCell extension. + + @class Backgrid.DatetimeCell + @extends Backgrid.Cell + + See: + + - Backgrid.Extension.MomentCell + - Backgrid.DatetimeFormatter +*/ +var DatetimeCell = Backgrid.DatetimeCell = Cell.extend({ + + /** @property */ + className: "datetime-cell", + + /** + @property {boolean} [includeDate=true] + */ + includeDate: DatetimeFormatter.prototype.defaults.includeDate, + + /** + @property {boolean} [includeTime=true] + */ + includeTime: DatetimeFormatter.prototype.defaults.includeTime, + + /** + @property {boolean} [includeMilli=false] + */ + includeMilli: DatetimeFormatter.prototype.defaults.includeMilli, + + /** @property {Backgrid.CellFormatter} [formatter=Backgrid.DatetimeFormatter] */ + formatter: DatetimeFormatter, + + /** + Initializes this cell and the datetime formatter. + + @param {Object} options + @param {Backbone.Model} options.model + @param {Backgrid.Column} options.column + */ + initialize: function (options) { + DatetimeCell.__super__.initialize.apply(this, arguments); + var formatter = this.formatter; + formatter.includeDate = this.includeDate; + formatter.includeTime = this.includeTime; + formatter.includeMilli = this.includeMilli; + + var placeholder = this.includeDate ? "YYYY-MM-DD" : ""; + placeholder += (this.includeDate && this.includeTime) ? "T" : ""; + placeholder += this.includeTime ? "HH:mm:ss" : ""; + placeholder += (this.includeTime && this.includeMilli) ? ".SSS" : ""; + + this.editor = this.editor.extend({ + attributes: _.extend({}, this.editor.prototype.attributes, this.editor.attributes, { + placeholder: placeholder + }) + }); + } + +}); + +/** + DateCell is a Backgrid.DatetimeCell without the time part. + + @class Backgrid.DateCell + @extends Backgrid.DatetimeCell +*/ +var DateCell = Backgrid.DateCell = DatetimeCell.extend({ + + /** @property */ + className: "date-cell", + + /** @property */ + includeTime: false + +}); + +/** + TimeCell is a Backgrid.DatetimeCell without the date part. + + @class Backgrid.TimeCell + @extends Backgrid.DatetimeCell +*/ +var TimeCell = Backgrid.TimeCell = DatetimeCell.extend({ + + /** @property */ + className: "time-cell", + + /** @property */ + includeDate: false + +}); + +/** + BooleanCellEditor renders a checkbox as its editor. + + @class Backgrid.BooleanCellEditor + @extends Backgrid.CellEditor +*/ +var BooleanCellEditor = Backgrid.BooleanCellEditor = CellEditor.extend({ + + /** @property */ + tagName: "input", + + /** @property */ + attributes: { + tabIndex: -1, + type: "checkbox" + }, + + /** @property */ + events: { + "mousedown": function () { + this.mouseDown = true; + }, + "blur": "enterOrExitEditMode", + "mouseup": function () { + this.mouseDown = false; + }, + "change": "saveOrCancel", + "keydown": "saveOrCancel" + }, + + /** + Renders a checkbox and check it if the model value of this column is true, + uncheck otherwise. + */ + render: function () { + var model = this.model; + var val = this.formatter.fromRaw(model.get(this.column.get("name")), model); + this.$el.prop("checked", val); + return this; + }, + + /** + Event handler. Hack to deal with the case where `blur` is fired before + `change` and `click` on a checkbox. + */ + enterOrExitEditMode: function (e) { + if (!this.mouseDown) { + var model = this.model; + model.trigger("backgrid:edited", model, this.column, new Command(e)); + } + }, + + /** + Event handler. Save the value into the model if the event is `change` or + one of the keyboard navigation key presses. Exit edit mode without saving + if `escape` was pressed. + */ + saveOrCancel: function (e) { + var model = this.model; + var column = this.column; + var formatter = this.formatter; + var command = new Command(e); + // skip ahead to `change` when space is pressed + if (command.passThru() && e.type != "change") return true; + if (command.cancel()) { + e.stopPropagation(); + model.trigger("backgrid:edited", model, column, command); + } + + var $el = this.$el; + if (command.save() || command.moveLeft() || command.moveRight() || command.moveUp() || + command.moveDown()) { + e.preventDefault(); + e.stopPropagation(); + var val = formatter.toRaw($el.prop("checked"), model); + model.set(column.get("name"), val); + model.trigger("backgrid:edited", model, column, command); + } + else if (e.type == "change") { + var val = formatter.toRaw($el.prop("checked"), model); + model.set(column.get("name"), val); + $el.focus(); + } + } + +}); + +/** + BooleanCell renders a checkbox both during display mode and edit mode. The + checkbox is checked if the model value is true, unchecked otherwise. + + @class Backgrid.BooleanCell + @extends Backgrid.Cell +*/ +var BooleanCell = Backgrid.BooleanCell = Cell.extend({ + + /** @property */ + className: "boolean-cell", + + /** @property */ + editor: BooleanCellEditor, + + /** @property */ + events: { + "click": "enterEditMode" + }, + + /** + Renders a checkbox and check it if the model value of this column is true, + uncheck otherwise. + */ + render: function () { + this.$el.empty(); + var model = this.model, column = this.column; + var editable = Backgrid.callByNeed(column.editable(), column, model); + this.$el.append($("", { + tabIndex: -1, + type: "checkbox", + checked: this.formatter.fromRaw(model.get(column.get("name")), model), + disabled: !editable + })); + this.delegateEvents(); + return this; + } + +}); + +/** + SelectCellEditor renders an HTML `",{tabIndex:-1,type:"checkbox",checked:this.formatter.fromRaw(a.get(b.get("name")),a),disabled:!c})),this.delegateEvents(),this}}),i.SelectCellEditor=r.extend({tagName:"select",events:{change:"save",blur:"close",keydown:"close"},template:b.template('',null,{variable:null}),setOptionValues:function(a){this.optionValues=a,this.optionValues=b.result(this,"optionValues")},setMultiple:function(a){this.multiple=a,this.$el.prop("multiple",a)},_renderOptions:function(a,c){for(var d="",e=0;e-1});return d},render:function(){this.$el.empty();var a=b.result(this,"optionValues"),c=this.model,d=this.formatter.fromRaw(c.get(this.column.get("name")),c);if(!b.isArray(a))throw new TypeError("optionValues must be an array");for(var e=null,f=null,e=null,g=null,i=null,j=0;j-1}));else{if(!b.isObject(e))throw new TypeError("optionValues elements must be a name-value pair or an object hash of { name: 'optgroup label', value: [option name-value pairs] }");g=e.name,i=h("",{label:g}),i.append(this._renderOptions.call(this,e.values,d)),this.$el.append(i)}}return this.delegateEvents(),this},save:function(){var a=this.model,b=this.column;a.set(b.get("name"),this.formatter.toRaw(this.$el.val(),a))},close:function(a){var b=this.model,c=this.column,d=new j(a);d.cancel()?(a.stopPropagation(),b.trigger("backgrid:edited",b,c,new j(a))):(d.save()||d.moveLeft()||d.moveRight()||d.moveUp()||d.moveDown()||"blur"==a.type)&&(a.preventDefault(),a.stopPropagation(),this.save(a),b.trigger("backgrid:edited",b,c,new j(a)))}})),B=i.SelectCell=t.extend({className:"select-cell",editor:A,multiple:!1,formatter:q,optionValues:void 0,delimiter:", ",initialize:function(){B.__super__.initialize.apply(this,arguments),this.listenTo(this.model,"backgrid:edit",function(a,b,c,d){b.get("name")==this.column.get("name")&&(d.setOptionValues(this.optionValues),d.setMultiple(this.multiple))})},render:function(){this.$el.empty();var a=b.result(this,"optionValues"),c=this.model,d=this.formatter.fromRaw(c.get(this.column.get("name")),c),e=[];try{if(!b.isArray(a)||b.isEmpty(a))throw new TypeError;for(var f=0;f|Array.<{name: string, values: Array.}>}");throw n}return this.delegateEvents(),this}}),C=i.Column=c.Model.extend({defaults:{name:void 0,label:void 0,sortable:!0,editable:!0,renderable:!0,formatter:void 0,sortType:"cycle",sortValue:void 0,direction:null,cell:void 0,headerCell:void 0},initialize:function(){this.has("label")||this.set({label:this.get("name")},{silent:!0});var a=i.resolveNameToClass(this.get("headerCell"),"HeaderCell"),b=i.resolveNameToClass(this.get("cell"),"Cell");this.set({cell:b,headerCell:a},{silent:!0})},sortValue:function(){var a=this.get("sortValue");return b.isString(a)?this[a]:b.isFunction(a)?a:function(a,b){return a.get(b)}}});b.each(["sortable","renderable","editable"],function(a){C.prototype[a]=function(){var c=this.get(a);return b.isString(c)?this[c]:b.isFunction(c)?c:!!c}});{var D=i.Columns=c.Collection.extend({model:C}),E=i.Row=c.View.extend({tagName:"tr",initialize:function(a){var b=this.columns=a.columns;b instanceof c.Collection||(b=this.columns=new D(b));for(var d=this.cells=[],e=0;e").text(b.get("label")).append(""):document.createTextNode(b.get("label")),this.$el.append(a),this.$el.addClass(b.get("name")),this.$el.addClass(b.get("direction")),this.delegateEvents(),this}}),H=(i.HeaderRow=i.Row.extend({requiredOptions:["columns","collection"],initialize:function(){i.Row.prototype.initialize.apply(this,arguments)},makeCell:function(a,b){var c=a.get("headerCell")||b.headerCell||G;return c=new c({column:a,collection:this.collection})}}),i.Header=c.View.extend({tagName:"thead",initialize:function(a){this.columns=a.columns,this.columns instanceof c.Collection||(this.columns=new D(this.columns)),this.row=new i.HeaderRow({columns:this.columns,collection:this.collection})},render:function(){return this.$el.append(this.row.render().$el),this.delegateEvents(),this},remove:function(){return this.row.remove.apply(this.row,arguments),c.View.prototype.remove.apply(this,arguments)}})),I=i.Body=c.View.extend({tagName:"tbody",initialize:function(a){this.columns=a.columns,this.columns instanceof c.Collection||(this.columns=new D(this.columns)),this.row=a.row||E,this.rows=this.collection.map(function(a){var b=new this.row({columns:this.columns,model:a});return b},this),this.emptyText=a.emptyText,this._unshiftEmptyRowMayBe();var b=this.collection;this.listenTo(b,"add",this.insertRow),this.listenTo(b,"remove",this.removeRow),this.listenTo(b,"sort",this.refresh),this.listenTo(b,"reset",this.refresh),this.listenTo(b,"backgrid:sort",this.sort),this.listenTo(b,"backgrid:edited",this.moveToNextCell)},_unshiftEmptyRowMayBe:function(){0===this.rows.length&&null!=this.emptyText&&this.rows.unshift(new F({emptyText:this.emptyText,columns:this.columns}))},insertRow:function(a,b,d){if(this.rows[0]instanceof F&&this.rows.pop().remove(),!(b instanceof c.Collection||d))return void this.collection.add(a,d=b);var e=new this.row({columns:this.columns,model:a}),f=b.indexOf(a);this.rows.splice(f,0,e);var g=this.$el,h=g.children(),i=e.render().$el;return f>=h.length?g.append(i):h.eq(f).before(i),this},removeRow:function(a,c,d){return d?((b.isUndefined(d.render)||d.render)&&this.rows[d.index].remove(),this.rows.splice(d.index,1),this._unshiftEmptyRowMayBe(),this):(this.collection.remove(a,d=c),void this._unshiftEmptyRowMayBe())},refresh:function(){for(var a=0;ag?-1:1}},moveToNextCell:function(a,b,c){var d,e,f,g,h,j=this.collection.indexOf(a),k=this.columns.indexOf(b);if(this.rows[j].cells[k].exitEditMode(),c.moveUp()||c.moveDown()||c.moveLeft()||c.moveRight()||c.save()){var l=this.columns.length,m=l*this.collection.length;if(c.moveUp()||c.moveDown()){g=j+(c.moveUp()?-1:1);var n=this.rows[g];n?(d=n.cells[k],i.callByNeed(d.column.editable(),d.column,a)&&(d.enterEditMode(),a.trigger("backgrid:next",g,k,!1))):a.trigger("backgrid:next",g,k,!0)}else if(c.moveLeft()||c.moveRight()){for(var o=c.moveRight(),p=j*l+k+(o?1:-1);p>=0&&m>p;o?p++:p--)if(g=~~(p/l),h=p-g*l,d=this.rows[g].cells[h],e=i.callByNeed(d.column.renderable(),d.column,d.model),f=i.callByNeed(d.column.editable(),d.column,a),e&&f){d.enterEditMode(),a.trigger("backgrid:next",g,h,!1);break}p==m&&a.trigger("backgrid:next",~~(p/l),p-g*l,!0)}}return this}});i.Footer=c.View.extend({tagName:"tfoot",initialize:function(a){this.columns=a.columns,this.columns instanceof c.Collection||(this.columns=new i.Columns(this.columns))}}),i.Grid=c.View.extend({tagName:"table",className:"backgrid",header:H,body:I,footer:null,initialize:function(a){a.columns instanceof c.Collection||(a.columns=new D(a.columns)),this.columns=a.columns;var d=b.omit(a,["el","id","attributes","className","tagName","events"]);this.body=a.body||this.body,this.body=new this.body(d),this.header=a.header||this.header,this.header&&(this.header=new this.header(d)),this.footer=a.footer||this.footer,this.footer&&(this.footer=new this.footer(d)),this.listenTo(this.columns,"reset",function(){this.header&&(this.header=new(this.header.remove().constructor)(d)),this.body=new(this.body.remove().constructor)(d),this.footer&&(this.footer=new(this.footer.remove().constructor)(d)),this.render()})},insertRow:function(){return this.body.insertRow.apply(this.body,arguments),this},removeRow:function(){return this.body.removeRow.apply(this.body,arguments),this},insertColumn:function(){return this.columns.add.apply(this.columns,arguments),this},removeColumn:function(){return this.columns.remove.apply(this.columns,arguments),this},sort:function(){return this.body.sort.apply(this.body,arguments),this},render:function(){return this.$el.empty(),this.header&&this.$el.append(this.header.render().$el),this.footer&&this.$el.append(this.footer.render().$el),this.$el.append(this.body.render().$el),this.delegateEvents(),this.trigger("backgrid:rendered",this),this},remove:function(){return this.header&&this.header.remove.apply(this.header,arguments),this.body.remove.apply(this.body,arguments),this.footer&&this.footer.remove.apply(this.footer,arguments),c.View.prototype.remove.apply(this,arguments)}})}return i}); \ No newline at end of file diff --git a/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js new file mode 100644 index 000000000..bc52ae291 --- /dev/null +++ b/web/pgadmin/static/js/backgrid/backgrid.pgadmin.js @@ -0,0 +1,234 @@ +(function(root, factory) { + // Set up Backform appropriately for the environment. Start with AMD. + if (typeof define === 'function' && define.amd) { + define(['underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify'], + function(_, $, Backbone, Backform, Backgrid, Alertify) { + // Export global even in AMD case in case this script is loaded with + // others that may still expect a global Backform. + return factory(root, _, $, Backbone, Backform, Alertify); + }); + + // Next for Node.js or CommonJS. jQuery may not be needed as a module. + } else if (typeof exports !== 'undefined') { + var _ = require('underscore') || root._, + $ = root.jQuery || root.$ || root.Zepto || root.ender, + Backbone = require('backbone') || root.Backbone, + Backform = require('backform') || root.Backform; + Alertify = require('alertify') || root.Alertify; + factory(root, _, $, Backbone, Backform, Alertify); + + // Finally, as a browser global. + } else { + factory(root, root._, (root.jQuery || root.Zepto || root.ender || root.$), root.Backbone, root.Backform); + } +} (this, function(root, _, $, Backbone, Backform, Alertify) { + var ObjectCellEditor = Backgrid.Extension.ObjectCellEditor = Backgrid.CellEditor.extend({ + modalTemplate: _.template([ + '
', + '
', + ' ', + '
' + ].join("\n")), + stringTemplate: _.template([ + '
', + ' ', + '
', + ' ', + '
', + '
' + ].join("\n")), + + extendWithOptions: function(options) { + _.extend(this, options); + }, + + render: function () { + return this; + }, + postRender: function(model, column) { + var editor = this, + el = this.el; + columns_length = this.columns_length; + + if (column != null && column.get("name") != this.column.get("name")) + return false; + + if (!_.isArray(this.schema)) throw new TypeError("schema must be an array"); + + // Create a Backbone model from our object if it does not exist + if (!this.origModel) { + this.origModel = this.model; + this.model = this.origModel.clone(); + } + + var $dialog = this.createDialog(columns_length); + + // Add the Bootstrap form + var $form = $('
'); + $dialog.find('div.subnode-body').append($form); + + // Call Backform to prepare dialog + back_el = $dialog.find('form.form-dialog'); + Backform.tabClassName = "sub-node-form col-sm-12"; + + objectView = new Backform.Dialog({ + el: back_el, model: this.model, schema: this.schema, + }); + + objectView.render(); + + return this; + }, + createDialog: function(noofcol) { + var editor1 = this, + $dialog = this.$dialog = $(this.modalTemplate({title: ""})), + tr = $(""), + td = $("", {class: 'editable sortable renderable', style: 'height: auto', colspan: noofcol+2}).appendTo(tr); + + noofcol = noofcol || 1; + // Handle close and save events + $dialog.find('button.cancel').click(function(e) { + e.preventDefault(); + editor1.cancel(); + tr.remove(); + return false; + }); + $dialog.find('button.save').click(function(e) { + e.preventDefault(); + editor1.save(); + tr.remove(); + return false; + }); + + // Show the Bootstrap modal dialog + td.append($dialog.css('display', 'block')); + this.el.parent('tr').after(tr); + + return $dialog; + }, + save: function(options) { + options || (options = {}); + var model = this.origModel, + column = this.column, + objectModel = this.model, + $form = this.$dialog.find('form'); + + // Retrieve values from the form, and store inside the object model + var changes = {}; + _.each(this.schema, function(field) { + inputType = (field.control == 'datepicker' ? 'input' : field.control); + val = $form.find(inputType + '[name='+field.name+']').first().val() + val = (field.cell == 'integer') ? parseInt(val) : + (field.cell == 'number') ? parseFloat(val) : val + + changes[field.name] = val; + }); + + objectModel.set(changes); + model.set(changes, options); + + model.trigger("backgrid:edited", model, column, new Backgrid.Command({keyCode:13})); + + return this; + }, + cancel: function() { + this.origModel.trigger("backgrid:edited", this.origModel, this.column, new Backgrid.Command({keyCode:27})); + return this; + }, + remove: function() { + this.$dialog.modal("hide").remove(); + Backgrid.CellEditor.prototype.remove.apply(this, arguments); + return this; + } + }); + + var PGSelectCell = Backgrid.Extension.PGSelectCell = Backgrid.SelectCell.extend({ + // It's possible to render an option group or use a + // function to provide option values too. + optionValues: function() { + var res = []; + opts = _.result(this.column.attributes, 'options'); + _.each(opts, function(o) { + res.push([o.label, o.value]); + }); + return res; + } + }); + + var ObjectCell = Backgrid.Extension.ObjectCell = Backgrid.Cell.extend({ + editorOptionDefaults: { + schema: [] + }, + className: "edit-cell", + editor: ObjectCellEditor, + initialize: function(options) { + Backgrid.Cell.prototype.initialize.apply(this, arguments); + + // Pass on cell options to the editor + var cell = this, + editorOptions = {}; + _.each(this.editorOptionDefaults, function(def, opt) { + if (!cell[opt]) cell[opt] = def; + if (options && options[opt]) cell[opt] = options[opt]; + editorOptions[opt] = cell[opt]; + }); + + editorOptions['el'] = $(this.el); + editorOptions['columns_length'] = this.column.collection.length + + this.listenTo(this.model, "backgrid:edit", function (model, column, cell, editor) { + if (column.get("name") == this.column.get("name")) + editor.extendWithOptions(editorOptions); + }); + }, + enterEditMode: function () { + var $content = this.$el.html(); + Backgrid.Cell.prototype.enterEditMode.apply(this, arguments); + var editable = Backgrid.callByNeed(this.column.editable(), this.column, this.model); + if (editable) this.$el.html(""); + }, + render: function(){ + this.$el.empty(); + this.$el.html(""); + this.delegateEvents(); + return this; + } + }); + + var DeleteCell = Backgrid.Extension.DeleteCell = Backgrid.Cell.extend({ + /** @property */ + className: "delete-cell", + events: { + "click": "deleteRow" + }, + deleteRow: function (e) { + e.preventDefault(); + that = this; + Alertify.confirm( + 'Delete Row', + 'Are You Sure, you want to delete this object?', + function(evt) { + that.model.collection.remove(that.model); + }, + function(evt) { + return true; + } + ); + }, + initialize: function () { + Backgrid.Cell.prototype.initialize.apply(this, arguments); + }, + render: function () { + this.$el.empty(); + this.$el.html(""); + this.delegateEvents(); + return this; + } + }); + + return Backgrid; + +})); diff --git a/web/pgadmin/static/js/bootstrap-datepicker.js b/web/pgadmin/static/js/bootstrap-datepicker.js index 1a183e239..11fedaf08 100644 --- a/web/pgadmin/static/js/bootstrap-datepicker.js +++ b/web/pgadmin/static/js/bootstrap-datepicker.js @@ -1,10 +1,18 @@ /*! - * Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker) + * Datepicker for Bootstrap v1.5.0 (https://github.com/eternicode/bootstrap-datepicker) * * Copyright 2012 Stefan Petre * Improvements by Andrew Rowls * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) - */(function($, undefined){ + */(function(factory){ + if (typeof define === "function" && define.amd) { + define(["jquery"], factory); + } else if (typeof exports === 'object') { + factory(require('jquery')); + } else { + factory(jQuery); + } +}(function($, undefined){ function UTCDate(){ return new Date(Date.UTC.apply(Date, arguments)); @@ -25,6 +33,9 @@ return this[method].apply(this, arguments); }; } + function isValidDate(d) { + return d && !isNaN(d.getTime()); + } var DateArray = (function(){ var extras = { @@ -115,6 +126,7 @@ this.setStartDate(this._o.startDate); this.setEndDate(this._o.endDate); this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); + this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted); this.setDatesDisabled(this.o.datesDisabled); this.fillDow(); @@ -175,6 +187,20 @@ o.minViewMode = 0; } + switch (o.maxViewMode) { + case 0: + case 'days': + o.maxViewMode = 0; + break; + case 1: + case 'months': + o.maxViewMode = 1; + break; + default: + o.maxViewMode = 2; + } + + o.startView = Math.min(o.startView, o.maxViewMode); o.startView = Math.max(o.startView, o.minViewMode); // true, false, or Number > 0 @@ -219,6 +245,13 @@ return parseInt(d, 10); }); + o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[]; + if (!$.isArray(o.daysOfWeekHighlighted)) + o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/); + o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){ + return parseInt(d, 10); + }); + o.datesDisabled = o.datesDisabled||[]; if (!$.isArray(o.datesDisabled)) { var datesDisabled = []; @@ -269,6 +302,7 @@ o.defaultViewDate = UTCToday(); } o.showOnFocus = o.showOnFocus !== undefined ? o.showOnFocus : true; + o.zIndexOffset = o.zIndexOffset !== undefined ? o.zIndexOffset : 10; }, _events: [], _secondaryEvents: [], @@ -376,9 +410,10 @@ this.element.is(e.target) || this.element.find(e.target).length || this.picker.is(e.target) || - this.picker.find(e.target).length + this.picker.find(e.target).length || + this.picker.hasClass('datepicker-inline') )){ - $(this.picker).hide(); + this.hide(); } }, this) }] @@ -534,7 +569,7 @@ } if (element) { - element.val('').change(); + element.val(''); } this.update(); @@ -567,11 +602,11 @@ var formatted = this.getFormattedDate(); if (!this.isInput){ if (this.component){ - this.element.find('input').val(formatted).change(); + this.element.find('input').val(formatted); } } else { - this.element.val(formatted).change(); + this.element.val(formatted); } return this; }, @@ -607,6 +642,12 @@ return this; }, + setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){ + this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted}); + this.update(); + return this; + }, + setDatesDisabled: function(datesDisabled){ this._process_options({datesDisabled: datesDisabled}); this.update(); @@ -619,17 +660,17 @@ var calendarWidth = this.picker.outerWidth(), calendarHeight = this.picker.outerHeight(), visualPadding = 10, - windowWidth = $(this.o.container).width(), - windowHeight = $(this.o.container).height(), - scrollTop = $(this.o.container).scrollTop(), - appendOffset = $(this.o.container).offset(); + container = $(this.o.container), + windowWidth = container.width(), + scrollTop = container.scrollTop(), + appendOffset = container.offset(); var parentsZindex = []; this.element.parents().each(function(){ var itemZIndex = $(this).css('z-index'); if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex)); }); - var zIndex = Math.max.apply(Math, parentsZindex) + 10; + var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset; var offset = this.component ? this.component.parent().offset() : this.element.offset(); var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); @@ -666,20 +707,17 @@ // auto y orientation is best-situation: top or bottom, no fudging, // decision based on which shows more of the calendar var yorient = this.o.orientation.y, - top_overflow, bottom_overflow; + top_overflow; if (yorient === 'auto'){ top_overflow = -scrollTop + top - calendarHeight; - bottom_overflow = scrollTop + windowHeight - (top + height + calendarHeight); - if (Math.max(top_overflow, bottom_overflow) === bottom_overflow) - yorient = 'top'; - else - yorient = 'bottom'; + yorient = top_overflow < 0 ? 'bottom' : 'top'; } + this.picker.addClass('datepicker-orient-' + yorient); if (yorient === 'top') - top += height; - else top -= calendarHeight + parseInt(this.picker.css('padding-top')); + else + top += height; if (this.o.rtl) { var right = windowWidth - (left + width); @@ -743,6 +781,8 @@ this.viewDate = new Date(this.o.startDate); else if (this.viewDate > this.o.endDate) this.viewDate = new Date(this.o.endDate); + else + this.viewDate = this.o.defaultViewDate; if (fromArgs){ // setting date by clicking @@ -757,6 +797,7 @@ this._trigger('clearDate'); this.fill(); + this.element.change(); return this; }, @@ -764,12 +805,11 @@ var dowCnt = this.o.weekStart, html = ''; if (this.o.calendarWeeks){ - this.picker.find('.datepicker-days thead tr:first-child .datepicker-switch') + this.picker.find('.datepicker-days .datepicker-switch') .attr('colspan', function(i, val){ return parseInt(val) + 1; }); - var cell = ' '; - html += cell; + html += ' '; } while (dowCnt < this.o.weekStart + 7){ html += ''+dates[this.o.language].daysMin[(dowCnt++)%7]+''; @@ -823,6 +863,9 @@ $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){ cls.push('disabled'); } + if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){ + cls.push('highlighted'); + } if (this.o.datesDisabled.length > 0 && $.grep(this.o.datesDisabled, function(d){ return isUTCEquals(date, d); }).length > 0) { @@ -836,6 +879,12 @@ if ($.inArray(date.valueOf(), this.range) !== -1){ cls.push('selected'); } + if (date.valueOf() === this.range[0]){ + cls.push('range-start'); + } + if (date.valueOf() === this.range[this.range.length-1]){ + cls.push('range-end'); + } } return cls; }, @@ -850,17 +899,21 @@ endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, todaytxt = dates[this.o.language].today || dates['en'].today || '', cleartxt = dates[this.o.language].clear || dates['en'].clear || '', + titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat, tooltip; if (isNaN(year) || isNaN(month)) return; this.picker.find('.datepicker-days thead .datepicker-switch') - .text(dates[this.o.language].months[month]+' '+year); + .text(DPGlobal.formatDate(new UTCDate(year, month), titleFormat, this.o.language)); this.picker.find('tfoot .today') .text(todaytxt) .toggle(this.o.todayBtn !== false); this.picker.find('tfoot .clear') .text(cleartxt) .toggle(this.o.clearBtn !== false); + this.picker.find('thead .datepicker-title') + .text(this.o.title) + .toggle(this.o.title !== ''); this.updateNavArrows(); this.fillMonths(); var prevMonth = UTCDate(year, month-1, 28), @@ -868,6 +921,9 @@ prevMonth.setUTCDate(day); prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7); var nextMonth = new Date(prevMonth); + if (prevMonth.getUTCFullYear() < 100){ + nextMonth.setUTCFullYear(prevMonth.getUTCFullYear()); + } nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); nextMonth = nextMonth.valueOf(); var html = []; @@ -921,8 +977,8 @@ this.picker.find('.datepicker-days tbody').empty().append(html.join('')); var months = this.picker.find('.datepicker-months') - .find('th:eq(1)') - .text(year) + .find('.datepicker-switch') + .text(this.o.maxViewMode < 2 ? 'Months' : year) .end() .find('span').removeClass('active'); @@ -956,7 +1012,7 @@ html = ''; year = parseInt(year/10, 10) * 10; var yearCont = this.picker.find('.datepicker-years') - .find('th:eq(1)') + .find('.datepicker-switch') .text(year + '-' + (year + 9)) .end() .find('td'); @@ -967,6 +1023,8 @@ classes; for (var i = -1; i < 11; i++){ classes = ['year']; + tooltip = null; + if (i === -1) classes.push('old'); else if (i === 10) @@ -975,7 +1033,24 @@ classes.push('active'); if (year < startYear || year > endYear) classes.push('disabled'); - html += '' + year + ''; + + if (this.o.beforeShowYear !== $.noop) { + var yrBefore = this.o.beforeShowYear(new Date(year, 0, 1)); + if (yrBefore === undefined) + yrBefore = {}; + else if (typeof(yrBefore) === 'boolean') + yrBefore = {enabled: yrBefore}; + else if (typeof(yrBefore) === 'string') + yrBefore = {classes: yrBefore}; + if (yrBefore.enabled === false) + classes.push('disabled'); + if (yrBefore.classes) + classes = classes.concat(yrBefore.classes.split(/\s+/)); + if (yrBefore.tooltip) + tooltip = yrBefore.tooltip; + } + + html += '' + year + ''; year += 1; } yearCont.html(html); @@ -1005,13 +1080,13 @@ break; case 1: case 2: - if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){ + if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){ this.picker.find('.prev').css({visibility: 'hidden'}); } else { this.picker.find('.prev').css({visibility: 'visible'}); } - if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){ + if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){ this.picker.find('.next').css({visibility: 'hidden'}); } else { @@ -1023,6 +1098,7 @@ click: function(e){ e.preventDefault(); + e.stopPropagation(); var target = $(e.target).closest('span, td, th'), year, month, day; if (target.length === 1){ @@ -1176,8 +1252,8 @@ }, moveMonth: function(date, dir){ - if (!date) - return undefined; + if (!isValidDate(date)) + return this.o.defaultViewDate; if (!dir) return date; var new_date = new Date(date.valueOf()), @@ -1235,8 +1311,10 @@ keydown: function(e){ if (!this.picker.is(':visible')){ - if (e.keyCode === 40 || e.keyCode === 27) // allow down to re-show picker + if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker this.show(); + e.stopPropagation(); + } return; } var dateChanged = false, @@ -1252,6 +1330,7 @@ else this.hide(); e.preventDefault(); + e.stopPropagation(); break; case 37: // left case 39: // right @@ -1314,6 +1393,9 @@ // As such, its behavior should not be hijacked. break; case 13: // enter + if (!this.o.forceParse) { + break; + } focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; if (this.o.keyboardNavigation) { this._toggle_multidate(focusDate); @@ -1361,13 +1443,13 @@ showMode: function(dir){ if (dir){ - this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir)); + this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir)); } this.picker .children('div') .hide() .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName) - .css('display', 'block'); + .show(); this.updateNavArrows(); } }; @@ -1410,8 +1492,13 @@ return; this.updating = true; - var dp = $(e.target).data('datepicker'), - new_date = dp.getUTCDate(), + var dp = $(e.target).data('datepicker'); + + if (typeof(dp) === "undefined") { + return; + } + + var new_date = dp.getUTCDate(), i = $.inArray(e.target, this.inputs), j = i - 1, k = i + 1, @@ -1509,14 +1596,20 @@ } if (typeof option === 'string' && typeof data[option] === 'function'){ internal_return = data[option].apply(data, args); - if (internal_return !== undefined) - return false; } }); - if (internal_return !== undefined) - return internal_return; - else + + if ( + internal_return === undefined || + internal_return instanceof Datepicker || + internal_return instanceof DateRangePicker + ) return this; + + if (this.length > 1) + throw new Error('Using only allowed for the collection of a single element (' + option + ' function)'); + else + return internal_return; }; $.fn.datepicker = datepickerPlugin; @@ -1524,10 +1617,12 @@ autoclose: false, beforeShowDay: $.noop, beforeShowMonth: $.noop, + beforeShowYear: $.noop, calendarWeeks: false, clearBtn: false, toggleActive: false, daysOfWeekDisabled: [], + daysOfWeekHighlighted: [], datesDisabled: [], endDate: Infinity, forceParse: true, @@ -1535,6 +1630,7 @@ keyboardNavigation: true, language: 'en', minViewMode: 0, + maxViewMode: 2, multidate: false, multidateSeparator: ',', orientation: "auto", @@ -1547,7 +1643,8 @@ disableTouchKeyboard: false, enableOnReadonly: true, container: 'body', - immediateUpdates: false + immediateUpdates: false, + title: '' }; var locale_opts = $.fn.datepicker.locale_opts = [ 'format', @@ -1563,7 +1660,8 @@ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], today: "Today", - clear: "Clear" + clear: "Clear", + titleFormat: "MM yyyy" } }; @@ -1593,7 +1691,9 @@ validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g, nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g, parseFormat: function(format){ - // IE treats \0 as a string end in inputs (truncating the value), + if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function') + return format; + // IE treats \0 as a string end in inputs (truncating the value), // so it's a bad format delimiter, anyway var separators = format.replace(this.validParts, '\0').split('\0'), parts = format.match(this.validParts); @@ -1609,7 +1709,9 @@ return date; if (typeof format === 'string') format = DPGlobal.parseFormat(format); - var part_re = /([\-+]\d+)([dmwy])/, + if (format.toValue) + return format.toValue(date, format, language); + var part_re = /([\-+]\d+)([dmwy])/, parts = date.match(/([\-+]\d+)([dmwy])/g), part, dir, i; if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){ @@ -1714,7 +1816,9 @@ return ''; if (typeof format === 'string') format = DPGlobal.parseFormat(format); - var val = { + if (format.toDisplay) + return format.toDisplay(date, format, language); + var val = { d: date.getUTCDate(), D: dates[language].daysShort[date.getUTCDay()], DD: dates[language].days[date.getUTCDay()], @@ -1736,6 +1840,9 @@ return date.join(''); }, headTemplate: ''+ + ''+ + ''+ + ''+ ''+ '«'+ ''+ @@ -1789,7 +1896,7 @@ /* DATEPICKER VERSION * =================== */ - $.fn.datepicker.version = "1.4.1-dev"; + $.fn.datepicker.version = '1.5.0'; /* DATEPICKER DATA-API * ================== */ @@ -1810,4 +1917,4 @@ datepickerPlugin.call($('[data-provide="datepicker-inline"]')); }); -}(window.jQuery)); +})); diff --git a/web/pgadmin/static/js/bootstrap-datepicker.min.js b/web/pgadmin/static/js/bootstrap-datepicker.min.js index ca550b183..52af7b434 100644 --- a/web/pgadmin/static/js/bootstrap-datepicker.min.js +++ b/web/pgadmin/static/js/bootstrap-datepicker.min.js @@ -1,8 +1,8 @@ /*! - * Datepicker for Bootstrap v1.5.0-dev (https://github.com/eternicode/bootstrap-datepicker) + * Datepicker for Bootstrap v1.5.0 (https://github.com/eternicode/bootstrap-datepicker) * * Copyright 2012 Stefan Petre * Improvements by Andrew Rowls * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) */ -!function(a,b){function c(){return new Date(Date.UTC.apply(Date,arguments))}function d(){var a=new Date;return c(a.getFullYear(),a.getMonth(),a.getDate())}function e(a,b){return a.getUTCFullYear()===b.getUTCFullYear()&&a.getUTCMonth()===b.getUTCMonth()&&a.getUTCDate()===b.getUTCDate()}function f(a){return function(){return this[a].apply(this,arguments)}}function g(b,c){function d(a,b){return b.toLowerCase()}var e,f=a(b).data(),g={},h=new RegExp("^"+c.toLowerCase()+"([A-Z])");c=new RegExp("^"+c.toLowerCase());for(var i in f)c.test(i)&&(e=i.replace(h,d),g[e]=f[i]);return g}function h(b){var c={};if(p[b]||(b=b.split("-")[0],p[b])){var d=p[b];return a.each(o,function(a,b){b in d&&(c[b]=d[b])}),c}}var i=function(){var b={get:function(a){return this.slice(a)[0]},contains:function(a){for(var b=a&&a.valueOf(),c=0,d=this.length;d>c;c++)if(this[c].valueOf()===b)return c;return-1},remove:function(a){this.splice(a,1)},replace:function(b){b&&(a.isArray(b)||(b=[b]),this.clear(),this.push.apply(this,b))},clear:function(){this.length=0},copy:function(){var a=new i;return a.replace(this),a}};return function(){var c=[];return c.push.apply(c,arguments),a.extend(c,b),c}}(),j=function(b,c){this._process_options(c),this.dates=new i,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=a(b),this.isInline=!1,this.isInput=this.element.is("input"),this.component=this.element.hasClass("date")?this.element.find(".add-on, .input-group-addon, .btn"):!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&0===this.component.length&&(this.component=!1),this.picker=a(q.template),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.viewMode=this.o.startView,this.o.calendarWeeks&&this.picker.find("tfoot .today, tfoot .clear").attr("colspan",function(a,b){return parseInt(b)+1}),this._allow_update=!1,this.setStartDate(this._o.startDate),this.setEndDate(this._o.endDate),this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled),this.setDatesDisabled(this.o.datesDisabled),this.fillDow(),this.fillMonths(),this._allow_update=!0,this.update(),this.showMode(),this.isInline&&this.show()};j.prototype={constructor:j,_process_options:function(e){this._o=a.extend({},this._o,e);var f=this.o=a.extend({},this._o),g=f.language;switch(p[g]||(g=g.split("-")[0],p[g]||(g=n.language)),f.language=g,f.startView){case 2:case"decade":f.startView=2;break;case 1:case"year":f.startView=1;break;default:f.startView=0}switch(f.minViewMode){case 1:case"months":f.minViewMode=1;break;case 2:case"years":f.minViewMode=2;break;default:f.minViewMode=0}f.startView=Math.max(f.startView,f.minViewMode),f.multidate!==!0&&(f.multidate=Number(f.multidate)||!1,f.multidate!==!1&&(f.multidate=Math.max(0,f.multidate))),f.multidateSeparator=String(f.multidateSeparator),f.weekStart%=7,f.weekEnd=(f.weekStart+6)%7;var h=q.parseFormat(f.format);if(f.startDate!==-1/0&&(f.startDate=f.startDate?f.startDate instanceof Date?this._local_to_utc(this._zero_time(f.startDate)):q.parseDate(f.startDate,h,f.language):-1/0),1/0!==f.endDate&&(f.endDate=f.endDate?f.endDate instanceof Date?this._local_to_utc(this._zero_time(f.endDate)):q.parseDate(f.endDate,h,f.language):1/0),f.daysOfWeekDisabled=f.daysOfWeekDisabled||[],a.isArray(f.daysOfWeekDisabled)||(f.daysOfWeekDisabled=f.daysOfWeekDisabled.split(/[,\s]*/)),f.daysOfWeekDisabled=a.map(f.daysOfWeekDisabled,function(a){return parseInt(a,10)}),f.datesDisabled=f.datesDisabled||[],!a.isArray(f.datesDisabled)){var i=[];i.push(q.parseDate(f.datesDisabled,h,f.language)),f.datesDisabled=i}f.datesDisabled=a.map(f.datesDisabled,function(a){return q.parseDate(a,h,f.language)});var j=String(f.orientation).toLowerCase().split(/\s+/g),k=f.orientation.toLowerCase();if(j=a.grep(j,function(a){return/^auto|left|right|top|bottom$/.test(a)}),f.orientation={x:"auto",y:"auto"},k&&"auto"!==k)if(1===j.length)switch(j[0]){case"top":case"bottom":f.orientation.y=j[0];break;case"left":case"right":f.orientation.x=j[0]}else k=a.grep(j,function(a){return/^left|right$/.test(a)}),f.orientation.x=k[0]||"auto",k=a.grep(j,function(a){return/^top|bottom$/.test(a)}),f.orientation.y=k[0]||"auto";else;if(f.defaultViewDate){var l=f.defaultViewDate.year||(new Date).getFullYear(),m=f.defaultViewDate.month||0,o=f.defaultViewDate.day||1;f.defaultViewDate=c(l,m,o)}else f.defaultViewDate=d();f.showOnFocus=f.showOnFocus!==b?f.showOnFocus:!0},_events:[],_secondaryEvents:[],_applyEvents:function(a){for(var c,d,e,f=0;fe?(this.picker.addClass("datepicker-orient-right"),n=k.left+m-b):this.picker.addClass("datepicker-orient-left");var p,q,r=this.o.orientation.y;if("auto"===r&&(p=-g+o-c,q=g+f-(o+l+c),r=Math.max(p,q)===q?"top":"bottom"),this.picker.addClass("datepicker-orient-"+r),"top"===r?o+=l:o-=c+parseInt(this.picker.css("padding-top")),this.o.rtl){var s=e-(n+m);this.picker.css({top:o,right:s,zIndex:j})}else this.picker.css({top:o,left:n,zIndex:j});return this},_allow_update:!0,update:function(){if(!this._allow_update)return this;var b=this.dates.copy(),c=[],d=!1;return arguments.length?(a.each(arguments,a.proxy(function(a,b){b instanceof Date&&(b=this._local_to_utc(b)),c.push(b)},this)),d=!0):(c=this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val(),c=c&&this.o.multidate?c.split(this.o.multidateSeparator):[c],delete this.element.data().date),c=a.map(c,a.proxy(function(a){return q.parseDate(a,this.o.format,this.o.language)},this)),c=a.grep(c,a.proxy(function(a){return athis.o.endDate||!a},this),!0),this.dates.replace(c),this.dates.length?this.viewDate=new Date(this.dates.get(-1)):this.viewDatethis.o.endDate&&(this.viewDate=new Date(this.o.endDate)),d?this.setValue():c.length&&String(b)!==String(this.dates)&&this._trigger("changeDate"),!this.dates.length&&b.length&&this._trigger("clearDate"),this.fill(),this},fillDow:function(){var a=this.o.weekStart,b="";if(this.o.calendarWeeks){this.picker.find(".datepicker-days thead tr:first-child .datepicker-switch").attr("colspan",function(a,b){return parseInt(b)+1});var c=' ';b+=c}for(;a'+p[this.o.language].daysMin[a++%7]+"";b+="",this.picker.find(".datepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;12>b;)a+=''+p[this.o.language].monthsShort[b++]+"";this.picker.find(".datepicker-months td").html(a)},setRange:function(b){b&&b.length?this.range=a.map(b,function(a){return a.valueOf()}):delete this.range,this.fill()},getClassNames:function(b){var c=[],d=this.viewDate.getUTCFullYear(),f=this.viewDate.getUTCMonth(),g=new Date;return b.getUTCFullYear()d||b.getUTCFullYear()===d&&b.getUTCMonth()>f)&&c.push("new"),this.focusDate&&b.valueOf()===this.focusDate.valueOf()&&c.push("focused"),this.o.todayHighlight&&b.getUTCFullYear()===g.getFullYear()&&b.getUTCMonth()===g.getMonth()&&b.getUTCDate()===g.getDate()&&c.push("today"),-1!==this.dates.contains(b)&&c.push("active"),(b.valueOf()this.o.endDate||-1!==a.inArray(b.getUTCDay(),this.o.daysOfWeekDisabled))&&c.push("disabled"),this.o.datesDisabled.length>0&&a.grep(this.o.datesDisabled,function(a){return e(b,a)}).length>0&&c.push("disabled","disabled-date"),this.range&&(b>this.range[0]&&b"),this.o.calendarWeeks)){var u=new Date(+n+(this.o.weekStart-n.getUTCDay()-7)%7*864e5),v=new Date(Number(u)+(11-u.getUTCDay())%7*864e5),w=new Date(Number(w=c(v.getUTCFullYear(),0,1))+(11-w.getUTCDay())%7*864e5),x=(v-w)/864e5/7+1;t.push(''+x+"")}if(s=this.getClassNames(n),s.push("day"),this.o.beforeShowDay!==a.noop){var y=this.o.beforeShowDay(this._utc_to_local(n));y===b?y={}:"boolean"==typeof y?y={enabled:y}:"string"==typeof y&&(y={classes:y}),y.enabled===!1&&s.push("disabled"),y.classes&&(s=s.concat(y.classes.split(/\s+/))),y.tooltip&&(d=y.tooltip)}s=a.unique(s),t.push('"+n.getUTCDate()+""),d=null,n.getUTCDay()===this.o.weekEnd&&t.push(""),n.setUTCDate(n.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(t.join(""));var z=this.picker.find(".datepicker-months").find("th:eq(1)").text(f).end().find("span").removeClass("active");if(a.each(this.dates,function(a,b){b.getUTCFullYear()===f&&z.eq(b.getUTCMonth()).addClass("active")}),(h>f||f>j)&&z.addClass("disabled"),f===h&&z.slice(0,i).addClass("disabled"),f===j&&z.slice(k+1).addClass("disabled"),this.o.beforeShowMonth!==a.noop){var A=this;a.each(z,function(b,c){if(!a(c).hasClass("disabled")){var d=new Date(f,b,1),e=A.o.beforeShowMonth(d);e===!1&&a(c).addClass("disabled")}})}t="",f=10*parseInt(f/10,10);var B=this.picker.find(".datepicker-years").find("th:eq(1)").text(f+"-"+(f+9)).end().find("td");f-=1;for(var C,D=a.map(this.dates,function(a){return a.getUTCFullYear()}),E=-1;11>E;E++)C=["year"],-1===E?C.push("old"):10===E&&C.push("new"),-1!==a.inArray(f,D)&&C.push("active"),(h>f||f>j)&&C.push("disabled"),t+=''+f+"",f+=1;B.html(t)}},updateNavArrows:function(){if(this._allow_update){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth();switch(this.viewMode){case 0:this.picker.find(".prev").css(this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()&&c<=this.o.startDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()&&c>=this.o.endDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"});break;case 1:case 2:this.picker.find(".prev").css(this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"})}}},click:function(b){b.preventDefault();var d,e,f,g=a(b.target).closest("span, td, th");if(1===g.length)switch(g[0].nodeName.toLowerCase()){case"th":switch(g[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var h=q.modes[this.viewMode].navStep*("prev"===g[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,h),this._trigger("changeMonth",this.viewDate);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,h),1===this.viewMode&&this._trigger("changeYear",this.viewDate)}this.fill();break;case"today":var i=new Date;i=c(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0),this.showMode(-2);var j="linked"===this.o.todayBtn?null:"view";this._setDate(i,j);break;case"clear":this.clearDates()}break;case"span":g.hasClass("disabled")||(this.viewDate.setUTCDate(1),g.hasClass("month")?(f=1,e=g.parent().find("span").index(g),d=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(e),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode?(this._setDate(c(d,e,f)),this.showMode()):this.showMode(-1)):(f=1,e=0,d=parseInt(g.text(),10)||0,this.viewDate.setUTCFullYear(d),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(c(d,e,f)),this.showMode(-1)),this.fill());break;case"td":g.hasClass("day")&&!g.hasClass("disabled")&&(f=parseInt(g.text(),10)||1,d=this.viewDate.getUTCFullYear(),e=this.viewDate.getUTCMonth(),g.hasClass("old")?0===e?(e=11,d-=1):e-=1:g.hasClass("new")&&(11===e?(e=0,d+=1):e+=1),this._setDate(c(d,e,f)))}this.picker.is(":visible")&&this._focused_from&&a(this._focused_from).focus(),delete this._focused_from},_toggle_multidate:function(a){var b=this.dates.contains(a);if(a||this.dates.clear(),-1!==b?(this.o.multidate===!0||this.o.multidate>1||this.o.toggleActive)&&this.dates.remove(b):this.o.multidate===!1?(this.dates.clear(),this.dates.push(a)):this.dates.push(a),"number"==typeof this.o.multidate)for(;this.dates.length>this.o.multidate;)this.dates.remove(0)},_setDate:function(a,b){b&&"date"!==b||this._toggle_multidate(a&&new Date(a)),b&&"view"!==b||(this.viewDate=a&&new Date(a)),this.fill(),this.setValue(),b&&"view"===b||this._trigger("changeDate");var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&c.change(),!this.o.autoclose||b&&"date"!==b||this.hide()},moveMonth:function(a,c){if(!a)return b;if(!c)return a;var d,e,f=new Date(a.valueOf()),g=f.getUTCDate(),h=f.getUTCMonth(),i=Math.abs(c);if(c=c>0?1:-1,1===i)e=-1===c?function(){return f.getUTCMonth()===h}:function(){return f.getUTCMonth()!==d},d=h+c,f.setUTCMonth(d),(0>d||d>11)&&(d=(d+12)%12);else{for(var j=0;i>j;j++)f=this.moveMonth(f,c);d=f.getUTCMonth(),f.setUTCDate(g),e=function(){return d!==f.getUTCMonth()}}for(;e();)f.setUTCDate(--g),f.setUTCMonth(d);return f},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.o.startDate&&a<=this.o.endDate},keydown:function(a){if(!this.picker.is(":visible"))return void((40===a.keyCode||27===a.keyCode)&&this.show());var b,c,e,f=!1,g=this.focusDate||this.viewDate;switch(a.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),a.preventDefault();break;case 37:case 39:if(!this.o.keyboardNavigation)break;b=37===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+b),e=new Date(g),e.setUTCDate(g.getUTCDate()+b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 38:case 40:if(!this.o.keyboardNavigation)break;b=38===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+7*b),e=new Date(g),e.setUTCDate(g.getUTCDate()+7*b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 32:break;case 13:g=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(g),f=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(a.preventDefault(),"function"==typeof a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}if(f){this._trigger(this.dates.length?"changeDate":"clearDate");var h;this.isInput?h=this.element:this.component&&(h=this.element.find("input")),h&&h.change()}},showMode:function(a){a&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(2,this.viewMode+a))),this.picker.children("div").hide().filter(".datepicker-"+q.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}};var k=function(b,c){this.element=a(b),this.inputs=a.map(c.inputs,function(a){return a.jquery?a[0]:a}),delete c.inputs,m.call(a(this.inputs),c).on("changeDate",a.proxy(this.dateUpdated,this)),this.pickers=a.map(this.inputs,function(b){return a(b).data("datepicker")}),this.updateDates()};k.prototype={updateDates:function(){this.dates=a.map(this.pickers,function(a){return a.getUTCDate()}),this.updateRanges()},updateRanges:function(){var b=a.map(this.dates,function(a){return a.valueOf()});a.each(this.pickers,function(a,c){c.setRange(b)})},dateUpdated:function(b){if(!this.updating){this.updating=!0;var c=a(b.target).data("datepicker"),d=c.getUTCDate(),e=a.inArray(b.target,this.inputs),f=e-1,g=e+1,h=this.inputs.length;if(-1!==e){if(a.each(this.pickers,function(a,b){b.getUTCDate()||b.setUTCDate(d)}),d=0&&dthis.dates[g])for(;h>g&&d>this.dates[g];)this.pickers[g++].setUTCDate(d);this.updateDates(),delete this.updating}}},remove:function(){a.map(this.pickers,function(a){a.remove()}),delete this.element.data().datepicker}};var l=a.fn.datepicker,m=function(c){var d=Array.apply(null,arguments);d.shift();var e;return this.each(function(){var f=a(this),i=f.data("datepicker"),l="object"==typeof c&&c;if(!i){var m=g(this,"date"),o=a.extend({},n,m,l),p=h(o.language),q=a.extend({},n,p,m,l);if(f.hasClass("input-daterange")||q.inputs){var r={inputs:q.inputs||f.find("input").toArray()};f.data("datepicker",i=new k(this,a.extend(q,r)))}else f.data("datepicker",i=new j(this,q))}return"string"==typeof c&&"function"==typeof i[c]&&(e=i[c].apply(i,d),e!==b)?!1:void 0}),e!==b?e:this};a.fn.datepicker=m;var n=a.fn.datepicker.defaults={autoclose:!1,beforeShowDay:a.noop,beforeShowMonth:a.noop,calendarWeeks:!1,clearBtn:!1,toggleActive:!1,daysOfWeekDisabled:[],datesDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,multidate:!1,multidateSeparator:",",orientation:"auto",rtl:!1,startDate:-1/0,startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0,disableTouchKeyboard:!1,enableOnReadonly:!0,container:"body",immediateUpdates:!1},o=a.fn.datepicker.locale_opts=["format","rtl","weekStart"];a.fn.datepicker.Constructor=j;var p=a.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear"}},q={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return a%4===0&&a%100!==0||a%400===0},getDaysInMonth:function(a,b){return[31,q.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(a){var b=a.replace(this.validParts,"\x00").split("\x00"),c=a.match(this.validParts);if(!b||!b.length||!c||0===c.length)throw new Error("Invalid date format.");return{separators:b,parts:c}},parseDate:function(d,e,f){function g(){var a=this.slice(0,m[k].length),b=m[k].slice(0,a.length);return a.toLowerCase()===b.toLowerCase()}if(!d)return b;if(d instanceof Date)return d;"string"==typeof e&&(e=q.parseFormat(e));var h,i,k,l=/([\-+]\d+)([dmwy])/,m=d.match(/([\-+]\d+)([dmwy])/g);if(/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(d)){for(d=new Date,k=0;kb;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!==b;)a.setUTCDate(a.getUTCDate()-1);return a},d:function(a,b){return a.setUTCDate(b)}};t.M=t.MM=t.mm=t.m,t.dd=t.d,d=c(d.getFullYear(),d.getMonth(),d.getDate(),0,0,0);var u=e.parts.slice();if(m.length!==u.length&&(u=a(u).filter(function(b,c){return-1!==a.inArray(c,s)}).toArray()),m.length===u.length){var v;for(k=0,v=u.length;v>k;k++){if(n=parseInt(m[k],10),h=u[k],isNaN(n))switch(h){case"MM":o=a(p[f].months).filter(g),n=a.inArray(o[0],p[f].months)+1;break;case"M":o=a(p[f].monthsShort).filter(g),n=a.inArray(o[0],p[f].monthsShort)+1}r[h]=n}var w,x;for(k=0;k=g;g++)f.length&&b.push(f.shift()),b.push(e[c.parts[g]]);return b.join("")},headTemplate:'«»',contTemplate:'',footTemplate:''};q.template='
'+q.headTemplate+""+q.footTemplate+'
'+q.headTemplate+q.contTemplate+q.footTemplate+'
'+q.headTemplate+q.contTemplate+q.footTemplate+"
",a.fn.datepicker.DPGlobal=q,a.fn.datepicker.noConflict=function(){return a.fn.datepicker=l,this},a.fn.datepicker.version="1.4.1-dev",a(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(b){var c=a(this);c.data("datepicker")||(b.preventDefault(),m.call(c,"show"))}),a(function(){m.call(a('[data-provide="datepicker-inline"]'))})}(window.jQuery); \ No newline at end of file +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a,b){function c(){return new Date(Date.UTC.apply(Date,arguments))}function d(){var a=new Date;return c(a.getFullYear(),a.getMonth(),a.getDate())}function e(a,b){return a.getUTCFullYear()===b.getUTCFullYear()&&a.getUTCMonth()===b.getUTCMonth()&&a.getUTCDate()===b.getUTCDate()}function f(a){return function(){return this[a].apply(this,arguments)}}function g(a){return a&&!isNaN(a.getTime())}function h(b,c){function d(a,b){return b.toLowerCase()}var e,f=a(b).data(),g={},h=new RegExp("^"+c.toLowerCase()+"([A-Z])");c=new RegExp("^"+c.toLowerCase());for(var i in f)c.test(i)&&(e=i.replace(h,d),g[e]=f[i]);return g}function i(b){var c={};if(q[b]||(b=b.split("-")[0],q[b])){var d=q[b];return a.each(p,function(a,b){b in d&&(c[b]=d[b])}),c}}var j=function(){var b={get:function(a){return this.slice(a)[0]},contains:function(a){for(var b=a&&a.valueOf(),c=0,d=this.length;d>c;c++)if(this[c].valueOf()===b)return c;return-1},remove:function(a){this.splice(a,1)},replace:function(b){b&&(a.isArray(b)||(b=[b]),this.clear(),this.push.apply(this,b))},clear:function(){this.length=0},copy:function(){var a=new j;return a.replace(this),a}};return function(){var c=[];return c.push.apply(c,arguments),a.extend(c,b),c}}(),k=function(b,c){this._process_options(c),this.dates=new j,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=a(b),this.isInline=!1,this.isInput=this.element.is("input"),this.component=this.element.hasClass("date")?this.element.find(".add-on, .input-group-addon, .btn"):!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&0===this.component.length&&(this.component=!1),this.picker=a(r.template),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.viewMode=this.o.startView,this.o.calendarWeeks&&this.picker.find("tfoot .today, tfoot .clear").attr("colspan",function(a,b){return parseInt(b)+1}),this._allow_update=!1,this.setStartDate(this._o.startDate),this.setEndDate(this._o.endDate),this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled),this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted),this.setDatesDisabled(this.o.datesDisabled),this.fillDow(),this.fillMonths(),this._allow_update=!0,this.update(),this.showMode(),this.isInline&&this.show()};k.prototype={constructor:k,_process_options:function(e){this._o=a.extend({},this._o,e);var f=this.o=a.extend({},this._o),g=f.language;switch(q[g]||(g=g.split("-")[0],q[g]||(g=o.language)),f.language=g,f.startView){case 2:case"decade":f.startView=2;break;case 1:case"year":f.startView=1;break;default:f.startView=0}switch(f.minViewMode){case 1:case"months":f.minViewMode=1;break;case 2:case"years":f.minViewMode=2;break;default:f.minViewMode=0}switch(f.maxViewMode){case 0:case"days":f.maxViewMode=0;break;case 1:case"months":f.maxViewMode=1;break;default:f.maxViewMode=2}f.startView=Math.min(f.startView,f.maxViewMode),f.startView=Math.max(f.startView,f.minViewMode),f.multidate!==!0&&(f.multidate=Number(f.multidate)||!1,f.multidate!==!1&&(f.multidate=Math.max(0,f.multidate))),f.multidateSeparator=String(f.multidateSeparator),f.weekStart%=7,f.weekEnd=(f.weekStart+6)%7;var h=r.parseFormat(f.format);if(f.startDate!==-(1/0)&&(f.startDate?f.startDate instanceof Date?f.startDate=this._local_to_utc(this._zero_time(f.startDate)):f.startDate=r.parseDate(f.startDate,h,f.language):f.startDate=-(1/0)),f.endDate!==1/0&&(f.endDate?f.endDate instanceof Date?f.endDate=this._local_to_utc(this._zero_time(f.endDate)):f.endDate=r.parseDate(f.endDate,h,f.language):f.endDate=1/0),f.daysOfWeekDisabled=f.daysOfWeekDisabled||[],a.isArray(f.daysOfWeekDisabled)||(f.daysOfWeekDisabled=f.daysOfWeekDisabled.split(/[,\s]*/)),f.daysOfWeekDisabled=a.map(f.daysOfWeekDisabled,function(a){return parseInt(a,10)}),f.daysOfWeekHighlighted=f.daysOfWeekHighlighted||[],a.isArray(f.daysOfWeekHighlighted)||(f.daysOfWeekHighlighted=f.daysOfWeekHighlighted.split(/[,\s]*/)),f.daysOfWeekHighlighted=a.map(f.daysOfWeekHighlighted,function(a){return parseInt(a,10)}),f.datesDisabled=f.datesDisabled||[],!a.isArray(f.datesDisabled)){var i=[];i.push(r.parseDate(f.datesDisabled,h,f.language)),f.datesDisabled=i}f.datesDisabled=a.map(f.datesDisabled,function(a){return r.parseDate(a,h,f.language)});var j=String(f.orientation).toLowerCase().split(/\s+/g),k=f.orientation.toLowerCase();if(j=a.grep(j,function(a){return/^auto|left|right|top|bottom$/.test(a)}),f.orientation={x:"auto",y:"auto"},k&&"auto"!==k)if(1===j.length)switch(j[0]){case"top":case"bottom":f.orientation.y=j[0];break;case"left":case"right":f.orientation.x=j[0]}else k=a.grep(j,function(a){return/^left|right$/.test(a)}),f.orientation.x=k[0]||"auto",k=a.grep(j,function(a){return/^top|bottom$/.test(a)}),f.orientation.y=k[0]||"auto";else;if(f.defaultViewDate){var l=f.defaultViewDate.year||(new Date).getFullYear(),m=f.defaultViewDate.month||0,n=f.defaultViewDate.day||1;f.defaultViewDate=c(l,m,n)}else f.defaultViewDate=d();f.showOnFocus=f.showOnFocus!==b?f.showOnFocus:!0,f.zIndexOffset=f.zIndexOffset!==b?f.zIndexOffset:10},_events:[],_secondaryEvents:[],_applyEvents:function(a){for(var c,d,e,f=0;ff?(this.picker.addClass("datepicker-orient-right"),n=k.left+m-b):this.picker.addClass("datepicker-orient-left");var p,q=this.o.orientation.y;if("auto"===q&&(p=-g+o-c,q=0>p?"bottom":"top"),this.picker.addClass("datepicker-orient-"+q),"top"===q?o-=c+parseInt(this.picker.css("padding-top")):o+=l,this.o.rtl){var r=f-(n+m);this.picker.css({top:o,right:r,zIndex:j})}else this.picker.css({top:o,left:n,zIndex:j});return this},_allow_update:!0,update:function(){if(!this._allow_update)return this;var b=this.dates.copy(),c=[],d=!1;return arguments.length?(a.each(arguments,a.proxy(function(a,b){b instanceof Date&&(b=this._local_to_utc(b)),c.push(b)},this)),d=!0):(c=this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val(),c=c&&this.o.multidate?c.split(this.o.multidateSeparator):[c],delete this.element.data().date),c=a.map(c,a.proxy(function(a){return r.parseDate(a,this.o.format,this.o.language)},this)),c=a.grep(c,a.proxy(function(a){return athis.o.endDate||!a},this),!0),this.dates.replace(c),this.dates.length?this.viewDate=new Date(this.dates.get(-1)):this.viewDatethis.o.endDate?this.viewDate=new Date(this.o.endDate):this.viewDate=this.o.defaultViewDate,d?this.setValue():c.length&&String(b)!==String(this.dates)&&this._trigger("changeDate"),!this.dates.length&&b.length&&this._trigger("clearDate"),this.fill(),this.element.change(),this},fillDow:function(){var a=this.o.weekStart,b="";for(this.o.calendarWeeks&&(this.picker.find(".datepicker-days .datepicker-switch").attr("colspan",function(a,b){return parseInt(b)+1}),b+=' ');a'+q[this.o.language].daysMin[a++%7]+"";b+="",this.picker.find(".datepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;12>b;)a+=''+q[this.o.language].monthsShort[b++]+"";this.picker.find(".datepicker-months td").html(a)},setRange:function(b){b&&b.length?this.range=a.map(b,function(a){return a.valueOf()}):delete this.range,this.fill()},getClassNames:function(b){var c=[],d=this.viewDate.getUTCFullYear(),f=this.viewDate.getUTCMonth(),g=new Date;return b.getUTCFullYear()d||b.getUTCFullYear()===d&&b.getUTCMonth()>f)&&c.push("new"),this.focusDate&&b.valueOf()===this.focusDate.valueOf()&&c.push("focused"),this.o.todayHighlight&&b.getUTCFullYear()===g.getFullYear()&&b.getUTCMonth()===g.getMonth()&&b.getUTCDate()===g.getDate()&&c.push("today"),-1!==this.dates.contains(b)&&c.push("active"),(b.valueOf()this.o.endDate||-1!==a.inArray(b.getUTCDay(),this.o.daysOfWeekDisabled))&&c.push("disabled"),-1!==a.inArray(b.getUTCDay(),this.o.daysOfWeekHighlighted)&&c.push("highlighted"),this.o.datesDisabled.length>0&&a.grep(this.o.datesDisabled,function(a){return e(b,a)}).length>0&&c.push("disabled","disabled-date"),this.range&&(b>this.range[0]&&b"),this.o.calendarWeeks)){var v=new Date(+o+(this.o.weekStart-o.getUTCDay()-7)%7*864e5),w=new Date(Number(v)+(11-v.getUTCDay())%7*864e5),x=new Date(Number(x=c(w.getUTCFullYear(),0,1))+(11-x.getUTCDay())%7*864e5),y=(w-x)/864e5/7+1;u.push(''+y+"")}if(t=this.getClassNames(o),t.push("day"),this.o.beforeShowDay!==a.noop){var z=this.o.beforeShowDay(this._utc_to_local(o));z===b?z={}:"boolean"==typeof z?z={enabled:z}:"string"==typeof z&&(z={classes:z}),z.enabled===!1&&t.push("disabled"),z.classes&&(t=t.concat(z.classes.split(/\s+/))),z.tooltip&&(d=z.tooltip)}t=a.unique(t),u.push('"+o.getUTCDate()+""),d=null,o.getUTCDay()===this.o.weekEnd&&u.push(""),o.setUTCDate(o.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(u.join(""));var A=this.picker.find(".datepicker-months").find(".datepicker-switch").text(this.o.maxViewMode<2?"Months":f).end().find("span").removeClass("active");if(a.each(this.dates,function(a,b){b.getUTCFullYear()===f&&A.eq(b.getUTCMonth()).addClass("active")}),(h>f||f>j)&&A.addClass("disabled"),f===h&&A.slice(0,i).addClass("disabled"),f===j&&A.slice(k+1).addClass("disabled"),this.o.beforeShowMonth!==a.noop){var B=this;a.each(A,function(b,c){if(!a(c).hasClass("disabled")){var d=new Date(f,b,1),e=B.o.beforeShowMonth(d);e===!1&&a(c).addClass("disabled")}})}u="",f=10*parseInt(f/10,10);var C=this.picker.find(".datepicker-years").find(".datepicker-switch").text(f+"-"+(f+9)).end().find("td");f-=1;for(var D,E=a.map(this.dates,function(a){return a.getUTCFullYear()}),F=-1;11>F;F++){if(D=["year"],d=null,-1===F?D.push("old"):10===F&&D.push("new"),-1!==a.inArray(f,E)&&D.push("active"),(h>f||f>j)&&D.push("disabled"),this.o.beforeShowYear!==a.noop){var G=this.o.beforeShowYear(new Date(f,0,1));G===b?G={}:"boolean"==typeof G?G={enabled:G}:"string"==typeof G&&(G={classes:G}),G.enabled===!1&&D.push("disabled"),G.classes&&(D=D.concat(G.classes.split(/\s+/))),G.tooltip&&(d=G.tooltip)}u+='"+f+"",f+=1}C.html(u)}},updateNavArrows:function(){if(this._allow_update){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth();switch(this.viewMode){case 0:this.o.startDate!==-(1/0)&&b<=this.o.startDate.getUTCFullYear()&&c<=this.o.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.o.endDate!==1/0&&b>=this.o.endDate.getUTCFullYear()&&c>=this.o.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:case 2:this.o.startDate!==-(1/0)&&b<=this.o.startDate.getUTCFullYear()||this.o.maxViewMode<2?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.o.endDate!==1/0&&b>=this.o.endDate.getUTCFullYear()||this.o.maxViewMode<2?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}}},click:function(b){b.preventDefault(),b.stopPropagation();var d,e,f,g=a(b.target).closest("span, td, th");if(1===g.length)switch(g[0].nodeName.toLowerCase()){case"th":switch(g[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var h=r.modes[this.viewMode].navStep*("prev"===g[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,h),this._trigger("changeMonth",this.viewDate);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,h),1===this.viewMode&&this._trigger("changeYear",this.viewDate)}this.fill();break;case"today":var i=new Date;i=c(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0),this.showMode(-2);var j="linked"===this.o.todayBtn?null:"view";this._setDate(i,j);break;case"clear":this.clearDates()}break;case"span":g.hasClass("disabled")||(this.viewDate.setUTCDate(1),g.hasClass("month")?(f=1,e=g.parent().find("span").index(g),d=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(e),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode?(this._setDate(c(d,e,f)),this.showMode()):this.showMode(-1)):(f=1,e=0,d=parseInt(g.text(),10)||0,this.viewDate.setUTCFullYear(d),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(c(d,e,f)),this.showMode(-1)),this.fill());break;case"td":g.hasClass("day")&&!g.hasClass("disabled")&&(f=parseInt(g.text(),10)||1,d=this.viewDate.getUTCFullYear(),e=this.viewDate.getUTCMonth(),g.hasClass("old")?0===e?(e=11,d-=1):e-=1:g.hasClass("new")&&(11===e?(e=0,d+=1):e+=1),this._setDate(c(d,e,f)))}this.picker.is(":visible")&&this._focused_from&&a(this._focused_from).focus(),delete this._focused_from},_toggle_multidate:function(a){var b=this.dates.contains(a);if(a||this.dates.clear(),-1!==b?(this.o.multidate===!0||this.o.multidate>1||this.o.toggleActive)&&this.dates.remove(b):this.o.multidate===!1?(this.dates.clear(),this.dates.push(a)):this.dates.push(a),"number"==typeof this.o.multidate)for(;this.dates.length>this.o.multidate;)this.dates.remove(0)},_setDate:function(a,b){b&&"date"!==b||this._toggle_multidate(a&&new Date(a)),b&&"view"!==b||(this.viewDate=a&&new Date(a)),this.fill(),this.setValue(),b&&"view"===b||this._trigger("changeDate");var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&c.change(),!this.o.autoclose||b&&"date"!==b||this.hide()},moveMonth:function(a,b){if(!g(a))return this.o.defaultViewDate;if(!b)return a;var c,d,e=new Date(a.valueOf()),f=e.getUTCDate(),h=e.getUTCMonth(),i=Math.abs(b);if(b=b>0?1:-1,1===i)d=-1===b?function(){return e.getUTCMonth()===h}:function(){return e.getUTCMonth()!==c},c=h+b,e.setUTCMonth(c),(0>c||c>11)&&(c=(c+12)%12);else{for(var j=0;i>j;j++)e=this.moveMonth(e,b);c=e.getUTCMonth(),e.setUTCDate(f),d=function(){return c!==e.getUTCMonth()}}for(;d();)e.setUTCDate(--f),e.setUTCMonth(c);return e},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.o.startDate&&a<=this.o.endDate},keydown:function(a){if(!this.picker.is(":visible"))return void((40===a.keyCode||27===a.keyCode)&&(this.show(),a.stopPropagation()));var b,c,e,f=!1,g=this.focusDate||this.viewDate;switch(a.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),a.preventDefault(),a.stopPropagation();break;case 37:case 39:if(!this.o.keyboardNavigation)break;b=37===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+b),e=new Date(g),e.setUTCDate(g.getUTCDate()+b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 38:case 40:if(!this.o.keyboardNavigation)break;b=38===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+7*b),e=new Date(g),e.setUTCDate(g.getUTCDate()+7*b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 32:break;case 13:if(!this.o.forceParse)break;g=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(g),f=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(a.preventDefault(),"function"==typeof a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}if(f){this.dates.length?this._trigger("changeDate"):this._trigger("clearDate");var h;this.isInput?h=this.element:this.component&&(h=this.element.find("input")),h&&h.change()}},showMode:function(a){a&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(this.o.maxViewMode,this.viewMode+a))),this.picker.children("div").hide().filter(".datepicker-"+r.modes[this.viewMode].clsName).show(),this.updateNavArrows()}};var l=function(b,c){this.element=a(b),this.inputs=a.map(c.inputs,function(a){return a.jquery?a[0]:a}),delete c.inputs,n.call(a(this.inputs),c).on("changeDate",a.proxy(this.dateUpdated,this)),this.pickers=a.map(this.inputs,function(b){return a(b).data("datepicker")}),this.updateDates()};l.prototype={updateDates:function(){this.dates=a.map(this.pickers,function(a){return a.getUTCDate()}),this.updateRanges()},updateRanges:function(){var b=a.map(this.dates,function(a){return a.valueOf()});a.each(this.pickers,function(a,c){c.setRange(b)})},dateUpdated:function(b){if(!this.updating){this.updating=!0;var c=a(b.target).data("datepicker");if("undefined"!=typeof c){var d=c.getUTCDate(),e=a.inArray(b.target,this.inputs),f=e-1,g=e+1,h=this.inputs.length;if(-1!==e){if(a.each(this.pickers,function(a,b){b.getUTCDate()||b.setUTCDate(d)}),d=0&&dthis.dates[g])for(;h>g&&d>this.dates[g];)this.pickers[g++].setUTCDate(d);this.updateDates(),delete this.updating}}}},remove:function(){a.map(this.pickers,function(a){a.remove()}),delete this.element.data().datepicker}};var m=a.fn.datepicker,n=function(c){var d=Array.apply(null,arguments);d.shift();var e;if(this.each(function(){var b=a(this),f=b.data("datepicker"),g="object"==typeof c&&c;if(!f){var j=h(this,"date"),m=a.extend({},o,j,g),n=i(m.language),p=a.extend({},o,n,j,g);if(b.hasClass("input-daterange")||p.inputs){var q={inputs:p.inputs||b.find("input").toArray()};b.data("datepicker",f=new l(this,a.extend(p,q)))}else b.data("datepicker",f=new k(this,p))}"string"==typeof c&&"function"==typeof f[c]&&(e=f[c].apply(f,d))}),e===b||e instanceof k||e instanceof l)return this;if(this.length>1)throw new Error("Using only allowed for the collection of a single element ("+c+" function)");return e};a.fn.datepicker=n;var o=a.fn.datepicker.defaults={autoclose:!1,beforeShowDay:a.noop,beforeShowMonth:a.noop,beforeShowYear:a.noop,calendarWeeks:!1,clearBtn:!1,toggleActive:!1,daysOfWeekDisabled:[],daysOfWeekHighlighted:[],datesDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,maxViewMode:2,multidate:!1,multidateSeparator:",",orientation:"auto",rtl:!1,startDate:-(1/0),startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0,disableTouchKeyboard:!1,enableOnReadonly:!0,container:"body",immediateUpdates:!1,title:""},p=a.fn.datepicker.locale_opts=["format","rtl","weekStart"];a.fn.datepicker.Constructor=k;var q=a.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear",titleFormat:"MM yyyy"}},r={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return a%4===0&&a%100!==0||a%400===0},getDaysInMonth:function(a,b){return[31,r.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(a){if("function"==typeof a.toValue&&"function"==typeof a.toDisplay)return a;var b=a.replace(this.validParts,"\x00").split("\x00"),c=a.match(this.validParts);if(!b||!b.length||!c||0===c.length)throw new Error("Invalid date format.");return{separators:b,parts:c}},parseDate:function(d,e,f){function g(){var a=this.slice(0,m[j].length),b=m[j].slice(0,a.length);return a.toLowerCase()===b.toLowerCase()}if(!d)return b;if(d instanceof Date)return d;if("string"==typeof e&&(e=r.parseFormat(e)),e.toValue)return e.toValue(d,e,f);var h,i,j,l=/([\-+]\d+)([dmwy])/,m=d.match(/([\-+]\d+)([dmwy])/g);if(/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(d)){for(d=new Date,j=0;jb;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!==b;)a.setUTCDate(a.getUTCDate()-1);return a},d:function(a,b){return a.setUTCDate(b)}};t.M=t.MM=t.mm=t.m,t.dd=t.d,d=c(d.getFullYear(),d.getMonth(),d.getDate(),0,0,0);var u=e.parts.slice();if(m.length!==u.length&&(u=a(u).filter(function(b,c){return-1!==a.inArray(c,s)}).toArray()),m.length===u.length){var v;for(j=0,v=u.length;v>j;j++){if(n=parseInt(m[j],10),h=u[j],isNaN(n))switch(h){case"MM":o=a(q[f].months).filter(g),n=a.inArray(o[0],q[f].months)+1;break;case"M":o=a(q[f].monthsShort).filter(g),n=a.inArray(o[0],q[f].monthsShort)+1}p[h]=n}var w,x;for(j=0;j=g;g++)f.length&&b.push(f.shift()),b.push(e[c.parts[g]]);return b.join("")},headTemplate:'«»',contTemplate:'',footTemplate:''};r.template='
'+r.headTemplate+""+r.footTemplate+'
'+r.headTemplate+r.contTemplate+r.footTemplate+'
'+r.headTemplate+r.contTemplate+r.footTemplate+"
",a.fn.datepicker.DPGlobal=r,a.fn.datepicker.noConflict=function(){return a.fn.datepicker=m,this},a.fn.datepicker.version="1.5.0",a(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(b){var c=a(this);c.data("datepicker")||(b.preventDefault(),n.call(c,"show"))}),a(function(){n.call(a('[data-provide="datepicker-inline"]'))})}); \ No newline at end of file diff --git a/web/pgadmin/templates/base.html b/web/pgadmin/templates/base.html index 62024da0a..3e13cba94 100755 --- a/web/pgadmin/templates/base.html +++ b/web/pgadmin/templates/base.html @@ -22,6 +22,7 @@ + {% for stylesheet in current_app.stylesheets %} @@ -44,9 +45,19 @@ "bootstrap": { "deps": ['jquery'], }, + "backgrid": { + "deps": ['backform'], + "exports": 'Backgrid', + }, "bootstrap.datepicker": { "deps": ['jquery', 'bootstrap'], "exports": 'jQuery.fn.datepicker' + }, + "pgadmin.backgrid": { + "deps": ["backgrid", "bootstrap.datepicker"], + }, + "pgadmin.backform": { + "deps": ['backform', "pgadmin.backgrid"], }{% for script in current_app.javascripts %}{% if 'deps' in script or 'exports' in script %}, '{{ script.name }}': { {% if 'deps' in script %}"deps": [ {% set comma = False %}{% for dep in script['deps'] %} {% if comma %},{% else %}{% set comma = True %}{% endif %} '{{ dep }}'{% endfor %}],{% endif %} @@ -65,6 +76,8 @@ backbone: "{{ url_for('static', filename='js/' + ('backbone' if config.DEBUG else 'backbone-min')) }}", "bootstrap.datepicker": "{{ url_for('static', filename='js/' + ('bootstrap-datepicker' if config.DEBUG else 'bootstrap-datepicker.min')) }}", backform: "{{ url_for('static', filename='js/backform') }}", + backgrid: "{{ url_for('static', filename='js/backgrid/' + ('backgrid' if config.DEBUG else 'backgrid.min')) }}", + "pgadmin.backgrid": "{{ url_for('static', filename='js/backgrid/backgrid.pgadmin') }}", 'pgadmin.backform': "{{ url_for('static', filename='js/backform.pgadmin') }}"{% for script in current_app.javascripts %}, '{{ script.name }}': "{{ script.path }}"{% endfor %} }