ionic-framework
ionic-framework copied to clipboard
feat: ion-datetime with date range
Feature Request
It would be great if the new ion-datetime would support a range feature (like for example in a hotel booking webpage) where you can provide a start and enddate and it shows on the calendar component.
Ionic version:
[ ] 4.x [ ] 5.x [x] 6.x
We really need this, as long as we don't have this feature I still need to use tools external to Ionic
it's a very useful feature. we need it also.
any news ?
We really need this, as long as we don't have this feature I still need to use tools external to Ionic
which external things are you using . I want to show multiple date range in same calendar is there any way you are aware about.
We really need this, as long as we don't have this feature I still need to use tools external to Ionic
which external things are you using . I want to show multiple date range in same calendar is there any way you are aware about.
https://www.npmjs.com/package/ion2-calendar It's cool
@liamdebeasi @willmartian almost one year from this request . Any news?
is for vue, use https://vcalendar.io/datepicker.html
Not a great solution but this is what I am doing in Angular. It allows me to select one date or all dates between two selected dates.
HTML
<ion-datetime (ionChange)="dateChange()" [multiple]="true" [(ngModel)]="dateStrings" presentation="date"></ion-datetime>
TS
// The value (one or multiple date strings).
dateStrings: string[];
// Cached values (used to prevent infinite date change events).
private currentDateStrings: string[];
dateChange() {
// Detect changes (prevents an infinite loop).
if (this.currentDateStrings === this.dateStrings) { return; }
// Make sure we have at least two dates (otherwise nothing to do).
if (!(this.dateStrings?.length > 1)) { return; }
// Sort the dates so the earliest one is first.
this.dateStrings.sort((a, b) => {
if (a > b) { return 1; }
else if (a < b) { return -1; }
else { return 0; }
});
// Revert to single selection (if required).
if (this.currentDateStrings?.length > 2) {
for (const d of this.currentDateStrings) {
if (this.dateStrings.indexOf(d) === -1) {
// Make sure this is not the first or last date (those are handled natively).
if (d === this.currentDateStrings[0]) { break; }
if (d === this.currentDateStrings[this.currentDateStrings.length - 1]) { break; }
this.dateStrings = [d];
// No need to continue.
break;
}
}
}
// Store the new value.
const newValue = [];
// Add all dates between the first and second dates.
for (let d = new Date(this.dateStrings[0]); d <= new Date(this.dateStrings[this.dateStrings.length - 1]); d.setDate(d.getDate() + 1)) {
newValue.push(this.getDateString(d));
}
// Update the values at the end so the UI gets updated only once.
this.dateStrings = newValue;
this.currentDateStrings = newValue;
}
any update about the ion-date-range range?
Is there any update about this feature?
updates?
Hi everyone,
We do not have any updates regarding this feature. Any updates will be posted on this thread as we have them.
Hi everyone,
We do not have any updates regarding this feature. Any updates will be posted on this thread as we have them.
Thanks, I have one question regarding a custom date range component which I'm making now.
I'm adding styles for the days in the range of dates but couldn't update UI when press the month next, prev buttons.
Could you possibly let me know how can I resolve this issue?
Also very interested in an update to this. Thanks.
any update?
Hello! Is there any update???
Hello! Is there any update???
Following. This would be so helpful. Thanks.
This could be helpful.
I think a direction to fix this issue for the ionic developer could be adding a property in html element that stop year / month wheel emitting value automatically each time user click on the wheel.
Instead use a "cache date time" for the component to register the year / month updates from wheel and only emits a new date value after user click on a day.
Like so.
<ion-datetime [auto-emits]="false">
Or something like
<ion-datetime [emits-when]="day">
It's not a perfect solution but, at the moment, a very cost-effective way to unlock the possibility to make a day range component first that is bug free. Developer can actually implement a proper day-range with a work-around function (just play with the date array) once this feature is disabled.
Hi everyone, We do not have any updates regarding this feature. Any updates will be posted on this thread as we have them.
Thanks, I have one question regarding a custom date range component which I'm making now. I'm adding styles for the days in the range of dates but couldn't update UI when press the month next, prev buttons. Could you possibly let me know how can I resolve this issue?
You can try to update ionic to v7, I had similar problem, where the calender value only emits once about user input in month and year.
update ionic to v7 solve the issue.
But then the calender updates the value everytime user spin the month and year wheel, its a disaster.
At work we managed the range selection this way (using Ionic v7, Vue3 + TypeScript and Luxon):
Using the component
<CustomDateRange
id="datetime-filter" // Using a ion-datetime-button to open it
min="2023-01-01T00:00:00"
:start="startDate"
:end="endDate"
@update:start="(d) => (startDate = d)"
@update:end="(d) => (endDate = d)"
/>
const startDate = ref<string>('2023-10-01');
const endDate = ref<string>('2023-10-23');
The component
<template>
<ion-datetime
class="clink-date-time-range"
presentation="date"
locale="es-ES"
multiple
:value="currentUserSelection"
v-on:ion-change="handleDateChange"
:highlighted-dates="defineHighlightStyle"
v-bind="$attrs"
/>
</template>
<script setup lang="ts">
import { IonDatetime, DatetimeChangeEventDetail } from '@ionic/vue';
import { IonDatetimeCustomEvent, DatetimeHighlightCallback } from '@ionic/core';
import { onMounted, ref } from 'vue';
import { DateTime } from 'luxon';
interface ClinkDatetimeRange {
start: string;
end: string;
}
const props = defineProps<ClinkDatetimeRange>();
const emit = defineEmits<{
(e: 'update:start' | 'update:end', date: string): void;
}>();
const currentUserSelection = ref<string[] | undefined>();
const previousUserSelection = ref<string[] | undefined>();
onMounted(() => {
const initRange: string[] = [props.start, props.end];
currentUserSelection.value = previousUserSelection.value = initRange;
});
const defineHighlightStyle: DatetimeHighlightCallback = (date: string) => {
if (!currentUserSelection.value || currentUserSelection.value.length < 2)
return;
const startDateCurrentRange = DateTime.fromFormat(
currentUserSelection.value[0],
'yyyy-MM-dd'
);
const endDateCurrentRange = DateTime.fromFormat(
currentUserSelection.value.at(-1) as string,
'yyyy-MM-dd'
);
const formattedDate = DateTime.fromFormat(date, 'yyyy-MM-dd');
const isDateWhithinRange =
formattedDate > startDateCurrentRange &&
formattedDate < endDateCurrentRange;
if (isDateWhithinRange)
return {
backgroundColor: '#4818f717',
};
};
const handleDateChange = (
e: IonDatetimeCustomEvent<DatetimeChangeEventDetail>
) => {
currentUserSelection.value = e.detail.value as string[] | undefined;
if (!currentUserSelection.value && !previousUserSelection.value) return;
if (!currentUserSelection.value || currentUserSelection.value.length < 2)
return;
currentUserSelection.value = [...currentUserSelection.value].sort((a, b) =>
a > b ? 1 : -1
);
if (previousUserSelection.value && previousUserSelection.value.length >= 2) {
const isSelectionWhithinPreviousRange =
currentUserSelection.value.length < previousUserSelection.value.length;
if (isSelectionWhithinPreviousRange) {
const selectedDateWhithinPreviousRange =
previousUserSelection.value.filter(
(date) => !(currentUserSelection.value as string[]).includes(date)
);
currentUserSelection.value = selectedDateWhithinPreviousRange;
} else {
const lastUserSelection = [(e.detail.value as string[]).at(-1) as string];
currentUserSelection.value = lastUserSelection;
}
}
previousUserSelection.value = currentUserSelection.value;
emit('update:start', currentUserSelection.value[0]);
emit('update:end', currentUserSelection.value.at(-1) as string);
};
</script>
did anybody manage to do this with angular 17?
did anybody manage to do this with angular 17?
I'm using the library @googlproxer/ion-range-calendar with Angular 17 and Ionic 7 and it works like a charm.
@djabif is there a example to look at? cant seem to get it running
@lukasrgr sorry but I can't share the code of this app but I can help you with the integration if you have any specific question
This is essential for a framework, please have this consider.
Choose Flutter, and make life easy. My new project had switched to the Flutter platform.
So the common feature, however, there is no option in Ionic, it has passed 3 years.
This needs to be added.
Realmente necesitamos esto, mientras no tengamos esta característica, todavía necesito usar herramientas externas a Ionic
¿Qué cosas externas estás usando? Quiero mostrar varios rangos de fechas en el mismo calendario, ¿hay alguna forma que usted sepa?
https://www.npmjs.com/package/ion2-calendar Es genial
Is that component available for Angular Ivy?