Litepicker icon indicating copy to clipboard operation
Litepicker copied to clipboard

can't reproduce hotelMode + bookedDays behavior on v2.0.11

Open er314 opened this issue 3 years ago • 5 comments

I'm porting my code from v1.5.7 to v2.0.11. I'm trying to get the same behavior as previously with "hotelMode" + "bookedDays", for the selection of a date range. So now without hotelMode and with lockDays.

-> I can't get it to work the same. -> See jsfiddle example : https://jsfiddle.net/wzjL4uhy/ on this example, lockDays is : [ ['2021-04-08','2021-04-10'] , '2021-04-15']

-> So I want to get the following behavior : A- NONE of these days should be valid for selection as start date B- the days '2021-04-08' and '2021-04-15' should BE valid for selection as end date

-> For example, A- I should NOT be able to select the following start dates : '2021-04-08' '2021-04-15' B- I should BE able to select the following date ranges : ['2021-04-07','2021-04-08'] ['2021-04-14','2021-04-15']

-> In addition the the lockDays setting above, I have set the following settings :

singleMode: false,
minDays: 2,
disallowLockDaysInRange: true,
selectForward: true,

and I've played with all possible values for setting lockDaysInclusivity, but I can't get both A- and B- to work.

-> What would you suggest ?

Note 1 : My asumption for simplifying things is that now with v2.0.11, the checkout dates must not be saved as lockDays. So in the lockDays taken as example : [ ['2021-04-08','2021-04-10'] , '2021-04-15'] this actually means that the date ranges which have been selected by the users were : [ ['2021-04-08','2021-04-11'] , ['2021-04-15','2021-04-16'] ] This asumption is supposed to simplify things, but yet, I can't get it to work.

Note 2 : Precisely, the (perfect) behavior of v1.5.7 was the following : A- date '2021-04-08' was NOT selectable as a start date B- but as soon as you selected date '2021-04-07' as start date, then date '2021-04-08' was becoming selectable as end date. This is what we should be able to reproduce in v2.0. -> I also created a fiddle for illustrating this, on v1.5.7 : https://jsfiddle.net/es0gvbuk/1/

Thanks for your views (and for your amazing tool :-)

er314 avatar Apr 22 '21 10:04 er314

I have exactly the same issue with this newest version. It was awsome to have both locked days and booked days. It was possible also to display them in a different way with litepickerDayIsLockedBgColor and litepickerDayIsBookedBgColor which also disappeared. I hope we could get a solution. Thanx, for this great tool.

godestalbin avatar May 20 '21 16:05 godestalbin

After struggling many hours on this, I think I found a quite acceptable solution:

            const {{booking.roomId}} = new Litepicker({ 
                element: document.getElementById('{{booking.roomId}}'),
                inlineMode: true,
                singleMode: false,
                numberOfColumns: 2,
                numberOfMonths: 2,
                switchingMonths: 1,
                selectForward: true,  // Otherwise it is more tricky to manage
                lockDays: {{booking.lockDays|safe}},
                disallowLockDaysInRange: true,
                lockDaysInclusivity: "[)",
                setup: (picker) => {
                    picker.on('before:click', (target) => {
                        picker.setOptions({lockDaysInclusivity: "()"});  //Starting to select range
                    });
                    picker.on('selected', (date1, date2) => {
                        if (date2 != null) {
                            picker.setOptions({lockDaysInclusivity: "[)"});  //After end date is selected
                        }
                    });
                    picker.on('error:range', () => {
                        picker.setOptions({lockDaysInclusivity: "[)"});  //In case a wrong range is selected
                    });
                },
                tooltipNumber: (totalDays) => {
                    return totalDays - 1;
                },
                tooltipText: {"one":"nuit","other":"nuits"},
                startDate: "{{booking.startDate|safe}}",
                endDate: "{{booking.endDate|safe}}" 
            });

By default end date of booked stays is excluded, thus we can start selecting from the end date of a previous stay. When starting to select (clicked date for the start date of a stay), the start date of booked stays is also excluded allowing to select as end date, the start date of another stay. At the same time the option to force select forward disables all the dates before the start date. Once the end date is selected or the selection is aborted, because we crossed antother stay (disallowLockDaysInRange: true), we revert to the initial settings: lockDaysInclusivity: "[)" If there is a nicer/better/simpler solution please advice ? Just noticed that my calendar is stuck one month backward and one month forward, any idea what could be wrong ?

godestalbin avatar May 22 '21 20:05 godestalbin

Hi, thanks for sharing your experiments, I agree that this approach (= event driven changes to the inclusivity setting) seems fully valid.

On my side, now I've got a solution which works nicely. It is based on the same approach , but I use different events & different inclusivity "states". Here it is : (note that by convention, my lockDays do not include the checkout days)

let picker = new Litepicker({ 
                element: document.getElementById('datepicker'),
                singleMode: false,
                minDays: 2,
                lockDays: [['2021-04-08','2021-04-10'], ['2021-04-15', '2021-04-15']],  // example booked : 3 nights, 1 night
                disallowLockDaysInRange: true,
                selectForward: true,
                autoApply: true,  // mandatory (constraint/limitation), otherwise rendering of lockdays would not refresh when start date + end date are selected but not applied yet
                lockDaysInclusivity: "[]",  // default : all lockDays are treated as locked
                setup: (picker) => {
                    picker.on('preselect', (date1, date2) => {
                        if ((date1 !== undefined) && (date2 === undefined)) {
                          // if start date (only) is selected, we "open" the ability to select end date on a lockDay-start
                            picker.setOptions({lockDaysInclusivity: "(]"});
                            picker.gotoDate(date1);  // need to force that, for proper calendar rendering during this preselect - without that, due to setOptions() dates reset, selecting a start date in a not-current month would provoke a jump back to current month
                        }
                    });
                    picker.on('selected', (date1, date2) => {
                            // when selection if done, we revert to the default (all lockDays are treated as locked)
                            picker.setOptions({lockDaysInclusivity: "[]"});
                    });
                    picker.on('error:range', (dateRange) => {
                            // if selection error, we revert to the default (all lockDays are treated as locked)
                            picker.setOptions({lockDaysInclusivity: "[]"});
                            picker.gotoDate(dateRange[0]);
                    });
                },
                tooltipNumber: (totalDays) => {
                    return totalDays - 1;
                },
            });

jsfiddle for it : https://jsfiddle.net/c4wshqv0/5/

Important note : I think I found a bug in litepicker's method rangeIsLocked(). This needs to be fixed in order for my above code to work as intended. -> the jsfiddle above is boasting a (quick & dirty) version of litepicker which has a fix. I have just opened a new/separate issue for this bug : #242

So in the end, I guess that we would need from wakirin :

  • is it confirmed that #242 is a bug ?
  • regarding "how to implement hotelMode", is the above approach acknowledged as valid & optimal ? -> then maybe add a recipe / example in litepicker documentation, so that in the future other users won't have to struggle as we did :-)

er314 avatar May 27 '21 23:05 er314

how to set predefined array of selected days in simple format like picker.multipleDays=['2021-11-05', '2021-11-13', '2021-11-23']?

hramenko avatar Nov 23 '21 07:11 hramenko

Just noticed that my calendar is stuck one month backward and one month forward, any idea what could be wrong ?

For my work project we've used your snippet and it works amazing, but we're facing the same issue with the navigation between months; it's currently august '22 and when we skip to september '22...

  • we're not able to skip to october '22 and further
  • we can click the "previous month"-button, but that makes us jump back to july '22 (so, the month before august '22)

When we disable the picker.setOptions({lockDaysInclusivity: "()"}); //Starting to select range-line navigating works splendid again but then the hotelMode doesn't.

@godestalbin or someone else involved, does anyone have the holy grail for this? 🙏🏽

dviate avatar Aug 02 '22 10:08 dviate