mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Introducing the infrastructure for colleciton of the subnodes listing,
creation, and editing within the properties panel infrastructure. We do use the backgrid.js for listing the subnode collection, and for editing/creating new object for the subnode, we do use the same infrastructure using the backform.
This commit is contained in:
committed by
Ashesh Vashi
parent
c53b57a013
commit
c1503ade47
240
web/pgadmin/static/css/backgrid/backgrid.css
Normal file
240
web/pgadmin/static/css/backgrid/backgrid.css
Normal file
@@ -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;
|
||||
}
|
||||
1
web/pgadmin/static/css/backgrid/backgrid.min.css
vendored
Normal file
1
web/pgadmin/static/css/backgrid/backgrid.min.css
vendored
Normal file
@@ -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}
|
||||
924
web/pgadmin/static/css/bootstrap-datepicker3.css
vendored
924
web/pgadmin/static/css/bootstrap-datepicker3.css
vendored
File diff suppressed because it is too large
Load Diff
8
web/pgadmin/static/css/bootstrap-datepicker3.min.css
vendored
Normal file
8
web/pgadmin/static/css/bootstrap-datepicker3.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 @@
|
||||
'<div class="<%=Backform.controlsClassName%>">',
|
||||
'<% for (var i=0; i < options.length; i++) { %>',
|
||||
' <% var option = options[i]; %>',
|
||||
' <% if (option.value === rawValue) { %>',
|
||||
' <% if (option.value === rawValue) { %>',
|
||||
' <span class="<%=Backform.controlClassName%> uneditable-input" disabled><%-option.label%></span>',
|
||||
' <% } %>',
|
||||
'<% } %>',
|
||||
@@ -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 = ["<div class='subnode-header'>",
|
||||
" <label class='control-label col-sm-4'>" + data.label + "</label>" ,
|
||||
" <button class='btn-sm btn-default add'>Add</buttton>",
|
||||
"</div>"].join("\n");
|
||||
gridBody = $("<div class='pgadmin-control-group backgrid form-group col-xs-12 object subnode' >").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;
|
||||
}));
|
||||
|
||||
2883
web/pgadmin/static/js/backgrid/backgrid.js
Normal file
2883
web/pgadmin/static/js/backgrid/backgrid.js
Normal file
File diff suppressed because it is too large
Load Diff
8
web/pgadmin/static/js/backgrid/backgrid.min.js
vendored
Normal file
8
web/pgadmin/static/js/backgrid/backgrid.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
234
web/pgadmin/static/js/backgrid/backgrid.pgadmin.js
Normal file
234
web/pgadmin/static/js/backgrid/backgrid.pgadmin.js
Normal file
@@ -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([
|
||||
'<div class="subnode-dialog">',
|
||||
' <div class="subnode-body"></div>',
|
||||
' <div class="subnode-footer">',
|
||||
' <button style ="float:right;margin-right:15px;margin-top: 4px;" class="cancel btn btn-danger" type="cancel">Cancel</button>',
|
||||
' <button style ="float:right;margin-right:10px;margin-top: 4px;" class="save btn btn-primary" type="save">Save</button>',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].join("\n")),
|
||||
stringTemplate: _.template([
|
||||
'<div class="form-group">',
|
||||
' <label class="control-label col-sm-4"><%=label%></label>',
|
||||
' <div class="col-sm-8">',
|
||||
' <input type="text" class="form-control" name="<%=name%>" value="<%=value%>" placeholder="<%=placeholder%>" />',
|
||||
' </div>',
|
||||
'</div>'
|
||||
].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 = $('<form class="form-dialog"></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 = $("<tr>"),
|
||||
td = $("<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("<i class='fa fa-minus-square-o'></i>");
|
||||
},
|
||||
render: function(){
|
||||
this.$el.empty();
|
||||
this.$el.html("<i class='fa fa-pencil-square-o'></i>");
|
||||
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("<i class='fa fa-trash'></i>");
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
return Backgrid;
|
||||
|
||||
}));
|
||||
205
web/pgadmin/static/js/bootstrap-datepicker.js
vendored
205
web/pgadmin/static/js/bootstrap-datepicker.js
vendored
@@ -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 = '<tr>';
|
||||
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 = '<th class="cw"> </th>';
|
||||
html += cell;
|
||||
html += '<th class="cw"> </th>';
|
||||
}
|
||||
while (dowCnt < this.o.weekStart + 7){
|
||||
html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
|
||||
@@ -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 += '<span class="' + classes.join(' ') + '">' + year + '</span>';
|
||||
|
||||
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 += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>' + year + '</span>';
|
||||
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: '<thead>'+
|
||||
'<tr>'+
|
||||
'<th colspan="7" class="datepicker-title"></th>'+
|
||||
'</tr>'+
|
||||
'<tr>'+
|
||||
'<th class="prev">«</th>'+
|
||||
'<th colspan="5" class="datepicker-switch"></th>'+
|
||||
@@ -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));
|
||||
}));
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user