mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-10-25 13:37:12 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			203 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="date-time-picker grow" :class="`size-${size}`" >
 | |
|     <VueDatePicker
 | |
|       ref="datetimePicker"
 | |
|       :class="{
 | |
|         'only-time': mode == 'time',
 | |
|       }"
 | |
|       @closed="closedHandler"
 | |
|       @cleared="clearedHandler"
 | |
|       v-model="compDatetime"
 | |
|       :teleport="teleport"
 | |
|       :no-today="true"
 | |
|       :clearable="clearable"
 | |
|       :format="format"
 | |
|       :month-change-on-scroll="false"
 | |
|       :six-weeks="true"
 | |
|       :disabled="disabled"
 | |
|       :auto-apply="true"
 | |
|       :partial-flow="true"
 | |
|       :markers="markers"
 | |
|       week-start="0"
 | |
|       :enable-time-picker="mode == 'datetime'"
 | |
|       :time-picker="mode == 'time'"
 | |
|       :placeholder="placeholder" >
 | |
|         <template #arrow-right>
 | |
|             <img class="slot-icon" src="/images/calendar/navigate_next.svg"/>
 | |
|         </template>
 | |
|         <template #arrow-left>
 | |
|             <img class="slot-icon" src="/images/calendar/navigate_before.svg"/>
 | |
|         </template>
 | |
|         <template v-if="customIcon" #input-icon>
 | |
|             <i :class="customIcon + ' -ml-1'"></i>
 | |
|         </template>
 | |
|         <template v-else-if="mode == 'time'" #input-icon>
 | |
|             <img class="input-slot-image" src="/images/calendar/clock.svg"/>
 | |
|         </template>
 | |
|         <template v-else #input-icon>
 | |
|             <img class="input-slot-image" src="/images/calendar/calendar.svg"/>
 | |
|         </template>
 | |
|         <template #clock-icon>
 | |
|             <img class="slot-icon" src="/images/calendar/clock.svg"/>
 | |
|         </template>
 | |
|         <template #calendar-icon>
 | |
|             <img class="slot-icon" src="/images/calendar/calendar.svg"/>
 | |
|         </template>
 | |
|         <template #arrow-up>
 | |
|             <img class="slot-icon" src="/images/calendar/up.svg"/>
 | |
|         </template>
 | |
|         <template #arrow-down>
 | |
|             <img class="slot-icon" src="/images/calendar/down.svg"/>
 | |
|         </template>
 | |
|     </VueDatePicker>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import VueDatePicker from '@vuepic/vue-datepicker';
 | |
| 
 | |
| export default {
 | |
|   name: 'DateTimePicker',
 | |
|   props: {
 | |
|     mode: { type: String, default: 'datetime' },
 | |
|     clearable: { type: Boolean, default: false },
 | |
|     teleport: { type: Boolean, default: true },
 | |
|     defaultValue: { type: Date, required: false },
 | |
|     placeholder: { type: String },
 | |
|     standAlone: { type: Boolean, default: false, required: false },
 | |
|     dateClassName: { type: String, default: '' },
 | |
|     timeClassName: { type: String, default: '' },
 | |
|     disabled: { type: Boolean, default: false },
 | |
|     customIcon: { type: String },
 | |
|     size: { type: String, default: 'xs' }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       manualUpdate: false,
 | |
|       datetime: this.defaultValue,
 | |
|       time: null,
 | |
|       markers: [
 | |
|         {
 | |
|           date: new Date(),
 | |
|           type: 'dot',
 | |
|           color: '#3B99FD'
 | |
|         }
 | |
|       ]
 | |
|     };
 | |
|   },
 | |
|   created() {
 | |
|     if (this.defaultValue) {
 | |
|       this.time = {
 | |
|         hours: this.defaultValue.getHours(),
 | |
|         minutes: this.defaultValue.getMinutes()
 | |
|       };
 | |
|     }
 | |
|   },
 | |
|   components: {
 | |
|     VueDatePicker
 | |
|   },
 | |
|   watch: {
 | |
|     defaultValue() {
 | |
|       this.datetime = this.defaultValue;
 | |
|       if (this.defaultValue instanceof Date) {
 | |
|         this.time = {
 | |
|           hours: this.defaultValue.getHours(),
 | |
|           minutes: this.defaultValue.getMinutes()
 | |
|         };
 | |
|       }
 | |
|     },
 | |
|     datetime() {
 | |
|       if (this.mode === 'time') {
 | |
|         this.time = null;
 | |
| 
 | |
|         if (this.datetime instanceof Date) {
 | |
|           this.time = {
 | |
|             hours: this.datetime.getHours(),
 | |
|             minutes: this.datetime.getMinutes()
 | |
|           };
 | |
|         }
 | |
| 
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       if (this.manualUpdate) {
 | |
|         this.manualUpdate = false;
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       if (this.datetime == null) {
 | |
|         this.$emit('cleared');
 | |
|       }
 | |
| 
 | |
|       if (this.defaultValue !== this.datetime) {
 | |
|         this.$emit('change', this.datetime);
 | |
|       }
 | |
|     },
 | |
|     time() {
 | |
|       if (this.manualUpdate) {
 | |
|         this.manualUpdate = false;
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       if (this.mode !== 'time') return;
 | |
| 
 | |
|       let newDate;
 | |
| 
 | |
|       if (this.time) {
 | |
|         newDate = new Date();
 | |
|         newDate.setHours(this.time.hours);
 | |
|         newDate.setMinutes(this.time.minutes);
 | |
|       } else {
 | |
|         newDate = {
 | |
|           hours: null,
 | |
|           minutes: null
 | |
|         };
 | |
|         this.$emit('cleared');
 | |
|       }
 | |
| 
 | |
|       if (this.defaultValue !== newDate) {
 | |
|         this.$emit('change', newDate);
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     compDatetime: {
 | |
|       get() {
 | |
|         if (this.mode === 'time') {
 | |
|           return this.time;
 | |
|         }
 | |
|         return this.datetime;
 | |
|       },
 | |
|       set(val) {
 | |
|         if (this.mode === 'time') {
 | |
|           this.time = val;
 | |
|         } else {
 | |
|           this.datetime = val;
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     format() {
 | |
|       if (this.mode === 'time') return 'HH:mm';
 | |
|       if (this.mode === 'date') return document.body.dataset.datetimePickerFormatVue;
 | |
|       return `${document.body.dataset.datetimePickerFormatVue} HH:mm`;
 | |
|     }
 | |
|   },
 | |
|   mounted() {
 | |
|     window.addEventListener('resize', this.close);
 | |
|   },
 | |
|   unmounted() {
 | |
|     window.removeEventListener('resize', this.close);
 | |
|   },
 | |
|   methods: {
 | |
|     close() {
 | |
|       this.$refs.datetimePicker.closeMenu();
 | |
|     },
 | |
|     closedHandler() {
 | |
|       this.$emit('closed');
 | |
|     },
 | |
|     clearedHandler() {
 | |
|       this.$emit('cleared');
 | |
|     }
 | |
|   }
 | |
| };
 | |
| </script>
 |