e9b6abda149b113def68d686c37d9043e0299a06.svn-base 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * @class Ext.form.DateField
  8. * @extends Ext.form.TriggerField Provides a date input field with a
  9. * {@link Ext.DatePicker} dropdown and automatic date validation.
  10. * @constructor Create a new DateField
  11. * @param {Object}
  12. * config
  13. */
  14. Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
  15. /**
  16. * @cfg {String} format The default date format string which can be
  17. * overriden for localization support. The format must be valid
  18. * according to {@link Date#parseDate} (defaults to 'm/d/y').
  19. */
  20. format : "m/d/y",
  21. /**
  22. * @cfg {String} altFormats Multiple date formats separated by "|" to try
  23. * when parsing a user input value and it doesn't match the defined
  24. * format (defaults to 'm/d/Y|m-d-y|m-d-Y|m/d|m-d|d').
  25. */
  26. altFormats : "m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
  27. /**
  28. * @cfg {Array} disabledDays An array of days to disable, 0 based. For
  29. * example, [0, 6] disables Sunday and Saturday (defaults to null).
  30. */
  31. disabledDays : null,
  32. /**
  33. * @cfg {String} disabledDaysText The tooltip to display when the date falls
  34. * on a disabled day (defaults to 'Disabled')
  35. */
  36. disabledDaysText : "Disabled",
  37. /**
  38. * @cfg {Array} disabledDates An array of "dates" to disable, as strings.
  39. * These strings will be used to build a dynamic regular expression so
  40. * they are very powerful. Some examples:
  41. * <ul>
  42. * <li>["03/08/2003", "09/16/2003"] would disable those exact dates</li>
  43. * <li>["03/08", "09/16"] would disable those days for every year</li>
  44. * <li>["^03/08"] would only match the beginning (useful if you are
  45. * using short years)</li>
  46. * <li>["03/../2006"] would disable every day in March 2006</li>
  47. * <li>["^03"] would disable every day in every March</li>
  48. * </ul>
  49. * In order to support regular expressions, if you are using a date
  50. * format that has "." in it, you will have to escape the dot when
  51. * restricting dates. For example: ["03\\.08\\.03"].
  52. */
  53. disabledDates : null,
  54. /**
  55. * @cfg {String} disabledDatesText The tooltip text to display when the date
  56. * falls on a disabled date (defaults to 'Disabled')
  57. */
  58. disabledDatesText : "Disabled",
  59. /**
  60. * @cfg {Date/String} minValue The minimum allowed date. Can be either a
  61. * Javascript date object or a string date in a valid format (defaults
  62. * to null).
  63. */
  64. minValue : null,
  65. /**
  66. * @cfg {Date/String} maxValue The maximum allowed date. Can be either a
  67. * Javascript date object or a string date in a valid format (defaults
  68. * to null).
  69. */
  70. maxValue : null,
  71. /**
  72. * @cfg {String} minText The error text to display when the date in the cell
  73. * is before minValue (defaults to 'The date in this field must be
  74. * after {minValue}').
  75. */
  76. minText : "The date in this field must be equal to or after {0}",
  77. /**
  78. * @cfg {String} maxText The error text to display when the date in the cell
  79. * is after maxValue (defaults to 'The date in this field must be
  80. * before {maxValue}').
  81. */
  82. maxText : "The date in this field must be equal to or before {0}",
  83. /**
  84. * @cfg {String} invalidText The error text to display when the date in the
  85. * field is invalid (defaults to '{value} is not a valid date - it must
  86. * be in the format {format}').
  87. */
  88. invalidText : "{0} is not a valid date - it must be in the format {1}",
  89. /**
  90. * @cfg {String} triggerClass An additional CSS class used to style the
  91. * trigger button. The trigger will always get the class
  92. * 'x-form-trigger' and triggerClass will be <b>appended</b> if
  93. * specified (defaults to 'x-form-date-trigger' which displays a
  94. * calendar icon).
  95. */
  96. triggerClass : 'x-form-date-trigger',
  97. /**
  98. * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a
  99. * default element spec (defaults to {tag: "input", type: "text", size:
  100. * "10", autocomplete: "off"})
  101. */
  102. // private
  103. defaultAutoCreate : {
  104. tag : "input",
  105. type : "text",
  106. size : "10",
  107. autocomplete : "off"
  108. },
  109. initComponent : function() {
  110. Ext.form.DateField.superclass.initComponent.call(this);
  111. if (typeof this.minValue == "string") {
  112. this.minValue = this.parseDate(this.minValue);
  113. }
  114. if (typeof this.maxValue == "string") {
  115. this.maxValue = this.parseDate(this.maxValue);
  116. }
  117. this.ddMatch = null;
  118. if (this.disabledDates) {
  119. var dd = this.disabledDates;
  120. var re = "(?:";
  121. for (var i = 0; i < dd.length; i++) {
  122. re += dd[i];
  123. if (i != dd.length - 1)
  124. re += "|";
  125. }
  126. this.ddMatch = new RegExp(re + ")");
  127. }
  128. },
  129. // private
  130. validateValue : function(value) {
  131. value = this.formatDate(value);
  132. if (!Ext.form.DateField.superclass.validateValue.call(this, value)) {
  133. return false;
  134. }
  135. if (value.length < 1) { // if it's blank and textfield didn't flag it
  136. // then it's valid
  137. return true;
  138. }
  139. var svalue = value;
  140. value = this.parseDate(value);
  141. if (!value) {
  142. this.markInvalid(String.format(this.invalidText, svalue,
  143. this.format));
  144. return false;
  145. }
  146. var time = value.getTime();
  147. if (this.minValue && time < this.minValue.getTime()) {
  148. this.markInvalid(String.format(this.minText, this
  149. .formatDate(this.minValue)));
  150. return false;
  151. }
  152. if (this.maxValue && time > this.maxValue.getTime()) {
  153. this.markInvalid(String.format(this.maxText, this
  154. .formatDate(this.maxValue)));
  155. return false;
  156. }
  157. if (this.disabledDays) {
  158. var day = value.getDay();
  159. for (var i = 0; i < this.disabledDays.length; i++) {
  160. if (day === this.disabledDays[i]) {
  161. this.markInvalid(this.disabledDaysText);
  162. return false;
  163. }
  164. }
  165. }
  166. var fvalue = this.formatDate(value);
  167. if (this.ddMatch && this.ddMatch.test(fvalue)) {
  168. this.markInvalid(String.format(this.disabledDatesText, fvalue));
  169. return false;
  170. }
  171. return true;
  172. },
  173. // private
  174. // Provides logic to override the default TriggerField.validateBlur which
  175. // just returns true
  176. validateBlur : function() {
  177. return !this.menu || !this.menu.isVisible();
  178. },
  179. /**
  180. * Returns the current date value of the date field.
  181. *
  182. * @return {Date} The date value
  183. */
  184. getValue : function() {
  185. return this
  186. .parseDate(Ext.form.DateField.superclass.getValue.call(this))
  187. || "";
  188. },
  189. /**
  190. * Sets the value of the date field. You can pass a date object or any
  191. * string that can be parsed into a valid date, using DateField.format as
  192. * the date format, according to the same rules as {@link Date#parseDate}
  193. * (the default format used is "m/d/y"). <br />
  194. * Usage:
  195. *
  196. * <pre><code>
  197. * //All of these calls set the same date value (May 4, 2006)
  198. *
  199. * //Pass a date object:
  200. * var dt = new Date('5/4/06');
  201. * dateField.setValue(dt);
  202. *
  203. * //Pass a date string (default format):
  204. * dateField.setValue('5/4/06');
  205. *
  206. * //Pass a date string (custom format):
  207. * dateField.format = 'Y-m-d';
  208. * dateField.setValue('2006-5-4');
  209. * </code></pre>
  210. *
  211. * @param {String/Date}
  212. * date The date or valid date string
  213. */
  214. setValue : function(date) {
  215. Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this
  216. .parseDate(date)));
  217. },
  218. // private
  219. parseDate : function(value) {
  220. if (!value || value instanceof Date) {
  221. return value;
  222. }
  223. var v = Date.parseDate(value, this.format);
  224. if (!v && this.altFormats) {
  225. if (!this.altFormatsArray) {
  226. this.altFormatsArray = this.altFormats.split("|");
  227. }
  228. for (var i = 0, len = this.altFormatsArray.length; i < len && !v; i++) {
  229. v = Date.parseDate(value, this.altFormatsArray[i]);
  230. }
  231. }
  232. return v;
  233. },
  234. // private
  235. onDestroy : function() {
  236. if (this.wrap) {
  237. this.wrap.remove();
  238. }
  239. Ext.form.DateField.superclass.onDestroy.call(this);
  240. },
  241. // private
  242. formatDate : function(date) {
  243. return (!date || !(date instanceof Date)) ? date : date
  244. .dateFormat(this.format);
  245. },
  246. // private
  247. menuListeners : {
  248. select : function(m, d) {
  249. this.setValue(d);
  250. },
  251. show : function() { // retain focus styling
  252. this.onFocus();
  253. },
  254. hide : function() {
  255. this.focus.defer(10, this);
  256. var ml = this.menuListeners;
  257. this.menu.un("select", ml.select, this);
  258. this.menu.un("show", ml.show, this);
  259. this.menu.un("hide", ml.hide, this);
  260. }
  261. },
  262. // private
  263. // Implements the default empty TriggerField.onTriggerClick function to
  264. // display the DatePicker
  265. onTriggerClick : function() {
  266. if (this.disabled) {
  267. return;
  268. }
  269. if (this.menu == null) {
  270. this.menu = new Ext.menu.DateMenu();
  271. }
  272. Ext.apply(this.menu.picker, {
  273. minDate : this.minValue,
  274. maxDate : this.maxValue,
  275. disabledDatesRE : this.ddMatch,
  276. disabledDatesText : this.disabledDatesText,
  277. disabledDays : this.disabledDays,
  278. disabledDaysText : this.disabledDaysText,
  279. format : this.format,
  280. minText : String.format(this.minText, this
  281. .formatDate(this.minValue)),
  282. maxText : String.format(this.maxText, this
  283. .formatDate(this.maxValue))
  284. });
  285. this.menu.on(Ext.apply({}, this.menuListeners, {
  286. scope : this
  287. }));
  288. this.menu.picker.setValue(this.getValue() || allGetServerTime());
  289. this.menu.show(this.el, "tl-bl?");
  290. },
  291. beforeBlur : function() {
  292. var v = this.parseDate(this.getRawValue());
  293. if (v) {
  294. this.setValue(v);
  295. }
  296. }
  297. /**
  298. * @cfg {Boolean} grow
  299. * @hide
  300. */
  301. /**
  302. * @cfg {Number} growMin
  303. * @hide
  304. */
  305. /**
  306. * @cfg {Number} growMax
  307. * @hide
  308. */
  309. /**
  310. * @hide
  311. * @method autoSize
  312. */
  313. });
  314. Ext.reg('datefield', Ext.form.DateField);