4646 </template >
4747 </NcActionInput >
4848 </template >
49+ <template v-else-if =" answerType .pickerType === ' time' " #actions >
50+ <NcActionCheckbox
51+ :model-value =" timeRange "
52+ @update :model-value =" onTimeRangeChange " >
53+ {{ t('forms', 'Use time range') }}
54+ </NcActionCheckbox >
55+ <NcActionInput
56+ type="time"
57+ is-native-picker
58+ :model-value =" timeMin "
59+ :label =" t (' forms' , ' Earliest time' )"
60+ hide-label
61+ :max =" timeMax "
62+ @update :model-value =" onTimeMinChange " >
63+ <template #icon >
64+ <NcIconSvgWrapper
65+ :svg =" svgClockLoader20 "
66+ :name =" t (' forms' , ' Earliest time' )" />
67+ </template >
68+ </NcActionInput >
69+ <NcActionInput
70+ type="time"
71+ is-native-picker
72+ :model-value =" timeMax "
73+ :label =" t (' forms' , ' Latest time' )"
74+ hide-label
75+ :min =" timeMin "
76+ @update :model-value =" onTimeMaxChange " >
77+ <template #icon >
78+ <NcIconSvgWrapper
79+ :svg =" svgClockLoader80 "
80+ :name =" t (' forms' , ' Latest time' )" />
81+ </template >
82+ </NcActionInput >
83+ </template >
4984 <div class =" question__content" >
5085 <NcDateTimePicker
5186 :value =" time "
5287 :disabled =" ! readOnly "
5388 :formatter =" formatter "
5489 :placeholder =" datetimePickerPlaceholder "
5590 :show-second =" false "
56- :type =" answerType . pickerType "
91+ :type =" dateTimePickerType "
5792 :disabled-date =" disabledDates "
93+ :disabled-time =" disabledTimes "
5894 :input-attr =" inputAttr "
59- :range =" extraSettings ?.dateRange "
6095 range-separator=" - "
6196 @change =" onValueChange " />
6297 </div >
6398 </Question >
6499</template >
65100
66101<script >
102+ import svgClockLoader20 from ' ../../../img/clock_loader_20.svg?raw'
103+ import svgClockLoader80 from ' ../../../img/clock_loader_80.svg?raw'
67104import svgEventIcon from ' ../../../img/event.svg?raw'
68105import svgTodayIcon from ' ../../../img/today.svg?raw'
69106
@@ -96,6 +133,8 @@ export default {
96133 stringify: this .stringifyDate ,
97134 parse: this .parseTimestampToDate ,
98135 },
136+ svgClockLoader80,
137+ svgClockLoader20,
99138 svgEventIcon,
100139 svgTodayIcon,
101140 }
@@ -104,15 +143,21 @@ export default {
104143 computed: {
105144 datetimePickerPlaceholder () {
106145 if (this .readOnly ) {
107- return this .extraSettings ? .dateRange
146+ return this .extraSettings ? .dateRange || this . extraSettings ? . timeRange
108147 ? this .answerType .submitPlaceholderRange
109148 : this .answerType .submitPlaceholder
110149 }
111- return this .extraSettings ? .dateRange
150+ return this .extraSettings ? .dateRange || this . extraSettings ? . timeRange
112151 ? this .answerType .createPlaceholderRange
113152 : this .answerType .createPlaceholder
114153 },
115154
155+ dateTimePickerType () {
156+ return this .extraSettings ? .dateRange || this .extraSettings ? .timeRange
157+ ? this .answerType .pickerType + ' -range'
158+ : this .answerType .pickerType
159+ },
160+
116161 /**
117162 * All non-exposed props onto datepicker input-element.
118163 *
@@ -126,7 +171,7 @@ export default {
126171 },
127172
128173 time () {
129- if (this .extraSettings ? .dateRange ) {
174+ if (this .extraSettings ? .dateRange || this . extraSettings ? . timeRange ) {
130175 return this .values
131176 ? [this .parse (this .values [0 ]), this .parse (this .values [1 ])]
132177 : null
@@ -155,6 +200,34 @@ export default {
155200 dateRange () {
156201 return this .extraSettings ? .dateRange ?? false
157202 },
203+
204+ /**
205+ * The maximum allowable time for the time input field
206+ */
207+ timeMax () {
208+ return this .extraSettings ? .timeMax
209+ ? moment (
210+ this .extraSettings .timeMax ,
211+ this .answerType .storageFormat ,
212+ ).toDate ()
213+ : new Date (new Date ().setHours (24 , 0 , 0 , 0 ))
214+ },
215+
216+ /**
217+ * The minimum allowable time for the time input field
218+ */
219+ timeMin () {
220+ return this .extraSettings ? .timeMin
221+ ? moment (
222+ this .extraSettings .timeMin ,
223+ this .answerType .storageFormat ,
224+ ).toDate ()
225+ : new Date (new Date ().setHours (0 , 0 , 0 , 0 ))
226+ },
227+
228+ timeRange () {
229+ return this .extraSettings ? .timeRange ?? false
230+ },
158231 },
159232
160233 methods: {
@@ -216,13 +289,56 @@ export default {
216289 this .onExtraSettingsChange ({ dateRange: value === true ?? null })
217290 },
218291
292+ /**
293+ * Handles the change event for the maximum time input.
294+ * Updates the maximum allowable date based on the provided value.
295+ *
296+ * @param {string | Date} value - The new maximum date value. Can be a string or a Date object.
297+ */
298+ onTimeMaxChange (value ) {
299+ this .onExtraSettingsChange ({
300+ timeMax:
301+ value === null
302+ || value === new Date (new Date ().setHours (24 , 0 , 0 , 0 ))
303+ ? null
304+ : moment (value).format (this .answerType .storageFormat ),
305+ })
306+ },
307+
308+ /**
309+ * Handles the change event for the minimum date input.
310+ * Updates the minimum allowable date based on the provided value.
311+ *
312+ * @param {string | Date} value - The new minimum date value. Can be a string or a Date object.
313+ */
314+ onTimeMinChange (value ) {
315+ this .onExtraSettingsChange ({
316+ timeMin:
317+ value === null
318+ || value === new Date (new Date ().setHours (0 , 0 , 0 , 0 ))
319+ ? null
320+ : moment (value).format (this .answerType .storageFormat ),
321+ })
322+ },
323+
324+ /**
325+ * Handles the change event for the date range selection.
326+ * Updates the extra settings with the new date range value.
327+ *
328+ * @param {boolean} value - The new value of the date range selection.
329+ * If true, the date range is enabled; otherwise, null.
330+ */
331+ onTimeRangeChange (value ) {
332+ this .onExtraSettingsChange ({ timeRange: value === true ?? null })
333+ },
334+
219335 /**
220336 * Store Value
221337 *
222338 * @param {Date|Array<Date>} date The date or date range to store
223339 */
224340 onValueChange (date ) {
225- if (this .extraSettings ? .dateRange ) {
341+ if (this .extraSettings ? .dateRange || this . extraSettings ? . timeRange ) {
226342 this .$emit (' update:values' , [
227343 moment (date[0 ]).format (this .answerType .storageFormat ),
228344 moment (date[1 ]).format (this .answerType .storageFormat ),
@@ -247,6 +363,19 @@ export default {
247363 )
248364 },
249365
366+ /**
367+ * Determines if a given time should be disabled.
368+ *
369+ * @param {Date} time - The time to check.
370+ * @return {boolean} - Returns true if the time should be disabled, otherwise false.
371+ */
372+ disabledTimes (time ) {
373+ return (
374+ (this .timeMin && time < this .timeMin )
375+ || (this .timeMax && time > this .timeMax )
376+ )
377+ },
378+
250379 /**
251380 * Datepicker timestamp to string
252381 *
0 commit comments