bootstrap-editable-datepicker.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /**
  2. Bootstrap-datepicker.
  3. Description and examples: https://github.com/eternicode/bootstrap-datepicker.
  4. For **i18n** you should include js file from here: https://github.com/eternicode/bootstrap-datepicker/tree/master/js/locales
  5. and set `language` option.
  6. Since 1.4.0 date has different appearance in **popup** and **inline** modes.
  7. @class date
  8. @extends abstractinput
  9. @final
  10. @example
  11. <a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-title="Select date">15/05/1984</a>
  12. <script>
  13. $(function(){
  14. $('#dob').editable({
  15. format: 'yyyy-mm-dd',
  16. viewformat: 'dd/mm/yyyy',
  17. datepicker: {
  18. weekStart: 1
  19. }
  20. }
  21. });
  22. });
  23. </script>
  24. **/
  25. (function ($) {
  26. "use strict";
  27. //store bootstrap-datepicker as bdateicker to exclude conflict with jQuery UI one
  28. $.fn.bdatepicker = $.fn.datepicker.noConflict();
  29. if (!$.fn.datepicker) { //if there were no other datepickers, keep also original name
  30. $.fn.datepicker = $.fn.bdatepicker;
  31. }
  32. var Date = function (options) {
  33. this.init('date', options, Date.defaults);
  34. this.initPicker(options, Date.defaults);
  35. };
  36. $.fn.editableutils.inherit(Date, $.fn.editabletypes.abstractinput);
  37. $.extend(Date.prototype, {
  38. dateValue: null,
  39. initPicker: function (options, defaults) {
  40. //'format' is set directly from settings or data-* attributes
  41. //by default viewformat equals to format
  42. if (!this.options.viewformat) {
  43. this.options.viewformat = this.options.format;
  44. }
  45. //try parse datepicker config defined as json string in data-datepicker
  46. options.datepicker = $.fn.editableutils.tryParseJson(options.datepicker, true);
  47. //overriding datepicker config (as by default jQuery extend() is not recursive)
  48. //since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
  49. this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, {
  50. format: this.options.viewformat
  51. });
  52. //language
  53. this.options.datepicker.language = this.options.datepicker.language || 'en';
  54. //store DPglobal
  55. this.dpg = $.fn.bdatepicker.DPGlobal;
  56. //store parsed formats
  57. this.parsedFormat = this.dpg.parseFormat(this.options.format);
  58. this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
  59. },
  60. render: function () {
  61. var self = this;
  62. this.$input.bdatepicker(this.options.datepicker).off('changeDate').on('changeDate', function (e) {
  63. self.dateValue = e.format(0);
  64. });
  65. //"clear" link
  66. if (this.options.clear) {
  67. this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function (e) {
  68. e.preventDefault();
  69. e.stopPropagation();
  70. this.clear();
  71. }, this));
  72. this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
  73. }
  74. },
  75. value2html: function (value, element) {
  76. var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '';
  77. Date.superclass.value2html.call(this, text, element);
  78. },
  79. html2value: function (html) {
  80. return this.parseDate(html, this.parsedViewFormat);
  81. },
  82. value2str: function (value) {
  83. return value ? this.dpg.formatDate(value, this.parsedFormat, this.options.datepicker.language) : '';
  84. },
  85. str2value: function (str) {
  86. return this.parseDate(str, this.parsedFormat);
  87. },
  88. value2submit: function (value) {
  89. return this.value2str(value);
  90. },
  91. value2input: function (value) {
  92. this.$input.bdatepicker('update', value);
  93. },
  94. input2value: function () {
  95. return this.$input.bdatepicker('getDates')[0];
  96. },
  97. activate: function () {
  98. },
  99. clear: function () {
  100. this.$input.data('datepicker').date = null;
  101. this.$input.find('.active').removeClass('active');
  102. if (!this.options.showbuttons) {
  103. this.$input.closest('form').submit();
  104. }
  105. },
  106. autosubmit: function () {
  107. this.$input.on('mouseup', '.day', function (e) {
  108. if ($(e.currentTarget).is('.old') || $(e.currentTarget).is('.new')) {
  109. return;
  110. }
  111. var $form = $(this).closest('form');
  112. setTimeout(function () {
  113. $form.submit();
  114. }, 200);
  115. });
  116. //changedate is not suitable as it triggered when showing datepicker. see #149
  117. /*
  118. this.$input.on('changeDate', function(e){
  119. var $form = $(this).closest('form');
  120. setTimeout(function() {
  121. $form.submit();
  122. }, 200);
  123. });
  124. */
  125. },
  126. /*
  127. For incorrect date bootstrap-datepicker returns current date that is not suitable
  128. for datefield.
  129. This function returns null for incorrect date.
  130. */
  131. parseDate: function (str, format) {
  132. var date = null, formattedBack;
  133. if (str) {
  134. date = this.dpg.parseDate(str, format, this.options.datepicker.language);
  135. if (typeof str === 'string') {
  136. formattedBack = this.dpg.formatDate(date, format, this.options.datepicker.language);
  137. if (str !== formattedBack) {
  138. date = null;
  139. }
  140. }
  141. }
  142. return date;
  143. }
  144. });
  145. Date.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
  146. /**
  147. @property tpl
  148. @default <div></div>
  149. **/
  150. tpl: '<div class="editable-date well"></div>',
  151. /**
  152. @property inputclass
  153. @default null
  154. **/
  155. inputclass: null,
  156. /**
  157. Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
  158. Possible tokens are: <code>d, dd, m, mm, yy, yyyy</code>
  159. @property format
  160. @type string
  161. @default yyyy-mm-dd
  162. **/
  163. format: 'yyyy-mm-dd',
  164. /**
  165. Format used for displaying date. Also applied when converting date from element's text on init.
  166. If not specified equals to <code>format</code>
  167. @property viewformat
  168. @type string
  169. @default null
  170. **/
  171. viewformat: null,
  172. /**
  173. Configuration of datepicker.
  174. Full list of options: http://bootstrap-datepicker.readthedocs.org/en/latest/options.html
  175. @property datepicker
  176. @type object
  177. @default {
  178. weekStart: 0,
  179. startView: 0,
  180. minViewMode: 0,
  181. autoclose: false
  182. }
  183. **/
  184. datepicker: {
  185. weekStart: 0,
  186. startView: 0,
  187. minViewMode: 0,
  188. autoclose: false
  189. },
  190. /**
  191. Text shown as clear date button.
  192. If <code>false</code> clear button will not be rendered.
  193. @property clear
  194. @type boolean|string
  195. @default 'x clear'
  196. **/
  197. clear: '&times; clear'
  198. });
  199. $.fn.editabletypes.date = Date;
  200. }(window.jQuery));
  201. /**
  202. Bootstrap datefield input - modification for inline mode.
  203. Shows normal <input type="text"> and binds popup datepicker.
  204. Automatically shown in inline mode.
  205. @class datefield
  206. @extends date
  207. @since 1.4.0
  208. **/
  209. (function ($) {
  210. "use strict";
  211. var DateField = function (options) {
  212. this.init('datefield', options, DateField.defaults);
  213. this.initPicker(options, DateField.defaults);
  214. };
  215. $.fn.editableutils.inherit(DateField, $.fn.editabletypes.date);
  216. $.extend(DateField.prototype, {
  217. render: function () {
  218. this.$input = this.$tpl.find('input');
  219. this.setClass();
  220. this.setAttr('placeholder');
  221. //bootstrap-datepicker is set `bdateicker` to exclude conflict with jQuery UI one. (in date.js)
  222. this.$tpl.bdatepicker(this.options.datepicker);
  223. //need to disable original event handlers
  224. this.$input.off('focus keydown');
  225. //update value of datepicker
  226. this.$input.keyup($.proxy(function () {
  227. this.$tpl.removeData('date');
  228. this.$tpl.bdatepicker('update');
  229. }, this));
  230. },
  231. value2input: function (value) {
  232. this.$input.val(value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '');
  233. this.$tpl.bdatepicker('update');
  234. },
  235. input2value: function () {
  236. return this.html2value(this.$input.val());
  237. },
  238. activate: function () {
  239. $.fn.editabletypes.text.prototype.activate.call(this);
  240. },
  241. autosubmit: function () {
  242. //reset autosubmit to empty
  243. }
  244. });
  245. DateField.defaults = $.extend({}, $.fn.editabletypes.date.defaults, {
  246. /**
  247. @property tpl
  248. **/
  249. tpl: '<div class="input-group date"><input type="text" class="form-control" readonly><span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span></div>',
  250. /**
  251. @property inputclass
  252. @default 'input-small'
  253. **/
  254. inputclass: 'input-small',
  255. /* datepicker config */
  256. datepicker: {
  257. weekStart: 0,
  258. startView: 0,
  259. minViewMode: 0,
  260. autoclose: true
  261. }
  262. });
  263. $.fn.editabletypes.datefield = DateField;
  264. }(window.jQuery));