rails_admin 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rails_admin/jquery.migrate.js +3 -0
  3. data/app/assets/javascripts/rails_admin/ra.filter-box.js +1 -4
  4. data/app/assets/javascripts/rails_admin/ra.nested-form-hooks.js +3 -3
  5. data/app/assets/javascripts/rails_admin/ra.widgets.js +1 -1
  6. data/app/assets/javascripts/rails_admin/rails_admin.js +2 -1
  7. data/app/assets/javascripts/rails_admin/ui.js +2 -2
  8. data/app/helpers/rails_admin/form_builder.rb +2 -0
  9. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +1 -1
  10. data/lib/rails_admin/version.rb +2 -2
  11. data/vendor/assets/javascripts/rails_admin/bootstrap-datetimepicker.js +317 -150
  12. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-affix.js +50 -28
  13. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-alert.js +10 -7
  14. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-button.js +35 -20
  15. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-carousel.js +48 -25
  16. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-collapse.js +70 -28
  17. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-dropdown.js +56 -42
  18. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-modal.js +118 -40
  19. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-popover.js +26 -16
  20. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-scrollspy.js +29 -27
  21. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-tab.js +46 -19
  22. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-tooltip.js +280 -60
  23. data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-transition.js +5 -5
  24. data/vendor/assets/javascripts/rails_admin/jquery.pjax.js +317 -160
  25. data/vendor/assets/javascripts/rails_admin/moment-with-locales.js +11210 -9290
  26. metadata +3 -3
  27. data/config/initializers/devise_patch.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e91bcbfc9a80b1718903e12a7a806f295115aab1917a5613632a9ee50a9b7973
4
- data.tar.gz: 278d75adfbb87dbfc1751f9c510eba68a13809873fce08dc6ed6e53355f0b9c8
3
+ metadata.gz: 36b3499d6b3b8d89882cdd41af33bfd4e4bf97fd5b035664ea73fda237a62279
4
+ data.tar.gz: d842cfc1f2dd3ec81aebf7c0fcf49111a0945d27abf07465fdf80c178e21d410
5
5
  SHA512:
6
- metadata.gz: 7a8fefb5416435b1e0a7622f6c6fc547b356b8d9e33fc30ea715030a33f4957952a587830a68565c574e50c1b3f6c98327a039accf75389a6d053a03c884be84
7
- data.tar.gz: 85258795ff168eff5d247eb77cec0a8fd1b630e830eb17b8144914592e3d3fd50808c924248cca101c13a8a21683e75eb5a6407b768d3580bd04daef412b339f
6
+ metadata.gz: 97579593acfe1b195682a979192b5c7436ba46ab4ba63c33ae9d4fa1f682b45f6a09fb80ecb66cc7aaac6ff23c744cbb2bf86b6ee22dc82e01d17a6edde24cd6
7
+ data.tar.gz: 2d4980005f040bebcccce89d734ed296d01ad0573b74dd8264af8cf308ff4b948766de73071c4762639058d40cefefbb33022f0acc1c650ad55aea70e314538f
@@ -0,0 +1,3 @@
1
+ /*! jQuery Migrate v3.3.3-pre | (c) OpenJS Foundation and other contributors | jquery.org/license */
2
+ "undefined"==typeof jQuery.migrateMute&&(jQuery.migrateMute=!0),function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e,window)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery"),window):t(jQuery,window)}(function(s,n){"use strict";function e(e){return 0<=function(e,t){for(var r=/^(\d+)\.(\d+)\.(\d+)/,n=r.exec(e)||[],o=r.exec(t)||[],i=1;i<=3;i++){if(+o[i]<+n[i])return 1;if(+n[i]<+o[i])return-1}return 0}(s.fn.jquery,e)}s.migrateVersion="3.3.3-pre",n.console&&n.console.log&&(s&&e("3.0.0")||n.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),s.migrateWarnings&&n.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),n.console.log("JQMIGRATE: Migrate is installed"+(s.migrateMute?"":" with logging active")+", version "+s.migrateVersion));var r={};function u(e){var t=n.console;s.migrateDeduplicateWarnings&&r[e]||(r[e]=!0,s.migrateWarnings.push(e),t&&t.warn&&!s.migrateMute&&(t.warn("JQMIGRATE: "+e),s.migrateTrace&&t.trace&&t.trace()))}function t(e,t,r,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return u(n),r},set:function(e){u(n),r=e}})}function o(e,t,r,n){e[t]=function(){return u(n),r.apply(this,arguments)}}s.migrateDeduplicateWarnings=!0,s.migrateWarnings=[],void 0===s.migrateTrace&&(s.migrateTrace=!0),s.migrateReset=function(){r={},s.migrateWarnings.length=0},"BackCompat"===n.document.compatMode&&u("jQuery is not compatible with Quirks Mode");var i,a,c,d={},l=s.fn.init,p=s.find,f=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,y=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,m=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;for(i in s.fn.init=function(e){var t=Array.prototype.slice.call(arguments);return"string"==typeof e&&"#"===e&&(u("jQuery( '#' ) is not a valid selector"),t[0]=[]),l.apply(this,t)},s.fn.init.prototype=s.fn,s.find=function(t){var r=Array.prototype.slice.call(arguments);if("string"==typeof t&&f.test(t))try{n.document.querySelector(t)}catch(e){t=t.replace(y,function(e,t,r,n){return"["+t+r+'"'+n+'"]'});try{n.document.querySelector(t),u("Attribute selector with '#' must be quoted: "+r[0]),r[0]=t}catch(e){u("Attribute selector with '#' was not fixed: "+r[0])}}return p.apply(this,r)},p)Object.prototype.hasOwnProperty.call(p,i)&&(s.find[i]=p[i]);o(s.fn,"size",function(){return this.length},"jQuery.fn.size() is deprecated and removed; use the .length property"),o(s,"parseJSON",function(){return JSON.parse.apply(null,arguments)},"jQuery.parseJSON is deprecated; use JSON.parse"),o(s,"holdReady",s.holdReady,"jQuery.holdReady is deprecated"),o(s,"unique",s.uniqueSort,"jQuery.unique is deprecated; use jQuery.uniqueSort"),t(s.expr,"filters",s.expr.pseudos,"jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),t(s.expr,":",s.expr.pseudos,"jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"),e("3.1.1")&&o(s,"trim",function(e){return null==e?"":(e+"").replace(m,"")},"jQuery.trim is deprecated; use String.prototype.trim"),e("3.2.0")&&(o(s,"nodeName",function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},"jQuery.nodeName is deprecated"),o(s,"isArray",Array.isArray,"jQuery.isArray is deprecated; use Array.isArray")),e("3.3.0")&&(o(s,"isNumeric",function(e){var t=typeof e;return("number"==t||"string"==t)&&!isNaN(e-parseFloat(e))},"jQuery.isNumeric() is deprecated"),s.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){d["[object "+t+"]"]=t.toLowerCase()}),o(s,"type",function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?d[Object.prototype.toString.call(e)]||"object":typeof e},"jQuery.type is deprecated"),o(s,"isFunction",function(e){return"function"==typeof e},"jQuery.isFunction() is deprecated"),o(s,"isWindow",function(e){return null!=e&&e===e.window},"jQuery.isWindow() is deprecated")),s.ajax&&(a=s.ajax,c=/(=)\?(?=&|$)|\?\?/,s.ajax=function(){var e=a.apply(this,arguments);return e.promise&&(o(e,"success",e.done,"jQXHR.success is deprecated and removed"),o(e,"error",e.fail,"jQXHR.error is deprecated and removed"),o(e,"complete",e.always,"jQXHR.complete is deprecated and removed")),e},e("4.0.0")||s.ajaxPrefilter("+json",function(e){!1!==e.jsonp&&(c.test(e.url)||"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&c.test(e.data))&&u("JSON-to-JSONP auto-promotion is deprecated")}));var g=s.fn.removeAttr,h=s.fn.toggleClass,v=/\S+/g;function j(e){return e.replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})}s.fn.removeAttr=function(e){var r=this;return s.each(e.match(v),function(e,t){s.expr.match.bool.test(t)&&(u("jQuery.fn.removeAttr no longer sets boolean properties: "+t),r.prop(t,!1))}),g.apply(this,arguments)};var Q,b=!(s.fn.toggleClass=function(t){return void 0!==t&&"boolean"!=typeof t?h.apply(this,arguments):(u("jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var e=this.getAttribute&&this.getAttribute("class")||"";e&&s.data(this,"__className__",e),this.setAttribute&&this.setAttribute("class",!e&&!1!==t&&s.data(this,"__className__")||"")}))}),w=/^[a-z]/,x=/^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;s.swap&&s.each(["height","width","reliableMarginRight"],function(e,t){var r=s.cssHooks[t]&&s.cssHooks[t].get;r&&(s.cssHooks[t].get=function(){var e;return b=!0,e=r.apply(this,arguments),b=!1,e})}),s.swap=function(e,t,r,n){var o,i,a={};for(i in b||u("jQuery.swap() is undocumented and deprecated"),t)a[i]=e.style[i],e.style[i]=t[i];for(i in o=r.apply(e,n||[]),t)e.style[i]=a[i];return o},e("3.4.0")&&"undefined"!=typeof Proxy&&(s.cssProps=new Proxy(s.cssProps||{},{set:function(){return u("JQMIGRATE: jQuery.cssProps is deprecated"),Reflect.set.apply(this,arguments)}})),s.cssNumber||(s.cssNumber={}),Q=s.fn.css,s.fn.css=function(e,t){var r,n,o=this;return e&&"object"==typeof e&&!Array.isArray(e)?(s.each(e,function(e,t){s.fn.css.call(o,e,t)}),this):("number"==typeof t&&(r=j(e),n=r,w.test(n)&&x.test(n[0].toUpperCase()+n.slice(1))||s.cssNumber[r]||u('Number-typed values are deprecated for jQuery.fn.css( "'+e+'", value )')),Q.apply(this,arguments))};var A,k,S,M,N=s.data;s.data=function(e,t,r){var n,o,i;if(t&&"object"==typeof t&&2===arguments.length){for(i in n=s.hasData(e)&&N.call(this,e),o={},t)i!==j(i)?(u("jQuery.data() always sets/gets camelCased names: "+i),n[i]=t[i]):o[i]=t[i];return N.call(this,e,o),t}return t&&"string"==typeof t&&t!==j(t)&&(n=s.hasData(e)&&N.call(this,e))&&t in n?(u("jQuery.data() always sets/gets camelCased names: "+t),2<arguments.length&&(n[t]=r),n[t]):N.apply(this,arguments)},s.fx&&(S=s.Tween.prototype.run,M=function(e){return e},s.Tween.prototype.run=function(){1<s.easing[this.easing].length&&(u("'jQuery.easing."+this.easing.toString()+"' should use only one argument"),s.easing[this.easing]=M),S.apply(this,arguments)},A=s.fx.interval||13,k="jQuery.fx.interval is deprecated",n.requestAnimationFrame&&Object.defineProperty(s.fx,"interval",{configurable:!0,enumerable:!0,get:function(){return n.document.hidden||u(k),A},set:function(e){u(k),A=e}}));var R=s.fn.load,H=s.event.add,C=s.event.fix;s.event.props=[],s.event.fixHooks={},t(s.event.props,"concat",s.event.props.concat,"jQuery.event.props.concat() is deprecated and removed"),s.event.fix=function(e){var t,r=e.type,n=this.fixHooks[r],o=s.event.props;if(o.length){u("jQuery.event.props are deprecated and removed: "+o.join());while(o.length)s.event.addProp(o.pop())}if(n&&!n._migrated_&&(n._migrated_=!0,u("jQuery.event.fixHooks are deprecated and removed: "+r),(o=n.props)&&o.length))while(o.length)s.event.addProp(o.pop());return t=C.call(this,e),n&&n.filter?n.filter(t,e):t},s.event.add=function(e,t){return e===n&&"load"===t&&"complete"===n.document.readyState&&u("jQuery(window).on('load'...) called after load event occurred"),H.apply(this,arguments)},s.each(["load","unload","error"],function(e,t){s.fn[t]=function(){var e=Array.prototype.slice.call(arguments,0);return"load"===t&&"string"==typeof e[0]?R.apply(this,e):(u("jQuery.fn."+t+"() is deprecated"),e.splice(0,0,t),arguments.length?this.on.apply(this,e):(this.triggerHandler.apply(this,e),this))}}),s.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,r){s.fn[r]=function(e,t){return u("jQuery.fn."+r+"() event shorthand is deprecated"),0<arguments.length?this.on(r,null,e,t):this.trigger(r)}}),s(function(){s(n.document).triggerHandler("ready")}),s.event.special.ready={setup:function(){this===n.document&&u("'ready' event is deprecated")}},s.fn.extend({bind:function(e,t,r){return u("jQuery.fn.bind() is deprecated"),this.on(e,null,t,r)},unbind:function(e,t){return u("jQuery.fn.unbind() is deprecated"),this.off(e,null,t)},delegate:function(e,t,r,n){return u("jQuery.fn.delegate() is deprecated"),this.on(t,e,r,n)},undelegate:function(e,t,r){return u("jQuery.fn.undelegate() is deprecated"),1===arguments.length?this.off(e,"**"):this.off(t,e||"**",r)},hover:function(e,t){return u("jQuery.fn.hover() is deprecated"),this.on("mouseenter",e).on("mouseleave",t||e)}});function T(e){var t=n.document.implementation.createHTMLDocument("");return t.body.innerHTML=e,t.body&&t.body.innerHTML}function P(e){var t=e.replace(O,"<$1></$2>");t!==e&&T(e)!==T(t)&&u("HTML tags must be properly nested and closed: "+e)}var O=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,q=s.htmlPrefilter;s.UNSAFE_restoreLegacyHtmlPrefilter=function(){s.htmlPrefilter=function(e){return P(e),e.replace(O,"<$1></$2>")}},s.htmlPrefilter=function(e){return P(e),q(e)};var D,_=s.fn.offset;s.fn.offset=function(){var e=this[0];return!e||e.nodeType&&e.getBoundingClientRect?_.apply(this,arguments):(u("jQuery.fn.offset() requires a valid DOM element"),arguments.length?this:void 0)},s.ajax&&(D=s.param,s.param=function(e,t){var r=s.ajaxSettings&&s.ajaxSettings.traditional;return void 0===t&&r&&(u("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),t=r),D.call(this,e,t)});var E,F,J=s.fn.andSelf||s.fn.addBack;return s.fn.andSelf=function(){return u("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),J.apply(this,arguments)},s.Deferred&&(E=s.Deferred,F=[["resolve","done",s.Callbacks("once memory"),s.Callbacks("once memory"),"resolved"],["reject","fail",s.Callbacks("once memory"),s.Callbacks("once memory"),"rejected"],["notify","progress",s.Callbacks("memory"),s.Callbacks("memory")]],s.Deferred=function(e){var i=E(),a=i.promise();return i.pipe=a.pipe=function(){var o=arguments;return u("deferred.pipe() is deprecated"),s.Deferred(function(n){s.each(F,function(e,t){var r="function"==typeof o[e]&&o[e];i[t[1]](function(){var e=r&&r.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[t[0]+"With"](this===a?n.promise():this,r?[e]:arguments)})}),o=null}).promise()},e&&e.call(i,i),i},s.Deferred.exceptionHook=E.exceptionHook),s});
3
+ //# sourceMappingURL=jquery-migrate.min.map
@@ -93,14 +93,11 @@
93
93
  .prop('name', multiple_values ? undefined : value_name)
94
94
  .data('name', value_name)
95
95
  .append('<option value="_discard">...</option>')
96
- if (!required) {
97
- control.append([
96
+ .append(required ? [] : [
98
97
  $('<option value="_present"></option>').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")),
99
98
  $('<option value="_blank"></option>').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank")),
100
99
  '<option disabled="disabled">---------</option>'
101
100
  ])
102
- }
103
- control.append(select_options)
104
101
  .add(
105
102
  $('<select multiple="multiple" class="select-multiple input-sm form-control"></select>')
106
103
  .css('display', multiple_values ? 'inline-block' : 'none')
@@ -24,9 +24,9 @@
24
24
  $(window.document).trigger('rails_admin.dom_ready', [field, parent_group]);
25
25
  new_tab.children('a').tab('show');
26
26
  if (!one_to_one) {
27
- nav.select(':hidden').show('slow');
27
+ nav.filter(':hidden').show('slow');
28
28
  }
29
- content.select(':hidden').show('slow');
29
+ content.filter(':hidden').show('slow');
30
30
  toggler.addClass('active').removeClass('disabled').children('i').addClass('icon-chevron-down').removeClass('icon-chevron-right');
31
31
  if (one_to_one) {
32
32
  controls.find('.add_nested_fields').removeClass('add_nested_fields').text(field.children('.object-infos').data('object-label'));
@@ -45,7 +45,7 @@
45
45
  (current_li.next().length ? current_li.next() : current_li.prev()).children('a:first').tab('show');
46
46
  current_li.remove();
47
47
  if (nav.children().length === 0) {
48
- nav.select(':visible').hide('slow');
48
+ nav.filter(':visible').hide('slow');
49
49
  toggler.removeClass('active').addClass('disabled').children('i').removeClass('icon-chevron-down').addClass('icon-chevron-right');
50
50
  }
51
51
  if (one_to_one) {
@@ -172,7 +172,7 @@
172
172
  field.find('> .controls .add_nested_fields').removeClass('add_nested_fields').text($(this).children('.object-infos').data('object-label'));
173
173
  nav.append(
174
174
  $('<li></li>').append(
175
- $('<a></a>').attr('data-toggle', 'tab').attr('href', '#' + this.id).text($(this).children('.object-infos').data('object-label'))
175
+ $('<a></a>').attr('data-toggle', 'tab').attr('href', '#' + $(this).id).text($(this).children('.object-infos').data('object-label'))
176
176
  )
177
177
  );
178
178
  });
@@ -1,4 +1,5 @@
1
- //= require 'jquery'
1
+ //= require 'jquery3'
2
+ //= require 'rails_admin/jquery.migrate'
2
3
  //= require 'jquery_ujs'
3
4
  //= require 'jquery.remotipart'
4
5
  //= require 'rails_admin/jquery-ui'
@@ -44,11 +44,11 @@
44
44
  if (!$(this).hasClass('disabled')) {
45
45
  if ($(this).has('i.icon-chevron-down').length) {
46
46
  $(this).removeClass('active').children('i').toggleClass('icon-chevron-down icon-chevron-right');
47
- $($(this).data('target')).select(':visible').hide('slow');
47
+ $($(this).data('target')).filter(':visible').hide('slow');
48
48
  } else {
49
49
  if ($(this).has('i.icon-chevron-right').length) {
50
50
  $(this).addClass('active').children('i').toggleClass('icon-chevron-down icon-chevron-right');
51
- $($(this).data('target')).select(':hidden').show('slow');
51
+ $($(this).data('target')).filter(':hidden').show('slow');
52
52
  }
53
53
  }
54
54
  }
@@ -1,3 +1,5 @@
1
+ require 'nested_form/builder_mixin'
2
+
1
3
  module RailsAdmin
2
4
  class FormBuilder < ::ActionView::Helpers::FormBuilder
3
5
  include ::NestedForm::BuilderMixin
@@ -116,7 +116,7 @@ module RailsAdmin
116
116
 
117
117
  current_page = page.presence || '1'
118
118
 
119
- versions = object.nil? ? versions_for_model(model) : object.versions
119
+ versions = object.nil? ? versions_for_model(model) : object.public_send(model.model.versions_association_name)
120
120
  versions = versions.where('event LIKE ?', "%#{query}%") if query.present?
121
121
  versions = versions.order(sort_reverse == 'true' ? "#{sort} DESC" : sort)
122
122
  versions = all ? versions : versions.send(Kaminari.config.page_method_name, current_page).per(per_page)
@@ -1,8 +1,8 @@
1
1
  module RailsAdmin
2
2
  class Version
3
3
  MAJOR = 2
4
- MINOR = 1
5
- PATCH = 1
4
+ MINOR = 2
5
+ PATCH = 0
6
6
  PRE = nil
7
7
 
8
8
  class << self
@@ -1,33 +1,8 @@
1
- /*! version : 4.14.30
2
- =========================================================
3
- bootstrap-datetimejs
4
- https://github.com/Eonasdan/bootstrap-datetimepicker
5
- Copyright (c) 2015 Jonathan Peterson
6
- =========================================================
7
- */
8
- /*
9
- The MIT License (MIT)
10
-
11
- Copyright (c) 2015 Jonathan Peterson
12
-
13
- Permission is hereby granted, free of charge, to any person obtaining a copy
14
- of this software and associated documentation files (the "Software"), to deal
15
- in the Software without restriction, including without limitation the rights
16
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
- copies of the Software, and to permit persons to whom the Software is
18
- furnished to do so, subject to the following conditions:
19
-
20
- The above copyright notice and this permission notice shall be included in
21
- all copies or substantial portions of the Software.
22
-
23
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
- THE SOFTWARE.
30
- */
1
+ /*!
2
+ * Bootstrap Datetime Picker v4.17.49
3
+ * Copyright 2015-2020 Jonathan Peterson
4
+ * Licensed under MIT (https://github.com/Eonasdan/bootstrap-datetimepicker/blob/master/LICENSE)
5
+ */
31
6
  /*global define:false */
32
7
  /*global exports:false */
33
8
  /*global require:false */
@@ -39,7 +14,7 @@
39
14
  // AMD is used - Register as an anonymous module.
40
15
  define(['jquery', 'moment'], factory);
41
16
  } else if (typeof exports === 'object') {
42
- factory(require('jquery'), require('moment'));
17
+ module.exports = factory(require('jquery'), require('moment'));
43
18
  } else {
44
19
  // Neither AMD nor CommonJS used. Use global variables.
45
20
  if (typeof jQuery === 'undefined') {
@@ -58,8 +33,8 @@
58
33
 
59
34
  var dateTimePicker = function (element, options) {
60
35
  var picker = {},
61
- date = moment().startOf('d'),
62
- viewDate = date.clone(),
36
+ date,
37
+ viewDate,
63
38
  unset = true,
64
39
  input,
65
40
  component = false,
@@ -132,6 +107,34 @@
132
107
  * Private functions
133
108
  *
134
109
  ********************************************************************************/
110
+
111
+ hasTimeZone = function () {
112
+ return moment.tz !== undefined && options.timeZone !== undefined && options.timeZone !== null && options.timeZone !== '';
113
+ },
114
+
115
+ getMoment = function (d) {
116
+ var returnMoment;
117
+
118
+ if (d === undefined || d === null) {
119
+ returnMoment = moment(); //TODO should this use format? and locale?
120
+ } else if (moment.isDate(d) || moment.isMoment(d)) {
121
+ // If the date that is passed in is already a Date() or moment() object,
122
+ // pass it directly to moment.
123
+ returnMoment = moment(d);
124
+ } else if (hasTimeZone()) { // There is a string to parse and a default time zone
125
+ // parse with the tz function which takes a default time zone if it is not in the format string
126
+ returnMoment = moment.tz(d, parseFormats, options.useStrict, options.timeZone);
127
+ } else {
128
+ returnMoment = moment(d, parseFormats, options.useStrict);
129
+ }
130
+
131
+ if (hasTimeZone()) {
132
+ returnMoment.tz(options.timeZone);
133
+ }
134
+
135
+ return returnMoment;
136
+ },
137
+
135
138
  isEnabled = function (granularity) {
136
139
  if (typeof granularity !== 'string' || granularity.length > 1) {
137
140
  throw new TypeError('isEnabled expects a single character string parameter');
@@ -154,6 +157,7 @@
154
157
  return false;
155
158
  }
156
159
  },
160
+
157
161
  hasTime = function () {
158
162
  return (isEnabled('h') || isEnabled('m') || isEnabled('s'));
159
163
  },
@@ -209,13 +213,11 @@
209
213
 
210
214
  if (isEnabled('h')) {
211
215
  topRow.append($('<td>')
212
- .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Increment Hour'}).addClass('btn').attr('data-action', 'incrementHours')
213
- .append($('<span>').addClass(options.icons.up))));
216
+ .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementHour }).addClass('btn').attr('data-action', 'incrementHours').append($('<span>').addClass(options.icons.up))));
214
217
  middleRow.append($('<td>')
215
- .append($('<span>').addClass('timepicker-hour').attr({'data-time-component':'hours', 'title':'Pick Hour'}).attr('data-action', 'showHours')));
218
+ .append($('<span>').addClass('timepicker-hour').attr({ 'data-time-component': 'hours', 'title': options.tooltips.pickHour }).attr('data-action', 'showHours')));
216
219
  bottomRow.append($('<td>')
217
- .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Decrement Hour'}).addClass('btn').attr('data-action', 'decrementHours')
218
- .append($('<span>').addClass(options.icons.down))));
220
+ .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementHour }).addClass('btn').attr('data-action', 'decrementHours').append($('<span>').addClass(options.icons.down))));
219
221
  }
220
222
  if (isEnabled('m')) {
221
223
  if (isEnabled('h')) {
@@ -224,12 +226,12 @@
224
226
  bottomRow.append($('<td>').addClass('separator'));
225
227
  }
226
228
  topRow.append($('<td>')
227
- .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Increment Minute'}).addClass('btn').attr('data-action', 'incrementMinutes')
229
+ .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementMinute }).addClass('btn').attr('data-action', 'incrementMinutes')
228
230
  .append($('<span>').addClass(options.icons.up))));
229
231
  middleRow.append($('<td>')
230
- .append($('<span>').addClass('timepicker-minute').attr({'data-time-component': 'minutes', 'title':'Pick Minute'}).attr('data-action', 'showMinutes')));
232
+ .append($('<span>').addClass('timepicker-minute').attr({ 'data-time-component': 'minutes', 'title': options.tooltips.pickMinute }).attr('data-action', 'showMinutes')));
231
233
  bottomRow.append($('<td>')
232
- .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Decrement Minute'}).addClass('btn').attr('data-action', 'decrementMinutes')
234
+ .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementMinute }).addClass('btn').attr('data-action', 'decrementMinutes')
233
235
  .append($('<span>').addClass(options.icons.down))));
234
236
  }
235
237
  if (isEnabled('s')) {
@@ -239,19 +241,19 @@
239
241
  bottomRow.append($('<td>').addClass('separator'));
240
242
  }
241
243
  topRow.append($('<td>')
242
- .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Increment Second'}).addClass('btn').attr('data-action', 'incrementSeconds')
244
+ .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementSecond }).addClass('btn').attr('data-action', 'incrementSeconds')
243
245
  .append($('<span>').addClass(options.icons.up))));
244
246
  middleRow.append($('<td>')
245
- .append($('<span>').addClass('timepicker-second').attr({'data-time-component': 'seconds', 'title':'Pick Second'}).attr('data-action', 'showSeconds')));
247
+ .append($('<span>').addClass('timepicker-second').attr({ 'data-time-component': 'seconds', 'title': options.tooltips.pickSecond }).attr('data-action', 'showSeconds')));
246
248
  bottomRow.append($('<td>')
247
- .append($('<a>').attr({href: '#', tabindex: '-1', 'title':'Decrement Second'}).addClass('btn').attr('data-action', 'decrementSeconds')
249
+ .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementSecond }).addClass('btn').attr('data-action', 'decrementSeconds')
248
250
  .append($('<span>').addClass(options.icons.down))));
249
251
  }
250
252
 
251
253
  if (!use24Hours) {
252
254
  topRow.append($('<td>').addClass('separator'));
253
255
  middleRow.append($('<td>')
254
- .append($('<button>').addClass('btn btn-primary').attr({'data-action': 'togglePeriod', tabindex: '-1', 'title':'Toggle Period'})));
256
+ .append($('<button>').addClass('btn btn-primary').attr({ 'data-action': 'togglePeriod', tabindex: '-1', 'title': options.tooltips.togglePeriod })));
255
257
  bottomRow.append($('<td>').addClass('separator'));
256
258
  }
257
259
 
@@ -285,16 +287,16 @@
285
287
  getToolbar = function () {
286
288
  var row = [];
287
289
  if (options.showTodayButton) {
288
- row.push($('<td>').append($('<a>').attr({'data-action':'today', 'title':'Go to today'}).append($('<span>').addClass(options.icons.today))));
290
+ row.push($('<td>').append($('<a>').attr({ 'data-action': 'today', 'title': options.tooltips.today }).append($('<span>').addClass(options.icons.today))));
289
291
  }
290
292
  if (!options.sideBySide && hasDate() && hasTime()) {
291
- row.push($('<td>').append($('<a>').attr({'data-action':'togglePicker', 'title':'Select Time'}).append($('<span>').addClass(options.icons.time))));
293
+ row.push($('<td>').append($('<a>').attr({ 'data-action': 'togglePicker', 'title': options.tooltips.selectTime }).append($('<span>').addClass(options.icons.time))));
292
294
  }
293
295
  if (options.showClear) {
294
- row.push($('<td>').append($('<a>').attr({'data-action':'clear', 'title':'Clear selection'}).append($('<span>').addClass(options.icons.clear))));
296
+ row.push($('<td>').append($('<a>').attr({ 'data-action': 'clear', 'title': options.tooltips.clear }).append($('<span>').addClass(options.icons.clear))));
295
297
  }
296
298
  if (options.showClose) {
297
- row.push($('<td>').append($('<a>').attr({'data-action':'close', 'title':'Close the picker'}).append($('<span>').addClass(options.icons.close))));
299
+ row.push($('<td>').append($('<a>').attr({ 'data-action': 'close', 'title': options.tooltips.close }).append($('<span>').addClass(options.icons.close))));
298
300
  }
299
301
  return $('<table>').addClass('table-condensed').append($('<tbody>').append($('<tr>').append(row)));
300
302
  },
@@ -313,17 +315,24 @@
313
315
  if (use24Hours) {
314
316
  template.addClass('usetwentyfour');
315
317
  }
318
+
316
319
  if (isEnabled('s') && !use24Hours) {
317
320
  template.addClass('wider');
318
321
  }
322
+
319
323
  if (options.sideBySide && hasDate() && hasTime()) {
320
324
  template.addClass('timepicker-sbs');
325
+ if (options.toolbarPlacement === 'top') {
326
+ template.append(toolbar);
327
+ }
321
328
  template.append(
322
329
  $('<div>').addClass('row')
323
- .append(dateView.addClass('col-sm-6'))
324
- .append(timeView.addClass('col-sm-6'))
330
+ .append(dateView.addClass('col-md-6'))
331
+ .append(timeView.addClass('col-md-6'))
325
332
  );
326
- template.append(toolbar);
333
+ if (options.toolbarPlacement === 'bottom') {
334
+ template.append(toolbar);
335
+ }
327
336
  return template;
328
337
  }
329
338
 
@@ -419,20 +428,20 @@
419
428
  widget.removeClass('pull-right');
420
429
  }
421
430
 
422
- // find the first parent element that has a relative css positioning
423
- if (parent.css('position') !== 'relative') {
431
+ // find the first parent element that has a non-static css positioning
432
+ if (parent.css('position') === 'static') {
424
433
  parent = parent.parents().filter(function () {
425
- return $(this).css('position') === 'relative';
434
+ return $(this).css('position') !== 'static';
426
435
  }).first();
427
436
  }
428
437
 
429
438
  if (parent.length === 0) {
430
- throw new Error('datetimepicker component should be placed within a relative positioned container');
439
+ throw new Error('datetimepicker component should be placed within a non-static positioned container');
431
440
  }
432
441
 
433
442
  widget.css({
434
443
  top: vertical === 'top' ? 'auto' : position.top + element.outerHeight(),
435
- bottom: vertical === 'top' ? position.top + element.outerHeight() : 'auto',
444
+ bottom: vertical === 'top' ? parent.outerHeight() - (parent === element ? 0 : position.top) : 'auto',
436
445
  left: horizontal === 'left' ? (parent === element ? 0 : position.left) : 'auto',
437
446
  right: horizontal === 'left' ? 'auto' : parent.outerWidth() - element.outerWidth() - (parent === element ? 0 : position.left)
438
447
  });
@@ -552,9 +561,9 @@
552
561
  monthsViewHeader = monthsView.find('th'),
553
562
  months = monthsView.find('tbody').find('span');
554
563
 
555
- monthsViewHeader.eq(0).find('span').attr('title', 'Previous Year');
556
- monthsViewHeader.eq(1).attr('title', 'Select Year');
557
- monthsViewHeader.eq(2).find('span').attr('title', 'Next Year');
564
+ monthsViewHeader.eq(0).find('span').attr('title', options.tooltips.prevYear);
565
+ monthsViewHeader.eq(1).attr('title', options.tooltips.selectYear);
566
+ monthsViewHeader.eq(2).find('span').attr('title', options.tooltips.nextYear);
558
567
 
559
568
  monthsView.find('.disabled').removeClass('disabled');
560
569
 
@@ -587,9 +596,9 @@
587
596
  endYear = viewDate.clone().add(6, 'y'),
588
597
  html = '';
589
598
 
590
- yearsViewHeader.eq(0).find('span').attr('title', 'Previous Decade');
591
- yearsViewHeader.eq(1).attr('title', 'Select Decade');
592
- yearsViewHeader.eq(2).find('span').attr('title', 'Next Decade');
599
+ yearsViewHeader.eq(0).find('span').attr('title', options.tooltips.prevDecade);
600
+ yearsViewHeader.eq(1).attr('title', options.tooltips.selectDecade);
601
+ yearsViewHeader.eq(2).find('span').attr('title', options.tooltips.nextDecade);
593
602
 
594
603
  yearsView.find('.disabled').removeClass('disabled');
595
604
 
@@ -614,33 +623,41 @@
614
623
  updateDecades = function () {
615
624
  var decadesView = widget.find('.datepicker-decades'),
616
625
  decadesViewHeader = decadesView.find('th'),
617
- startDecade = viewDate.isBefore(moment({y: 1999})) ? moment({y: 1899}) : moment({y: 1999}),
626
+ startDecade = moment({ y: viewDate.year() - (viewDate.year() % 100) - 1 }),
618
627
  endDecade = startDecade.clone().add(100, 'y'),
628
+ startedAt = startDecade.clone(),
629
+ minDateDecade = false,
630
+ maxDateDecade = false,
631
+ endDecadeYear,
619
632
  html = '';
620
633
 
621
- decadesViewHeader.eq(0).find('span').attr('title', 'Previous Century');
622
- decadesViewHeader.eq(2).find('span').attr('title', 'Next Century');
634
+ decadesViewHeader.eq(0).find('span').attr('title', options.tooltips.prevCentury);
635
+ decadesViewHeader.eq(2).find('span').attr('title', options.tooltips.nextCentury);
623
636
 
624
637
  decadesView.find('.disabled').removeClass('disabled');
625
638
 
626
- if (startDecade.isSame(moment({y: 1900})) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) {
639
+ if (startDecade.isSame(moment({ y: 1900 })) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) {
627
640
  decadesViewHeader.eq(0).addClass('disabled');
628
641
  }
629
642
 
630
643
  decadesViewHeader.eq(1).text(startDecade.year() + '-' + endDecade.year());
631
644
 
632
- if (startDecade.isSame(moment({y: 2000})) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) {
645
+ if (startDecade.isSame(moment({ y: 2000 })) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) {
633
646
  decadesViewHeader.eq(2).addClass('disabled');
634
647
  }
635
648
 
636
649
  while (!startDecade.isAfter(endDecade, 'y')) {
637
- html += '<span data-action="selectDecade" class="decade' + (startDecade.isSame(date, 'y') ? ' active' : '') +
638
- (!isValid(startDecade, 'y') ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>';
650
+ endDecadeYear = startDecade.year() + 12;
651
+ minDateDecade = options.minDate && options.minDate.isAfter(startDecade, 'y') && options.minDate.year() <= endDecadeYear;
652
+ maxDateDecade = options.maxDate && options.maxDate.isAfter(startDecade, 'y') && options.maxDate.year() <= endDecadeYear;
653
+ html += '<span data-action="selectDecade" class="decade' + (date.isAfter(startDecade) && date.year() <= endDecadeYear ? ' active' : '') +
654
+ (!isValid(startDecade, 'y') && !minDateDecade && !maxDateDecade ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>';
639
655
  startDecade.add(12, 'y');
640
656
  }
641
657
  html += '<span></span><span></span><span></span>'; //push the dangling block over, at least this way it's even
642
658
 
643
659
  decadesView.find('td').html(html);
660
+ decadesViewHeader.eq(1).text((startedAt.year() + 1) + '-' + (startDecade.year()));
644
661
  },
645
662
 
646
663
  fillDate = function () {
@@ -649,16 +666,16 @@
649
666
  currentDate,
650
667
  html = [],
651
668
  row,
652
- clsName,
669
+ clsNames = [],
653
670
  i;
654
671
 
655
672
  if (!hasDate()) {
656
673
  return;
657
674
  }
658
675
 
659
- daysViewHeader.eq(0).find('span').attr('title', 'Previous Month');
660
- daysViewHeader.eq(1).attr('title', 'Select Month');
661
- daysViewHeader.eq(2).find('span').attr('title', 'Next Month');
676
+ daysViewHeader.eq(0).find('span').attr('title', options.tooltips.prevMonth);
677
+ daysViewHeader.eq(1).attr('title', options.tooltips.selectMonth);
678
+ daysViewHeader.eq(2).find('span').attr('title', options.tooltips.nextMonth);
662
679
 
663
680
  daysView.find('.disabled').removeClass('disabled');
664
681
  daysViewHeader.eq(1).text(viewDate.format(options.dayViewHeaderFormat));
@@ -680,26 +697,31 @@
680
697
  }
681
698
  html.push(row);
682
699
  }
683
- clsName = '';
700
+ clsNames = ['day'];
684
701
  if (currentDate.isBefore(viewDate, 'M')) {
685
- clsName += ' old';
702
+ clsNames.push('old');
686
703
  }
687
704
  if (currentDate.isAfter(viewDate, 'M')) {
688
- clsName += ' new';
705
+ clsNames.push('new');
689
706
  }
690
707
  if (currentDate.isSame(date, 'd') && !unset) {
691
- clsName += ' active';
708
+ clsNames.push('active');
692
709
  }
693
710
  if (!isValid(currentDate, 'd')) {
694
- clsName += ' disabled';
711
+ clsNames.push('disabled');
695
712
  }
696
- if (currentDate.isSame(moment(), 'd')) {
697
- clsName += ' today';
713
+ if (currentDate.isSame(getMoment(), 'd')) {
714
+ clsNames.push('today');
698
715
  }
699
716
  if (currentDate.day() === 0 || currentDate.day() === 6) {
700
- clsName += ' weekend';
717
+ clsNames.push('weekend');
701
718
  }
702
- row.append('<td data-action="selectDay" data-day="' + currentDate.format('L') + '" class="day' + clsName + '">' + currentDate.date() + '</td>');
719
+ notifyEvent({
720
+ type: 'dp.classify',
721
+ date: currentDate,
722
+ classNames: clsNames
723
+ });
724
+ row.append('<td data-action="selectDay" data-day="' + currentDate.format('L') + '" class="' + clsNames.join(' ') + '">' + currentDate.date() + '</td>');
703
725
  currentDate.add(1, 'd');
704
726
  }
705
727
 
@@ -819,8 +841,16 @@
819
841
 
820
842
  targetMoment = targetMoment.clone().locale(options.locale);
821
843
 
844
+ if (hasTimeZone()) {
845
+ targetMoment.tz(options.timeZone);
846
+ }
847
+
822
848
  if (options.stepping !== 1) {
823
- targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping) % 60).seconds(0);
849
+ targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping)).seconds(0);
850
+
851
+ while (options.minDate && targetMoment.isBefore(options.minDate)) {
852
+ targetMoment.add(options.stepping, 'minutes');
853
+ }
824
854
  }
825
855
 
826
856
  if (isValid(targetMoment)) {
@@ -838,16 +868,25 @@
838
868
  } else {
839
869
  if (!options.keepInvalid) {
840
870
  input.val(unset ? '' : date.format(actualFormat));
871
+ } else {
872
+ notifyEvent({
873
+ type: 'dp.change',
874
+ date: targetMoment,
875
+ oldDate: oldDate
876
+ });
841
877
  }
842
878
  notifyEvent({
843
879
  type: 'dp.error',
844
- date: targetMoment
880
+ date: targetMoment,
881
+ oldDate: oldDate
845
882
  });
846
883
  }
847
884
  },
848
885
 
886
+ /**
887
+ * Hides the widget. Possibly will emit dp.hide
888
+ */
849
889
  hide = function () {
850
- ///<summary>Hides the widget. Possibly will emit dp.hide</summary>
851
890
  var transitioning = false;
852
891
  if (!widget) {
853
892
  return picker;
@@ -880,6 +919,11 @@
880
919
  type: 'dp.hide',
881
920
  date: date.clone()
882
921
  });
922
+
923
+ input.blur();
924
+
925
+ viewDate = date.clone();
926
+
883
927
  return picker;
884
928
  },
885
929
 
@@ -887,6 +931,18 @@
887
931
  setValue(null);
888
932
  },
889
933
 
934
+ parseInputDate = function (inputDate) {
935
+ if (options.parseInputDate === undefined) {
936
+ if (!moment.isMoment(inputDate) || inputDate instanceof Date) {
937
+ inputDate = getMoment(inputDate);
938
+ }
939
+ } else {
940
+ inputDate = options.parseInputDate(inputDate);
941
+ }
942
+ //inputDate.locale(options.locale);
943
+ return inputDate;
944
+ },
945
+
890
946
  /********************************************************************************
891
947
  *
892
948
  * Widget UI interaction functions
@@ -1099,8 +1155,9 @@
1099
1155
  clear: clear,
1100
1156
 
1101
1157
  today: function () {
1102
- if (isValid(moment(), 'd')) {
1103
- setValue(moment());
1158
+ var todaysDate = getMoment();
1159
+ if (isValid(todaysDate, 'd')) {
1160
+ setValue(todaysDate);
1104
1161
  }
1105
1162
  },
1106
1163
 
@@ -1115,8 +1172,10 @@
1115
1172
  return false;
1116
1173
  },
1117
1174
 
1175
+ /**
1176
+ * Shows the widget. Possibly will emit dp.show and dp.change
1177
+ */
1118
1178
  show = function () {
1119
- ///<summary>Shows the widget. Possibly will emit dp.show and dp.change</summary>
1120
1179
  var currentMoment,
1121
1180
  useCurrentGranularity = {
1122
1181
  'year': function (m) {
@@ -1141,14 +1200,13 @@
1141
1200
  }
1142
1201
  if (input.val() !== undefined && input.val().trim().length !== 0) {
1143
1202
  setValue(parseInputDate(input.val().trim()));
1144
- } else if (options.useCurrent && unset && ((input.is('input') && input.val().trim().length === 0) || options.inline)) {
1145
- currentMoment = moment();
1203
+ } else if (unset && options.useCurrent && (options.inline || (input.is('input') && input.val().trim().length === 0))) {
1204
+ currentMoment = getMoment();
1146
1205
  if (typeof options.useCurrent === 'string') {
1147
1206
  currentMoment = useCurrentGranularity[options.useCurrent](currentMoment);
1148
1207
  }
1149
1208
  setValue(currentMoment);
1150
1209
  }
1151
-
1152
1210
  widget = getTemplate();
1153
1211
 
1154
1212
  fillDow();
@@ -1168,9 +1226,8 @@
1168
1226
  if (component && component.hasClass('btn')) {
1169
1227
  component.toggleClass('active');
1170
1228
  }
1171
- widget.show();
1172
1229
  place();
1173
-
1230
+ widget.show();
1174
1231
  if (options.focusOnShow && !input.is(':focus')) {
1175
1232
  input.focus();
1176
1233
  }
@@ -1181,25 +1238,13 @@
1181
1238
  return picker;
1182
1239
  },
1183
1240
 
1241
+ /**
1242
+ * Shows or hides the widget
1243
+ */
1184
1244
  toggle = function () {
1185
- /// <summary>Shows or hides the widget</summary>
1186
1245
  return (widget ? hide() : show());
1187
1246
  },
1188
1247
 
1189
- parseInputDate = function (inputDate) {
1190
- if (options.parseInputDate === undefined) {
1191
- if (moment.isMoment(inputDate) || inputDate instanceof Date) {
1192
- inputDate = moment(inputDate);
1193
- } else {
1194
- inputDate = moment(inputDate, parseFormats, options.useStrict);
1195
- }
1196
- } else {
1197
- inputDate = options.parseInputDate(inputDate);
1198
- }
1199
- inputDate.locale(options.locale);
1200
- return inputDate;
1201
- },
1202
-
1203
1248
  keydown = function (e) {
1204
1249
  var handler = null,
1205
1250
  index,
@@ -1284,7 +1329,7 @@
1284
1329
  detachDatePickerElementEvents = function () {
1285
1330
  input.off({
1286
1331
  'change': change,
1287
- 'blur': hide,
1332
+ 'blur': blur,
1288
1333
  'keydown': keydown,
1289
1334
  'keyup': keyup,
1290
1335
  'focus': options.allowInputToggle ? hide : ''
@@ -1467,7 +1512,7 @@
1467
1512
  }
1468
1513
 
1469
1514
  if ((typeof newFormat !== 'string') && ((typeof newFormat !== 'boolean') || (newFormat !== false))) {
1470
- throw new TypeError('format() expects a sting or boolean:false parameter ' + newFormat);
1515
+ throw new TypeError('format() expects a string or boolean:false parameter ' + newFormat);
1471
1516
  }
1472
1517
 
1473
1518
  options.format = newFormat;
@@ -1477,6 +1522,20 @@
1477
1522
  return picker;
1478
1523
  };
1479
1524
 
1525
+ picker.timeZone = function (newZone) {
1526
+ if (arguments.length === 0) {
1527
+ return options.timeZone;
1528
+ }
1529
+
1530
+ if (typeof newZone !== 'string') {
1531
+ throw new TypeError('newZone() expects a string parameter');
1532
+ }
1533
+
1534
+ options.timeZone = newZone;
1535
+
1536
+ return picker;
1537
+ };
1538
+
1480
1539
  picker.dayViewHeaderFormat = function (newFormat) {
1481
1540
  if (arguments.length === 0) {
1482
1541
  return options.dayViewHeaderFormat;
@@ -1589,8 +1648,8 @@
1589
1648
  var tries = 0;
1590
1649
  while (!isValid(date, 'd')) {
1591
1650
  date.add(1, 'd');
1592
- if (tries === 7) {
1593
- throw 'Tried 7 times to find a valid date';
1651
+ if (tries === 31) {
1652
+ throw 'Tried 31 times to find a valid date';
1594
1653
  }
1595
1654
  tries++;
1596
1655
  }
@@ -1613,7 +1672,7 @@
1613
1672
 
1614
1673
  if (typeof maxDate === 'string') {
1615
1674
  if (maxDate === 'now' || maxDate === 'moment') {
1616
- maxDate = moment();
1675
+ maxDate = getMoment();
1617
1676
  }
1618
1677
  }
1619
1678
 
@@ -1630,7 +1689,7 @@
1630
1689
  setValue(options.maxDate);
1631
1690
  }
1632
1691
  if (viewDate.isAfter(parsedDate)) {
1633
- viewDate = parsedDate.clone();
1692
+ viewDate = parsedDate.clone().subtract(options.stepping, 'm');
1634
1693
  }
1635
1694
  update();
1636
1695
  return picker;
@@ -1649,7 +1708,7 @@
1649
1708
 
1650
1709
  if (typeof minDate === 'string') {
1651
1710
  if (minDate === 'now' || minDate === 'moment') {
1652
- minDate = moment();
1711
+ minDate = getMoment();
1653
1712
  }
1654
1713
  }
1655
1714
 
@@ -1666,7 +1725,7 @@
1666
1725
  setValue(options.minDate);
1667
1726
  }
1668
1727
  if (viewDate.isBefore(parsedDate)) {
1669
- viewDate = parsedDate.clone();
1728
+ viewDate = parsedDate.clone().add(options.stepping, 'm');
1670
1729
  }
1671
1730
  update();
1672
1731
  return picker;
@@ -1691,7 +1750,9 @@
1691
1750
 
1692
1751
  if (typeof defaultDate === 'string') {
1693
1752
  if (defaultDate === 'now' || defaultDate === 'moment') {
1694
- defaultDate = moment();
1753
+ defaultDate = getMoment();
1754
+ } else {
1755
+ defaultDate = getMoment(defaultDate);
1695
1756
  }
1696
1757
  }
1697
1758
 
@@ -1705,7 +1766,7 @@
1705
1766
 
1706
1767
  options.defaultDate = parsedDate;
1707
1768
 
1708
- if (options.defaultDate && options.inline || (input.val().trim() === '' && input.attr('placeholder') === undefined)) {
1769
+ if ((options.defaultDate && options.inline) || input.val().trim() === '') {
1709
1770
  setValue(options.defaultDate);
1710
1771
  }
1711
1772
  return picker;
@@ -1798,6 +1859,22 @@
1798
1859
  return picker;
1799
1860
  };
1800
1861
 
1862
+ picker.tooltips = function (tooltips) {
1863
+ if (arguments.length === 0) {
1864
+ return $.extend({}, options.tooltips);
1865
+ }
1866
+
1867
+ if (!(tooltips instanceof Object)) {
1868
+ throw new TypeError('tooltips() expects parameter to be an Object');
1869
+ }
1870
+ $.extend(options.tooltips, tooltips);
1871
+ if (widget) {
1872
+ hide();
1873
+ show();
1874
+ }
1875
+ return picker;
1876
+ };
1877
+
1801
1878
  picker.useStrict = function (useStrict) {
1802
1879
  if (arguments.length === 0) {
1803
1880
  return options.useStrict;
@@ -2012,10 +2089,18 @@
2012
2089
  };
2013
2090
 
2014
2091
  picker.keyBinds = function (keyBinds) {
2092
+ if (arguments.length === 0) {
2093
+ return options.keyBinds;
2094
+ }
2095
+
2015
2096
  options.keyBinds = keyBinds;
2016
2097
  return picker;
2017
2098
  };
2018
2099
 
2100
+ picker.getMoment = function (d) {
2101
+ return getMoment(d);
2102
+ };
2103
+
2019
2104
  picker.debug = function (debug) {
2020
2105
  if (typeof debug !== 'boolean') {
2021
2106
  throw new TypeError('debug() expects a boolean parameter');
@@ -2193,16 +2278,12 @@
2193
2278
  update();
2194
2279
  return picker;
2195
2280
  };
2196
-
2281
+ /**
2282
+ * Returns the component's model current viewDate, a moment object or null if not set. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.
2283
+ * @param {Takes string, viewDate, moment, null parameter.} newDate
2284
+ * @returns {viewDate.clone()}
2285
+ */
2197
2286
  picker.viewDate = function (newDate) {
2198
- ///<signature helpKeyword="$.fn.datetimepicker.viewDate">
2199
- ///<summary>Returns the component's model current viewDate, a moment object or null if not set.</summary>
2200
- ///<returns type="Moment">viewDate.clone()</returns>
2201
- ///</signature>
2202
- ///<signature>
2203
- ///<summary>Sets the components model current moment to it. Passing a null value unsets the components model current moment. Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.</summary>
2204
- ///<param name="newDate" locid="$.fn.datetimepicker.date_p:newDate">Takes string, viewDate, moment, null parameter.</param>
2205
- ///</signature>
2206
2287
  if (arguments.length === 0) {
2207
2288
  return viewDate.clone();
2208
2289
  }
@@ -2226,7 +2307,7 @@
2226
2307
  input = element;
2227
2308
  } else {
2228
2309
  input = element.find(options.datepickerInput);
2229
- if (input.size() === 0) {
2310
+ if (input.length === 0) {
2230
2311
  input = element.find('input');
2231
2312
  } else if (!input.is('input')) {
2232
2313
  throw new Error('CSS class "' + options.datepickerInput + '" cannot be applied to non input element');
@@ -2235,8 +2316,8 @@
2235
2316
 
2236
2317
  if (element.hasClass('input-group')) {
2237
2318
  // in case there is more then one 'input-group-addon' Issue #48
2238
- if (element.find('.datepickerbutton').size() === 0) {
2239
- component = element.find('[class^="input-group-"]');
2319
+ if (element.find('.datepickerbutton').length === 0) {
2320
+ component = element.find('.input-group-addon');
2240
2321
  } else {
2241
2322
  component = element.find('.datepickerbutton');
2242
2323
  }
@@ -2246,6 +2327,10 @@
2246
2327
  throw new Error('Could not initialize DateTimePicker without an input element');
2247
2328
  }
2248
2329
 
2330
+ // Set defaults for date here now instead of in var declaration
2331
+ date = getMoment();
2332
+ viewDate = date.clone();
2333
+
2249
2334
  $.extend(true, options, dataToOptions());
2250
2335
 
2251
2336
  picker.options(options);
@@ -2275,18 +2360,68 @@
2275
2360
  *
2276
2361
  ********************************************************************************/
2277
2362
 
2363
+ /**
2364
+ * See (http://jquery.com/).
2365
+ * @name jQuery
2366
+ * @class
2367
+ * See the jQuery Library (http://jquery.com/) for full details. This just
2368
+ * documents the function and classes that are added to jQuery by this plug-in.
2369
+ */
2370
+ /**
2371
+ * See (http://jquery.com/)
2372
+ * @name fn
2373
+ * @class
2374
+ * See the jQuery Library (http://jquery.com/) for full details. This just
2375
+ * documents the function and classes that are added to jQuery by this plug-in.
2376
+ * @memberOf jQuery
2377
+ */
2378
+ /**
2379
+ * Show comments
2380
+ * @class datetimepicker
2381
+ * @memberOf jQuery.fn
2382
+ */
2278
2383
  $.fn.datetimepicker = function (options) {
2279
- return this.each(function () {
2280
- var $this = $(this);
2281
- if (!$this.data('DateTimePicker')) {
2282
- // create a private copy of the defaults object
2283
- options = $.extend(true, {}, $.fn.datetimepicker.defaults, options);
2284
- $this.data('DateTimePicker', dateTimePicker($this, options));
2285
- }
2286
- });
2384
+ options = options || {};
2385
+
2386
+ var args = Array.prototype.slice.call(arguments, 1),
2387
+ isInstance = true,
2388
+ thisMethods = ['destroy', 'hide', 'show', 'toggle'],
2389
+ returnValue;
2390
+
2391
+ if (typeof options === 'object') {
2392
+ return this.each(function () {
2393
+ var $this = $(this),
2394
+ _options;
2395
+ if (!$this.data('DateTimePicker')) {
2396
+ // create a private copy of the defaults object
2397
+ _options = $.extend(true, {}, $.fn.datetimepicker.defaults, options);
2398
+ $this.data('DateTimePicker', dateTimePicker($this, _options));
2399
+ }
2400
+ });
2401
+ } else if (typeof options === 'string') {
2402
+ this.each(function () {
2403
+ var $this = $(this),
2404
+ instance = $this.data('DateTimePicker');
2405
+ if (!instance) {
2406
+ throw new Error('bootstrap-datetimepicker("' + options + '") method was called on an element that is not using DateTimePicker');
2407
+ }
2408
+
2409
+ returnValue = instance[options].apply(instance, args);
2410
+ isInstance = returnValue === instance;
2411
+ });
2412
+
2413
+ if (isInstance || $.inArray(options, thisMethods) > -1) {
2414
+ return this;
2415
+ }
2416
+
2417
+ return returnValue;
2418
+ }
2419
+
2420
+ throw new TypeError('Invalid arguments for DateTimePicker: ' + options);
2287
2421
  };
2288
2422
 
2289
2423
  $.fn.datetimepicker.defaults = {
2424
+ timeZone: '',
2290
2425
  format: false,
2291
2426
  dayViewHeaderFormat: 'MMMM YYYY',
2292
2427
  extraFormats: false,
@@ -2310,6 +2445,33 @@
2310
2445
  clear: 'glyphicon glyphicon-trash',
2311
2446
  close: 'glyphicon glyphicon-remove'
2312
2447
  },
2448
+ tooltips: {
2449
+ today: 'Go to today',
2450
+ clear: 'Clear selection',
2451
+ close: 'Close the picker',
2452
+ selectMonth: 'Select Month',
2453
+ prevMonth: 'Previous Month',
2454
+ nextMonth: 'Next Month',
2455
+ selectYear: 'Select Year',
2456
+ prevYear: 'Previous Year',
2457
+ nextYear: 'Next Year',
2458
+ selectDecade: 'Select Decade',
2459
+ prevDecade: 'Previous Decade',
2460
+ nextDecade: 'Next Decade',
2461
+ prevCentury: 'Previous Century',
2462
+ nextCentury: 'Next Century',
2463
+ pickHour: 'Pick Hour',
2464
+ incrementHour: 'Increment Hour',
2465
+ decrementHour: 'Decrement Hour',
2466
+ pickMinute: 'Pick Minute',
2467
+ incrementMinute: 'Increment Minute',
2468
+ decrementMinute: 'Decrement Minute',
2469
+ pickSecond: 'Pick Second',
2470
+ incrementSecond: 'Increment Second',
2471
+ decrementSecond: 'Decrement Second',
2472
+ togglePeriod: 'Toggle Period',
2473
+ selectTime: 'Select Time'
2474
+ },
2313
2475
  useStrict: false,
2314
2476
  sideBySide: false,
2315
2477
  daysOfWeekDisabled: false,
@@ -2335,11 +2497,11 @@
2335
2497
  if (!widget) {
2336
2498
  return;
2337
2499
  }
2338
- var d = this.date() || moment();
2500
+ var d = this.date() || this.getMoment();
2339
2501
  if (widget.find('.datepicker').is(':visible')) {
2340
2502
  this.date(d.clone().subtract(7, 'd'));
2341
2503
  } else {
2342
- this.date(d.clone().add(1, 'm'));
2504
+ this.date(d.clone().add(this.stepping(), 'm'));
2343
2505
  }
2344
2506
  },
2345
2507
  down: function (widget) {
@@ -2347,18 +2509,18 @@
2347
2509
  this.show();
2348
2510
  return;
2349
2511
  }
2350
- var d = this.date() || moment();
2512
+ var d = this.date() || this.getMoment();
2351
2513
  if (widget.find('.datepicker').is(':visible')) {
2352
2514
  this.date(d.clone().add(7, 'd'));
2353
2515
  } else {
2354
- this.date(d.clone().subtract(1, 'm'));
2516
+ this.date(d.clone().subtract(this.stepping(), 'm'));
2355
2517
  }
2356
2518
  },
2357
2519
  'control up': function (widget) {
2358
2520
  if (!widget) {
2359
2521
  return;
2360
2522
  }
2361
- var d = this.date() || moment();
2523
+ var d = this.date() || this.getMoment();
2362
2524
  if (widget.find('.datepicker').is(':visible')) {
2363
2525
  this.date(d.clone().subtract(1, 'y'));
2364
2526
  } else {
@@ -2369,7 +2531,7 @@
2369
2531
  if (!widget) {
2370
2532
  return;
2371
2533
  }
2372
- var d = this.date() || moment();
2534
+ var d = this.date() || this.getMoment();
2373
2535
  if (widget.find('.datepicker').is(':visible')) {
2374
2536
  this.date(d.clone().add(1, 'y'));
2375
2537
  } else {
@@ -2380,7 +2542,7 @@
2380
2542
  if (!widget) {
2381
2543
  return;
2382
2544
  }
2383
- var d = this.date() || moment();
2545
+ var d = this.date() || this.getMoment();
2384
2546
  if (widget.find('.datepicker').is(':visible')) {
2385
2547
  this.date(d.clone().subtract(1, 'd'));
2386
2548
  }
@@ -2389,7 +2551,7 @@
2389
2551
  if (!widget) {
2390
2552
  return;
2391
2553
  }
2392
- var d = this.date() || moment();
2554
+ var d = this.date() || this.getMoment();
2393
2555
  if (widget.find('.datepicker').is(':visible')) {
2394
2556
  this.date(d.clone().add(1, 'd'));
2395
2557
  }
@@ -2398,7 +2560,7 @@
2398
2560
  if (!widget) {
2399
2561
  return;
2400
2562
  }
2401
- var d = this.date() || moment();
2563
+ var d = this.date() || this.getMoment();
2402
2564
  if (widget.find('.datepicker').is(':visible')) {
2403
2565
  this.date(d.clone().subtract(1, 'M'));
2404
2566
  }
@@ -2407,7 +2569,7 @@
2407
2569
  if (!widget) {
2408
2570
  return;
2409
2571
  }
2410
- var d = this.date() || moment();
2572
+ var d = this.date() || this.getMoment();
2411
2573
  if (widget.find('.datepicker').is(':visible')) {
2412
2574
  this.date(d.clone().add(1, 'M'));
2413
2575
  }
@@ -2423,12 +2585,15 @@
2423
2585
  // if(toggle.length > 0) toggle.click();
2424
2586
  //},
2425
2587
  'control space': function (widget) {
2588
+ if (!widget) {
2589
+ return;
2590
+ }
2426
2591
  if (widget.find('.timepicker').is(':visible')) {
2427
2592
  widget.find('.btn[data-action="togglePeriod"]').click();
2428
2593
  }
2429
2594
  },
2430
2595
  t: function () {
2431
- this.date(moment());
2596
+ this.date(this.getMoment());
2432
2597
  },
2433
2598
  'delete': function () {
2434
2599
  this.clear();
@@ -2441,4 +2606,6 @@
2441
2606
  enabledHours: false,
2442
2607
  viewDate: false
2443
2608
  };
2609
+
2610
+ return $.fn.datetimepicker;
2444
2611
  }));