x-editable-rails 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/x-editable-rails/version.rb +1 -1
- data/vendor/assets/javascripts/editable/bootstrap-editable.js +1142 -713
- data/vendor/assets/javascripts/editable/jquery-editable-poshytip.js +353 -182
- data/vendor/assets/javascripts/editable/jqueryui-editable.js +352 -181
- data/vendor/assets/stylesheets/editable/{bootstrap-editable.css → bootstrap-editable.scss} +164 -8
- data/vendor/assets/stylesheets/editable/{jquery-editable.css → jquery-editable.scss} +11 -3
- data/vendor/assets/stylesheets/editable/{jqueryui-editable.css → jqueryui-editable.scss} +11 -3
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5efea27a1619957c2f3197189d9e17bb51a3b4ef
|
4
|
+
data.tar.gz: 8af1c69ce928792a5ac658b3b2b8d75bdc27b878
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f3de3e4bf6ea289cc325353c619c2479591589ec968c8bb2db9084d5e53753187616c6a6c4fd6aee43528cc1566bcccee8d52290a7ef29b189fa14dfb9988c1
|
7
|
+
data.tar.gz: f3bf084a7399627b4ab3d5a8315eab3c3d1ead2e233e2d402a4c820f8892cbffd3782622de4106ce77064e07bc9bb080fc62250a962887064f1ab2b5e834e6a5
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! X-editable - v1.4.
|
1
|
+
/*! X-editable - v1.4.5
|
2
2
|
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
|
3
3
|
* http://github.com/vitalets/x-editable
|
4
4
|
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
|
@@ -65,6 +65,10 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
65
65
|
//show loading state
|
66
66
|
this.showLoading();
|
67
67
|
|
68
|
+
//flag showing is form now saving value to server.
|
69
|
+
//It is needed to wait when closing form.
|
70
|
+
this.isSaving = false;
|
71
|
+
|
68
72
|
/**
|
69
73
|
Fired when rendering starts
|
70
74
|
@event rendering
|
@@ -217,31 +221,38 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
217
221
|
return;
|
218
222
|
}
|
219
223
|
|
224
|
+
//convert value for submitting to server
|
225
|
+
var submitValue = this.input.value2submit(newValue);
|
226
|
+
|
227
|
+
this.isSaving = true;
|
228
|
+
|
220
229
|
//sending data to server
|
221
|
-
$.when(this.save(
|
230
|
+
$.when(this.save(submitValue))
|
222
231
|
.done($.proxy(function(response) {
|
232
|
+
this.isSaving = false;
|
233
|
+
|
223
234
|
//run success callback
|
224
235
|
var res = typeof this.options.success === 'function' ? this.options.success.call(this.options.scope, response, newValue) : null;
|
225
|
-
|
236
|
+
|
226
237
|
//if success callback returns false --> keep form open and do not activate input
|
227
238
|
if(res === false) {
|
228
239
|
this.error(false);
|
229
240
|
this.showForm(false);
|
230
241
|
return;
|
231
|
-
}
|
232
|
-
|
242
|
+
}
|
243
|
+
|
233
244
|
//if success callback returns string --> keep form open, show error and activate input
|
234
245
|
if(typeof res === 'string') {
|
235
246
|
this.error(res);
|
236
247
|
this.showForm();
|
237
248
|
return;
|
238
|
-
}
|
239
|
-
|
249
|
+
}
|
250
|
+
|
240
251
|
//if success callback returns object like {newValue: <something>} --> use that value instead of submitted
|
241
252
|
//it is usefull if you want to chnage value in url-function
|
242
253
|
if(res && typeof res === 'object' && res.hasOwnProperty('newValue')) {
|
243
254
|
newValue = res.newValue;
|
244
|
-
}
|
255
|
+
}
|
245
256
|
|
246
257
|
//clear error message
|
247
258
|
this.error(false);
|
@@ -251,37 +262,42 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
251
262
|
@event save
|
252
263
|
@param {Object} event event object
|
253
264
|
@param {Object} params additional params
|
254
|
-
@param {mixed} params.newValue
|
265
|
+
@param {mixed} params.newValue raw new value
|
266
|
+
@param {mixed} params.submitValue submitted value as string
|
255
267
|
@param {Object} params.response ajax response
|
256
268
|
|
257
269
|
@example
|
258
270
|
$('#form-div').on('save'), function(e, params){
|
259
271
|
if(params.newValue === 'username') {...}
|
260
|
-
});
|
261
|
-
**/
|
262
|
-
this.$div.triggerHandler('save', {newValue: newValue, response: response});
|
272
|
+
});
|
273
|
+
**/
|
274
|
+
this.$div.triggerHandler('save', {newValue: newValue, submitValue: submitValue, response: response});
|
263
275
|
}, this))
|
264
276
|
.fail($.proxy(function(xhr) {
|
277
|
+
this.isSaving = false;
|
278
|
+
|
265
279
|
var msg;
|
266
280
|
if(typeof this.options.error === 'function') {
|
267
281
|
msg = this.options.error.call(this.options.scope, xhr, newValue);
|
268
282
|
} else {
|
269
283
|
msg = typeof xhr === 'string' ? xhr : xhr.responseText || xhr.statusText || 'Unknown error!';
|
270
284
|
}
|
271
|
-
|
285
|
+
|
272
286
|
this.error(msg);
|
273
287
|
this.showForm();
|
274
288
|
}, this));
|
275
289
|
},
|
276
290
|
|
277
|
-
save: function(
|
278
|
-
//convert value for submitting to server
|
279
|
-
var submitValue = this.input.value2submit(newValue);
|
280
|
-
|
291
|
+
save: function(submitValue) {
|
281
292
|
//try parse composite pk defined as json string in data-pk
|
282
293
|
this.options.pk = $.fn.editableutils.tryParseJson(this.options.pk, true);
|
283
294
|
|
284
295
|
var pk = (typeof this.options.pk === 'function') ? this.options.pk.call(this.options.scope) : this.options.pk,
|
296
|
+
/*
|
297
|
+
send on server in following cases:
|
298
|
+
1. url is function
|
299
|
+
2. url is string AND (pk defined OR send option = always)
|
300
|
+
*/
|
285
301
|
send = !!(typeof this.options.url === 'function' || (this.options.url && ((this.options.send === 'always') || (this.options.send === 'auto' && pk !== null && pk !== undefined)))),
|
286
302
|
params;
|
287
303
|
|
@@ -816,6 +832,27 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|
816
832
|
$.error('Unknown type: '+ type);
|
817
833
|
return false;
|
818
834
|
}
|
835
|
+
},
|
836
|
+
|
837
|
+
//see http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
|
838
|
+
supportsTransitions: function () {
|
839
|
+
var b = document.body || document.documentElement,
|
840
|
+
s = b.style,
|
841
|
+
p = 'transition',
|
842
|
+
v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms'];
|
843
|
+
|
844
|
+
if(typeof s[p] === 'string') {
|
845
|
+
return true;
|
846
|
+
}
|
847
|
+
|
848
|
+
// Tests for vendor specific prop
|
849
|
+
p = p.charAt(0).toUpperCase() + p.substr(1);
|
850
|
+
for(var i=0; i<v.length; i++) {
|
851
|
+
if(typeof s[v[i] + p] === 'string') {
|
852
|
+
return true;
|
853
|
+
}
|
854
|
+
}
|
855
|
+
return false;
|
819
856
|
}
|
820
857
|
|
821
858
|
};
|
@@ -856,6 +893,9 @@ Applied as jQuery method.
|
|
856
893
|
this.formOptions.scope = this.$element[0];
|
857
894
|
|
858
895
|
this.initContainer();
|
896
|
+
|
897
|
+
//flag to hide container, when saving value will finish
|
898
|
+
this.delayedHide = false;
|
859
899
|
|
860
900
|
//bind 'destroyed' listener to destroy container when element is removed from dom
|
861
901
|
this.$element.on('destroyed', $.proxy(function(){
|
@@ -960,7 +1000,14 @@ Applied as jQuery method.
|
|
960
1000
|
save: $.proxy(this.save, this), //click on submit button (value changed)
|
961
1001
|
nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
|
962
1002
|
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
|
963
|
-
show: $.proxy(
|
1003
|
+
show: $.proxy(function() {
|
1004
|
+
if(this.delayedHide) {
|
1005
|
+
this.hide(this.delayedHide.reason);
|
1006
|
+
this.delayedHide = false;
|
1007
|
+
} else {
|
1008
|
+
this.setPosition();
|
1009
|
+
}
|
1010
|
+
}, this), //re-position container every time form is shown (occurs each time after loading state)
|
964
1011
|
rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown
|
965
1012
|
resize: $.proxy(this.setPosition, this), //this allows to re-position container when form size is changed
|
966
1013
|
rendered: $.proxy(function(){
|
@@ -1004,11 +1051,11 @@ Applied as jQuery method.
|
|
1004
1051
|
|
1005
1052
|
/*
|
1006
1053
|
Currently, form is re-rendered on every show.
|
1007
|
-
The main reason is that we dont know, what container
|
1008
|
-
remove(), detach() or just hide().
|
1054
|
+
The main reason is that we dont know, what will container do with content when closed:
|
1055
|
+
remove(), detach() or just hide() - it depends on container.
|
1009
1056
|
|
1010
1057
|
Detaching form itself before hide and re-insert before show is good solution,
|
1011
|
-
but visually it looks ugly
|
1058
|
+
but visually it looks ugly --> container changes size before hide.
|
1012
1059
|
*/
|
1013
1060
|
|
1014
1061
|
//if form already exist - delete previous data
|
@@ -1041,10 +1088,18 @@ Applied as jQuery method.
|
|
1041
1088
|
return;
|
1042
1089
|
}
|
1043
1090
|
|
1091
|
+
//if form is saving value, schedule hide
|
1092
|
+
if(this.$form.data('editableform').isSaving) {
|
1093
|
+
this.delayedHide = {reason: reason};
|
1094
|
+
return;
|
1095
|
+
} else {
|
1096
|
+
this.delayedHide = false;
|
1097
|
+
}
|
1098
|
+
|
1044
1099
|
this.$element.removeClass('editable-open');
|
1045
1100
|
this.innerHide();
|
1046
|
-
|
1047
|
-
/**
|
1101
|
+
|
1102
|
+
/**
|
1048
1103
|
Fired when container was hidden. It occurs on both save or cancel.
|
1049
1104
|
**Note:** Bootstrap popover has own `hidden` event that now cannot be separated from x-editable's one.
|
1050
1105
|
The workaround is to check `arguments.length` that is always `2` for x-editable.
|
@@ -1058,20 +1113,20 @@ Applied as jQuery method.
|
|
1058
1113
|
//auto-open next editable
|
1059
1114
|
$(this).closest('tr').next().find('.editable').editable('show');
|
1060
1115
|
}
|
1061
|
-
});
|
1062
|
-
**/
|
1116
|
+
});
|
1117
|
+
**/
|
1063
1118
|
this.$element.triggerHandler('hidden', reason || 'manual');
|
1064
1119
|
},
|
1065
|
-
|
1120
|
+
|
1066
1121
|
/* internal show method. To be overwritten in child classes */
|
1067
1122
|
innerShow: function () {
|
1068
1123
|
|
1069
1124
|
},
|
1070
|
-
|
1125
|
+
|
1071
1126
|
/* internal hide method. To be overwritten in child classes */
|
1072
1127
|
innerHide: function () {
|
1073
|
-
|
1074
|
-
},
|
1128
|
+
|
1129
|
+
},
|
1075
1130
|
|
1076
1131
|
/**
|
1077
1132
|
Toggles container visibility (show / hide)
|
@@ -1116,7 +1171,7 @@ Applied as jQuery method.
|
|
1116
1171
|
**/
|
1117
1172
|
this.$element.triggerHandler('save', params);
|
1118
1173
|
|
1119
|
-
//hide must be after trigger, as saving value may require methods
|
1174
|
+
//hide must be after trigger, as saving value may require methods of plugin, applied to input
|
1120
1175
|
this.hide('save');
|
1121
1176
|
},
|
1122
1177
|
|
@@ -1276,7 +1331,7 @@ Applied as jQuery method.
|
|
1276
1331
|
onblur: 'cancel',
|
1277
1332
|
|
1278
1333
|
/**
|
1279
|
-
Animation speed (inline mode)
|
1334
|
+
Animation speed (inline mode only)
|
1280
1335
|
@property anim
|
1281
1336
|
@type string
|
1282
1337
|
@default false
|
@@ -1380,6 +1435,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1380
1435
|
} else {
|
1381
1436
|
this.init();
|
1382
1437
|
}
|
1438
|
+
|
1439
|
+
//check for transition support
|
1440
|
+
if(this.options.highlight && !$.fn.editableutils.supportsTransitions()) {
|
1441
|
+
this.options.highlight = false;
|
1442
|
+
}
|
1383
1443
|
};
|
1384
1444
|
|
1385
1445
|
Editable.prototype = {
|
@@ -1424,25 +1484,33 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1424
1484
|
if(this.options.toggle !== 'manual') {
|
1425
1485
|
this.$element.addClass('editable-click');
|
1426
1486
|
this.$element.on(this.options.toggle + '.editable', $.proxy(function(e){
|
1427
|
-
//prevent following link
|
1428
|
-
|
1487
|
+
//prevent following link if editable enabled
|
1488
|
+
if(!this.options.disabled) {
|
1489
|
+
e.preventDefault();
|
1490
|
+
}
|
1429
1491
|
|
1430
1492
|
//stop propagation not required because in document click handler it checks event target
|
1431
1493
|
//e.stopPropagation();
|
1432
1494
|
|
1433
1495
|
if(this.options.toggle === 'mouseenter') {
|
1434
1496
|
//for hover only show container
|
1435
|
-
this.show();
|
1497
|
+
this.show();
|
1436
1498
|
} else {
|
1437
1499
|
//when toggle='click' we should not close all other containers as they will be closed automatically in document click listener
|
1438
1500
|
var closeAll = (this.options.toggle !== 'click');
|
1439
1501
|
this.toggle(closeAll);
|
1440
|
-
}
|
1502
|
+
}
|
1441
1503
|
}, this));
|
1442
1504
|
} else {
|
1443
1505
|
this.$element.attr('tabindex', -1); //do not stop focus on element when toggled manually
|
1444
1506
|
}
|
1445
1507
|
|
1508
|
+
//if display is function it's far more convinient to have autotext = always to render correctly on init
|
1509
|
+
//see https://github.com/vitalets/x-editable-yii/issues/34
|
1510
|
+
if(typeof this.options.display === 'function') {
|
1511
|
+
this.options.autotext = 'always';
|
1512
|
+
}
|
1513
|
+
|
1446
1514
|
//check conditions for autotext:
|
1447
1515
|
switch(this.options.autotext) {
|
1448
1516
|
case 'always':
|
@@ -1621,12 +1689,29 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1621
1689
|
return;
|
1622
1690
|
}
|
1623
1691
|
|
1624
|
-
|
1692
|
+
/*
|
1693
|
+
isEmpty may be set directly as param of method.
|
1694
|
+
It is required when we enable/disable field and can't rely on content
|
1695
|
+
as node content is text: "Empty" that is not empty %)
|
1696
|
+
*/
|
1697
|
+
if(isEmpty !== undefined) {
|
1698
|
+
this.isEmpty = isEmpty;
|
1699
|
+
} else {
|
1700
|
+
//detect empty
|
1701
|
+
if($.trim(this.$element.html()) === '') {
|
1702
|
+
this.isEmpty = true;
|
1703
|
+
} else if($.trim(this.$element.text()) !== '') {
|
1704
|
+
this.isEmpty = false;
|
1705
|
+
} else {
|
1706
|
+
//e.g. '<img>'
|
1707
|
+
this.isEmpty = !this.$element.height() || !this.$element.width();
|
1708
|
+
}
|
1709
|
+
}
|
1625
1710
|
|
1626
1711
|
//emptytext shown only for enabled
|
1627
1712
|
if(!this.options.disabled) {
|
1628
1713
|
if (this.isEmpty) {
|
1629
|
-
this.$element.
|
1714
|
+
this.$element.html(this.options.emptytext);
|
1630
1715
|
if(this.options.emptyclass) {
|
1631
1716
|
this.$element.addClass(this.options.emptyclass);
|
1632
1717
|
}
|
@@ -1721,6 +1806,21 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1721
1806
|
}
|
1722
1807
|
}
|
1723
1808
|
|
1809
|
+
//highlight when saving
|
1810
|
+
if(this.options.highlight) {
|
1811
|
+
var $e = this.$element,
|
1812
|
+
$bgColor = $e.css('background-color');
|
1813
|
+
|
1814
|
+
$e.css('background-color', this.options.highlight);
|
1815
|
+
setTimeout(function(){
|
1816
|
+
$e.css('background-color', $bgColor);
|
1817
|
+
$e.addClass('editable-bg-transition');
|
1818
|
+
setTimeout(function(){
|
1819
|
+
$e.removeClass('editable-bg-transition');
|
1820
|
+
}, 1700);
|
1821
|
+
}, 0);
|
1822
|
+
}
|
1823
|
+
|
1724
1824
|
//set new value
|
1725
1825
|
this.setValue(params.newValue, false, params.response);
|
1726
1826
|
|
@@ -1787,6 +1887,8 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1787
1887
|
if(this.container) {
|
1788
1888
|
this.container.destroy();
|
1789
1889
|
}
|
1890
|
+
|
1891
|
+
this.input.destroy();
|
1790
1892
|
|
1791
1893
|
if(this.options.toggle !== 'manual') {
|
1792
1894
|
this.$element.removeClass('editable-click');
|
@@ -1844,28 +1946,37 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
1844
1946
|
/**
|
1845
1947
|
Returns current values of editable elements.
|
1846
1948
|
Note that it returns an **object** with name-value pairs, not a value itself. It allows to get data from several elements.
|
1847
|
-
If value of some editable is `null` or `undefined` it is excluded from result object.
|
1949
|
+
If value of some editable is `null` or `undefined` it is excluded from result object.
|
1950
|
+
When param `isSingle` is set to **true** - it is supposed you have single element and will return value of editable instead of object.
|
1848
1951
|
|
1849
1952
|
@method getValue()
|
1953
|
+
@param {bool} isSingle whether to return just value of single element
|
1850
1954
|
@returns {Object} object of element names and values
|
1851
1955
|
@example
|
1852
1956
|
$('#username, #fullname').editable('getValue');
|
1853
|
-
//
|
1957
|
+
//result:
|
1854
1958
|
{
|
1855
1959
|
username: "superuser",
|
1856
1960
|
fullname: "John"
|
1857
1961
|
}
|
1962
|
+
//isSingle = true
|
1963
|
+
$('#username').editable('getValue', true);
|
1964
|
+
//result "superuser"
|
1858
1965
|
**/
|
1859
1966
|
case 'getValue':
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1967
|
+
if(arguments.length === 2 && arguments[1] === true) { //isSingle = true
|
1968
|
+
result = this.eq(0).data(datakey).value;
|
1969
|
+
} else {
|
1970
|
+
this.each(function () {
|
1971
|
+
var $this = $(this), data = $this.data(datakey);
|
1972
|
+
if (data && data.value !== undefined && data.value !== null) {
|
1973
|
+
result[data.options.name] = data.input.value2submit(data.value);
|
1974
|
+
}
|
1975
|
+
});
|
1976
|
+
}
|
1866
1977
|
return result;
|
1867
1978
|
|
1868
|
-
/**
|
1979
|
+
/**
|
1869
1980
|
This method collects values from several editable elements and submit them all to server.
|
1870
1981
|
Internally it runs client-side validation for all fields and submits only in case of success.
|
1871
1982
|
See <a href="#newrecord">creating new records</a> for details.
|
@@ -2089,7 +2200,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
|
|
2089
2200
|
});
|
2090
2201
|
</script>
|
2091
2202
|
**/
|
2092
|
-
selector: null
|
2203
|
+
selector: null,
|
2204
|
+
/**
|
2205
|
+
Color used to highlight element after update. Implemented via CSS3 transition, works in modern browsers.
|
2206
|
+
|
2207
|
+
@property highlight
|
2208
|
+
@type string|boolean
|
2209
|
+
@since 1.4.5
|
2210
|
+
@default #FFFF80
|
2211
|
+
**/
|
2212
|
+
highlight: '#FFFF80'
|
2093
2213
|
};
|
2094
2214
|
|
2095
2215
|
}(window.jQuery));
|
@@ -2103,23 +2223,23 @@ To create your own input you can inherit from this class.
|
|
2103
2223
|
**/
|
2104
2224
|
(function ($) {
|
2105
2225
|
"use strict";
|
2106
|
-
|
2226
|
+
|
2107
2227
|
//types
|
2108
2228
|
$.fn.editabletypes = {};
|
2109
|
-
|
2229
|
+
|
2110
2230
|
var AbstractInput = function () { };
|
2111
2231
|
|
2112
2232
|
AbstractInput.prototype = {
|
2113
2233
|
/**
|
2114
2234
|
Initializes input
|
2115
|
-
|
2235
|
+
|
2116
2236
|
@method init()
|
2117
2237
|
**/
|
2118
2238
|
init: function(type, options, defaults) {
|
2119
2239
|
this.type = type;
|
2120
2240
|
this.options = $.extend({}, defaults, options);
|
2121
2241
|
},
|
2122
|
-
|
2242
|
+
|
2123
2243
|
/*
|
2124
2244
|
this method called before render to init $tpl that is inserted in DOM
|
2125
2245
|
*/
|
@@ -2133,107 +2253,107 @@ To create your own input you can inherit from this class.
|
|
2133
2253
|
/**
|
2134
2254
|
Renders input from tpl. Can return jQuery deferred object.
|
2135
2255
|
Can be overwritten in child objects
|
2136
|
-
|
2137
|
-
@method render()
|
2138
|
-
**/
|
2256
|
+
|
2257
|
+
@method render()
|
2258
|
+
**/
|
2139
2259
|
render: function() {
|
2140
2260
|
|
2141
2261
|
},
|
2142
2262
|
|
2143
2263
|
/**
|
2144
2264
|
Sets element's html by value.
|
2145
|
-
|
2146
|
-
@method value2html(value, element)
|
2265
|
+
|
2266
|
+
@method value2html(value, element)
|
2147
2267
|
@param {mixed} value
|
2148
2268
|
@param {DOMElement} element
|
2149
|
-
**/
|
2269
|
+
**/
|
2150
2270
|
value2html: function(value, element) {
|
2151
|
-
$(element).text(value);
|
2271
|
+
$(element).text($.trim(value));
|
2152
2272
|
},
|
2153
|
-
|
2273
|
+
|
2154
2274
|
/**
|
2155
2275
|
Converts element's html to value
|
2156
|
-
|
2157
|
-
@method html2value(html)
|
2276
|
+
|
2277
|
+
@method html2value(html)
|
2158
2278
|
@param {string} html
|
2159
2279
|
@returns {mixed}
|
2160
|
-
**/
|
2280
|
+
**/
|
2161
2281
|
html2value: function(html) {
|
2162
2282
|
return $('<div>').html(html).text();
|
2163
2283
|
},
|
2164
|
-
|
2284
|
+
|
2165
2285
|
/**
|
2166
2286
|
Converts value to string (for internal compare). For submitting to server used value2submit().
|
2167
|
-
|
2287
|
+
|
2168
2288
|
@method value2str(value)
|
2169
2289
|
@param {mixed} value
|
2170
2290
|
@returns {string}
|
2171
|
-
**/
|
2291
|
+
**/
|
2172
2292
|
value2str: function(value) {
|
2173
2293
|
return value;
|
2174
2294
|
},
|
2175
|
-
|
2295
|
+
|
2176
2296
|
/**
|
2177
2297
|
Converts string received from server into value. Usually from `data-value` attribute.
|
2178
|
-
|
2179
|
-
@method str2value(str)
|
2298
|
+
|
2299
|
+
@method str2value(str)
|
2180
2300
|
@param {string} str
|
2181
2301
|
@returns {mixed}
|
2182
|
-
**/
|
2302
|
+
**/
|
2183
2303
|
str2value: function(str) {
|
2184
2304
|
return str;
|
2185
2305
|
},
|
2186
2306
|
|
2187
2307
|
/**
|
2188
2308
|
Converts value for submitting to server. Result can be string or object.
|
2189
|
-
|
2309
|
+
|
2190
2310
|
@method value2submit(value)
|
2191
2311
|
@param {mixed} value
|
2192
2312
|
@returns {mixed}
|
2193
|
-
**/
|
2313
|
+
**/
|
2194
2314
|
value2submit: function(value) {
|
2195
2315
|
return value;
|
2196
|
-
},
|
2197
|
-
|
2316
|
+
},
|
2317
|
+
|
2198
2318
|
/**
|
2199
2319
|
Sets value of input.
|
2200
|
-
|
2320
|
+
|
2201
2321
|
@method value2input(value)
|
2202
2322
|
@param {mixed} value
|
2203
|
-
**/
|
2323
|
+
**/
|
2204
2324
|
value2input: function(value) {
|
2205
2325
|
this.$input.val(value);
|
2206
2326
|
},
|
2207
|
-
|
2327
|
+
|
2208
2328
|
/**
|
2209
2329
|
Returns value of input. Value can be object (e.g. datepicker)
|
2210
|
-
|
2330
|
+
|
2211
2331
|
@method input2value()
|
2212
|
-
**/
|
2332
|
+
**/
|
2213
2333
|
input2value: function() {
|
2214
2334
|
return this.$input.val();
|
2215
2335
|
},
|
2216
2336
|
|
2217
2337
|
/**
|
2218
2338
|
Activates input. For text it sets focus.
|
2219
|
-
|
2339
|
+
|
2220
2340
|
@method activate()
|
2221
|
-
**/
|
2341
|
+
**/
|
2222
2342
|
activate: function() {
|
2223
2343
|
if(this.$input.is(':visible')) {
|
2224
2344
|
this.$input.focus();
|
2225
2345
|
}
|
2226
2346
|
},
|
2227
|
-
|
2347
|
+
|
2228
2348
|
/**
|
2229
2349
|
Creates input.
|
2230
|
-
|
2350
|
+
|
2231
2351
|
@method clear()
|
2232
2352
|
**/
|
2233
2353
|
clear: function() {
|
2234
2354
|
this.$input.val(null);
|
2235
2355
|
},
|
2236
|
-
|
2356
|
+
|
2237
2357
|
/**
|
2238
2358
|
method to escape html.
|
2239
2359
|
**/
|
@@ -2243,18 +2363,24 @@ To create your own input you can inherit from this class.
|
|
2243
2363
|
|
2244
2364
|
/**
|
2245
2365
|
attach handler to automatically submit form when value changed (useful when buttons not shown)
|
2246
|
-
**/
|
2366
|
+
**/
|
2247
2367
|
autosubmit: function() {
|
2248
2368
|
|
2249
2369
|
},
|
2250
2370
|
|
2371
|
+
/**
|
2372
|
+
Additional actions when destroying element
|
2373
|
+
**/
|
2374
|
+
destroy: function() {
|
2375
|
+
},
|
2376
|
+
|
2251
2377
|
// -------- helper functions --------
|
2252
2378
|
setClass: function() {
|
2253
2379
|
if(this.options.inputclass) {
|
2254
2380
|
this.$input.addClass(this.options.inputclass);
|
2255
2381
|
}
|
2256
2382
|
},
|
2257
|
-
|
2383
|
+
|
2258
2384
|
setAttr: function(attr) {
|
2259
2385
|
if (this.options[attr] !== undefined && this.options[attr] !== null) {
|
2260
2386
|
this.$input.attr(attr, this.options[attr]);
|
@@ -2356,30 +2482,33 @@ List - abstract class for inputs that have source option loaded from js array or
|
|
2356
2482
|
// ------------- additional functions ------------
|
2357
2483
|
|
2358
2484
|
onSourceReady: function (success, error) {
|
2485
|
+
//run source if it function
|
2486
|
+
var source;
|
2487
|
+
if ($.isFunction(this.options.source)) {
|
2488
|
+
source = this.options.source.call(this.options.scope);
|
2489
|
+
this.sourceData = null;
|
2490
|
+
//note: if function returns the same source as URL - sourceData will be taken from cahce and no extra request performed
|
2491
|
+
} else {
|
2492
|
+
source = this.options.source;
|
2493
|
+
}
|
2494
|
+
|
2359
2495
|
//if allready loaded just call success
|
2360
|
-
if($.isArray(this.sourceData)) {
|
2496
|
+
if(this.options.sourceCache && $.isArray(this.sourceData)) {
|
2361
2497
|
success.call(this);
|
2362
2498
|
return;
|
2363
2499
|
}
|
2364
2500
|
|
2365
|
-
//
|
2501
|
+
//try parse json in single quotes (for double quotes jquery does automatically)
|
2366
2502
|
try {
|
2367
|
-
|
2503
|
+
source = $.fn.editableutils.tryParseJson(source, false);
|
2368
2504
|
} catch (e) {
|
2369
2505
|
error.call(this);
|
2370
2506
|
return;
|
2371
2507
|
}
|
2372
|
-
|
2373
|
-
var source = this.options.source;
|
2374
|
-
|
2375
|
-
//run source if it function
|
2376
|
-
if ($.isFunction(source)) {
|
2377
|
-
source = source.call(this.options.scope);
|
2378
|
-
}
|
2379
2508
|
|
2380
2509
|
//loading from url
|
2381
2510
|
if (typeof source === 'string') {
|
2382
|
-
//try to get from cache
|
2511
|
+
//try to get sourceData from cache
|
2383
2512
|
if(this.options.sourceCache) {
|
2384
2513
|
var cacheID = source,
|
2385
2514
|
cache;
|
@@ -3299,25 +3428,29 @@ Range (inherit from number)
|
|
3299
3428
|
}(window.jQuery));
|
3300
3429
|
/**
|
3301
3430
|
Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
|
3302
|
-
Please see [original docs](http://ivaynberg.github.com/select2) for detailed description and options.
|
3303
|
-
|
3431
|
+
Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options.
|
3432
|
+
Compatible **select2 version is 3.4.1**!
|
3433
|
+
You should manually download and include select2 distributive:
|
3304
3434
|
|
3305
3435
|
<link href="select2/select2.css" rel="stylesheet" type="text/css"></link>
|
3306
3436
|
<script src="select2/select2.js"></script>
|
3307
3437
|
|
3308
|
-
|
3438
|
+
To make it **bootstrap-styled** you can use css from [here](https://github.com/t0m/select2-bootstrap-css):
|
3309
3439
|
|
3310
3440
|
<link href="select2-bootstrap.css" rel="stylesheet" type="text/css"></link>
|
3311
3441
|
|
3312
|
-
**Note:** currently `
|
3313
|
-
|
3442
|
+
**Note:** currently `autotext` feature does not work for select2 with `ajax` remote source.
|
3443
|
+
You need initially put both `data-value` and element's text youself:
|
3444
|
+
|
3445
|
+
<a href="#" data-type="select2" data-value="1">Text1</a>
|
3446
|
+
|
3314
3447
|
|
3315
3448
|
@class select2
|
3316
3449
|
@extends abstractinput
|
3317
3450
|
@since 1.4.1
|
3318
3451
|
@final
|
3319
3452
|
@example
|
3320
|
-
<a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-
|
3453
|
+
<a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a>
|
3321
3454
|
<script>
|
3322
3455
|
$(function(){
|
3323
3456
|
$('#country').editable({
|
@@ -3338,56 +3471,47 @@ $(function(){
|
|
3338
3471
|
|
3339
3472
|
var Constructor = function (options) {
|
3340
3473
|
this.init('select2', options, Constructor.defaults);
|
3341
|
-
|
3474
|
+
|
3342
3475
|
options.select2 = options.select2 || {};
|
3476
|
+
|
3477
|
+
this.sourceData = null;
|
3343
3478
|
|
3344
|
-
|
3345
|
-
|
3346
|
-
|
3347
|
-
|
3348
|
-
|
3349
|
-
//detect whether it is multi-valued
|
3350
|
-
this.isMultiple = options.select2.tags || options.select2.multiple;
|
3479
|
+
//placeholder
|
3480
|
+
if(options.placeholder) {
|
3481
|
+
options.select2.placeholder = options.placeholder;
|
3482
|
+
}
|
3351
3483
|
|
3352
|
-
|
3353
|
-
|
3354
|
-
|
3355
|
-
|
3356
|
-
|
3484
|
+
//if not `tags` mode, use source
|
3485
|
+
if(!options.select2.tags && options.source) {
|
3486
|
+
var source = options.source;
|
3487
|
+
//if source is function, call it (once!)
|
3488
|
+
if ($.isFunction(options.source)) {
|
3489
|
+
source = options.source.call(options.scope);
|
3490
|
+
}
|
3357
3491
|
|
3358
|
-
|
3359
|
-
|
3360
|
-
//
|
3361
|
-
|
3362
|
-
|
3363
|
-
console.log('attached');
|
3364
|
-
var original = $(element).data('select2').postprocessResults;
|
3365
|
-
console.log(original);
|
3366
|
-
$(element).data('select2').postprocessResults = function(data, initial) {
|
3367
|
-
console.log('postprocess');
|
3368
|
-
// this.element.triggerHandler('loaded', [data]);
|
3369
|
-
original.apply(this, arguments);
|
3370
|
-
}
|
3371
|
-
|
3372
|
-
// $(element).on('loaded', function(){console.log('loaded');});
|
3373
|
-
$(element).data('select2').updateResults(true);
|
3492
|
+
if (typeof source === 'string') {
|
3493
|
+
options.select2.ajax = options.select2.ajax || {};
|
3494
|
+
//some default ajax params
|
3495
|
+
if(!options.select2.ajax.data) {
|
3496
|
+
options.select2.ajax.data = function(term) {return { query:term };};
|
3374
3497
|
}
|
3375
|
-
|
3376
|
-
|
3377
|
-
var val = that.str2value(element.val()),
|
3378
|
-
data = $.fn.editableutils.itemsByValue(val, mixin.data, 'id');
|
3379
|
-
|
3380
|
-
//for single-valued mode should not use array. Take first element instead.
|
3381
|
-
if($.isArray(data) && data.length && !that.isMultiple) {
|
3382
|
-
data = data[0];
|
3498
|
+
if(!options.select2.ajax.results) {
|
3499
|
+
options.select2.ajax.results = function(data) { return {results:data };};
|
3383
3500
|
}
|
3384
|
-
|
3385
|
-
|
3386
|
-
|
3387
|
-
|
3501
|
+
options.select2.ajax.url = source;
|
3502
|
+
} else {
|
3503
|
+
//check format and convert x-editable format to select2 format (if needed)
|
3504
|
+
this.sourceData = this.convertSource(source);
|
3505
|
+
options.select2.data = this.sourceData;
|
3506
|
+
}
|
3507
|
+
}
|
3388
3508
|
|
3389
3509
|
//overriding objects in config (as by default jQuery extend() is not recursive)
|
3390
|
-
this.options.select2 = $.extend({}, Constructor.defaults.select2,
|
3510
|
+
this.options.select2 = $.extend({}, Constructor.defaults.select2, options.select2);
|
3511
|
+
|
3512
|
+
//detect whether it is multi-valued
|
3513
|
+
this.isMultiple = this.options.select2.tags || this.options.select2.multiple;
|
3514
|
+
this.isRemote = ('ajax' in this.options.select2);
|
3391
3515
|
};
|
3392
3516
|
|
3393
3517
|
$.fn.editableutils.inherit(Constructor, $.fn.editabletypes.abstractinput);
|
@@ -3395,21 +3519,17 @@ $(function(){
|
|
3395
3519
|
$.extend(Constructor.prototype, {
|
3396
3520
|
render: function() {
|
3397
3521
|
this.setClass();
|
3522
|
+
|
3398
3523
|
//apply select2
|
3399
3524
|
this.$input.select2(this.options.select2);
|
3400
3525
|
|
3401
|
-
//when data is loaded via ajax, we need to know when it's done
|
3402
|
-
if(
|
3403
|
-
|
3404
|
-
|
3405
|
-
|
3406
|
-
|
3407
|
-
this.element.triggerHandler('loaded', [data]);
|
3408
|
-
original.apply(this, arguments);
|
3409
|
-
}
|
3410
|
-
*/
|
3526
|
+
//when data is loaded via ajax, we need to know when it's done to populate listData
|
3527
|
+
if(this.isRemote) {
|
3528
|
+
//listen to loaded event to populate data
|
3529
|
+
this.$input.on('select2-loaded', $.proxy(function(e) {
|
3530
|
+
this.sourceData = e.items.results;
|
3531
|
+
}, this));
|
3411
3532
|
}
|
3412
|
-
|
3413
3533
|
|
3414
3534
|
//trigger resize of editableform to re-position container in multi-valued mode
|
3415
3535
|
if(this.isMultiple) {
|
@@ -3421,20 +3541,16 @@ $(function(){
|
|
3421
3541
|
|
3422
3542
|
value2html: function(value, element) {
|
3423
3543
|
var text = '', data;
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3427
|
-
|
3428
|
-
|
3429
|
-
|
3430
|
-
|
3431
|
-
} else if(this.options.select2.data) {
|
3432
|
-
data = $.fn.editableutils.itemsByValue(value, this.options.select2.data, 'id');
|
3433
|
-
} else {
|
3434
|
-
//if('ajax' in this.options.select2) {
|
3435
|
-
}
|
3544
|
+
|
3545
|
+
if(this.options.select2.tags) { //in tags mode just assign value
|
3546
|
+
data = value;
|
3547
|
+
} else if(this.sourceData) {
|
3548
|
+
data = $.fn.editableutils.itemsByValue(value, this.sourceData, 'id');
|
3549
|
+
} else {
|
3550
|
+
//can not get list of possible values (e.g. autotext for select2 with ajax source)
|
3436
3551
|
}
|
3437
3552
|
|
3553
|
+
//data may be array (when multiple values allowed)
|
3438
3554
|
if($.isArray(data)) {
|
3439
3555
|
//collect selected data and show with separator
|
3440
3556
|
text = [];
|
@@ -3455,7 +3571,26 @@ $(function(){
|
|
3455
3571
|
},
|
3456
3572
|
|
3457
3573
|
value2input: function(value) {
|
3458
|
-
|
3574
|
+
//for remote source .val() is not working, need to look in sourceData
|
3575
|
+
if(this.isRemote) {
|
3576
|
+
//todo: check value for array
|
3577
|
+
var item, items;
|
3578
|
+
//if sourceData loaded, use it to get text for display
|
3579
|
+
if(this.sourceData) {
|
3580
|
+
items = $.fn.editableutils.itemsByValue(value, this.sourceData, 'id');
|
3581
|
+
if(items.length) {
|
3582
|
+
item = items[0];
|
3583
|
+
}
|
3584
|
+
}
|
3585
|
+
//if item not found by sourceData, use element text (e.g. for the first show)
|
3586
|
+
if(!item) {
|
3587
|
+
item = {id: value, text: $(this.options.scope).text()};
|
3588
|
+
}
|
3589
|
+
//select2('data', ...) allows to set both id and text --> usefull for initial show when items are not loaded
|
3590
|
+
this.$input.select2('data', item).trigger('change', true); //second argument needed to separate initial change from user's click (for autosubmit)
|
3591
|
+
} else {
|
3592
|
+
this.$input.val(value).trigger('change', true); //second argument needed to separate initial change from user's click (for autosubmit)
|
3593
|
+
}
|
3459
3594
|
},
|
3460
3595
|
|
3461
3596
|
input2value: function() {
|
@@ -3488,6 +3623,22 @@ $(function(){
|
|
3488
3623
|
$(this).closest('form').submit();
|
3489
3624
|
}
|
3490
3625
|
});
|
3626
|
+
},
|
3627
|
+
|
3628
|
+
/*
|
3629
|
+
Converts source from x-editable format: {value: 1, text: "1"} to
|
3630
|
+
select2 format: {id: 1, text: "1"}
|
3631
|
+
*/
|
3632
|
+
convertSource: function(source) {
|
3633
|
+
if($.isArray(source) && source.length && source[0].value !== undefined) {
|
3634
|
+
for(var i = 0; i<source.length; i++) {
|
3635
|
+
if(source[i].value !== undefined) {
|
3636
|
+
source[i].id = source[i].value;
|
3637
|
+
delete source[i].value;
|
3638
|
+
}
|
3639
|
+
}
|
3640
|
+
}
|
3641
|
+
return source;
|
3491
3642
|
}
|
3492
3643
|
|
3493
3644
|
});
|
@@ -3539,12 +3690,22 @@ $(function(){
|
|
3539
3690
|
}(window.jQuery));
|
3540
3691
|
|
3541
3692
|
/**
|
3542
|
-
* Combodate - 1.0.
|
3693
|
+
* Combodate - 1.0.4
|
3543
3694
|
* Dropdown date and time picker.
|
3544
3695
|
* Converts text input into dropdowns to pick day, month, year, hour, minute and second.
|
3545
3696
|
* Uses momentjs as datetime library http://momentjs.com.
|
3546
3697
|
* For i18n include corresponding file from https://github.com/timrwood/moment/tree/master/lang
|
3547
3698
|
*
|
3699
|
+
* Confusion at noon and midnight - see http://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight
|
3700
|
+
* In combodate:
|
3701
|
+
* 12:00 pm --> 12:00 (24-h format, midday)
|
3702
|
+
* 12:00 am --> 00:00 (24-h format, midnight, start of day)
|
3703
|
+
*
|
3704
|
+
* Differs from momentjs parse rules:
|
3705
|
+
* 00:00 pm, 12:00 pm --> 12:00 (24-h format, day not change)
|
3706
|
+
* 00:00 am, 12:00 am --> 00:00 (24-h format, day not change)
|
3707
|
+
*
|
3708
|
+
*
|
3548
3709
|
* Author: Vitaliy Potapov
|
3549
3710
|
* Project page: http://github.com/vitalets/combodate
|
3550
3711
|
* Copyright (c) 2012 Vitaliy Potapov. Released under MIT License.
|
@@ -3694,9 +3855,10 @@ $(function(){
|
|
3694
3855
|
|
3695
3856
|
for(i=0; i<=11; i++) {
|
3696
3857
|
if(longNames) {
|
3697
|
-
|
3858
|
+
//see https://github.com/timrwood/momentjs.com/pull/36
|
3859
|
+
name = moment().date(1).month(i).format('MMMM');
|
3698
3860
|
} else if(shortNames) {
|
3699
|
-
name = moment().month(i).format('MMM');
|
3861
|
+
name = moment().date(1).month(i).format('MMM');
|
3700
3862
|
} else if(twoDigit) {
|
3701
3863
|
name = this.leadZero(i+1);
|
3702
3864
|
} else {
|
@@ -3732,9 +3894,10 @@ $(function(){
|
|
3732
3894
|
h12 = this.options.template.indexOf('h') !== -1,
|
3733
3895
|
h24 = this.options.template.indexOf('H') !== -1,
|
3734
3896
|
twoDigit = this.options.template.toLowerCase().indexOf('hh') !== -1,
|
3897
|
+
min = h12 ? 1 : 0,
|
3735
3898
|
max = h12 ? 12 : 23;
|
3736
3899
|
|
3737
|
-
for(i=
|
3900
|
+
for(i=min; i<=max; i++) {
|
3738
3901
|
name = twoDigit ? this.leadZero(i) : i;
|
3739
3902
|
items.push([i, name]);
|
3740
3903
|
}
|
@@ -3783,7 +3946,7 @@ $(function(){
|
|
3783
3946
|
},
|
3784
3947
|
|
3785
3948
|
/*
|
3786
|
-
Returns current date value.
|
3949
|
+
Returns current date value from combos.
|
3787
3950
|
If format not specified - `options.format` used.
|
3788
3951
|
If format = `null` - Moment object returned.
|
3789
3952
|
*/
|
@@ -3812,12 +3975,14 @@ $(function(){
|
|
3812
3975
|
return '';
|
3813
3976
|
}
|
3814
3977
|
|
3815
|
-
//convert hours
|
3978
|
+
//convert hours 12h --> 24h
|
3816
3979
|
if(this.$ampm) {
|
3817
|
-
|
3818
|
-
|
3819
|
-
|
3820
|
-
|
3980
|
+
//12:00 pm --> 12:00 (24-h format, midday), 12:00 am --> 00:00 (24-h format, midnight, start of day)
|
3981
|
+
if(values.hour === 12) {
|
3982
|
+
values.hour = this.$ampm.val() === 'am' ? 0 : 12;
|
3983
|
+
} else {
|
3984
|
+
values.hour = this.$ampm.val() === 'am' ? values.hour : values.hour+12;
|
3985
|
+
}
|
3821
3986
|
}
|
3822
3987
|
|
3823
3988
|
dt = moment([values.year, values.month, values.day, values.hour, values.minute, values.second]);
|
@@ -3868,11 +4033,17 @@ $(function(){
|
|
3868
4033
|
});
|
3869
4034
|
|
3870
4035
|
if(this.$ampm) {
|
3871
|
-
|
3872
|
-
|
4036
|
+
//12:00 pm --> 12:00 (24-h format, midday), 12:00 am --> 00:00 (24-h format, midnight, start of day)
|
4037
|
+
if(values.hour >= 12) {
|
3873
4038
|
values.ampm = 'pm';
|
4039
|
+
if(values.hour > 12) {
|
4040
|
+
values.hour -= 12;
|
4041
|
+
}
|
3874
4042
|
} else {
|
3875
|
-
values.ampm = 'am';
|
4043
|
+
values.ampm = 'am';
|
4044
|
+
if(values.hour === 0) {
|
4045
|
+
values.hour = 12;
|
4046
|
+
}
|
3876
4047
|
}
|
3877
4048
|
}
|
3878
4049
|
|
@@ -4244,7 +4415,7 @@ Editableform based on Twitter Bootstrap
|
|
4244
4415
|
*/
|
4245
4416
|
/*jshint laxcomma: true*/
|
4246
4417
|
setPosition: function () {
|
4247
|
-
|
4418
|
+
|
4248
4419
|
(function() {
|
4249
4420
|
var $tip = this.tip()
|
4250
4421
|
, inside
|
@@ -4298,309 +4469,27 @@ Editableform based on Twitter Bootstrap
|
|
4298
4469
|
});
|
4299
4470
|
|
4300
4471
|
}(window.jQuery));
|
4301
|
-
|
4302
|
-
|
4303
|
-
|
4304
|
-
|
4305
|
-
|
4306
|
-
|
4307
|
-
|
4308
|
-
|
4309
|
-
|
4310
|
-
|
4311
|
-
|
4312
|
-
|
4313
|
-
|
4314
|
-
|
4315
|
-
|
4316
|
-
|
4317
|
-
|
4318
|
-
|
4319
|
-
|
4320
|
-
}
|
4321
|
-
}
|
4322
|
-
});
|
4323
|
-
});
|
4324
|
-
</script>
|
4325
|
-
**/
|
4326
|
-
(function ($) {
|
4327
|
-
"use strict";
|
4328
|
-
|
4329
|
-
var Date = function (options) {
|
4330
|
-
this.init('date', options, Date.defaults);
|
4331
|
-
this.initPicker(options, Date.defaults);
|
4332
|
-
};
|
4472
|
+
/* =========================================================
|
4473
|
+
* bootstrap-datepicker.js
|
4474
|
+
* http://www.eyecon.ro/bootstrap-datepicker
|
4475
|
+
* =========================================================
|
4476
|
+
* Copyright 2012 Stefan Petre
|
4477
|
+
* Improvements by Andrew Rowls
|
4478
|
+
*
|
4479
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
4480
|
+
* you may not use this file except in compliance with the License.
|
4481
|
+
* You may obtain a copy of the License at
|
4482
|
+
*
|
4483
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
4484
|
+
*
|
4485
|
+
* Unless required by applicable law or agreed to in writing, software
|
4486
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
4487
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
4488
|
+
* See the License for the specific language governing permissions and
|
4489
|
+
* limitations under the License.
|
4490
|
+
* ========================================================= */
|
4333
4491
|
|
4334
|
-
|
4335
|
-
|
4336
|
-
$.extend(Date.prototype, {
|
4337
|
-
initPicker: function(options, defaults) {
|
4338
|
-
//'format' is set directly from settings or data-* attributes
|
4339
|
-
|
4340
|
-
//by default viewformat equals to format
|
4341
|
-
if(!this.options.viewformat) {
|
4342
|
-
this.options.viewformat = this.options.format;
|
4343
|
-
}
|
4344
|
-
|
4345
|
-
//overriding datepicker config (as by default jQuery extend() is not recursive)
|
4346
|
-
//since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
|
4347
|
-
this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, {
|
4348
|
-
format: this.options.viewformat
|
4349
|
-
});
|
4350
|
-
|
4351
|
-
//language
|
4352
|
-
this.options.datepicker.language = this.options.datepicker.language || 'en';
|
4353
|
-
|
4354
|
-
//store DPglobal
|
4355
|
-
this.dpg = $.fn.datepicker.DPGlobal;
|
4356
|
-
|
4357
|
-
//store parsed formats
|
4358
|
-
this.parsedFormat = this.dpg.parseFormat(this.options.format);
|
4359
|
-
this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
|
4360
|
-
},
|
4361
|
-
|
4362
|
-
render: function () {
|
4363
|
-
this.$input.datepicker(this.options.datepicker);
|
4364
|
-
|
4365
|
-
//"clear" link
|
4366
|
-
if(this.options.clear) {
|
4367
|
-
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
|
4368
|
-
e.preventDefault();
|
4369
|
-
e.stopPropagation();
|
4370
|
-
this.clear();
|
4371
|
-
}, this));
|
4372
|
-
|
4373
|
-
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
|
4374
|
-
}
|
4375
|
-
},
|
4376
|
-
|
4377
|
-
value2html: function(value, element) {
|
4378
|
-
var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '';
|
4379
|
-
Date.superclass.value2html(text, element);
|
4380
|
-
},
|
4381
|
-
|
4382
|
-
html2value: function(html) {
|
4383
|
-
return html ? this.dpg.parseDate(html, this.parsedViewFormat, this.options.datepicker.language) : null;
|
4384
|
-
},
|
4385
|
-
|
4386
|
-
value2str: function(value) {
|
4387
|
-
return value ? this.dpg.formatDate(value, this.parsedFormat, this.options.datepicker.language) : '';
|
4388
|
-
},
|
4389
|
-
|
4390
|
-
str2value: function(str) {
|
4391
|
-
return str ? this.dpg.parseDate(str, this.parsedFormat, this.options.datepicker.language) : null;
|
4392
|
-
},
|
4393
|
-
|
4394
|
-
value2submit: function(value) {
|
4395
|
-
return this.value2str(value);
|
4396
|
-
},
|
4397
|
-
|
4398
|
-
value2input: function(value) {
|
4399
|
-
this.$input.datepicker('update', value);
|
4400
|
-
},
|
4401
|
-
|
4402
|
-
input2value: function() {
|
4403
|
-
return this.$input.data('datepicker').date;
|
4404
|
-
},
|
4405
|
-
|
4406
|
-
activate: function() {
|
4407
|
-
},
|
4408
|
-
|
4409
|
-
clear: function() {
|
4410
|
-
this.$input.data('datepicker').date = null;
|
4411
|
-
this.$input.find('.active').removeClass('active');
|
4412
|
-
if(!this.options.showbuttons) {
|
4413
|
-
this.$input.closest('form').submit();
|
4414
|
-
}
|
4415
|
-
},
|
4416
|
-
|
4417
|
-
autosubmit: function() {
|
4418
|
-
this.$input.on('mouseup', '.day', function(e){
|
4419
|
-
if($(e.currentTarget).is('.old') || $(e.currentTarget).is('.new')) {
|
4420
|
-
return;
|
4421
|
-
}
|
4422
|
-
var $form = $(this).closest('form');
|
4423
|
-
setTimeout(function() {
|
4424
|
-
$form.submit();
|
4425
|
-
}, 200);
|
4426
|
-
});
|
4427
|
-
//changedate is not suitable as it triggered when showing datepicker. see #149
|
4428
|
-
/*
|
4429
|
-
this.$input.on('changeDate', function(e){
|
4430
|
-
var $form = $(this).closest('form');
|
4431
|
-
setTimeout(function() {
|
4432
|
-
$form.submit();
|
4433
|
-
}, 200);
|
4434
|
-
});
|
4435
|
-
*/
|
4436
|
-
}
|
4437
|
-
|
4438
|
-
});
|
4439
|
-
|
4440
|
-
Date.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
4441
|
-
/**
|
4442
|
-
@property tpl
|
4443
|
-
@default <div></div>
|
4444
|
-
**/
|
4445
|
-
tpl:'<div class="editable-date well"></div>',
|
4446
|
-
/**
|
4447
|
-
@property inputclass
|
4448
|
-
@default null
|
4449
|
-
**/
|
4450
|
-
inputclass: null,
|
4451
|
-
/**
|
4452
|
-
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
|
4453
|
-
Possible tokens are: <code>d, dd, m, mm, yy, yyyy</code>
|
4454
|
-
|
4455
|
-
@property format
|
4456
|
-
@type string
|
4457
|
-
@default yyyy-mm-dd
|
4458
|
-
**/
|
4459
|
-
format:'yyyy-mm-dd',
|
4460
|
-
/**
|
4461
|
-
Format used for displaying date. Also applied when converting date from element's text on init.
|
4462
|
-
If not specified equals to <code>format</code>
|
4463
|
-
|
4464
|
-
@property viewformat
|
4465
|
-
@type string
|
4466
|
-
@default null
|
4467
|
-
**/
|
4468
|
-
viewformat: null,
|
4469
|
-
/**
|
4470
|
-
Configuration of datepicker.
|
4471
|
-
Full list of options: http://vitalets.github.com/bootstrap-datepicker
|
4472
|
-
|
4473
|
-
@property datepicker
|
4474
|
-
@type object
|
4475
|
-
@default {
|
4476
|
-
weekStart: 0,
|
4477
|
-
startView: 0,
|
4478
|
-
minViewMode: 0,
|
4479
|
-
autoclose: false
|
4480
|
-
}
|
4481
|
-
**/
|
4482
|
-
datepicker:{
|
4483
|
-
weekStart: 0,
|
4484
|
-
startView: 0,
|
4485
|
-
minViewMode: 0,
|
4486
|
-
autoclose: false
|
4487
|
-
},
|
4488
|
-
/**
|
4489
|
-
Text shown as clear date button.
|
4490
|
-
If <code>false</code> clear button will not be rendered.
|
4491
|
-
|
4492
|
-
@property clear
|
4493
|
-
@type boolean|string
|
4494
|
-
@default 'x clear'
|
4495
|
-
**/
|
4496
|
-
clear: '× clear'
|
4497
|
-
});
|
4498
|
-
|
4499
|
-
$.fn.editabletypes.date = Date;
|
4500
|
-
|
4501
|
-
}(window.jQuery));
|
4502
|
-
|
4503
|
-
/**
|
4504
|
-
Bootstrap datefield input - modification for inline mode.
|
4505
|
-
Shows normal <input type="text"> and binds popup datepicker.
|
4506
|
-
Automatically shown in inline mode.
|
4507
|
-
|
4508
|
-
@class datefield
|
4509
|
-
@extends date
|
4510
|
-
|
4511
|
-
@since 1.4.0
|
4512
|
-
**/
|
4513
|
-
(function ($) {
|
4514
|
-
"use strict";
|
4515
|
-
|
4516
|
-
var DateField = function (options) {
|
4517
|
-
this.init('datefield', options, DateField.defaults);
|
4518
|
-
this.initPicker(options, DateField.defaults);
|
4519
|
-
};
|
4520
|
-
|
4521
|
-
$.fn.editableutils.inherit(DateField, $.fn.editabletypes.date);
|
4522
|
-
|
4523
|
-
$.extend(DateField.prototype, {
|
4524
|
-
render: function () {
|
4525
|
-
this.$input = this.$tpl.find('input');
|
4526
|
-
this.setClass();
|
4527
|
-
this.setAttr('placeholder');
|
4528
|
-
|
4529
|
-
this.$tpl.datepicker(this.options.datepicker);
|
4530
|
-
|
4531
|
-
//need to disable original event handlers
|
4532
|
-
this.$input.off('focus keydown');
|
4533
|
-
|
4534
|
-
//update value of datepicker
|
4535
|
-
this.$input.keyup($.proxy(function(){
|
4536
|
-
this.$tpl.removeData('date');
|
4537
|
-
this.$tpl.datepicker('update');
|
4538
|
-
}, this));
|
4539
|
-
|
4540
|
-
},
|
4541
|
-
|
4542
|
-
value2input: function(value) {
|
4543
|
-
this.$input.val(value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '');
|
4544
|
-
this.$tpl.datepicker('update');
|
4545
|
-
},
|
4546
|
-
|
4547
|
-
input2value: function() {
|
4548
|
-
return this.html2value(this.$input.val());
|
4549
|
-
},
|
4550
|
-
|
4551
|
-
activate: function() {
|
4552
|
-
$.fn.editabletypes.text.prototype.activate.call(this);
|
4553
|
-
},
|
4554
|
-
|
4555
|
-
autosubmit: function() {
|
4556
|
-
//reset autosubmit to empty
|
4557
|
-
}
|
4558
|
-
});
|
4559
|
-
|
4560
|
-
DateField.defaults = $.extend({}, $.fn.editabletypes.date.defaults, {
|
4561
|
-
/**
|
4562
|
-
@property tpl
|
4563
|
-
**/
|
4564
|
-
tpl:'<div class="input-append date"><input type="text"/><span class="add-on"><i class="icon-th"></i></span></div>',
|
4565
|
-
/**
|
4566
|
-
@property inputclass
|
4567
|
-
@default 'input-small'
|
4568
|
-
**/
|
4569
|
-
inputclass: 'input-small',
|
4570
|
-
|
4571
|
-
/* datepicker config */
|
4572
|
-
datepicker: {
|
4573
|
-
weekStart: 0,
|
4574
|
-
startView: 0,
|
4575
|
-
minViewMode: 0,
|
4576
|
-
autoclose: true
|
4577
|
-
}
|
4578
|
-
});
|
4579
|
-
|
4580
|
-
$.fn.editabletypes.datefield = DateField;
|
4581
|
-
|
4582
|
-
}(window.jQuery));
|
4583
|
-
/* =========================================================
|
4584
|
-
* bootstrap-datepicker.js
|
4585
|
-
* http://www.eyecon.ro/bootstrap-datepicker
|
4586
|
-
* =========================================================
|
4587
|
-
* Copyright 2012 Stefan Petre
|
4588
|
-
* Improvements by Andrew Rowls
|
4589
|
-
*
|
4590
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
4591
|
-
* you may not use this file except in compliance with the License.
|
4592
|
-
* You may obtain a copy of the License at
|
4593
|
-
*
|
4594
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
4595
|
-
*
|
4596
|
-
* Unless required by applicable law or agreed to in writing, software
|
4597
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
4598
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
4599
|
-
* See the License for the specific language governing permissions and
|
4600
|
-
* limitations under the License.
|
4601
|
-
* ========================================================= */
|
4602
|
-
|
4603
|
-
!function( $ ) {
|
4492
|
+
(function( $ ) {
|
4604
4493
|
|
4605
4494
|
function UTCDate(){
|
4606
4495
|
return new Date(Date.UTC.apply(Date, arguments));
|
@@ -4615,12 +4504,9 @@ Automatically shown in inline mode.
|
|
4615
4504
|
var Datepicker = function(element, options) {
|
4616
4505
|
var that = this;
|
4617
4506
|
|
4507
|
+
this._process_options(options);
|
4508
|
+
|
4618
4509
|
this.element = $(element);
|
4619
|
-
this.language = options.language||this.element.data('date-language')||"en";
|
4620
|
-
this.language = this.language in dates ? this.language : this.language.split('-')[0]; //Check if "de-DE" style date is available, if not language should fallback to 2 letter code eg "de"
|
4621
|
-
this.language = this.language in dates ? this.language : "en";
|
4622
|
-
this.isRTL = dates[this.language].rtl||false;
|
4623
|
-
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||dates[this.language].format||'mm/dd/yyyy');
|
4624
4510
|
this.isInline = false;
|
4625
4511
|
this.isInput = this.element.is('input');
|
4626
4512
|
this.component = this.element.is('.date') ? this.element.find('.add-on, .btn') : false;
|
@@ -4628,13 +4514,6 @@ Automatically shown in inline mode.
|
|
4628
4514
|
if(this.component && this.component.length === 0)
|
4629
4515
|
this.component = false;
|
4630
4516
|
|
4631
|
-
this.forceParse = true;
|
4632
|
-
if ('forceParse' in options) {
|
4633
|
-
this.forceParse = options.forceParse;
|
4634
|
-
} else if ('dateForceParse' in this.element.data()) {
|
4635
|
-
this.forceParse = this.element.data('date-force-parse');
|
4636
|
-
}
|
4637
|
-
|
4638
4517
|
this.picker = $(DPGlobal.template);
|
4639
4518
|
this._buildEvents();
|
4640
4519
|
this._attachEvents();
|
@@ -4644,65 +4523,17 @@ Automatically shown in inline mode.
|
|
4644
4523
|
} else {
|
4645
4524
|
this.picker.addClass('datepicker-dropdown dropdown-menu');
|
4646
4525
|
}
|
4647
|
-
|
4526
|
+
|
4527
|
+
if (this.o.rtl){
|
4648
4528
|
this.picker.addClass('datepicker-rtl');
|
4649
4529
|
this.picker.find('.prev i, .next i')
|
4650
4530
|
.toggleClass('icon-arrow-left icon-arrow-right');
|
4651
4531
|
}
|
4652
4532
|
|
4653
|
-
this.autoclose = false;
|
4654
|
-
if ('autoclose' in options) {
|
4655
|
-
this.autoclose = options.autoclose;
|
4656
|
-
} else if ('dateAutoclose' in this.element.data()) {
|
4657
|
-
this.autoclose = this.element.data('date-autoclose');
|
4658
|
-
}
|
4659
|
-
|
4660
|
-
this.keyboardNavigation = true;
|
4661
|
-
if ('keyboardNavigation' in options) {
|
4662
|
-
this.keyboardNavigation = options.keyboardNavigation;
|
4663
|
-
} else if ('dateKeyboardNavigation' in this.element.data()) {
|
4664
|
-
this.keyboardNavigation = this.element.data('date-keyboard-navigation');
|
4665
|
-
}
|
4666
|
-
|
4667
|
-
this.viewMode = this.startViewMode = 0;
|
4668
|
-
switch(options.startView || this.element.data('date-start-view')){
|
4669
|
-
case 2:
|
4670
|
-
case 'decade':
|
4671
|
-
this.viewMode = this.startViewMode = 2;
|
4672
|
-
break;
|
4673
|
-
case 1:
|
4674
|
-
case 'year':
|
4675
|
-
this.viewMode = this.startViewMode = 1;
|
4676
|
-
break;
|
4677
|
-
}
|
4678
|
-
|
4679
|
-
this.minViewMode = options.minViewMode||this.element.data('date-min-view-mode')||0;
|
4680
|
-
if (typeof this.minViewMode === 'string') {
|
4681
|
-
switch (this.minViewMode) {
|
4682
|
-
case 'months':
|
4683
|
-
this.minViewMode = 1;
|
4684
|
-
break;
|
4685
|
-
case 'years':
|
4686
|
-
this.minViewMode = 2;
|
4687
|
-
break;
|
4688
|
-
default:
|
4689
|
-
this.minViewMode = 0;
|
4690
|
-
break;
|
4691
|
-
}
|
4692
|
-
}
|
4693
|
-
|
4694
|
-
this.viewMode = this.startViewMode = Math.max(this.startViewMode, this.minViewMode);
|
4695
4533
|
|
4696
|
-
this.
|
4697
|
-
this.todayHighlight = (options.todayHighlight||this.element.data('date-today-highlight')||false);
|
4534
|
+
this.viewMode = this.o.startView;
|
4698
4535
|
|
4699
|
-
this.calendarWeeks
|
4700
|
-
if ('calendarWeeks' in options) {
|
4701
|
-
this.calendarWeeks = options.calendarWeeks;
|
4702
|
-
} else if ('dateCalendarWeeks' in this.element.data()) {
|
4703
|
-
this.calendarWeeks = this.element.data('date-calendar-weeks');
|
4704
|
-
}
|
4705
|
-
if (this.calendarWeeks)
|
4536
|
+
if (this.o.calendarWeeks)
|
4706
4537
|
this.picker.find('tfoot th.today')
|
4707
4538
|
.attr('colspan', function(i, val){
|
4708
4539
|
return parseInt(val) + 1;
|
@@ -4710,14 +4541,10 @@ Automatically shown in inline mode.
|
|
4710
4541
|
|
4711
4542
|
this._allow_update = false;
|
4712
4543
|
|
4713
|
-
this.
|
4714
|
-
this.
|
4715
|
-
this.
|
4716
|
-
|
4717
|
-
this.daysOfWeekDisabled = [];
|
4718
|
-
this.setStartDate(options.startDate||this.element.data('date-startdate'));
|
4719
|
-
this.setEndDate(options.endDate||this.element.data('date-enddate'));
|
4720
|
-
this.setDaysOfWeekDisabled(options.daysOfWeekDisabled||this.element.data('date-days-of-week-disabled'));
|
4544
|
+
this.setStartDate(this.o.startDate);
|
4545
|
+
this.setEndDate(this.o.endDate);
|
4546
|
+
this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
|
4547
|
+
|
4721
4548
|
this.fillDow();
|
4722
4549
|
this.fillMonths();
|
4723
4550
|
|
@@ -4734,6 +4561,68 @@ Automatically shown in inline mode.
|
|
4734
4561
|
Datepicker.prototype = {
|
4735
4562
|
constructor: Datepicker,
|
4736
4563
|
|
4564
|
+
_process_options: function(opts){
|
4565
|
+
// Store raw options for reference
|
4566
|
+
this._o = $.extend({}, this._o, opts);
|
4567
|
+
// Processed options
|
4568
|
+
var o = this.o = $.extend({}, this._o);
|
4569
|
+
|
4570
|
+
// Check if "de-DE" style date is available, if not language should
|
4571
|
+
// fallback to 2 letter code eg "de"
|
4572
|
+
var lang = o.language;
|
4573
|
+
if (!dates[lang]) {
|
4574
|
+
lang = lang.split('-')[0];
|
4575
|
+
if (!dates[lang])
|
4576
|
+
lang = defaults.language;
|
4577
|
+
}
|
4578
|
+
o.language = lang;
|
4579
|
+
|
4580
|
+
switch(o.startView){
|
4581
|
+
case 2:
|
4582
|
+
case 'decade':
|
4583
|
+
o.startView = 2;
|
4584
|
+
break;
|
4585
|
+
case 1:
|
4586
|
+
case 'year':
|
4587
|
+
o.startView = 1;
|
4588
|
+
break;
|
4589
|
+
default:
|
4590
|
+
o.startView = 0;
|
4591
|
+
}
|
4592
|
+
|
4593
|
+
switch (o.minViewMode) {
|
4594
|
+
case 1:
|
4595
|
+
case 'months':
|
4596
|
+
o.minViewMode = 1;
|
4597
|
+
break;
|
4598
|
+
case 2:
|
4599
|
+
case 'years':
|
4600
|
+
o.minViewMode = 2;
|
4601
|
+
break;
|
4602
|
+
default:
|
4603
|
+
o.minViewMode = 0;
|
4604
|
+
}
|
4605
|
+
|
4606
|
+
o.startView = Math.max(o.startView, o.minViewMode);
|
4607
|
+
|
4608
|
+
o.weekStart %= 7;
|
4609
|
+
o.weekEnd = ((o.weekStart + 6) % 7);
|
4610
|
+
|
4611
|
+
var format = DPGlobal.parseFormat(o.format)
|
4612
|
+
if (o.startDate !== -Infinity) {
|
4613
|
+
o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
|
4614
|
+
}
|
4615
|
+
if (o.endDate !== Infinity) {
|
4616
|
+
o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
|
4617
|
+
}
|
4618
|
+
|
4619
|
+
o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
|
4620
|
+
if (!$.isArray(o.daysOfWeekDisabled))
|
4621
|
+
o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
|
4622
|
+
o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function (d) {
|
4623
|
+
return parseInt(d, 10);
|
4624
|
+
});
|
4625
|
+
},
|
4737
4626
|
_events: [],
|
4738
4627
|
_secondaryEvents: [],
|
4739
4628
|
_applyEvents: function(evs){
|
@@ -4794,7 +4683,12 @@ Automatically shown in inline mode.
|
|
4794
4683
|
[$(document), {
|
4795
4684
|
mousedown: $.proxy(function (e) {
|
4796
4685
|
// Clicked outside the datepicker, hide it
|
4797
|
-
if (
|
4686
|
+
if (!(
|
4687
|
+
this.element.is(e.target) ||
|
4688
|
+
this.element.find(e.target).size() ||
|
4689
|
+
this.picker.is(e.target) ||
|
4690
|
+
this.picker.find(e.target).size()
|
4691
|
+
)) {
|
4798
4692
|
this.hide();
|
4799
4693
|
}
|
4800
4694
|
}, this)
|
@@ -4815,6 +4709,19 @@ Automatically shown in inline mode.
|
|
4815
4709
|
_detachSecondaryEvents: function(){
|
4816
4710
|
this._unapplyEvents(this._secondaryEvents);
|
4817
4711
|
},
|
4712
|
+
_trigger: function(event, altdate){
|
4713
|
+
var date = altdate || this.date,
|
4714
|
+
local_date = new Date(date.getTime() + (date.getTimezoneOffset()*60000));
|
4715
|
+
|
4716
|
+
this.element.trigger({
|
4717
|
+
type: event,
|
4718
|
+
date: local_date,
|
4719
|
+
format: $.proxy(function(altformat){
|
4720
|
+
var format = altformat || this.o.format;
|
4721
|
+
return DPGlobal.formatDate(date, format, this.o.language);
|
4722
|
+
}, this)
|
4723
|
+
});
|
4724
|
+
},
|
4818
4725
|
|
4819
4726
|
show: function(e) {
|
4820
4727
|
if (!this.isInline)
|
@@ -4826,10 +4733,7 @@ Automatically shown in inline mode.
|
|
4826
4733
|
if (e) {
|
4827
4734
|
e.preventDefault();
|
4828
4735
|
}
|
4829
|
-
this.
|
4830
|
-
type: 'show',
|
4831
|
-
date: this.date
|
4832
|
-
});
|
4736
|
+
this._trigger('show');
|
4833
4737
|
},
|
4834
4738
|
|
4835
4739
|
hide: function(e){
|
@@ -4837,21 +4741,18 @@ Automatically shown in inline mode.
|
|
4837
4741
|
if (!this.picker.is(':visible')) return;
|
4838
4742
|
this.picker.hide().detach();
|
4839
4743
|
this._detachSecondaryEvents();
|
4840
|
-
this.viewMode = this.
|
4744
|
+
this.viewMode = this.o.startView;
|
4841
4745
|
this.showMode();
|
4842
4746
|
|
4843
4747
|
if (
|
4844
|
-
this.forceParse &&
|
4748
|
+
this.o.forceParse &&
|
4845
4749
|
(
|
4846
4750
|
this.isInput && this.element.val() ||
|
4847
4751
|
this.hasInput && this.element.find('input').val()
|
4848
4752
|
)
|
4849
4753
|
)
|
4850
4754
|
this.setValue();
|
4851
|
-
this.
|
4852
|
-
type: 'hide',
|
4853
|
-
date: this.date
|
4854
|
-
});
|
4755
|
+
this._trigger('hide');
|
4855
4756
|
},
|
4856
4757
|
|
4857
4758
|
remove: function() {
|
@@ -4889,7 +4790,6 @@ Automatically shown in inline mode.
|
|
4889
4790
|
if (this.component){
|
4890
4791
|
this.element.find('input').val(formatted);
|
4891
4792
|
}
|
4892
|
-
this.element.data('date', formatted);
|
4893
4793
|
} else {
|
4894
4794
|
this.element.val(formatted);
|
4895
4795
|
}
|
@@ -4897,36 +4797,24 @@ Automatically shown in inline mode.
|
|
4897
4797
|
|
4898
4798
|
getFormattedDate: function(format) {
|
4899
4799
|
if (format === undefined)
|
4900
|
-
format = this.format;
|
4901
|
-
return DPGlobal.formatDate(this.date, format, this.language);
|
4800
|
+
format = this.o.format;
|
4801
|
+
return DPGlobal.formatDate(this.date, format, this.o.language);
|
4902
4802
|
},
|
4903
4803
|
|
4904
4804
|
setStartDate: function(startDate){
|
4905
|
-
this.startDate
|
4906
|
-
if (this.startDate !== -Infinity) {
|
4907
|
-
this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language);
|
4908
|
-
}
|
4805
|
+
this._process_options({startDate: startDate});
|
4909
4806
|
this.update();
|
4910
4807
|
this.updateNavArrows();
|
4911
4808
|
},
|
4912
4809
|
|
4913
4810
|
setEndDate: function(endDate){
|
4914
|
-
this.endDate
|
4915
|
-
if (this.endDate !== Infinity) {
|
4916
|
-
this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language);
|
4917
|
-
}
|
4811
|
+
this._process_options({endDate: endDate});
|
4918
4812
|
this.update();
|
4919
4813
|
this.updateNavArrows();
|
4920
4814
|
},
|
4921
4815
|
|
4922
4816
|
setDaysOfWeekDisabled: function(daysOfWeekDisabled){
|
4923
|
-
this.daysOfWeekDisabled
|
4924
|
-
if (!$.isArray(this.daysOfWeekDisabled)) {
|
4925
|
-
this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
|
4926
|
-
}
|
4927
|
-
this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {
|
4928
|
-
return parseInt(d, 10);
|
4929
|
-
});
|
4817
|
+
this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
|
4930
4818
|
this.update();
|
4931
4819
|
this.updateNavArrows();
|
4932
4820
|
},
|
@@ -4955,16 +4843,17 @@ Automatically shown in inline mode.
|
|
4955
4843
|
fromArgs = true;
|
4956
4844
|
} else {
|
4957
4845
|
date = this.isInput ? this.element.val() : this.element.data('date') || this.element.find('input').val();
|
4846
|
+
delete this.element.data().date;
|
4958
4847
|
}
|
4959
4848
|
|
4960
|
-
this.date = DPGlobal.parseDate(date, this.format, this.language);
|
4849
|
+
this.date = DPGlobal.parseDate(date, this.o.format, this.o.language);
|
4961
4850
|
|
4962
4851
|
if(fromArgs) this.setValue();
|
4963
4852
|
|
4964
|
-
if (this.date < this.startDate) {
|
4965
|
-
this.viewDate = new Date(this.startDate);
|
4966
|
-
} else if (this.date > this.endDate) {
|
4967
|
-
this.viewDate = new Date(this.endDate);
|
4853
|
+
if (this.date < this.o.startDate) {
|
4854
|
+
this.viewDate = new Date(this.o.startDate);
|
4855
|
+
} else if (this.date > this.o.endDate) {
|
4856
|
+
this.viewDate = new Date(this.o.endDate);
|
4968
4857
|
} else {
|
4969
4858
|
this.viewDate = new Date(this.date);
|
4970
4859
|
}
|
@@ -4972,15 +4861,15 @@ Automatically shown in inline mode.
|
|
4972
4861
|
},
|
4973
4862
|
|
4974
4863
|
fillDow: function(){
|
4975
|
-
var dowCnt = this.weekStart,
|
4864
|
+
var dowCnt = this.o.weekStart,
|
4976
4865
|
html = '<tr>';
|
4977
|
-
if(this.calendarWeeks){
|
4866
|
+
if(this.o.calendarWeeks){
|
4978
4867
|
var cell = '<th class="cw"> </th>';
|
4979
4868
|
html += cell;
|
4980
4869
|
this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
|
4981
4870
|
}
|
4982
|
-
while (dowCnt < this.weekStart + 7) {
|
4983
|
-
html += '<th class="dow">'+dates[this.language].daysMin[(dowCnt++)%7]+'</th>';
|
4871
|
+
while (dowCnt < this.o.weekStart + 7) {
|
4872
|
+
html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
|
4984
4873
|
}
|
4985
4874
|
html += '</tr>';
|
4986
4875
|
this.picker.find('.datepicker-days thead').append(html);
|
@@ -4990,46 +4879,93 @@ Automatically shown in inline mode.
|
|
4990
4879
|
var html = '',
|
4991
4880
|
i = 0;
|
4992
4881
|
while (i < 12) {
|
4993
|
-
html += '<span class="month">'+dates[this.language].monthsShort[i++]+'</span>';
|
4882
|
+
html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
|
4994
4883
|
}
|
4995
4884
|
this.picker.find('.datepicker-months td').html(html);
|
4996
4885
|
},
|
4997
4886
|
|
4887
|
+
setRange: function(range){
|
4888
|
+
if (!range || !range.length)
|
4889
|
+
delete this.range;
|
4890
|
+
else
|
4891
|
+
this.range = $.map(range, function(d){ return d.valueOf(); });
|
4892
|
+
this.fill();
|
4893
|
+
},
|
4894
|
+
|
4895
|
+
getClassNames: function(date){
|
4896
|
+
var cls = [],
|
4897
|
+
year = this.viewDate.getUTCFullYear(),
|
4898
|
+
month = this.viewDate.getUTCMonth(),
|
4899
|
+
currentDate = this.date.valueOf(),
|
4900
|
+
today = new Date();
|
4901
|
+
if (date.getUTCFullYear() < year || (date.getUTCFullYear() == year && date.getUTCMonth() < month)) {
|
4902
|
+
cls.push('old');
|
4903
|
+
} else if (date.getUTCFullYear() > year || (date.getUTCFullYear() == year && date.getUTCMonth() > month)) {
|
4904
|
+
cls.push('new');
|
4905
|
+
}
|
4906
|
+
// Compare internal UTC date with local today, not UTC today
|
4907
|
+
if (this.o.todayHighlight &&
|
4908
|
+
date.getUTCFullYear() == today.getFullYear() &&
|
4909
|
+
date.getUTCMonth() == today.getMonth() &&
|
4910
|
+
date.getUTCDate() == today.getDate()) {
|
4911
|
+
cls.push('today');
|
4912
|
+
}
|
4913
|
+
if (currentDate && date.valueOf() == currentDate) {
|
4914
|
+
cls.push('active');
|
4915
|
+
}
|
4916
|
+
if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
|
4917
|
+
$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1) {
|
4918
|
+
cls.push('disabled');
|
4919
|
+
}
|
4920
|
+
if (this.range){
|
4921
|
+
if (date > this.range[0] && date < this.range[this.range.length-1]){
|
4922
|
+
cls.push('range');
|
4923
|
+
}
|
4924
|
+
if ($.inArray(date.valueOf(), this.range) != -1){
|
4925
|
+
cls.push('selected');
|
4926
|
+
}
|
4927
|
+
}
|
4928
|
+
return cls;
|
4929
|
+
},
|
4930
|
+
|
4998
4931
|
fill: function() {
|
4999
4932
|
var d = new Date(this.viewDate),
|
5000
4933
|
year = d.getUTCFullYear(),
|
5001
4934
|
month = d.getUTCMonth(),
|
5002
|
-
startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity,
|
5003
|
-
startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() : -Infinity,
|
5004
|
-
endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,
|
5005
|
-
endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() : Infinity,
|
4935
|
+
startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
|
4936
|
+
startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
|
4937
|
+
endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
|
4938
|
+
endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
|
5006
4939
|
currentDate = this.date && this.date.valueOf(),
|
5007
|
-
|
5008
|
-
this.picker.find('.datepicker-days thead th.switch')
|
5009
|
-
.text(dates[this.language].months[month]+' '+year);
|
4940
|
+
tooltip;
|
4941
|
+
this.picker.find('.datepicker-days thead th.datepicker-switch')
|
4942
|
+
.text(dates[this.o.language].months[month]+' '+year);
|
5010
4943
|
this.picker.find('tfoot th.today')
|
5011
|
-
.text(dates[this.language].today)
|
5012
|
-
.toggle(this.todayBtn !== false);
|
4944
|
+
.text(dates[this.o.language].today)
|
4945
|
+
.toggle(this.o.todayBtn !== false);
|
4946
|
+
this.picker.find('tfoot th.clear')
|
4947
|
+
.text(dates[this.o.language].clear)
|
4948
|
+
.toggle(this.o.clearBtn !== false);
|
5013
4949
|
this.updateNavArrows();
|
5014
4950
|
this.fillMonths();
|
5015
4951
|
var prevMonth = UTCDate(year, month-1, 28,0,0,0,0),
|
5016
4952
|
day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
|
5017
4953
|
prevMonth.setUTCDate(day);
|
5018
|
-
prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7)%7);
|
4954
|
+
prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
|
5019
4955
|
var nextMonth = new Date(prevMonth);
|
5020
4956
|
nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
|
5021
4957
|
nextMonth = nextMonth.valueOf();
|
5022
4958
|
var html = [];
|
5023
4959
|
var clsName;
|
5024
4960
|
while(prevMonth.valueOf() < nextMonth) {
|
5025
|
-
if (prevMonth.getUTCDay() == this.weekStart) {
|
4961
|
+
if (prevMonth.getUTCDay() == this.o.weekStart) {
|
5026
4962
|
html.push('<tr>');
|
5027
|
-
if(this.calendarWeeks){
|
4963
|
+
if(this.o.calendarWeeks){
|
5028
4964
|
// ISO 8601: First week contains first thursday.
|
5029
4965
|
// ISO also states week starts on Monday, but we can be more abstract here.
|
5030
4966
|
var
|
5031
4967
|
// Start of current week: based on weekstart/current date
|
5032
|
-
ws = new Date(+prevMonth + (this.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
|
4968
|
+
ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
|
5033
4969
|
// Thursday of this week
|
5034
4970
|
th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
|
5035
4971
|
// First Thursday of year, year from thursday
|
@@ -5040,28 +4976,26 @@ Automatically shown in inline mode.
|
|
5040
4976
|
|
5041
4977
|
}
|
5042
4978
|
}
|
5043
|
-
clsName =
|
5044
|
-
|
5045
|
-
|
5046
|
-
|
5047
|
-
|
5048
|
-
|
5049
|
-
|
5050
|
-
|
5051
|
-
|
5052
|
-
|
5053
|
-
|
5054
|
-
clsName
|
5055
|
-
|
5056
|
-
|
5057
|
-
|
5058
|
-
|
5059
|
-
|
5060
|
-
|
5061
|
-
|
5062
|
-
|
5063
|
-
html.push('<td class="day'+clsName+'">'+prevMonth.getUTCDate() + '</td>');
|
5064
|
-
if (prevMonth.getUTCDay() == this.weekEnd) {
|
4979
|
+
clsName = this.getClassNames(prevMonth);
|
4980
|
+
clsName.push('day');
|
4981
|
+
|
4982
|
+
var before = this.o.beforeShowDay(prevMonth);
|
4983
|
+
if (before === undefined)
|
4984
|
+
before = {};
|
4985
|
+
else if (typeof(before) === 'boolean')
|
4986
|
+
before = {enabled: before};
|
4987
|
+
else if (typeof(before) === 'string')
|
4988
|
+
before = {classes: before};
|
4989
|
+
if (before.enabled === false)
|
4990
|
+
clsName.push('disabled');
|
4991
|
+
if (before.classes)
|
4992
|
+
clsName = clsName.concat(before.classes.split(/\s+/));
|
4993
|
+
if (before.tooltip)
|
4994
|
+
tooltip = before.tooltip;
|
4995
|
+
|
4996
|
+
clsName = $.unique(clsName);
|
4997
|
+
html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
|
4998
|
+
if (prevMonth.getUTCDay() == this.o.weekEnd) {
|
5065
4999
|
html.push('</tr>');
|
5066
5000
|
}
|
5067
5001
|
prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
|
@@ -5096,7 +5030,7 @@ Automatically shown in inline mode.
|
|
5096
5030
|
.find('td');
|
5097
5031
|
year -= 1;
|
5098
5032
|
for (var i = -1; i < 11; i++) {
|
5099
|
-
html += '<span class="year'+(i == -1
|
5033
|
+
html += '<span class="year'+(i == -1 ? ' old' : i == 10 ? ' new' : '')+(currentYear == year ? ' active' : '')+(year < startYear || year > endYear ? ' disabled' : '')+'">'+year+'</span>';
|
5100
5034
|
year += 1;
|
5101
5035
|
}
|
5102
5036
|
yearCont.html(html);
|
@@ -5110,12 +5044,12 @@ Automatically shown in inline mode.
|
|
5110
5044
|
month = d.getUTCMonth();
|
5111
5045
|
switch (this.viewMode) {
|
5112
5046
|
case 0:
|
5113
|
-
if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear() && month <= this.startDate.getUTCMonth()) {
|
5047
|
+
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()) {
|
5114
5048
|
this.picker.find('.prev').css({visibility: 'hidden'});
|
5115
5049
|
} else {
|
5116
5050
|
this.picker.find('.prev').css({visibility: 'visible'});
|
5117
5051
|
}
|
5118
|
-
if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear() && month >= this.endDate.getUTCMonth()) {
|
5052
|
+
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()) {
|
5119
5053
|
this.picker.find('.next').css({visibility: 'hidden'});
|
5120
5054
|
} else {
|
5121
5055
|
this.picker.find('.next').css({visibility: 'visible'});
|
@@ -5123,12 +5057,12 @@ Automatically shown in inline mode.
|
|
5123
5057
|
break;
|
5124
5058
|
case 1:
|
5125
5059
|
case 2:
|
5126
|
-
if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) {
|
5060
|
+
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()) {
|
5127
5061
|
this.picker.find('.prev').css({visibility: 'hidden'});
|
5128
5062
|
} else {
|
5129
5063
|
this.picker.find('.prev').css({visibility: 'visible'});
|
5130
5064
|
}
|
5131
|
-
if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) {
|
5065
|
+
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()) {
|
5132
5066
|
this.picker.find('.next').css({visibility: 'hidden'});
|
5133
5067
|
} else {
|
5134
5068
|
this.picker.find('.next').css({visibility: 'visible'});
|
@@ -5144,7 +5078,7 @@ Automatically shown in inline mode.
|
|
5144
5078
|
switch(target[0].nodeName.toLowerCase()) {
|
5145
5079
|
case 'th':
|
5146
5080
|
switch(target[0].className) {
|
5147
|
-
case 'switch':
|
5081
|
+
case 'datepicker-switch':
|
5148
5082
|
this.showMode(1);
|
5149
5083
|
break;
|
5150
5084
|
case 'prev':
|
@@ -5166,9 +5100,22 @@ Automatically shown in inline mode.
|
|
5166
5100
|
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
|
5167
5101
|
|
5168
5102
|
this.showMode(-2);
|
5169
|
-
var which = this.todayBtn == 'linked' ? null : 'view';
|
5103
|
+
var which = this.o.todayBtn == 'linked' ? null : 'view';
|
5170
5104
|
this._setDate(date, which);
|
5171
5105
|
break;
|
5106
|
+
case 'clear':
|
5107
|
+
var element;
|
5108
|
+
if (this.isInput)
|
5109
|
+
element = this.element;
|
5110
|
+
else if (this.component)
|
5111
|
+
element = this.element.find('input');
|
5112
|
+
if (element)
|
5113
|
+
element.val("").change();
|
5114
|
+
this._trigger('changeDate');
|
5115
|
+
this.update();
|
5116
|
+
if (this.o.autoclose)
|
5117
|
+
this.hide();
|
5118
|
+
break;
|
5172
5119
|
}
|
5173
5120
|
break;
|
5174
5121
|
case 'span':
|
@@ -5179,11 +5126,8 @@ Automatically shown in inline mode.
|
|
5179
5126
|
var month = target.parent().find('span').index(target);
|
5180
5127
|
var year = this.viewDate.getUTCFullYear();
|
5181
5128
|
this.viewDate.setUTCMonth(month);
|
5182
|
-
this.
|
5183
|
-
|
5184
|
-
date: this.viewDate
|
5185
|
-
});
|
5186
|
-
if ( this.minViewMode == 1 ) {
|
5129
|
+
this._trigger('changeMonth', this.viewDate);
|
5130
|
+
if (this.o.minViewMode === 1) {
|
5187
5131
|
this._setDate(UTCDate(year, month, day,0,0,0,0));
|
5188
5132
|
}
|
5189
5133
|
} else {
|
@@ -5191,11 +5135,8 @@ Automatically shown in inline mode.
|
|
5191
5135
|
var day = 1;
|
5192
5136
|
var month = 0;
|
5193
5137
|
this.viewDate.setUTCFullYear(year);
|
5194
|
-
this.
|
5195
|
-
|
5196
|
-
date: this.viewDate
|
5197
|
-
});
|
5198
|
-
if ( this.minViewMode == 2 ) {
|
5138
|
+
this._trigger('changeYear', this.viewDate);
|
5139
|
+
if (this.o.minViewMode === 2) {
|
5199
5140
|
this._setDate(UTCDate(year, month, day,0,0,0,0));
|
5200
5141
|
}
|
5201
5142
|
}
|
@@ -5232,15 +5173,12 @@ Automatically shown in inline mode.
|
|
5232
5173
|
|
5233
5174
|
_setDate: function(date, which){
|
5234
5175
|
if (!which || which == 'date')
|
5235
|
-
this.date = date;
|
5176
|
+
this.date = new Date(date);
|
5236
5177
|
if (!which || which == 'view')
|
5237
|
-
this.viewDate = date;
|
5178
|
+
this.viewDate = new Date(date);
|
5238
5179
|
this.fill();
|
5239
5180
|
this.setValue();
|
5240
|
-
this.
|
5241
|
-
type: 'changeDate',
|
5242
|
-
date: this.date
|
5243
|
-
});
|
5181
|
+
this._trigger('changeDate');
|
5244
5182
|
var element;
|
5245
5183
|
if (this.isInput) {
|
5246
5184
|
element = this.element;
|
@@ -5249,7 +5187,7 @@ Automatically shown in inline mode.
|
|
5249
5187
|
}
|
5250
5188
|
if (element) {
|
5251
5189
|
element.change();
|
5252
|
-
if (this.autoclose && (!which || which == 'date')) {
|
5190
|
+
if (this.o.autoclose && (!which || which == 'date')) {
|
5253
5191
|
this.hide();
|
5254
5192
|
}
|
5255
5193
|
}
|
@@ -5300,7 +5238,7 @@ Automatically shown in inline mode.
|
|
5300
5238
|
},
|
5301
5239
|
|
5302
5240
|
dateWithinRange: function(date){
|
5303
|
-
return date >= this.startDate && date <= this.endDate;
|
5241
|
+
return date >= this.o.startDate && date <= this.o.endDate;
|
5304
5242
|
},
|
5305
5243
|
|
5306
5244
|
keydown: function(e){
|
@@ -5319,7 +5257,7 @@ Automatically shown in inline mode.
|
|
5319
5257
|
break;
|
5320
5258
|
case 37: // left
|
5321
5259
|
case 39: // right
|
5322
|
-
if (!this.keyboardNavigation) break;
|
5260
|
+
if (!this.o.keyboardNavigation) break;
|
5323
5261
|
dir = e.keyCode == 37 ? -1 : 1;
|
5324
5262
|
if (e.ctrlKey){
|
5325
5263
|
newDate = this.moveYear(this.date, dir);
|
@@ -5344,7 +5282,7 @@ Automatically shown in inline mode.
|
|
5344
5282
|
break;
|
5345
5283
|
case 38: // up
|
5346
5284
|
case 40: // down
|
5347
|
-
if (!this.keyboardNavigation) break;
|
5285
|
+
if (!this.o.keyboardNavigation) break;
|
5348
5286
|
dir = e.keyCode == 38 ? -1 : 1;
|
5349
5287
|
if (e.ctrlKey){
|
5350
5288
|
newDate = this.moveYear(this.date, dir);
|
@@ -5376,10 +5314,7 @@ Automatically shown in inline mode.
|
|
5376
5314
|
break;
|
5377
5315
|
}
|
5378
5316
|
if (dateChanged){
|
5379
|
-
this.
|
5380
|
-
type: 'changeDate',
|
5381
|
-
date: this.date
|
5382
|
-
});
|
5317
|
+
this._trigger('changeDate');
|
5383
5318
|
var element;
|
5384
5319
|
if (this.isInput) {
|
5385
5320
|
element = this.element;
|
@@ -5394,7 +5329,7 @@ Automatically shown in inline mode.
|
|
5394
5329
|
|
5395
5330
|
showMode: function(dir) {
|
5396
5331
|
if (dir) {
|
5397
|
-
this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
|
5332
|
+
this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
|
5398
5333
|
}
|
5399
5334
|
/*
|
5400
5335
|
vitalets: fixing bug of very special conditions:
|
@@ -5411,24 +5346,151 @@ Automatically shown in inline mode.
|
|
5411
5346
|
}
|
5412
5347
|
};
|
5413
5348
|
|
5414
|
-
|
5349
|
+
var DateRangePicker = function(element, options){
|
5350
|
+
this.element = $(element);
|
5351
|
+
this.inputs = $.map(options.inputs, function(i){ return i.jquery ? i[0] : i; });
|
5352
|
+
delete options.inputs;
|
5353
|
+
|
5354
|
+
$(this.inputs)
|
5355
|
+
.datepicker(options)
|
5356
|
+
.bind('changeDate', $.proxy(this.dateUpdated, this));
|
5357
|
+
|
5358
|
+
this.pickers = $.map(this.inputs, function(i){ return $(i).data('datepicker'); });
|
5359
|
+
this.updateDates();
|
5360
|
+
};
|
5361
|
+
DateRangePicker.prototype = {
|
5362
|
+
updateDates: function(){
|
5363
|
+
this.dates = $.map(this.pickers, function(i){ return i.date; });
|
5364
|
+
this.updateRanges();
|
5365
|
+
},
|
5366
|
+
updateRanges: function(){
|
5367
|
+
var range = $.map(this.dates, function(d){ return d.valueOf(); });
|
5368
|
+
$.each(this.pickers, function(i, p){
|
5369
|
+
p.setRange(range);
|
5370
|
+
});
|
5371
|
+
},
|
5372
|
+
dateUpdated: function(e){
|
5373
|
+
var dp = $(e.target).data('datepicker'),
|
5374
|
+
new_date = dp.getUTCDate(),
|
5375
|
+
i = $.inArray(e.target, this.inputs),
|
5376
|
+
l = this.inputs.length;
|
5377
|
+
if (i == -1) return;
|
5378
|
+
|
5379
|
+
if (new_date < this.dates[i]){
|
5380
|
+
// Date being moved earlier/left
|
5381
|
+
while (i>=0 && new_date < this.dates[i]){
|
5382
|
+
this.pickers[i--].setUTCDate(new_date);
|
5383
|
+
}
|
5384
|
+
}
|
5385
|
+
else if (new_date > this.dates[i]){
|
5386
|
+
// Date being moved later/right
|
5387
|
+
while (i<l && new_date > this.dates[i]){
|
5388
|
+
this.pickers[i++].setUTCDate(new_date);
|
5389
|
+
}
|
5390
|
+
}
|
5391
|
+
this.updateDates();
|
5392
|
+
},
|
5393
|
+
remove: function(){
|
5394
|
+
$.map(this.pickers, function(p){ p.remove(); });
|
5395
|
+
delete this.element.data().datepicker;
|
5396
|
+
}
|
5397
|
+
};
|
5398
|
+
|
5399
|
+
function opts_from_el(el, prefix){
|
5400
|
+
// Derive options from element data-attrs
|
5401
|
+
var data = $(el).data(),
|
5402
|
+
out = {}, inkey,
|
5403
|
+
replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'),
|
5404
|
+
prefix = new RegExp('^' + prefix.toLowerCase());
|
5405
|
+
for (var key in data)
|
5406
|
+
if (prefix.test(key)){
|
5407
|
+
inkey = key.replace(replace, function(_,a){ return a.toLowerCase(); });
|
5408
|
+
out[inkey] = data[key];
|
5409
|
+
}
|
5410
|
+
return out;
|
5411
|
+
}
|
5412
|
+
|
5413
|
+
function opts_from_locale(lang){
|
5414
|
+
// Derive options from locale plugins
|
5415
|
+
var out = {};
|
5416
|
+
// Check if "de-DE" style date is available, if not language should
|
5417
|
+
// fallback to 2 letter code eg "de"
|
5418
|
+
if (!dates[lang]) {
|
5419
|
+
lang = lang.split('-')[0]
|
5420
|
+
if (!dates[lang])
|
5421
|
+
return;
|
5422
|
+
}
|
5423
|
+
var d = dates[lang];
|
5424
|
+
$.each(locale_opts, function(i,k){
|
5425
|
+
if (k in d)
|
5426
|
+
out[k] = d[k];
|
5427
|
+
});
|
5428
|
+
return out;
|
5429
|
+
}
|
5430
|
+
|
5431
|
+
var old = $.fn.datepicker;
|
5432
|
+
var datepicker = $.fn.datepicker = function ( option ) {
|
5415
5433
|
var args = Array.apply(null, arguments);
|
5416
5434
|
args.shift();
|
5417
|
-
|
5435
|
+
var internal_return,
|
5436
|
+
this_return;
|
5437
|
+
this.each(function () {
|
5418
5438
|
var $this = $(this),
|
5419
5439
|
data = $this.data('datepicker'),
|
5420
5440
|
options = typeof option == 'object' && option;
|
5421
5441
|
if (!data) {
|
5422
|
-
|
5442
|
+
var elopts = opts_from_el(this, 'date'),
|
5443
|
+
// Preliminary otions
|
5444
|
+
xopts = $.extend({}, defaults, elopts, options),
|
5445
|
+
locopts = opts_from_locale(xopts.language),
|
5446
|
+
// Options priority: js args, data-attrs, locales, defaults
|
5447
|
+
opts = $.extend({}, defaults, locopts, elopts, options);
|
5448
|
+
if ($this.is('.input-daterange') || opts.inputs){
|
5449
|
+
var ropts = {
|
5450
|
+
inputs: opts.inputs || $this.find('input').toArray()
|
5451
|
+
};
|
5452
|
+
$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
|
5453
|
+
}
|
5454
|
+
else{
|
5455
|
+
$this.data('datepicker', (data = new Datepicker(this, opts)));
|
5456
|
+
}
|
5423
5457
|
}
|
5424
5458
|
if (typeof option == 'string' && typeof data[option] == 'function') {
|
5425
|
-
data[option].apply(data, args);
|
5459
|
+
internal_return = data[option].apply(data, args);
|
5460
|
+
if (internal_return !== undefined)
|
5461
|
+
return false;
|
5426
5462
|
}
|
5427
5463
|
});
|
5464
|
+
if (internal_return !== undefined)
|
5465
|
+
return internal_return;
|
5466
|
+
else
|
5467
|
+
return this;
|
5428
5468
|
};
|
5429
5469
|
|
5430
|
-
$.fn.datepicker.defaults = {
|
5470
|
+
var defaults = $.fn.datepicker.defaults = {
|
5471
|
+
autoclose: false,
|
5472
|
+
beforeShowDay: $.noop,
|
5473
|
+
calendarWeeks: false,
|
5474
|
+
clearBtn: false,
|
5475
|
+
daysOfWeekDisabled: [],
|
5476
|
+
endDate: Infinity,
|
5477
|
+
forceParse: true,
|
5478
|
+
format: 'mm/dd/yyyy',
|
5479
|
+
keyboardNavigation: true,
|
5480
|
+
language: 'en',
|
5481
|
+
minViewMode: 0,
|
5482
|
+
rtl: false,
|
5483
|
+
startDate: -Infinity,
|
5484
|
+
startView: 0,
|
5485
|
+
todayBtn: false,
|
5486
|
+
todayHighlight: false,
|
5487
|
+
weekStart: 0
|
5431
5488
|
};
|
5489
|
+
var locale_opts = $.fn.datepicker.locale_opts = [
|
5490
|
+
'format',
|
5491
|
+
'rtl',
|
5492
|
+
'weekStart'
|
5493
|
+
];
|
5432
5494
|
$.fn.datepicker.Constructor = Datepicker;
|
5433
5495
|
var dates = $.fn.datepicker.dates = {
|
5434
5496
|
en: {
|
@@ -5437,7 +5499,8 @@ Automatically shown in inline mode.
|
|
5437
5499
|
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
5438
5500
|
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
5439
5501
|
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
5440
|
-
today: "Today"
|
5502
|
+
today: "Today",
|
5503
|
+
clear: "Clear"
|
5441
5504
|
}
|
5442
5505
|
};
|
5443
5506
|
|
@@ -5478,6 +5541,8 @@ Automatically shown in inline mode.
|
|
5478
5541
|
},
|
5479
5542
|
parseDate: function(date, format, language) {
|
5480
5543
|
if (date instanceof Date) return date;
|
5544
|
+
if (typeof format === 'string')
|
5545
|
+
format = DPGlobal.parseFormat(format);
|
5481
5546
|
if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
|
5482
5547
|
var part_re = /([\-+]\d+)([dmwy])/,
|
5483
5548
|
parts = date.match(/([\-+]\d+)([dmwy])/g),
|
@@ -5568,6 +5633,8 @@ Automatically shown in inline mode.
|
|
5568
5633
|
return date;
|
5569
5634
|
},
|
5570
5635
|
formatDate: function(date, format, language){
|
5636
|
+
if (typeof format === 'string')
|
5637
|
+
format = DPGlobal.parseFormat(format);
|
5571
5638
|
var val = {
|
5572
5639
|
d: date.getUTCDate(),
|
5573
5640
|
D: dates[language].daysShort[date.getUTCDay()],
|
@@ -5582,7 +5649,7 @@ Automatically shown in inline mode.
|
|
5582
5649
|
val.mm = (val.m < 10 ? '0' : '') + val.m;
|
5583
5650
|
var date = [],
|
5584
5651
|
seps = $.extend([], format.separators);
|
5585
|
-
for (var i=0, cnt = format.parts.length; i
|
5652
|
+
for (var i=0, cnt = format.parts.length; i <= cnt; i++) {
|
5586
5653
|
if (seps.length)
|
5587
5654
|
date.push(seps.shift());
|
5588
5655
|
date.push(val[format.parts[i]]);
|
@@ -5592,12 +5659,12 @@ Automatically shown in inline mode.
|
|
5592
5659
|
headTemplate: '<thead>'+
|
5593
5660
|
'<tr>'+
|
5594
5661
|
'<th class="prev"><i class="icon-arrow-left"/></th>'+
|
5595
|
-
'<th colspan="5" class="switch"></th>'+
|
5662
|
+
'<th colspan="5" class="datepicker-switch"></th>'+
|
5596
5663
|
'<th class="next"><i class="icon-arrow-right"/></th>'+
|
5597
5664
|
'</tr>'+
|
5598
5665
|
'</thead>',
|
5599
5666
|
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
|
5600
|
-
footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'
|
5667
|
+
footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr><tr><th colspan="7" class="clear"></th></tr></tfoot>'
|
5601
5668
|
};
|
5602
5669
|
DPGlobal.template = '<div class="datepicker">'+
|
5603
5670
|
'<div class="datepicker-days">'+
|
@@ -5623,10 +5690,348 @@ Automatically shown in inline mode.
|
|
5623
5690
|
'</div>'+
|
5624
5691
|
'</div>';
|
5625
5692
|
|
5626
|
-
$.fn.datepicker.DPGlobal = DPGlobal;
|
5693
|
+
$.fn.datepicker.DPGlobal = DPGlobal;
|
5694
|
+
|
5695
|
+
|
5696
|
+
/* DATEPICKER NO CONFLICT
|
5697
|
+
* =================== */
|
5698
|
+
|
5699
|
+
$.fn.datepicker.noConflict = function(){
|
5700
|
+
$.fn.datepicker = old;
|
5701
|
+
return this;
|
5702
|
+
};
|
5703
|
+
|
5704
|
+
|
5705
|
+
/* DATEPICKER DATA-API
|
5706
|
+
* ================== */
|
5707
|
+
|
5708
|
+
$(document).on(
|
5709
|
+
'focus.datepicker.data-api click.datepicker.data-api',
|
5710
|
+
'[data-provide="datepicker"]',
|
5711
|
+
function(e){
|
5712
|
+
var $this = $(this);
|
5713
|
+
if ($this.data('datepicker')) return;
|
5714
|
+
e.preventDefault();
|
5715
|
+
// component click requires us to explicitly show it
|
5716
|
+
datepicker.call($this, 'show');
|
5717
|
+
}
|
5718
|
+
);
|
5719
|
+
$(function(){
|
5720
|
+
//$('[data-provide="datepicker-inline"]').datepicker();
|
5721
|
+
//vit: changed to support noConflict()
|
5722
|
+
datepicker.call($('[data-provide="datepicker-inline"]'));
|
5723
|
+
});
|
5724
|
+
|
5725
|
+
}( window.jQuery ));
|
5726
|
+
|
5727
|
+
/**
|
5728
|
+
Bootstrap-datepicker.
|
5729
|
+
Description and examples: https://github.com/eternicode/bootstrap-datepicker.
|
5730
|
+
For **i18n** you should include js file from here: https://github.com/eternicode/bootstrap-datepicker/tree/master/js/locales
|
5731
|
+
and set `language` option.
|
5732
|
+
Since 1.4.0 date has different appearance in **popup** and **inline** modes.
|
5733
|
+
|
5734
|
+
@class date
|
5735
|
+
@extends abstractinput
|
5736
|
+
@final
|
5737
|
+
@example
|
5738
|
+
<a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
|
5739
|
+
<script>
|
5740
|
+
$(function(){
|
5741
|
+
$('#dob').editable({
|
5742
|
+
format: 'yyyy-mm-dd',
|
5743
|
+
viewformat: 'dd/mm/yyyy',
|
5744
|
+
datepicker: {
|
5745
|
+
weekStart: 1
|
5746
|
+
}
|
5747
|
+
}
|
5748
|
+
});
|
5749
|
+
});
|
5750
|
+
</script>
|
5751
|
+
**/
|
5752
|
+
(function ($) {
|
5753
|
+
"use strict";
|
5754
|
+
|
5755
|
+
//store bootstrap-datepicker as bdateicker to exclude conflict with jQuery UI one
|
5756
|
+
$.fn.bdatepicker = $.fn.datepicker.noConflict();
|
5757
|
+
if(!$.fn.datepicker) { //if there were no other datepickers, keep also original name
|
5758
|
+
$.fn.datepicker = $.fn.bdatepicker;
|
5759
|
+
}
|
5760
|
+
|
5761
|
+
var Date = function (options) {
|
5762
|
+
this.init('date', options, Date.defaults);
|
5763
|
+
this.initPicker(options, Date.defaults);
|
5764
|
+
};
|
5765
|
+
|
5766
|
+
$.fn.editableutils.inherit(Date, $.fn.editabletypes.abstractinput);
|
5767
|
+
|
5768
|
+
$.extend(Date.prototype, {
|
5769
|
+
initPicker: function(options, defaults) {
|
5770
|
+
//'format' is set directly from settings or data-* attributes
|
5771
|
+
|
5772
|
+
//by default viewformat equals to format
|
5773
|
+
if(!this.options.viewformat) {
|
5774
|
+
this.options.viewformat = this.options.format;
|
5775
|
+
}
|
5776
|
+
|
5777
|
+
//overriding datepicker config (as by default jQuery extend() is not recursive)
|
5778
|
+
//since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
|
5779
|
+
this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, {
|
5780
|
+
format: this.options.viewformat
|
5781
|
+
});
|
5782
|
+
|
5783
|
+
//language
|
5784
|
+
this.options.datepicker.language = this.options.datepicker.language || 'en';
|
5785
|
+
|
5786
|
+
//store DPglobal
|
5787
|
+
this.dpg = $.fn.bdatepicker.DPGlobal;
|
5788
|
+
|
5789
|
+
//store parsed formats
|
5790
|
+
this.parsedFormat = this.dpg.parseFormat(this.options.format);
|
5791
|
+
this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
|
5792
|
+
},
|
5793
|
+
|
5794
|
+
render: function () {
|
5795
|
+
this.$input.bdatepicker(this.options.datepicker);
|
5796
|
+
|
5797
|
+
//"clear" link
|
5798
|
+
if(this.options.clear) {
|
5799
|
+
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
|
5800
|
+
e.preventDefault();
|
5801
|
+
e.stopPropagation();
|
5802
|
+
this.clear();
|
5803
|
+
}, this));
|
5804
|
+
|
5805
|
+
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
|
5806
|
+
}
|
5807
|
+
},
|
5808
|
+
|
5809
|
+
value2html: function(value, element) {
|
5810
|
+
var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '';
|
5811
|
+
Date.superclass.value2html(text, element);
|
5812
|
+
},
|
5813
|
+
|
5814
|
+
html2value: function(html) {
|
5815
|
+
return this.parseDate(html, this.parsedViewFormat);
|
5816
|
+
},
|
5817
|
+
|
5818
|
+
value2str: function(value) {
|
5819
|
+
return value ? this.dpg.formatDate(value, this.parsedFormat, this.options.datepicker.language) : '';
|
5820
|
+
},
|
5821
|
+
|
5822
|
+
str2value: function(str) {
|
5823
|
+
return this.parseDate(str, this.parsedFormat);
|
5824
|
+
},
|
5825
|
+
|
5826
|
+
value2submit: function(value) {
|
5827
|
+
return this.value2str(value);
|
5828
|
+
},
|
5829
|
+
|
5830
|
+
value2input: function(value) {
|
5831
|
+
this.$input.bdatepicker('update', value);
|
5832
|
+
},
|
5833
|
+
|
5834
|
+
input2value: function() {
|
5835
|
+
return this.$input.data('datepicker').date;
|
5836
|
+
},
|
5837
|
+
|
5838
|
+
activate: function() {
|
5839
|
+
},
|
5840
|
+
|
5841
|
+
clear: function() {
|
5842
|
+
this.$input.data('datepicker').date = null;
|
5843
|
+
this.$input.find('.active').removeClass('active');
|
5844
|
+
if(!this.options.showbuttons) {
|
5845
|
+
this.$input.closest('form').submit();
|
5846
|
+
}
|
5847
|
+
},
|
5848
|
+
|
5849
|
+
autosubmit: function() {
|
5850
|
+
this.$input.on('mouseup', '.day', function(e){
|
5851
|
+
if($(e.currentTarget).is('.old') || $(e.currentTarget).is('.new')) {
|
5852
|
+
return;
|
5853
|
+
}
|
5854
|
+
var $form = $(this).closest('form');
|
5855
|
+
setTimeout(function() {
|
5856
|
+
$form.submit();
|
5857
|
+
}, 200);
|
5858
|
+
});
|
5859
|
+
//changedate is not suitable as it triggered when showing datepicker. see #149
|
5860
|
+
/*
|
5861
|
+
this.$input.on('changeDate', function(e){
|
5862
|
+
var $form = $(this).closest('form');
|
5863
|
+
setTimeout(function() {
|
5864
|
+
$form.submit();
|
5865
|
+
}, 200);
|
5866
|
+
});
|
5867
|
+
*/
|
5868
|
+
},
|
5869
|
+
|
5870
|
+
/*
|
5871
|
+
For incorrect date bootstrap-datepicker returns current date that is not suitable
|
5872
|
+
for datefield.
|
5873
|
+
This function returns null for incorrect date.
|
5874
|
+
*/
|
5875
|
+
parseDate: function(str, format) {
|
5876
|
+
var date = null, formattedBack;
|
5877
|
+
if(str) {
|
5878
|
+
date = this.dpg.parseDate(str, format, this.options.datepicker.language);
|
5879
|
+
if(typeof str === 'string') {
|
5880
|
+
formattedBack = this.dpg.formatDate(date, format, this.options.datepicker.language);
|
5881
|
+
if(str !== formattedBack) {
|
5882
|
+
date = null;
|
5883
|
+
}
|
5884
|
+
}
|
5885
|
+
}
|
5886
|
+
return date;
|
5887
|
+
}
|
5888
|
+
|
5889
|
+
});
|
5890
|
+
|
5891
|
+
Date.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
5892
|
+
/**
|
5893
|
+
@property tpl
|
5894
|
+
@default <div></div>
|
5895
|
+
**/
|
5896
|
+
tpl:'<div class="editable-date well"></div>',
|
5897
|
+
/**
|
5898
|
+
@property inputclass
|
5899
|
+
@default null
|
5900
|
+
**/
|
5901
|
+
inputclass: null,
|
5902
|
+
/**
|
5903
|
+
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
|
5904
|
+
Possible tokens are: <code>d, dd, m, mm, yy, yyyy</code>
|
5905
|
+
|
5906
|
+
@property format
|
5907
|
+
@type string
|
5908
|
+
@default yyyy-mm-dd
|
5909
|
+
**/
|
5910
|
+
format:'yyyy-mm-dd',
|
5911
|
+
/**
|
5912
|
+
Format used for displaying date. Also applied when converting date from element's text on init.
|
5913
|
+
If not specified equals to <code>format</code>
|
5914
|
+
|
5915
|
+
@property viewformat
|
5916
|
+
@type string
|
5917
|
+
@default null
|
5918
|
+
**/
|
5919
|
+
viewformat: null,
|
5920
|
+
/**
|
5921
|
+
Configuration of datepicker.
|
5922
|
+
Full list of options: http://vitalets.github.com/bootstrap-datepicker
|
5923
|
+
|
5924
|
+
@property datepicker
|
5925
|
+
@type object
|
5926
|
+
@default {
|
5927
|
+
weekStart: 0,
|
5928
|
+
startView: 0,
|
5929
|
+
minViewMode: 0,
|
5930
|
+
autoclose: false
|
5931
|
+
}
|
5932
|
+
**/
|
5933
|
+
datepicker:{
|
5934
|
+
weekStart: 0,
|
5935
|
+
startView: 0,
|
5936
|
+
minViewMode: 0,
|
5937
|
+
autoclose: false
|
5938
|
+
},
|
5939
|
+
/**
|
5940
|
+
Text shown as clear date button.
|
5941
|
+
If <code>false</code> clear button will not be rendered.
|
5942
|
+
|
5943
|
+
@property clear
|
5944
|
+
@type boolean|string
|
5945
|
+
@default 'x clear'
|
5946
|
+
**/
|
5947
|
+
clear: '× clear'
|
5948
|
+
});
|
5627
5949
|
|
5628
|
-
|
5950
|
+
$.fn.editabletypes.date = Date;
|
5951
|
+
|
5952
|
+
}(window.jQuery));
|
5629
5953
|
|
5954
|
+
/**
|
5955
|
+
Bootstrap datefield input - modification for inline mode.
|
5956
|
+
Shows normal <input type="text"> and binds popup datepicker.
|
5957
|
+
Automatically shown in inline mode.
|
5958
|
+
|
5959
|
+
@class datefield
|
5960
|
+
@extends date
|
5961
|
+
|
5962
|
+
@since 1.4.0
|
5963
|
+
**/
|
5964
|
+
(function ($) {
|
5965
|
+
"use strict";
|
5966
|
+
|
5967
|
+
var DateField = function (options) {
|
5968
|
+
this.init('datefield', options, DateField.defaults);
|
5969
|
+
this.initPicker(options, DateField.defaults);
|
5970
|
+
};
|
5971
|
+
|
5972
|
+
$.fn.editableutils.inherit(DateField, $.fn.editabletypes.date);
|
5973
|
+
|
5974
|
+
$.extend(DateField.prototype, {
|
5975
|
+
render: function () {
|
5976
|
+
this.$input = this.$tpl.find('input');
|
5977
|
+
this.setClass();
|
5978
|
+
this.setAttr('placeholder');
|
5979
|
+
|
5980
|
+
//bootstrap-datepicker is set `bdateicker` to exclude conflict with jQuery UI one. (in date.js)
|
5981
|
+
this.$tpl.bdatepicker(this.options.datepicker);
|
5982
|
+
|
5983
|
+
//need to disable original event handlers
|
5984
|
+
this.$input.off('focus keydown');
|
5985
|
+
|
5986
|
+
//update value of datepicker
|
5987
|
+
this.$input.keyup($.proxy(function(){
|
5988
|
+
this.$tpl.removeData('date');
|
5989
|
+
this.$tpl.bdatepicker('update');
|
5990
|
+
}, this));
|
5991
|
+
|
5992
|
+
},
|
5993
|
+
|
5994
|
+
value2input: function(value) {
|
5995
|
+
this.$input.val(value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '');
|
5996
|
+
this.$tpl.bdatepicker('update');
|
5997
|
+
},
|
5998
|
+
|
5999
|
+
input2value: function() {
|
6000
|
+
return this.html2value(this.$input.val());
|
6001
|
+
},
|
6002
|
+
|
6003
|
+
activate: function() {
|
6004
|
+
$.fn.editabletypes.text.prototype.activate.call(this);
|
6005
|
+
},
|
6006
|
+
|
6007
|
+
autosubmit: function() {
|
6008
|
+
//reset autosubmit to empty
|
6009
|
+
}
|
6010
|
+
});
|
6011
|
+
|
6012
|
+
DateField.defaults = $.extend({}, $.fn.editabletypes.date.defaults, {
|
6013
|
+
/**
|
6014
|
+
@property tpl
|
6015
|
+
**/
|
6016
|
+
tpl:'<div class="input-append date"><input type="text"/><span class="add-on"><i class="icon-th"></i></span></div>',
|
6017
|
+
/**
|
6018
|
+
@property inputclass
|
6019
|
+
@default 'input-small'
|
6020
|
+
**/
|
6021
|
+
inputclass: 'input-small',
|
6022
|
+
|
6023
|
+
/* datepicker config */
|
6024
|
+
datepicker: {
|
6025
|
+
weekStart: 0,
|
6026
|
+
startView: 0,
|
6027
|
+
minViewMode: 0,
|
6028
|
+
autoclose: true
|
6029
|
+
}
|
6030
|
+
});
|
6031
|
+
|
6032
|
+
$.fn.editabletypes.datefield = DateField;
|
6033
|
+
|
6034
|
+
}(window.jQuery));
|
5630
6035
|
/**
|
5631
6036
|
Bootstrap-datetimepicker.
|
5632
6037
|
Based on [smalot bootstrap-datetimepicker plugin](https://github.com/smalot/bootstrap-datetimepicker).
|
@@ -5634,7 +6039,7 @@ Before usage you should manually include dependent js and css:
|
|
5634
6039
|
|
5635
6040
|
<link href="css/datetimepicker.css" rel="stylesheet" type="text/css"></link>
|
5636
6041
|
<script src="js/bootstrap-datetimepicker.js"></script>
|
5637
|
-
|
6042
|
+
|
5638
6043
|
For **i18n** you should include js file from here: https://github.com/smalot/bootstrap-datetimepicker/tree/master/js/locales
|
5639
6044
|
and set `language` option.
|
5640
6045
|
|
@@ -5659,14 +6064,14 @@ $(function(){
|
|
5659
6064
|
**/
|
5660
6065
|
(function ($) {
|
5661
6066
|
"use strict";
|
5662
|
-
|
6067
|
+
|
5663
6068
|
var DateTime = function (options) {
|
5664
6069
|
this.init('datetime', options, DateTime.defaults);
|
5665
6070
|
this.initPicker(options, DateTime.defaults);
|
5666
6071
|
};
|
5667
6072
|
|
5668
6073
|
$.fn.editableutils.inherit(DateTime, $.fn.editabletypes.abstractinput);
|
5669
|
-
|
6074
|
+
|
5670
6075
|
$.extend(DateTime.prototype, {
|
5671
6076
|
initPicker: function(options, defaults) {
|
5672
6077
|
//'format' is set directly from settings or data-* attributes
|
@@ -5675,13 +6080,13 @@ $(function(){
|
|
5675
6080
|
if(!this.options.viewformat) {
|
5676
6081
|
this.options.viewformat = this.options.format;
|
5677
6082
|
}
|
5678
|
-
|
6083
|
+
|
5679
6084
|
//overriding datetimepicker config (as by default jQuery extend() is not recursive)
|
5680
6085
|
//since 1.4 datetimepicker internally uses viewformat instead of format. Format is for submit only
|
5681
6086
|
this.options.datetimepicker = $.extend({}, defaults.datetimepicker, options.datetimepicker, {
|
5682
6087
|
format: this.options.viewformat
|
5683
6088
|
});
|
5684
|
-
|
6089
|
+
|
5685
6090
|
//language
|
5686
6091
|
this.options.datetimepicker.language = this.options.datetimepicker.language || 'en';
|
5687
6092
|
|
@@ -5691,16 +6096,21 @@ $(function(){
|
|
5691
6096
|
//store parsed formats
|
5692
6097
|
this.parsedFormat = this.dpg.parseFormat(this.options.format, this.options.formatType);
|
5693
6098
|
this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat, this.options.formatType);
|
5694
|
-
|
5695
|
-
//
|
5696
|
-
this.options.datetimepicker.startView = this.options.startView;
|
5697
|
-
this.options.datetimepicker.minView = this.options.minView;
|
5698
|
-
this.options.datetimepicker.maxView = this.options.maxView;
|
5699
6099
|
},
|
5700
|
-
|
6100
|
+
|
5701
6101
|
render: function () {
|
5702
6102
|
this.$input.datetimepicker(this.options.datetimepicker);
|
5703
|
-
|
6103
|
+
|
6104
|
+
//adjust container position when viewMode changes
|
6105
|
+
//see https://github.com/smalot/bootstrap-datetimepicker/pull/80
|
6106
|
+
this.$input.on('changeMode', function(e) {
|
6107
|
+
var f = $(this).closest('form').parent();
|
6108
|
+
//timeout here, otherwise container changes position before form has new size
|
6109
|
+
setTimeout(function(){
|
6110
|
+
f.triggerHandler('resize');
|
6111
|
+
}, 0);
|
6112
|
+
});
|
6113
|
+
|
5704
6114
|
//"clear" link
|
5705
6115
|
if(this.options.clear) {
|
5706
6116
|
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
|
@@ -5708,11 +6118,11 @@ $(function(){
|
|
5708
6118
|
e.stopPropagation();
|
5709
6119
|
this.clear();
|
5710
6120
|
}, this));
|
5711
|
-
|
6121
|
+
|
5712
6122
|
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
|
5713
|
-
}
|
6123
|
+
}
|
5714
6124
|
},
|
5715
|
-
|
6125
|
+
|
5716
6126
|
value2html: function(value, element) {
|
5717
6127
|
//formatDate works with UTCDate!
|
5718
6128
|
var text = value ? this.dpg.formatDate(this.toUTC(value), this.parsedViewFormat, this.options.datetimepicker.language, this.options.formatType) : '';
|
@@ -5720,45 +6130,45 @@ $(function(){
|
|
5720
6130
|
DateTime.superclass.value2html(text, element);
|
5721
6131
|
} else {
|
5722
6132
|
return text;
|
5723
|
-
}
|
6133
|
+
}
|
5724
6134
|
},
|
5725
6135
|
|
5726
6136
|
html2value: function(html) {
|
5727
6137
|
//parseDate return utc date!
|
5728
|
-
var value =
|
6138
|
+
var value = this.parseDate(html, this.parsedViewFormat);
|
5729
6139
|
return value ? this.fromUTC(value) : null;
|
5730
|
-
},
|
5731
|
-
|
6140
|
+
},
|
6141
|
+
|
5732
6142
|
value2str: function(value) {
|
5733
6143
|
//formatDate works with UTCDate!
|
5734
6144
|
return value ? this.dpg.formatDate(this.toUTC(value), this.parsedFormat, this.options.datetimepicker.language, this.options.formatType) : '';
|
5735
|
-
},
|
5736
|
-
|
6145
|
+
},
|
6146
|
+
|
5737
6147
|
str2value: function(str) {
|
5738
6148
|
//parseDate return utc date!
|
5739
|
-
var value =
|
6149
|
+
var value = this.parseDate(str, this.parsedFormat);
|
5740
6150
|
return value ? this.fromUTC(value) : null;
|
5741
|
-
},
|
5742
|
-
|
6151
|
+
},
|
6152
|
+
|
5743
6153
|
value2submit: function(value) {
|
5744
6154
|
return this.value2str(value);
|
5745
|
-
},
|
6155
|
+
},
|
5746
6156
|
|
5747
6157
|
value2input: function(value) {
|
5748
6158
|
if(value) {
|
5749
6159
|
this.$input.data('datetimepicker').setDate(value);
|
5750
6160
|
}
|
5751
6161
|
},
|
5752
|
-
|
6162
|
+
|
5753
6163
|
input2value: function() {
|
5754
6164
|
//date may be cleared, in that case getDate() triggers error
|
5755
6165
|
var dt = this.$input.data('datetimepicker');
|
5756
6166
|
return dt.date ? dt.getDate() : null;
|
5757
|
-
},
|
5758
|
-
|
6167
|
+
},
|
6168
|
+
|
5759
6169
|
activate: function() {
|
5760
6170
|
},
|
5761
|
-
|
6171
|
+
|
5762
6172
|
clear: function() {
|
5763
6173
|
this.$input.data('datetimepicker').date = null;
|
5764
6174
|
this.$input.find('.active').removeClass('active');
|
@@ -5766,7 +6176,7 @@ $(function(){
|
|
5766
6176
|
this.$input.closest('form').submit();
|
5767
6177
|
}
|
5768
6178
|
},
|
5769
|
-
|
6179
|
+
|
5770
6180
|
autosubmit: function() {
|
5771
6181
|
this.$input.on('mouseup', '.minute', function(e){
|
5772
6182
|
var $form = $(this).closest('form');
|
@@ -5775,19 +6185,38 @@ $(function(){
|
|
5775
6185
|
}, 200);
|
5776
6186
|
});
|
5777
6187
|
},
|
5778
|
-
|
6188
|
+
|
5779
6189
|
//convert date from local to utc
|
5780
6190
|
toUTC: function(value) {
|
5781
6191
|
return value ? new Date(value.valueOf() - value.getTimezoneOffset() * 60000) : value;
|
5782
6192
|
},
|
5783
|
-
|
6193
|
+
|
5784
6194
|
//convert date from utc to local
|
5785
6195
|
fromUTC: function(value) {
|
5786
6196
|
return value ? new Date(value.valueOf() + value.getTimezoneOffset() * 60000) : value;
|
6197
|
+
},
|
6198
|
+
|
6199
|
+
/*
|
6200
|
+
For incorrect date bootstrap-datetimepicker returns current date that is not suitable
|
6201
|
+
for datetimefield.
|
6202
|
+
This function returns null for incorrect date.
|
6203
|
+
*/
|
6204
|
+
parseDate: function(str, format) {
|
6205
|
+
var date = null, formattedBack;
|
6206
|
+
if(str) {
|
6207
|
+
date = this.dpg.parseDate(str, format, this.options.datetimepicker.language, this.options.formatType);
|
6208
|
+
if(typeof str === 'string') {
|
6209
|
+
formattedBack = this.dpg.formatDate(date, format, this.options.datetimepicker.language, this.options.formatType);
|
6210
|
+
if(str !== formattedBack) {
|
6211
|
+
date = null;
|
6212
|
+
}
|
6213
|
+
}
|
6214
|
+
}
|
6215
|
+
return date;
|
5787
6216
|
}
|
5788
6217
|
|
5789
6218
|
});
|
5790
|
-
|
6219
|
+
|
5791
6220
|
DateTime.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
|
5792
6221
|
/**
|
5793
6222
|
@property tpl
|
@@ -5797,7 +6226,7 @@ $(function(){
|
|
5797
6226
|
/**
|
5798
6227
|
@property inputclass
|
5799
6228
|
@default null
|
5800
|
-
**/
|
6229
|
+
**/
|
5801
6230
|
inputclass: null,
|
5802
6231
|
/**
|
5803
6232
|
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
|
@@ -5816,12 +6245,12 @@ $(function(){
|
|
5816
6245
|
@property viewformat
|
5817
6246
|
@type string
|
5818
6247
|
@default null
|
5819
|
-
**/
|
5820
|
-
viewformat: null,
|
6248
|
+
**/
|
6249
|
+
viewformat: null,
|
5821
6250
|
/**
|
5822
6251
|
Configuration of datetimepicker.
|
5823
6252
|
Full list of options: https://github.com/smalot/bootstrap-datetimepicker
|
5824
|
-
|
6253
|
+
|
5825
6254
|
@property datetimepicker
|
5826
6255
|
@type object
|
5827
6256
|
@default { }
|
@@ -5833,13 +6262,13 @@ $(function(){
|
|
5833
6262
|
/**
|
5834
6263
|
Text shown as clear date button.
|
5835
6264
|
If <code>false</code> clear button will not be rendered.
|
5836
|
-
|
6265
|
+
|
5837
6266
|
@property clear
|
5838
6267
|
@type boolean|string
|
5839
|
-
@default 'x clear'
|
6268
|
+
@default 'x clear'
|
5840
6269
|
**/
|
5841
6270
|
clear: '× clear'
|
5842
|
-
});
|
6271
|
+
});
|
5843
6272
|
|
5844
6273
|
$.fn.editabletypes.datetime = DateTime;
|
5845
6274
|
|