datepicker.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { ReactiveCache } from '/imports/reactiveCache';
  2. import { TAPi18n } from '/imports/i18n';
  3. // Helper to check if a date is valid
  4. function isValidDate(date) {
  5. return date instanceof Date && !isNaN(date);
  6. }
  7. // Format date as YYYY-MM-DD
  8. function formatDate(date) {
  9. if (!isValidDate(date)) return '';
  10. const year = date.getFullYear();
  11. const month = String(date.getMonth() + 1).padStart(2, '0');
  12. const day = String(date.getDate()).padStart(2, '0');
  13. return `${year}-${month}-${day}`;
  14. }
  15. // Format time as HH:mm
  16. function formatTime(date) {
  17. if (!isValidDate(date)) return '';
  18. const hours = String(date.getHours()).padStart(2, '0');
  19. const minutes = String(date.getMinutes()).padStart(2, '0');
  20. return `${hours}:${minutes}`;
  21. }
  22. export class DatePicker extends BlazeComponent {
  23. template() {
  24. return 'datepicker';
  25. }
  26. onCreated(defaultTime = '1970-01-01 08:00:00') {
  27. this.error = new ReactiveVar('');
  28. this.card = this.data();
  29. this.date = new ReactiveVar(new Date('invalid'));
  30. this.defaultTime = defaultTime;
  31. }
  32. startDayOfWeek() {
  33. const currentUser = ReactiveCache.getCurrentUser();
  34. if (currentUser) {
  35. return currentUser.getStartDayOfWeek();
  36. } else {
  37. return 1;
  38. }
  39. }
  40. onRendered() {
  41. // Set initial values for native HTML inputs
  42. if (isValidDate(this.date.get())) {
  43. const dateInput = this.find('#date');
  44. const timeInput = this.find('#time');
  45. if (dateInput) {
  46. dateInput.value = formatDate(this.date.get());
  47. }
  48. if (timeInput && !timeInput.value && this.defaultTime) {
  49. const defaultDate = new Date(this.defaultTime);
  50. timeInput.value = formatTime(defaultDate);
  51. } else if (timeInput && isValidDate(this.date.get())) {
  52. timeInput.value = formatTime(this.date.get());
  53. }
  54. }
  55. }
  56. showDate() {
  57. if (isValidDate(this.date.get())) return formatDate(this.date.get());
  58. return '';
  59. }
  60. showTime() {
  61. if (isValidDate(this.date.get())) return formatTime(this.date.get());
  62. return '';
  63. }
  64. dateFormat() {
  65. return 'YYYY-MM-DD';
  66. }
  67. timeFormat() {
  68. return 'HH:mm';
  69. }
  70. events() {
  71. return [
  72. {
  73. 'change .js-date-field'() {
  74. // Native HTML date input validation
  75. const dateValue = this.find('#date').value;
  76. if (dateValue) {
  77. // HTML date input format is always YYYY-MM-DD
  78. const dateObj = new Date(dateValue + 'T12:00:00');
  79. if (isValidDate(dateObj)) {
  80. this.error.set('');
  81. } else {
  82. this.error.set('invalid-date');
  83. }
  84. }
  85. },
  86. 'change .js-time-field'() {
  87. // Native HTML time input validation
  88. const timeValue = this.find('#time').value;
  89. if (timeValue) {
  90. // HTML time input format is always HH:mm
  91. const timeObj = new Date(`1970-01-01T${timeValue}:00`);
  92. if (isValidDate(timeObj)) {
  93. this.error.set('');
  94. } else {
  95. this.error.set('invalid-time');
  96. }
  97. }
  98. },
  99. 'submit .edit-date'(evt) {
  100. evt.preventDefault();
  101. const dateValue = evt.target.date.value;
  102. const timeValue = evt.target.time.value || '12:00'; // Default to 12:00 if no time given
  103. if (!dateValue) {
  104. this.error.set('invalid-date');
  105. evt.target.date.focus();
  106. return;
  107. }
  108. // Combine date and time: HTML date input is YYYY-MM-DD, time input is HH:mm
  109. const dateTimeString = `${dateValue}T${timeValue}:00`;
  110. const newCompleteDate = new Date(dateTimeString);
  111. if (!isValidDate(newCompleteDate)) {
  112. this.error.set('invalid');
  113. return;
  114. }
  115. this._storeDate(newCompleteDate);
  116. Popup.back();
  117. },
  118. 'click .js-delete-date'(evt) {
  119. evt.preventDefault();
  120. this._deleteDate();
  121. Popup.back();
  122. },
  123. },
  124. ];
  125. }
  126. }