Skip to content

Commit 6c7f07e

Browse files
committed
fix: datepicker fixes
1 parent de190ef commit 6c7f07e

File tree

2 files changed

+99
-121
lines changed

2 files changed

+99
-121
lines changed

packages/demo/src/FormFieldDemos/DatepickerDemo.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
<!-- <jp-datepicker {showClearButton} />-->
1212
<!-- <jp-datepicker label="datepicker" {showClearButton} />-->
1313
<!-- <jp-datepicker label="datepicker label outside" labelType="outside" {showClearButton} />-->
14-
<jp-datepicker value="Wed Jun 25 2025 02:00:00 GMT+0200 (Central European Summer Time), Thu Jun 26 2025 02:00:00 GMT+0200 (Central European Summer Time)"
15-
label="datepicker enable multiple" enableMultiple="true" {showClearButton} />
14+
<jp-datepicker value="2025-06-04T00:00:00.000Z, 2025-06-05T00:00:00.000Z"
15+
label="datepicker enable multiple" enableMultiple="true" returnFormat="iso" {showClearButton} />
16+
<!-- <jp-datepicker label="datepicker enable multiple" enableMultiple="true" returnFormat="iso" {showClearButton} />-->
1617
<!--<jp-datepicker
1718
label="datepicker enable multiple separator"
1819
enableMultiple="true"
@@ -36,7 +37,7 @@
3637
<button type="button" on:click="{() => {
3738
const datepicker = document.querySelector('jp-datepicker');
3839
if (datepicker) {
39-
console.log(datepicker);
40+
console.log(datepicker.getValue());
4041
}
4142
}}">submit</button>
4243
</form>

packages/lib/src/form-fields/datepicker/datepicker.wc.svelte

Lines changed: 95 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import rightArrowIcon from '../../icons/right-arrow.svg?raw';
2424
import closeCrossIcon from '../../icons/close-cross.svg?raw';
2525
import { clickOutside } from '../../utils/click-outside';
26-
import { createEventDispatcher, tick } from 'svelte';
26+
import { createEventDispatcher } from 'svelte';
2727
import { formatDisplayDate, formatReturnDate } from '../../utils/dateFormatter';
2828
import Day from '../datepicker/Day.svelte';
2929
import Month from '../datepicker/Month.svelte';
@@ -54,7 +54,6 @@
5454
5555
let selectedDateObject = new Date();
5656
let displayedDateString = '';
57-
let returnDate = formatDisplayDate(selectedDateObject, displayFormat, returnFormatFunction);
5857
let selectedDates: { year: any; month: any; day: any }[] = [];
5958
let date: { year: number; month: number; day: number };
6059
let dates: (string | number | Date)[] = [];
@@ -225,7 +224,7 @@
225224
return mData;
226225
};
227226
228-
function toggleMenu(event) {
227+
function toggleMenu(event: any) {
229228
if (event && event.target && event.target.closest('.menu')) {
230229
return;
231230
}
@@ -290,43 +289,28 @@
290289
$: {
291290
if (value) {
292291
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);
325306
326307
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();
330314
}
331315
} else {
332316
const tmp = new Date(value);
@@ -336,90 +320,11 @@
336320
dateSelected = tmp.getDate();
337321
pickerMonth = tmp.getMonth();
338322
pickerYear = tmp.getFullYear();
339-
340-
selectedDateObject = tmp;
341-
displayedDateString = formatDisplayDate(
342-
selectedDateObject,
343-
displayFormat,
344-
displayFormatFunction
345-
);
346323
}
347324
}
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-
}
359325
}
360326
}
361327
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-
423328
$: if (monthSelected == 12 && yearSelected) {
424329
monthSelected = 0;
425330
yearSelected++;
@@ -440,6 +345,78 @@
440345
441346
$: pickerRows = getPickerRows(pickerMonth, pickerYear);
442347
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+
}
443420
$: displayLabel = required ? `${label} *` : label;
444421
</script>
445422

@@ -464,7 +441,7 @@
464441
{#if label && labelType === 'inside'}
465442
<span
466443
class="jp-datepicker-field-label"
467-
class:jp-datepicker-field-label-move={openPicker || internalValue || displayLabel}
444+
class:jp-datepicker-field-label-move={openPicker || internalValue}
468445
>{@html displayLabel}</span
469446
>
470447
{/if}

0 commit comments

Comments
 (0)