feature(datepicker): let users define his own date model implementation

Please remember, the issues forum is NOT for support requests. It is for bugs and feature requests only.
Please read https://github.com/ng-bootstrap/ng-bootstrap/blob/master/CONTRIBUTING.md and search
existing issues (both open and closed) prior to opening any new issue and ensure you follow the instructions therein.

Bug description:

The user is forced to use NgbDateStruct as his application-model for dates.
If as a user I want to manage the dates using native JavaScript Date class, then I first need to convert Date to NgbDateStruct before assigning it to the date-pickers’ model.
Then, before persisting the model I need to convert back from NgbDateStruct to Date.
It could be nice that NgbDateParserFormatter let the user to define methods to convert from user-model date implementation to ng-bootstrap/datepicker NgbDate implementation, and then back from NgbDate to user-model date implementation.

Link to minimally-working plunker that reproduces the issue:

You can fork a plunker from one of our demos and use it as a starting point.
Please note that we can not act on bug reports without a minimal reproduction scenario in plunker. Here is why:

Version of Angular, ng-bootstrap, and Bootstrap:

Angular: 4.0.3

ng-bootstrap: 1.0.0-beta.1

Bootstrap: 4.0.0-beta

3 thoughts on “feature(datepicker): let users define his own date model implementation

  1. Ok @pkozlowski-opensource , I took some of your suggestions with little modifications on names:

    • I’ve split the code into a new class named NgbDateModelAdapter
    • Default implementation provided is under NgbDateModelStructAdapter class and configured / provided in DatepickerModule
    • Methods names are called modelToNgbDate and ngbDateToModel instead modelToStruct and structToModel (NgbStruct would be the model not the target of conversion`).
    • I added some basic tests based on the ngb-date-formatter-parser.spec.ts file.

    More details can be seen on the following commit: edriang@29f3a78

    Also note that material is taking a slightly different approach here: https://github.com/angular/material2/blob/master/src/lib/core/datetime/date-adapter.ts

    I can see they have only one adapter to configure all. In NgBootstrap configuration is split in different classes / services (ie: formatter/parser and I18N)

    In NgBootstrap you have NgbDate to manage internal dates, and then NgbStruct to represent selected date model. That’s why I think that the solution adding a simple adapter does the trick here without many modifications.

  2. Hi @maxokorokov, thank you for the suggestions.

    I’ve committed a new version, you can see the changes here: edriang@38b335a

    About your questions:

    why not justNgbDateAdapter? also ngbDateToModel looks redundant to me.

    Done. Liked the renaming suggestions.

    we should use it not only for the ngModel conversion, but everywhere else in the NgbDatepicker like markDisabled, maxDate, minDate and also in DateTemplateContext and NgbDateParserFormatter, right ?

    I don’t know if this is necessary, as a user I only care about ngModel. I mean, I don’t have any problem configuring maxDate, minDate, etc, using NgbDateStruct format. I wanted to make few changes as possible regarding internal model manipulation. Do you think this is necessary?

    should we type NgbDatepicker as NgbDatepicker accordingly? should we use any as you do now? I would prefer the first one, but not sure what impact it would have


    does it make sense to have the NgbDateStructAdapter as the default one, or switch to NgbDateNativeAdatper with the default JS date as a model right away?

    I think this is necessary if we want to keep retro-compatibility with actual implementation. Changing default Date model will be a breaking change for anyone using this datepicker

    With this commit, I’ve also pushed a modification on the demo project. I’ve updated the API doc section regarding NgbDateAdapter and also provided a minimal example defining a custom NgbDateNativeAdapter and using it in the example component.

    I’ll be waiting for any other change or suggestion. Thanks