Skip to content
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

Override the default for dateParser / dateFormatter? #459

Closed
johnnyreilly opened this issue Jul 1, 2015 · 14 comments
Closed

Override the default for dateParser / dateFormatter? #459

johnnyreilly opened this issue Jul 1, 2015 · 14 comments

Comments

@johnnyreilly
Copy link
Contributor

Hi,

I've been having a play with Globalize 1.x with a view to finally migrating jquery-validation-globalize over to it. To do this I've focussing on date parsing and number parsing - that's the only functionality of Globalize that jquery-validation-globalize uses.

There's a big jump involved in switching from Globalize 0.1 to Globalize 1.x (it turns out getting set up with Globalize 1.x is no small feat!). I'm hoping to do my best to make the switch in using jquery-validation-globalize as painless as possible.

The existing jquery-validation-globalize takes Globalize as a dependency and swaps out the various validation methods to use Globalize for number and date parsing. There's really very little to it - I enclose the source for clarity:

(function ($, Globalize) {

    // Clone original methods we want to call into
    var originalMethods = {
        min: $.validator.methods.min,
        max: $.validator.methods.max,
        range: $.validator.methods.range
    };

    // Tell the validator that we want numbers parsed using Globalize

    $.validator.methods.number = function (value, element) {
        var val = Globalize.parseFloat(value);
        return this.optional(element) || ($.isNumeric(val));
    };

    // Tell the validator that we want dates parsed using Globalize

    $.validator.methods.date = function (value, element) {
        var val = Globalize.parseDate(value);
        return this.optional(element) || (val instanceof Date);
    };

    // Tell the validator that we want numbers parsed using Globalize, 
    // then call into original implementation with parsed value

    $.validator.methods.min = function (value, element, param) {
        var val = Globalize.parseFloat(value);
        return originalMethods.min.call(this, val, element, param);
    };

    $.validator.methods.max = function (value, element, param) {
        var val = Globalize.parseFloat(value);
        return originalMethods.max.call(this, val, element, param);
    };

    $.validator.methods.range = function (value, element, param) {
        var val = Globalize.parseFloat(value);
        return originalMethods.range.call(this, val, element, param);
    };

}(jQuery, Globalize));

As you can probably tell this relies on Globalize having been initialised to the required culture (that's locale in 1.x). It looks like I can take a similar approach by initialising Globalize 1.x to the required locale.

From my initial testing it seems that I can just swap out usage of parseFloat and replace it with parseNumber as per the migration guide. Since numbers are pretty straightforward it looks this this just works. (further testing still required)

However, dates are not so straightforward as there's a million and one ways to express a date. So, my question: is there a way to specify default dateParser / dateFormatter options? Looking at the source code I suspect the answer is "not right now".

Which is a shame. Would it be possible to have this ability? This would make migration of jquery-validation-global more straightforward and would, I suspect, be a generally useful thing. I tend to use only one date formatting / parsing style and so I would much rather have the ability to set this during initialisation and then rely on this behaviour subsequently. It also seems an good thing to have given that you already have the concept of a default locale as a possibilty.

@rxaviers
Copy link
Member

rxaviers commented Jul 1, 2015

is there a way to specify default dateParser / dateFormatter options?

Yeap, the default is { skeleton: "yMd" }. Is that what you ask?

@johnnyreilly
Copy link
Contributor Author

Hi @rxaviers,

What I'm wondering is is there away to override the default? To make it { datetime: "medium" } instead, for example?

@rxaviers rxaviers changed the title Default dateParser / dateFormatter? Override the default for dateParser / dateFormatter? Jul 1, 2015
@rxaviers
Copy link
Member

rxaviers commented Jul 1, 2015

It's clear now, thanks. Will read your use case better when I find time and get back to you.

@johnnyreilly
Copy link
Contributor Author

Thanks @rxaviers!

@johnnyreilly johnnyreilly mentioned this issue Jul 24, 2015
@rxaviers
Copy link
Member

@johnnyreilly, I didn't fully understand the relationship between overriding the default dateParser / dateFormatter options and how this should solve the mapping between 0.x to 1.x date patterns (ways to express a date)?

@johnnyreilly
Copy link
Contributor Author

@rxaviers essentially it's about not having to specify a date format each time the parsing takes place or pass in one format right at the start. Ideally I don't want to require users to pass a date format to jquery.validation.globalize.js on initialisation. Rather, I would like to be able to rely on the default dateParser. If users can configure the default then they would be able to control that and implicitly control the date parsing that jquery.validation.globalize.js does.

Obviously there's other approaches but controlling the default seems like it would be a useful feature anyway. The "out-of-the-box" default doesn't seem too useful as it stands.

Does that make sense?

@rxaviers
Copy link
Member

Can't this be configured at the validator scope? For example:

    $.validator.methods.dateDefaultOptions = null;
    $.validator.methods.date = function (value, element) {
        var val = Globalize.parseDate(value, $.validator.methods.dateDefaultOptions);
        return this.optional(element) || (val instanceof Date);
    };

Globalize dateParser / dateFormatter default mimics ecma-402 default.

@johnnyreilly
Copy link
Contributor Author

That's probably good enough for me. Let me try it out and report back.

Though, my use case aside i think the existing fixed default doesn't add much value. But if you're seeking to align with a spec then fair enough I guess.

@rxaviers
Copy link
Member

Awesome. Just let me know if something else pops up.

@johnnyreilly
Copy link
Contributor Author

Hi @rxaviers,

I've just been giving it a go and unfortunately I had to start again from scratch (long story). Anyway, I've used Bower to upgrade to 1.0.0 and I have a cldr-data folder. Yay! But it doesn't contain any cldr-data. Boo!

I've read and re-read the cldr-data-bower documentation but for the life of me I can't figure out how I actually get the CLDR data itself.

Could you clarify it for me please?

For what it's worth I don't understand what this actually means:

On the bower.json of your application, list the i18n dependencies as you'd
normally do. For example, let's say they are FooNumberFormat and BarDateFormat.

"dependencies": {
  "foo-number-format": "1.2.3",
  "bar-date-format": "4.5.6"
}

In the example what are "foo-number-format" and "bar-date-format"? Could you share a real world example perhaps?

I added the .bowerrc additions as suggested but it didn't make any difference that I could tell... I have no cldr data 😢

@johnnyreilly
Copy link
Contributor Author

Cracked it (I think).

To make it work you need to delete your local bower_components, create the .bowerrc and then enter the magic bower install.

Hey presto cldr-data.

I didn't seem to need any dependencies:

"dependencies": {
  "foo-number-format": "1.2.3",
  "bar-date-format": "4.5.6"
}

I wonder if it might be worth highlighting in the docs that if you should remove all bower stuff and reinstall if you want to pull the cldr-data down. What do you think?

@rxaviers
Copy link
Member

rxaviers commented Aug 7, 2015

Hey @johnnyreilly, thanks for raising these points up.

Quick answer, it didn't work because you might have run bower install before having created the postinstall hook .bowerrc.

Longer answer:

Developers can use any tool to fetch CLDR data being bower one of them. When using bower, https://github.com/rxaviers/cldr-data-bower is the package I suggest. Its documentation needs obvious improvements given your comments and I have filed an issue rxaviers/cldr-data-bower#4 to keep track of the points you mentioned. Feel free to add new comments or correct me there as you see fit please. A PR would be very much appreciated :P.

The current discussion of this issue is diverging from its original scope. So, I'm closing it.

I wonder if it might be worth highlighting in the docs that if you should remove all bower stuff and reinstall if you want to pull the cldr-data down. What do you think?

Sure, feel free to submit a PR with a suggestion. I'm sure there are improvements to be done that will help users to overcome these questions. Although, I am not convinced about the remove and reinstall thing. I guess you ran bower install, but hadn't create the hook first.

I want to emphasize that your help has been very much welcome and appreciated so far and I'm looking forward to further contributions. Thanks

@rxaviers rxaviers closed this as completed Aug 7, 2015
@johnnyreilly
Copy link
Contributor Author

Hi @rxaviers, I'll try and submit a docs PR when I get a moment. Cheers.

@rxaviers
Copy link
Member

rxaviers commented Aug 7, 2015

Awesome, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants