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

min/max date $watch continuously #23

Open
luciformed opened this issue Apr 29, 2015 · 5 comments
Open

min/max date $watch continuously #23

luciformed opened this issue Apr 29, 2015 · 5 comments

Comments

@luciformed
Copy link

Common use case is to have two pickers to specify start and end dates, where end date cannot be before the start date. Doesn't it make sense to keep watching for min/max date changes?

@davidlgj
Copy link
Contributor

The standard approach in schema form has been to not watch changes in form definitions but instead let the user issue a schemaFormRedraw event , this is to keep the number of watches down.

Two solutions spring to mind (if the standard solution is not enough), one is to add an option to watch for changes of min/max, the other is to create an addon with two date fields explicitly for ranges.

@luciformed
Copy link
Author

I'm not sure how the latter approach could work, one field handling 2 keys?
Could $validators be used somehow to implement a solution to this?

@davidlgj
Copy link
Contributor

I need to get an example going on how to do something like that soon, you aren't the first one to ask :) But basically you could swing something by letting it include the two fields, like a fieldset limited to two fields.

$validators could be used to validate the ranges, but wouldn't let you change min/max unless we watch them.

@ghost
Copy link

ghost commented Sep 9, 2015

Hi @davidlgj @luciformed ,

I have find some work-around for this issue, Please have a look at my plnkr link http://plnkr.co/edit/Tkhgnh?p=preview

I am an angular schema form noob. So, I would really appreciate your suggestion on my fix.

Before going through the code, I would like to share you the logic what I followed.

When we select the start date (i.e., 9 september, 2015) the end date can't be before the given date
When we select the end date (i.e., 9 septermber, 2015) the start date can't be after the given date

Let me start with the template changes, I have added three attributes to the template "rangeStartDateField","rangeEndDateField","rangeSelector"

            ******************** datepicker.html *********************************

    <div class="form-group {{form.htmlClass}}" ng-class="{'has-error': hasError()}">
      <label class="control-label" ng-show="showTitle()">{{form.title}}</label>
      <div ng-class="{'input-group': (form.fieldAddonLeft || form.fieldAddonRight)}">
        <span ng-if="form.fieldAddonLeft"
          class="input-group-addon"
          ng-bind-html="form.fieldAddonLeft"></span>
        <input ng-show="form.key"
           style="background-color: white"
           type="text"
           class="form-control {{form.fieldHtmlClass}}"
           schema-validate="form"
           ng-model="$$value$$"
           ng-disabled="form.readonly"
           pick-a-date="form.pickadate"
           min-date="form.minDate"
           emit="form.minDate"
           max-date="form.maxDate"
           rangeStartDateField ="form.rangeStartDateField"
           rangeEndDateField="form.rangeEndDateField"
           rangeSelector="form.rangeSelector"
           name="{{form.key.slice(-1)[0]}}"
           format="form.format" />
        <span ng-if="form.fieldAddonRight"
          class="input-group-addon"
          ng-bind-html="form.fieldAddonRight"></span>
      </div>
      <span class="help-block">{{ (hasError() && errorMessage(schemaError())) || form.description}}</span>
    </div>

I have changed the config section of the bootstrap-datepicker.js

       ******************** bootstrap-datepicker.js *********************************
        var datepicker = function(name, schema, options) {
        if (schema.type === 'string' && (schema.format === 'date' || schema.format === 'date-time')) {
            var f = schemaFormProvider.stdFormObj(name, schema, options);
            f.key = options.path;
            f.type = 'datepicker';
            f.rangeStartDateField = options.rangeStartDateField;
            f.rangeEndDateField = options.rangeEndDateField;
            f.rangeSelector = options.rangeSelector;
            console.log("angular schema form >  addon > datepicker > form definition > ", f);
            options.lookup[sfPathProvider.stringify(options.path)] = f;
            return f;
        }
        };

When we select the date, the date has been pushed to the view using ngModel.$parsers.push(function()); , Here I am getting the start date or end date and $emit the event

        ******************** bootstrap-datepicker.js *********************************
        ngModel.$parsers.push(function() {
            /*
                range selector
            */
            if (angular.isDefined(scope.$parent.form.rangeSelector) && scope.$parent.form.rangeSelector ==="true") {
                    /*
                        selected start date should be set as min date for end date field
                        $emit the event 
                    */
                var key = scope.$parent.form.key[0];
                if (angular.isDefined(key) && angular.isDefined(scope.$parent.form.rangeStartDateField) && key === scope.$parent.form.rangeStartDateField) {
                    var rangeEndDateField = {};
                    rangeEndDateField.minDate = picker.get('select', scope.format || defaultFormat);
                    rangeEndDateField.key = scope.$parent.form.rangeEndDateField;
                    scope.$root.$emit( "rangeEndDateField", rangeEndDateField);
                } 
            /*
                   selected end date should be set as max date for start date field
                   $emit the event
            */
            else if (angular.isDefined(key) && angular.isDefined(scope.$parent.form.rangeEndDateField) && key === scope.$parent.form.rangeEndDateField) {
                   var rangeStartDateField = {};
                   rangeStartDateField.maxDate = picker.get('select', scope.format || defaultFormat);
                   rangeStartDateField.key = scope.$parent.form.rangeStartDateField;
                   scope.$root.$emit("rangeStartDateField", rangeStartDateField);
                }
                }

                return picker.get('select', scope.format || defaultFormat);
            });

added the listeners to the event and updating the min and max date of the field as per my logic

     ******************** bootstrap-datepicker.js *********************************
       /*
        listener for the event rangeEndDateField
        */
        scope.$root.$on("rangeEndDateField", function(event, data) {
        var key = scope.$parent.form.key[0];
        if (angular.isDefined(key) && key === data.key) {
            picker.set('min', formatDate(data.minDate));
            console.log("angular schema form >  addon > datepicker > event listener > event name : rangeEndDateField > ", event, key, data);
        }
        });
        /*
        listener for the event rangeStartDateField
        */
        scope.$root.$on("rangeStartDateField", function(event, data) {
        var key = scope.$parent.form.key[0];
        if (angular.isDefined(key) && key === data.key) {
            console.log("angular schema form >  addon > datepicker > event listener > event name : rangeStartDateField > ", event, key, data);
            picker.set('max', formatDate(data.maxDate));
        }
        });

This is my schema and form definition

      $scope.schema = {
        "type": "object",
        "title": "Comment",
        "properties": {

          "userStartDate": {
        "type": "string",
        "format": "date",
        "title":"Product Start Date"
          },
          "userEndDate": {
        "type": "string",
        "format": "date",
        "title":"Product End Date"
          },

        },

      };



      $scope.form = [
     {
          "key": "userStartDate",
          "type": "datepicker",
          "format": "yyyy-mm-dd",
          "minDate": "2015-07-01",
          "maxDate": "2015-11-30",
          "rangeStartDateField": "userStartDate",
          "rangeEndDateField": "userEndDate",
          "rangeSelector": "true"
        }, {
          "key": "userEndDate",
          "type": "datepicker",
          "format": "yyyy-mm-dd",
          "minDate": "2015-07-01",
          "maxDate": "2015-11-30",
          "rangeStartDateField": "startDate",
          "rangeEndDateField": "userEndDate",
          "rangeSelector": "true"
        }, {
          "type": "submit",
          "style": "btn-info",
          "title": "OK"
        }
      ];

@jamesdhakera
Copy link

any updates on this ?

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

3 participants