|
23 | 23 | import rightArrowIcon from '../../icons/right-arrow.svg?raw';
|
24 | 24 | import closeCrossIcon from '../../icons/close-cross.svg?raw';
|
25 | 25 | import { clickOutside } from '../../utils/click-outside';
|
26 |
| - import { createEventDispatcher, tick } from 'svelte'; |
| 26 | + import { createEventDispatcher } from 'svelte'; |
27 | 27 | import { formatDisplayDate, formatReturnDate } from '../../utils/dateFormatter';
|
28 | 28 | import Day from '../datepicker/Day.svelte';
|
29 | 29 | import Month from '../datepicker/Month.svelte';
|
|
54 | 54 |
|
55 | 55 | let selectedDateObject = new Date();
|
56 | 56 | let displayedDateString = '';
|
57 |
| - let returnDate = formatDisplayDate(selectedDateObject, displayFormat, returnFormatFunction); |
58 | 57 | let selectedDates: { year: any; month: any; day: any }[] = [];
|
59 | 58 | let date: { year: number; month: number; day: number };
|
60 | 59 | let dates: (string | number | Date)[] = [];
|
|
225 | 224 | return mData;
|
226 | 225 | };
|
227 | 226 |
|
228 |
| - function toggleMenu(event) { |
| 227 | + function toggleMenu(event: any) { |
229 | 228 | if (event && event.target && event.target.closest('.menu')) {
|
230 | 229 | return;
|
231 | 230 | }
|
|
290 | 289 | $: {
|
291 | 290 | if (value) {
|
292 | 291 | if (enableMultiple) {
|
293 |
| - const valueArray = typeof value === 'string' ? value.split(separator) : [value]; |
294 |
| - dates = []; |
295 |
| - selectedDates = []; |
296 |
| -
|
297 |
| - valueArray.forEach((dateValue) => { |
298 |
| - if (dateValue && dateValue.trim()) { |
299 |
| - try { |
300 |
| - const tmp = new Date(dateValue.trim()); |
301 |
| - if (!isNaN(tmp.getTime())) { |
302 |
| - const isoString = `${tmp.getFullYear()}-${tmp.getMonth() + 1 < 10 ? '0' : ''}${tmp.getMonth() + 1}-${tmp.getDate() < 10 ? '0' : ''}${tmp.getDate()}`; |
303 |
| - if (!dates.includes(isoString)) { |
304 |
| - dates.push(isoString); |
305 |
| - } |
306 |
| -
|
307 |
| - const dateObj = { year: tmp.getFullYear(), month: tmp.getMonth(), day: tmp.getDate() }; |
308 |
| - if (!selectedDates.some(d => d.year === dateObj.year && d.month === dateObj.month && d.day === dateObj.day)) { |
309 |
| - selectedDates.push(dateObj); |
310 |
| - } |
311 |
| - } |
312 |
| - } catch (e) { |
313 |
| - console.warn('Invalid date value:', dateValue); |
314 |
| - } |
315 |
| - } |
316 |
| - }); |
317 |
| -
|
318 |
| - dates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); |
319 |
| -
|
320 |
| - let displayList = dates.map((elem) => |
321 |
| - formatDisplayDate(new Date(elem), displayFormat, displayFormatFunction) |
322 |
| - ); |
323 |
| -
|
324 |
| - displayedDateString = displayList.join(separator); |
| 292 | + dates = value |
| 293 | + .split(separator) |
| 294 | + .map((v) => new Date(v.trim())) |
| 295 | + .filter((d) => !isNaN(d.getTime())) |
| 296 | + .map((d) => { |
| 297 | + return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d |
| 298 | + .getDate() |
| 299 | + .toString() |
| 300 | + .padStart(2, '0')}`; |
| 301 | + }); |
| 302 | +
|
| 303 | + displayedDateString = dates |
| 304 | + .map((d) => formatDisplayDate(new Date(d), displayFormat, displayFormatFunction)) |
| 305 | + .join(separator); |
325 | 306 |
|
326 | 307 | if (dates.length > 0) {
|
327 |
| - const firstDate = new Date(dates[0]); |
328 |
| - pickerMonth = firstDate.getMonth(); |
329 |
| - pickerYear = firstDate.getFullYear(); |
| 308 | + const last = new Date(dates[dates.length - 1]); |
| 309 | + yearSelected = last.getFullYear(); |
| 310 | + monthSelected = last.getMonth(); |
| 311 | + dateSelected = last.getDate(); |
| 312 | + pickerMonth = last.getMonth(); |
| 313 | + pickerYear = last.getFullYear(); |
330 | 314 | }
|
331 | 315 | } else {
|
332 | 316 | const tmp = new Date(value);
|
|
336 | 320 | dateSelected = tmp.getDate();
|
337 | 321 | pickerMonth = tmp.getMonth();
|
338 | 322 | pickerYear = tmp.getFullYear();
|
339 |
| -
|
340 |
| - selectedDateObject = tmp; |
341 |
| - displayedDateString = formatDisplayDate( |
342 |
| - selectedDateObject, |
343 |
| - displayFormat, |
344 |
| - displayFormatFunction |
345 |
| - ); |
346 | 323 | }
|
347 | 324 | }
|
348 |
| - } else { |
349 |
| - if (enableMultiple) { |
350 |
| - dates = []; |
351 |
| - selectedDates = []; |
352 |
| - displayedDateString = ''; |
353 |
| - } else { |
354 |
| - yearSelected = null; |
355 |
| - monthSelected = null; |
356 |
| - dateSelected = null; |
357 |
| - displayedDateString = ''; |
358 |
| - } |
359 | 325 | }
|
360 | 326 | }
|
361 | 327 |
|
362 |
| - $: if (enableMultiple) { |
363 |
| - if (dates.length > 0) { |
364 |
| - let displayList = dates.map((elem) => |
365 |
| - formatDisplayDate(new Date(elem), displayFormat, displayFormatFunction) |
366 |
| - ); |
367 |
| - displayedDateString = displayList.join(separator); |
368 |
| -
|
369 |
| - let returnValues = dates.map((elem) => |
370 |
| - formatReturnDate(new Date(elem), returnFormat, returnFormatFunction) |
371 |
| - ); |
372 |
| -
|
373 |
| - attachedInternals.setValidity({}); |
374 |
| - attachedInternals.setFormValue(dates.join(separator)); |
375 |
| -
|
376 |
| - returnDate = returnValues.join(separator); |
377 |
| - dispatch('value', { value: returnValues.join(separator) }); |
378 |
| - } else { |
379 |
| - displayedDateString = ''; |
380 |
| - if (required) { |
381 |
| - attachedInternals.setValidity( |
382 |
| - { valueMissing: true }, |
383 |
| - requiredValidationMessage || `Date is required.`, |
384 |
| - bindingElement |
385 |
| - ); |
386 |
| - } |
387 |
| - attachedInternals.setFormValue(''); |
388 |
| - dispatch('value', { value: '' }); |
389 |
| - } |
390 |
| - } |
391 |
| -
|
392 |
| - $: if (!enableMultiple) { |
393 |
| - if (yearSelected) { |
394 |
| - internalValue = `${yearSelected}-${monthSelected + 1 < 10 ? '0' : ''}${monthSelected + 1}-${ |
395 |
| - dateSelected < 10 ? '0' : '' |
396 |
| - }${dateSelected}`; |
397 |
| - selectedDateObject = new Date(internalValue); |
398 |
| - displayedDateString = formatDisplayDate( |
399 |
| - selectedDateObject, |
400 |
| - displayFormat, |
401 |
| - displayFormatFunction |
402 |
| - ); |
403 |
| - attachedInternals.setValidity({}); |
404 |
| - attachedInternals.setFormValue(internalValue); |
405 |
| - dispatch('value', { |
406 |
| - value: formatReturnDate(selectedDateObject, returnFormat, returnFormatFunction) |
407 |
| - }); |
408 |
| - } else { |
409 |
| - if (required) { |
410 |
| - attachedInternals.setValidity( |
411 |
| - { valueMissing: true }, |
412 |
| - requiredValidationMessage || `Date is required.`, |
413 |
| - bindingElement |
414 |
| - ); |
415 |
| - } |
416 |
| - displayedDateString = ''; |
417 |
| - attachedInternals.setFormValue(''); |
418 |
| - dispatch('value', { value: '' }); |
419 |
| - } |
420 |
| - attachedInternals.checkValidity(); |
421 |
| - } |
422 |
| -
|
423 | 328 | $: if (monthSelected == 12 && yearSelected) {
|
424 | 329 | monthSelected = 0;
|
425 | 330 | yearSelected++;
|
|
440 | 345 |
|
441 | 346 | $: pickerRows = getPickerRows(pickerMonth, pickerYear);
|
442 | 347 |
|
| 348 | + $: { |
| 349 | + if (enableMultiple && yearSelected != null && monthSelected != null && dateSelected != null) { |
| 350 | + if (datePicked) { |
| 351 | + internalValue = `${yearSelected}-${monthSelected + 1 < 10 ? '0' : ''}${monthSelected + 1}-${dateSelected < 10 ? '0' : ''}${dateSelected}`; |
| 352 | + if (!dates.includes(internalValue)) { |
| 353 | + dates.push(internalValue); |
| 354 | + } |
| 355 | +
|
| 356 | + dates.sort((a, b) => new Date(a).getTime() - new Date(b).getTime()); |
| 357 | +
|
| 358 | + let displayList = dates.map((elem) => |
| 359 | + formatDisplayDate(new Date(elem), displayFormat, displayFormatFunction) |
| 360 | + ); |
| 361 | + displayedDateString = displayList.join(separator); |
| 362 | +
|
| 363 | + let returnValues = dates.map((elem) => |
| 364 | + formatReturnDate(new Date(elem), returnFormat, returnFormatFunction) |
| 365 | + ); |
| 366 | +
|
| 367 | + attachedInternals.setValidity({}); |
| 368 | + attachedInternals.setFormValue(dates.join(separator)); |
| 369 | +
|
| 370 | + dispatch('value', { value: returnValues.join(separator) }); |
| 371 | + } else { |
| 372 | + internalValue = `${yearSelected}-${monthSelected + 1 < 10 ? '0' : ''}${monthSelected + 1}-${dateSelected < 10 ? '0' : ''}${dateSelected}`; |
| 373 | + const toDeleteTime = new Date(internalValue).getTime(); |
| 374 | + dates = dates.filter((d) => new Date(d).getTime() !== toDeleteTime); |
| 375 | +
|
| 376 | + let displayList = dates.map((elem) => |
| 377 | + formatDisplayDate(new Date(elem), displayFormat, displayFormatFunction) |
| 378 | + ); |
| 379 | + displayedDateString = displayList.join(separator); |
| 380 | +
|
| 381 | + let returnValues = dates.map((elem) => |
| 382 | + formatReturnDate(new Date(elem), returnFormat, returnFormatFunction) |
| 383 | + ); |
| 384 | +
|
| 385 | + attachedInternals.setValidity({}); |
| 386 | + attachedInternals.setFormValue(dates.join(separator)); |
| 387 | +
|
| 388 | + dispatch('value', { value: returnValues.join(separator) }); |
| 389 | + } |
| 390 | + } else { |
| 391 | + if (yearSelected) { |
| 392 | + internalValue = `${yearSelected}-${monthSelected + 1 < 10 ? '0' : ''}${monthSelected + 1}-${ |
| 393 | + dateSelected < 10 ? '0' : '' |
| 394 | + }${dateSelected}`; |
| 395 | + selectedDateObject = new Date(internalValue); |
| 396 | + displayedDateString = formatDisplayDate( |
| 397 | + selectedDateObject, |
| 398 | + displayFormat, |
| 399 | + displayFormatFunction |
| 400 | + ); |
| 401 | + attachedInternals.setValidity({}); |
| 402 | + attachedInternals.setFormValue(internalValue); |
| 403 | + dispatch('value', { |
| 404 | + value: formatReturnDate(selectedDateObject, returnFormat, returnFormatFunction) |
| 405 | + }); |
| 406 | + } else { |
| 407 | + if (required) { |
| 408 | + attachedInternals.setValidity( |
| 409 | + { valueMissing: true }, |
| 410 | + requiredValidationMessage || `Date is required.`, |
| 411 | + bindingElement |
| 412 | + ); |
| 413 | + } |
| 414 | + displayedDateString = ''; |
| 415 | + dispatch('value', { value: '' }); |
| 416 | + } |
| 417 | + attachedInternals.checkValidity(); |
| 418 | + } |
| 419 | + } |
443 | 420 | $: displayLabel = required ? `${label} *` : label;
|
444 | 421 | </script>
|
445 | 422 |
|
|
464 | 441 | {#if label && labelType === 'inside'}
|
465 | 442 | <span
|
466 | 443 | class="jp-datepicker-field-label"
|
467 |
| - class:jp-datepicker-field-label-move={openPicker || internalValue || displayLabel} |
| 444 | + class:jp-datepicker-field-label-move={openPicker || internalValue} |
468 | 445 | >{@html displayLabel}</span
|
469 | 446 | >
|
470 | 447 | {/if}
|
|
0 commit comments