jtsage / jtsage-datebox

A multi-mode date and time picker for Bootstrap (3&4), jQueryMobile, Foundation, Bulma, FomanticUI, and UIKit (or others)
http://datebox.jtsage.dev/
Other
474 stars 166 forks source link

beforeToday or afterToday stop +- months working #365

Closed gregh3269 closed 9 years ago

gregh3269 commented 9 years ago

Hello,

I am using calbox, download builder 1.4.5 and CalBox Calendar Mode only checked. Testing on android tablet and ff 31.4.0 on centos 6.

If I add beforeToday or afterToday the +- months stop working: <..> input name="eventDateString" id="eventDateString" type="text" value="31/01/15" data-role="datebox" data-options='{"mode": "calbox", "themeHeader" : "b", "overrideDateFormat": "%d/%m/%y", "beforeToday": true, "minDays" : 1, "afterToday": true, "maxDays" : 90 }' readonly="readonly" data-inline="true"

If I remove both beforeToday and afterToday it works ok. Adding either also stops it working.

Any ideas?

Greg

jtsage commented 9 years ago

So, I pulled a clean copy and tested this - I'm wondering if you are thinking afterToday/beforeToday : true is doing something it's not supposed to. When I set afterToday: true, the + button should be disabled, as no dates after today are valid. Same with the - button and beforeToday...

Looking at your options list, using min/maxDays, it makes afterToday/beforeToday counterintuitive.

gregh3269 commented 9 years ago

I am sure this used to work. If want 1 day before today and 90 days after today, I used to use this:

"beforeToday": true, "minDays" : 1 == 1 day before today. "afterToday": true, "maxDays" : 90 == 90 days after today.

Can this be done now?

Cheers Greg

jtsage commented 9 years ago

Yes, it did used to work that way, because in fact beforeToday/afterToday were quite broken for a while.

beforeToday: true === do not allow any dates before today. afterToday: true === do not allow any dates after today.

It's sort of reversed from standard thinking, since they are exclusive limit switches, not inclusive limit switches.

http://dev.jtsage.com/jQM-DateBox/api/afterToday/ http://dev.jtsage.com/jQM-DateBox/api/beforeToday/

http://dev.jtsage.com/jQM-DateBox/doc/4-2-limit/ (first section)

jtsage commented 9 years ago

In response to "how is this done", just drop the before/afterToday those min/maxDays declarations should do what you want. (testing to be sure right now)

Added note: there is something funky with min/max - they are turning off the +/- buttons when they shouldn't be... looking into this...

gregh3269 commented 9 years ago

"minDays" : 1, "maxDays" : 90

which is what you are suggesting, seems to work. Thanks.

btw, if I try:

"minDays" : 90, "maxDays" : 90

and go back to December it wont then go forward back to January?

Cheers Greg

jtsage commented 9 years ago

Indeed. take a look at the commit just above SHA: 8459a245f4eeb23c85715ca368312c669863d4b2

Basically, turns out if you use the minimum allowed date when trying to compute if you above the maximum, everything breaks. I've run the build system, so a fresh copy from the download builder should fix this.

gregh3269 commented 9 years ago

I use a computed "minDays" : ${yesterdays} but if I use 0 it allows all the days, could this be changed to allow no days similar to "beforeToday": true? :)

I will have to add some nasty logic on my form to switch from "minDays" : ${yesterdays} to "beforeToday": true otherwise.

Cheers Greg.

gregh3269 commented 9 years ago

Ah, sorry it already does it! ("minDays" : 0)

Tried the new download and it works. Thanks. :)

Cheers Greg

gregh3269 commented 9 years ago

Oops, "minDays" : 0 on its own allows yesterdays, whilst with a "maxDays" : 90 it does not?

Cheers Greg

jtsage commented 9 years ago

Hmm. I'm playing with a way to do this. And actually, you are looking at needing afterToday to be true.... I've been playing with the toggle sample... it seems to go like this..

afterToday: true === The chosen date must either be "today" or after today - allow no dates before today.

beforeToday: true === The chosen date must either be "today" or before today - allow no dates after today.

notToday: true === The chosen date must no be "today".

Now, looking at this, these definitions rather suck. Alas, I really can't change them - it would break anybody who is counting on the current logic.

Now, as for min/maxDays === 0. Setting one of these to zero will work... Setting both to zero will fail the early check on if calbox should even run the "check if a date is valid" bit of code.

So, 2 options.

1.) I've added an option, calAlwaysValidateDates which will force it to always check the dates...

2.) or you can not set both min and max to zero (impractical).

New version and docs available.

http://dev.jtsage.com/jQM-DateBox/api/calAlwaysValidateDates/

jtsage commented 9 years ago

fwiw, the other cheap way to force the check is to set something like blackDates to an empty array. i.e.

blackDates: []

note 2: this is probably the only place in the whole of datebox where I used falsy logic - of course it would bite me now.

gregh3269 commented 9 years ago

"blackDates" : [] does the trick, but not obvious what it is there for. I guess I can set a "maxDays" : 365 which does the same thing, as would not set a date that far into the future on this form.

Cheers Greg.

gregh3269 commented 9 years ago

Rechecking all my dates, I want all the dates before today to be disabled, and then 90 days after today to be enabled. I have to use:

"afterToday": true, "maxDays" : 90

is it the correct way round?

It should be "beforeToday": true, "maxDays" : 90

afterToday Limit dates after today's date

beforeToday Limit dates before today's date

Cheers Greg

jtsage commented 9 years ago

Yeah, it's bad documentation - and really, it's not the best way to name these - but, i'm kinda locked into it now - if I change it, I'll break anyones implementation that is using it as currently implemented.

afterToday: true - "Selected date must be after today's date (or on it)" beforeToday: true - "Selected date must be "before" today's date (or on it)"

I've updated the docs to be a bit more clear, I hope. Personally, I think you were better off with:

data-options='... "minDays": 0, "maxDays": 90, "calAlwaysValidateDates": true ...'
gregh3269 commented 9 years ago

Ah, missed the "calAlwaysValidateDates": true which works great and easy to understand.

Cheers Greg

...it also works on my two and from date picker!

$(document).on('pagecreate',function(){ // enable/disable picker dates $('#endDateString').bind('datebox', function(e, p) { if (p.method === 'open') { // Convert date using date box to mm/dd/yyyy for new Date(..) var theDate = $('#dbox').datebox('parseDate', '%d/%m/%y', $('#startDateString').val()); var startDate = new Date($('#dbox').datebox('callFormat', '%m/%d/%Y', theDate)); var todaysDate = new Date(); // Length of 1 Day var lengthOfDay = 24 * 60 * 60 * 1000; // Get the difference var diff = parseInt((((startDate.getTime() - todaysDate.getTime()) / lengthOfDay)+1)-1,10); // Set allow/disallow anything else if(diff == 0){ $('#endDateString').datebox({'maxDays': 0 }); $('#endDateString').datebox({'calAlwaysValidateDates': true }); } else { $('#endDateString').datebox({'minDays': diff}); $('#endDateString').datebox({'maxDays': 0}); $('#endDateString').datebox({'calAlwaysValidateDates': true }); } } });
$('#startDateString').bind('datebox', function(e, p) { if (p.method === 'open') { // Convert date using date box to mm/dd/yyyy for new Date(..) var theDate = $('#dbox').datebox('parseDate', '%d/%m/%y', $('#endDateString').val()); var endDate = new Date($('#dbox').datebox('callFormat', '%m/%d/%Y', theDate)); var todaysDate = new Date(); // Length of 1 Day var lengthOfDay = 1000 * 60 * 60 \
24; // Get the difference
var diff = parseInt((((endDate.getTime() - todaysDate.getTime()) / lengthOfDay)+1),10); // Set allow/disallow anything else if(diff == 0){ $('#startDateString').datebox({'maxDays': 0 }); $('#startDateString').datebox({'calAlwaysValidateDates': true }); } else { $('#startDateString').datebox({'minDays': diff}); $('#startDateString').datebox({'maxDays': 0}); $('#startDateString').datebox({'calAlwaysValidateDates': true }); } } }); });

jtsage commented 9 years ago

Excellent - glad it worked out.

Fwiw (and let me stress, the performance hit is negligable), it would be slightly more efficient to collapse your options strings...

$('#startDateString').datebox({ 'minDays': diff, 'maxDays': 0, 'calAlwaysValidateDates': true });

Again, the performance hit is next to nothing really - but I'm pretty sure that every time you do an assignment it redraws the element.

gregh3269 commented 9 years ago

Ah, good point! Tidy, nice :)

Cheers Greg.