That's the number of milliseconds in a day. Instead of a magic precalculated number, why not create all the relevant constants so the values become perfectly clear:
Personally, I find these kinds of string constants get in the way:
STRING_DIV = 'div',
STRING_TR = 'tr',
The string 'div' is never going to change to something else, is it? It would be better to just use the string directly where you need it.
This is an amazing and scary piece of code:
/**
* Get the count of the number of
* days in a month, given the
* month and year
*/
getCountDays = function( year, month ) {
var
// Set flip based on if month is
// before or after July
flip = ( month > 6 ) ? true : false
// If it's February
if ( month === 1 ) {
// If it's not a leap year
// then 28 otherwise 29
return ( year % 4 ) ? 28 : 29
}
// If it's an odd month ID
if ( month % 2 ) {
// If it's after July then 31
// otherwise 30
return ( flip ) ? 31 : 30
}
// If it's an even month ID
// and it's after July then 30
// otherwise 31
return ( flip ) ? 30 : 31
}, //getCountDays
It also calculates leap years incorrectly - try getCountDays(1900,1). February 1900 had 28 days, not 29.
Why not let JavaScript do the work for you?
getCountDays = function( year, month ) {
var msInMonth = new Date(year,month+1) - new Date(year,month);
return Math.floor( msInMonth / MILLISECONDS_IN_DAY );
},
This will handle all leap years correctly.
You can probably do something similar in your createDate function to avoid the manual tests.
Also the name getCountDays is not very informative. Maybe getDaysInMonth?
The settings options use names_with_underscores, but that's not very idiomatic in JavaScript (except for capitalized constants). camelCaseNames would be more comfortable.
Just a followup on my "amazing and scary" comment. The "amazing" part is a genuine compliment: you found a pattern in the number of days in each month that I never noticed (the 'flip' trick). Being able to see these kinds of patterns and take advantage of them is an invaluable skill in programming.
The problem here, of course, is that it makes the code a lot harder to understand. To understand and verify the function, I'd start by writing out a table of the days in each month while reciting the "30 days hath September" rhyme. :-) Then I'd have to go through all the the flip and non-flip cases in the code and compare against my table.
Let's imagine that JavaScript didn't have convenient date calculations so we couldn't use the updated function I posted above. If that were the case, what would be a simpler way to code the function? Just use the table of months directly. After all, there are only 12 months to deal with, so it's very simple:
Yeah, I agree. There doesn't seem to be an easy way to choose a year. Intuition tells me "this is a text box, I should be able to just edit that text" but it won't let me.
I thought that when I use it as a textbox it would automatically auto complete and hint a month, or dynamically show calendar selecting date while I'm typing, it did neither of those things.
Also I haven't looked at the API that hard, but from the examples it looks like it only supports american way of setting the date i.e. DD/Month/YYYY
Update: another big omission, I can select year only by scrolling through it month by month. i.e. try selecting February 12, 2016
Keyboard support for entering a date manually would be great. The GUI is great. Would like to see what the author could come up with for a pick a time.
Please, never use the Dojo Toolkit. I was forced to use it on a project and working with it was reinventing the wheel while pulling out hair. It was overly complicated for something that needed to be straightforward and simple.
Amen to that. The doc for it sucks too (not that there's enough there, but most doc for it found by google et al is obsolete/deprecated. And last but not least... the plugin ecosystem for dojo sucks even worse, and whatever widgets/dijits actually exist for it, usually look like @ss.
The only one who seems to be committed to dojo is...IBM.
ESRI the top worldwide provider of GIS software is also sold on Dojo and Dijits. I agree that their digits are uglier than Android Cupcake. I have had to use Dojo on several projects now and I also agree on how abysmal their docs are. They provide tiny little code snippets but aren't even clear of the context. "Ok, fine... where do I PUT this snip... isn't this a TUTORIAL???!!??" I've been much happier with the look and feel of ExtJS but its documentation is even worse.
I should add, I also feel like these big frameworks have all the components and dont do a good job of each component. I rather use something that is by itself but the author is passionate about the widget and it is the best it can be.
It should not be a matter of "feeling", but testing things out. Usually frameworks like Jquery UI, YUI, dojo toolkit do a very good job, jquery doesn't provide any widget infrastructure, but still it does a good job afaik.
I don't really like Dojo, but their system is so modular, you don't have to include 90% of stuff. Kinda like jQuery-ui, you can choose not to include all the other cruft.
Now with Dojo AMD (1.7+) it's even better and cleaner. You only require what you need and then build.
One issue: when you change the input type from "date" to "text", you lose the common backend format that date input fields are supposed to have. With a normal date input element, input.value returns a date in the format "yyyy-mm-dd" regardless of the display format (in Chrome, at least), and the submitted POST/GET variables reflect the same format. With your date picker, I get values like "31+October%2C+2012". Is there any way to modify your library to mimic the former behavior? Otherwise, you might want to note in your docs that this date picker might require tweaking your server side form processing code.
Indeed. In fact, I'd posture that the comments, after the first, are wrong; the lines' intents are to _set_!
// Set the element as readonly
element.readOnly = true
// Get the date today
DATE_TODAY = P.getDateToday()
// Get the date to select
DATE_SELECTED = P.getDateSelected()
// Get the month to focus
MONTH_FOCUSED = P.getMonthFocused()
// Get the date ranges
DATE_MIN = P.getDateRange( SETTINGS.date_min )
DATE_MAX = P.getDateRange( SETTINGS.date_max, 1 )
Sometimes I feel like the JS community is more concerned with "style" than practicality. I always do one variable per var, so much more readable and much easier to debug.
>6k and a jQuery dependency? Dates aren't as hard as they used to be. I'm working on a pure-JS datepicker for modern browsers that will clock in at under 5k minified, with no dependencies. Take a look at my work so far here: https://github.com/potch/fortnight.js
(Edited to correct that the likely final minified size will be closer to 5k. Hoping to add accessibility features and localizability.)
Freezes up Chrome 23, Firefox 16.0.2 (shows "stop this script?" box) and Safari 6.0. Opera does not freeze, but the UI is very slow, suggesting something is still wrong.
Your date arithmetic jumps through some weird hoops to accomplish something really simple. To increment a date by one day, for example, can be done like so:
d = new Date(base);
d.setDate(d.getDate() + 1);
Changing rel() to do this fixes the loop problem, but something else is surely wrong, because the result page now looks like this: http://i.imgur.com/ZUAJg.png
Under 5k/100 lines uncompressed. You can easily modify above to work in a prototype fashion without a library. Unfortunately I was lazy when I wrote it and used ender/jquery for selector support.
If you are going to offer something you claim to be better, it should be better. I did a "git clone" and opened the example:
* The example looks unappealing. Not styled, not bound to a text field.
* It's not clear to my why clicking twice in a row produces a range — should this not be accomplished through mouse dragging or similar?
* If I select an end date that precedes the start date, it shows an alert box, which apparently is hardwired into the library. Not only does this make it impossible to translate the widget into multiple languages, but it's really not the task of the library to handle the error like this (an "onInvalidRange" or similar should be provided for the app to plug in).
* Month name is hardwired, no translation possible.
* No week numbers.
* No highlighting of today, holidays, or indeed of the selected range.
* No way to plug in custom dates that should be highlighted (for example, "booked" dates).
In other words, this is incomplete. I can't speak for most people, but it's useless to me. Sure, I could take your code and extend it to fit my app, but I could just as easily write it from scratch -- which defeats the point of reusability.
Sorry if this comes across a bit harsh, but you did open yourself to criticism:
> I have always wondered why javascript date pickers were always over complicated for the job.
Frankly, I suspect you have underestimated the job. :-)
Looks like Chrome's native date pickers are competing with fortnight. When I click on one of the input fields, while holding the click in, I get a fortnight picker. As soon as I let go, I get a native picker.
1) I think you should put a little tiny triangle / down arrow on the right side of the text-box to give it the official "selection" ui signal.
2) I think you should NOT grey out dates that have already passed and are not selectable but instead keep them the same black color as the others, just <strikethrough> them. They're really hard to see when grayed out that much and it confused me a little bit when I first saw the month.
Nice. It needs a way to "click off" the picker to close it, without choosing a new date. E.g. the date is pre-selected, I open it, and then I want to close it again without changing the date. I intuitively expected that if I click the original field it will toggle off again, or I clicked elsewhere on the page it would close, like a lightbox overlay.
Is it really critical? If you take the datepicker of the TFL official website (http://www.tfl.gov.uk/) they start the week on sunday too. But I agree it can be a pain when you assume the first day is monday.
Yeah, I've booked travel on the wrong dates before because I've selected the dates visually. Really annoying. As you've spotted it's an endemic problem in the UK, and it needs fixing. Even Apple get it right, and they have a strong bias to USA-ify (at least more than, say, Microsoft).
There is some strange bug in which I cant navigate more than one month before or after. It happens after I fill the initial date box. And then as I play around with the other dropdowns, I suddenly won't be able to move more than one month back or forward in any of the dropdown pickers.
This is a beautiful interface, but it doesn't provide any practical way to select dates in the distant past. "What is your birthdate" is one of many example questions that couldn't be answered without tens of dozens of clicks.
If it supported keyboard input, that problem would be solved.
HTML5 has type="date" for input fields. It'd be kinda cool if this could automatically use those in situations where the browser doesn't support the picker natively. Unless I totally misunderstand the point ;-)
Support for input type="date" can be tested by creating an element like that and checking the type attribute. But how can you tell if the browser has support for the native picker? You can't. That is why this picker takes the approach of changing the type date always to text to prevent double date pickers.
But how can you tell if the browser has support for the native picker? You can't.
That's what I was wondering. If there were a way, it'd be pretty awesome to use a library like this as a polyfill rather than as a separate thing you attach to text inputs.
Looks great. I like that it is big with plenty of spacing. Most date pickers seem to squish together the numbers without any apparent reason.
It'd be so helpful if makers of these js elements put screenshots of what the element looks like on top 3 mobile devices. Of course, this raises the question that they would need access to these devices. Which raises the question, for people who do mobile-heavy web dev, how do you test things rapidly beside having an iPhone next to you to constantly hit refresh?
This doesn't seem to work on IE9 (either that, or I just don't understand how it's supposed to work). All of the examples appear to me as plain old editable text fields.
"Bind it like this: $( '.datepicker' ).datepicker()" - so the very first instruction is an incorrect reference to JavaScript 'binding' as something that extends or provides features to an element, vs what it truly does: change the scope reference of the 'this' keyword in a function. Oh jQuery, thank you for obscuring the actual JavaScript language for developers everywhere sigh
Looks great! And with a few (minor) modifications I was able to get it to work with a non-jQuery framework! Thanks for that. I'm getting fed up with all of these ".js" projects that rely heavily on jQuery when they don't need to. I'm going to keep this library in mind for a project I'm working on.
Nice work, thanks for the contribution. Will definitely use. Funny thing to, just created a web app that centers around a calendar and date picking. Was using jQuery UI datepicker but with some tweaking, I might use this.
Some more missing stuff: does not allow to block specific days or weekdays (e.g. sundays) that should not be picked. Also time ranges (hover over a days and the next x days get highlighted) would be nice.
Looks cool but on iOs it won't let you close the picker unless you select a date other than what's selected. Touching the input again might be a good way to close it.
So i guess im answering my own question here. jqueryui names their datepicker under the same function name, I have to have jqueryUI and dont have the capacity to install a custom version of jquery ui to remove datepicker so this is basically useless to me.
pickadate is just as opinionated as jquery ui. why must component writers insist on hard-coded (and non-customisable) use-cases. there's simply no need to mandate an `input` element.
This value is not what it says:
That's the number of milliseconds in a day. Instead of a magic precalculated number, why not create all the relevant constants so the values become perfectly clear: Personally, I find these kinds of string constants get in the way: The string 'div' is never going to change to something else, is it? It would be better to just use the string directly where you need it.This is an amazing and scary piece of code:
It also calculates leap years incorrectly - try getCountDays(1900,1). February 1900 had 28 days, not 29.Why not let JavaScript do the work for you?
This will handle all leap years correctly.You can probably do something similar in your createDate function to avoid the manual tests.
Also the name getCountDays is not very informative. Maybe getDaysInMonth?
The settings options use names_with_underscores, but that's not very idiomatic in JavaScript (except for capitalized constants). camelCaseNames would be more comfortable.