Baremetrics / calendar

Date range picker for Baremetrics
MIT License
680 stars 79 forks source link

Preserve and display preset titles #96

Open hheimbuerger opened 5 years ago

hheimbuerger commented 5 years ago

Motivation

We need the ability to persist the state of the datepicker across page loads. This presents a major UX problem related to presets: if the user selects a Today preset and then reloads the page on the next day, what’s the expected behavior? I don’t think there’s a single ‘right’ answer, but we decided that we wanted to go with ‘constantly updating’ presets.

Current behavior

The current behavior of datepicker is that any preset the user selects is immediately turned into a fixed daterange. So if the user selects This month on Jan 31, this is converted into the interval Jan 1 - Jan 31 and the component immediately forgets that the prefix was ever chosen. If the user reloads the “this month” view on Feb 1, they will again see the Jan 1 - Jan 31 interval.

Intended behavior

What we wanted to do is two-fold: First, we wanted to have the ability to actually keep the preset around and show it to the user after they’ve selected it. And second, we wanted to be able to read from the component when the user has chosen a preset as opposed to a date range, so that we can persist the specific user choice. To continue the aforementioned example: has the user selected This month from the presets, or have they selected the interval from Jan 1 to Jan 31?

Implementation

We introduce a new element with class dr-date-preset, which is by default hidden, and shown instead of the three dr-date-start, dr-dates-dash and dr-date-end elements if a preset is currently selected.

When a preset is selected, this element is shown and shows the title of the current preset. When that preset title is clicked, the title turns into the current date interval and the dropdown to choose another start and end date appears.

This new functionality has to be enabled by setting the new configuration flag sticky_presets to true, Theoretically, if you don’t set this new configuration option, the behavior of the component should be unchanged. But I leave it to the reviewers to confirm that.

The change events (callback), now contain a new field preset_label which is set to the title of the preset if a preset was chosen, and null if a date interval was selected.

A new component with this configuration has been added to the test page.

Credit

This feature branch was developed in pair programming by @serglo and @hheimbuerger. Equal credit should be given, I just happen to be the messenger.

Preview

2019-05-26_20-12-38

hheimbuerger commented 5 years ago

The biggest challenge I have is setting a prefix programmatically on the component (e.g. after depersisting a prefix from a storage system). Here's the code I'm currently using, but it's obviously not very pretty:

function setPrefix(prefix) {
    // simulate a click on the preset dropdown item to the given prefix label
    $('.dr-list-item[data-label="' + prefix + '"]', backing_component.element).trigger('click');
    backing_component.calendarSetDates();
    backing_component.presetToggle();
}

I'd appreciate if someone could come up with a better implementation.