New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow multiple input formats, add onClear callback for better Ember/Knockout/etc integration and allow other date libraries instead of Moment.js #134
Conversation
- Cleaned up `setDate()` so both null date and invalid date string clear the current selection. - Extracted `clearDate()` method from `setDate()` for clearing the current selection with options for clearing the input field (if set) and preventing `onClear` callback. - `onClear` callback is called by `clearDate()` so users can be notified of invalid/empty date. The user's callback can get the field text value to show a required validation message if empty or invalid date validation message if not empty. - `onSelect` and `onClear` are useful when integrating with MVC frameworks such as Knockout.js and Ember.js where `onSelect` and `onClear` sets and clears the component's date value. - `clearInvalidInput` option can be set to `true` to automatically clear the input field value (if `field` is set) on invalid input.
@@ -580,7 +608,33 @@ | |||
*/ | |||
toString: function(format) | |||
{ | |||
return !isDate(this._d) ? '' : hasMoment ? moment(this._d).format(format || this._o.format) : this._d.toDateString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I hate seeing nested ternary operators on a single line.
@@ -79,6 +79,7 @@ Pikaday has many useful options: | |||
* `bound` automatically show/hide the datepicker on `field` focus (default `true` if `field` is set) | |||
* `position` preferred position of the datepicker relative to the form field, e.g.: `top right`, `bottom right` **Note:** automatic adjustment may occur to avoid datepicker from being displayed outside the viewport, see [positions example][] (default to 'bottom left') | |||
* `format` the default output format for `.toString()` and `field` value (requires [Moment.js][moment] for custom formatting) | |||
* `inputFormats` optional array of allowed input formats for `field` value and `.setDate()` with string (requires [Moment.js][moment] for custom parsing). **Note:** The default output `format` will be added to `inputFormats` if not already included. See the [moment.js example][] for example usage. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was also thinking of parseFormats
for this option name as it is used by parseDate()
and seemed more explicit. Feel free to suggest better names for any of these option and method names etc.
- `parseDate()` method was extracted from `_onInputChange()` to remove duplicate date string parsing in Pikaday constructor for `defaultDate` and in `setDate()` (was only parsing with JS Date.parse?). - `parseDate()` method was added to Pikaday prototype instead of a helper/private method to allow for overriding both `toString()` and `parseDate()` to support other JS date libraries. See Sugar example. - A big feature of Moment.js is that it allows for multiple input formats. `inputFormats` option was added to allow users to specify an array of allowed input formats. Defaults to the display format. Moment example updated accordingly.
@@ -233,7 +244,7 @@ Hide the picker making it invisible. | |||
|
|||
Hide the picker and remove all event listeners — no going back! | |||
|
|||
### Internationalization |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think this section belonged under the Methods heading
- Added expected type of `defaultDate` option similar to `minDate` and `maxDate` to remove confusion (Pikaday#15).
The wrong month is sometimes shown when minDate year > default date's From the issue's description: When you set minDate for a date after the currently selected date, the calendar, when shown, should display the month where minDate is. This works if both dates are in the same year, but if the new minDate's year is greater than the selected one, the month shown will be a mix of the selected date's month with the minDate's year. There is a separate issue in that `setMinDate` and `setMaxDate` do not update the min/maxMonth and min/maxYear internal options.
this._m = minMonth; | ||
} | ||
this._m = minMonth; | ||
} else if (this._y == minYear && !isNaN(minMonth) && this._m < minMonth) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this is checking if min/maxMonth isNan? As far as I can tell, the config
function checks the min and max dates are valid dates before extracting the min and max months. I think minMonth and maxMonth should be defaulted to 0 and 11 instead of undefined, however.
@@ -11,7 +11,7 @@ Pikaday | |||
|
|||
![Pikaday Screenshot][screenshot] | |||
|
|||
**Production ready?** Since version 1.0.0 Pikaday is stable and used in production. If you do however find bugs or have feature requests please submit them to the [GitHub issue tracker][issues]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spaces on the eol are significant in markdown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I wasn't sure about this. I'll fixup the README accordingly. Any other feedback? :-)
Do you mind rebasing from master? |
Sure. I'm almost done adding some Mocha tests too. On Tue, Apr 8, 2014 at 4:23 PM, Ramiro Rikkert notifications@github.comwrote:
|
Datejs replaces the native Date.parse method with one that understands basic natual language. Unfortunately, it returns a Date object or null on error unlike the native Date.parse method that returns milliseconds since the UNIX epoch 1/1/1970 or NaN on error that Pikaday relied on. - I have updated the parseDate method to check the result of Date.parse instead of using it immediately in a new Date constructor - A Datejs example has been added and the README updated accordingly - Sugar.js example also updated to support format option and remove mention of customising single Pikaday instance due to bug with Pikaday constructor parsing default value string from field with normal parseDate before it could be updated by user with this method. This would require a new config option for custom formatter and parser for Pikaday instance. - README also updated to fix Knockout link and Javascript renamed to JavaScript for consistency
I've just come back from holidays so I'll get back on top of this PR and hope to have it done soon. I'll put up an early example of the test framework I've made to see if it's on the right track. |
I have a test suite ruining trough testing. |
I used Mocha as you asked and created a tests folder with a pikaday.html file with the following: <html>
<head>
<meta charset="utf-8">
<title>Pikaday Tests</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
</head>
<body>
<div id="mocha"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/should/should.js"></script>
<script src="../pikaday.js"></script>
<script>
mocha.setup('bdd')
describe('Pikaday', function() {
describe('#toString()', function() {
it('should return empty string when date not set', function() {
var pikaday = new Pikaday();
pikaday.toString().should.equal('');
})
it('should return date string when date is set', function() {
var date = new Date('2014-04-25');
var pikaday = new Pikaday();
pikaday.setDate(date);
pikaday.toString().should.equal(date.toDateString());
})
})
describe('#getDate()', function() {
it('', function() {
})
})
describe('#setDate()', function() {
it('', function() {
})
})
describe('#clearDate()', function() {
it('', function() {
})
})
describe('#parseDate()', function() {
it('', function() {
})
})
describe('#gotoDate()', function() {
it('', function() {
})
})
...
})
mocha.checkLeaks();
mocha.globals(['jQuery']);
mocha.run();
</script>
</body>
</html> I wasn't sure how to have an html test file that uses Moment and one without Moment. Including pikaday.js automatically includes Moment.js as it finds the Was this the kind of test suite and setup you had in mind with Mocha? |
Check out the test framework and test stubs that I added. |
Sure, i can do that. Am busy with work this week so will continue on the On Thursday, 1 May 2014, Ramiro Rikkert notifications@github.com wrote:
|
@rikkert How do I create multiple PRs for Pikaday from my bjbrewster/Pikaday fork? I guess I could fork Pikaday multiple times or scale back my single PR to a smaller set of fixes and once you've merged that I can create another PR etc? |
Easiest is to make a new branch for each PR of the relevant commit. |
Have these been merged somewhere or is this still in the works? I would love to start using some of these features. |
Hello, I got a bit lost regarding creating many PRs from my own repo. I'll try to Cheers, On Fri, Sep 12, 2014 at 12:00 PM, Michael Keller notifications@github.com
|
Great! In the meantime I'm just using your fork. I have one suggestion: when you call EDITED to remove the question on a proper way to clear min and max time since I just figured it out. |
Not sure if |
Ya it might not be for everybody. I'm setting the min/max more dynamically based on what the user has filled into the other box as opposed to hard limits for the page's state. Perhaps it's an argument the same way you have a boolean for clearing the display. But, again, if it's a small use case, setting it in the callback is easy enough. |
So is this PR dead? |
I still think it's an improvement. |
Great PR. Why isn't it accepted? |
I find this PR very useful. Any chances it will be accepted? |
+1 |
@bjbrewster @mhkeller Is this PR dead? Is it safe to replace into my existing code that is already using the current pikaday? The functionality I'm wanting is the multiple input formats. |
Yes, use the parse and toString method that have been added. |
Thanks for creating this awesome and yet simple date picker. We are using this library on a fundraising portal raising money for charity so know that its helping make a difference in the world. We needed a few changes to make it easier to integrate with Ember.js so I would like to contribute back to your project.
This change is loosely based on #57 to add callback on clear/invalid date and also fixes #61, #48, #15, #93, #98. I decided upon
onClear
for the name of the callback, in the same vein asonSelect
, named after the methodclearDate()
that I extracted fromsetDate()
. Feel free to suggest better names. It was very tempting to callonSelect
callback withnull
for empty/invalid date, but this would most likely break a lot of code by the Pikaday community that relies on the callback always having a valid date so a new callback must be introduced instead. I would also like to add a suite of automated JS tests to improve code quality.setDate()
so both null date and invalid date string clear the current selection.clearDate()
method fromsetDate()
for clearing the current selection with options for clearing the input field (if set) and preventingonClear
callback.onClear
callback is called byclearDate()
so users can be notified of invalid/empty date. The user's callback can get the field text value to show a required validation message if empty or invalid date validation message if not empty.onSelect
andonClear
are useful when integrating with MVC frameworks such as Knockout.js and Ember.js whereonSelect
andonClear
sets and clears the binding/component's date value.clearInvalidInput
option can be set totrue
to automatically clear the input field value (iffield
is set) on invalid input. This is a simple way of telling the user the entered date is invalid.parseDate()
method was extracted from_onInputChange()
to remove duplicate date string parsing in Pikaday constructor fordefaultDate
and insetDate()
(was only parsing with JS Date.parse?).parseDate()
method was added to Pikaday prototype instead of a helper/private method to allow for overriding bothtoString()
andparseDate()
on Pikaday.prototype to support other JS date libraries.See Datejs and Sugar examples.
inputFormats
option was added to allow users to specify an array of allowed input formats. Defaults to the display format. Moment example updated accordingly.draw
method.