0

Here is my form:

<form name="user_submission" novalidate="novalidate" method="post">
        <input type="date" name="date_of_birth" ng-focus="save_data()" ng-model-options="{timezone: 'UTC'}" ng-pattern="/^(19\d{2}|[2-9]\d{3})-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])$/" ng-model="step_content.date_of_birth" required ng-maxlength="10" ng-minlength="10"  >
    <br>
                    <span class="error" ng-show="user_submission.date_of_birth.$error.pattern">Wrong format!</span>
                    <span class="error" ng-show="user_submission.date_of_birth.$error.date">Wrong Date!</span>
                    <span class="error" ng-show="user_submission.date_of_birth.$error.minlength">Wrong Date!</span>
                    <span class="error" ng-show="user_submission.date_of_birth.$error.maxlength">Wrong Date!</span>
</form>

Here is what I get from above form: ( which perfect )

enter image description here

I need to confine the Year to 'yyyy' however no matter what I do still I can type more than 4 digits.

enter image description here

I tried a directive for it:

// Usage: <input limit-to="4" type="number" >

app.directive("limitTo", [function() {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var limit = parseInt(attrs.limitTo);
            angular.element(elem).on("keydown", function() {
                if (this.value.length == limit) return false;
            });
        }
    }
}]);

However when I add the limitTo to the date field I simply can't enter a full year which I think Angular overrides the 'yyyy' by adding a number from right and then removing a 'y' from left so limitTo=10 simply is not going to work.

I am out of option.

Any help or direction would be greatly appreciated.

Thanks in advance.

1 Answer 1

0

I gave up and written my own directive, I am not removing this question in case someone has the same issue.

Here is a directive that I made, a bit permeative but it does the job. Tested in Chrome, Safari, and Firefox.

Here is the Plunker address: https://plnkr.co/edit/XwNR618DM8IULxu9KLMe

( I couldn't sort out the address for plunker in template so I embedded in the Plunker because of the embedding the template focus directive is not working. If you implement this with the following code, your cursor should move from one textfield to another one upon completing it. )

    app.directive('multiSelectDate', function () {

        return {
            restrict: 'EA',
            scope: {
                datasource: '='
            },
            controller: function ($scope) {

                $scope.date = {
                    day: [],
                    month: [],
                    year: []
                };

                if (typeof $scope.datasource != 'undefined' && $scope.datasource != '') {
                    var sources = $scope.datasource.split('/');

                    if (typeof sources == 'object') {
                        $scope.date = {
                            day: [sources[0][0], sources[0][1]],
                            month: [sources[1][0], sources[1][1]],
                            year: [sources[2][0], sources[2][1], sources[2][2], sources[2][3]],
                        };
                    }
                }

                $scope.only_one_allowed = function(array) {
                    var val = [];
                    angular.forEach(array, function(value, index){
                        if (typeof value != 'undefined') {
                            if (value.length > 1) {
                                val[index] = value.split('')[1];
                            } else {
                                val[index] = value
                            }
                        }
                    });
                    return val;
                };

                $scope.only_number_allowed = function(array, type) {

                    if (type == 'year') {
                        var year_1st_digit = /1|2/;
                        var year_2nd_digit = /0|9/;
                        var year_rest_digit = /[0-9]/;

                        if (!year_1st_digit.test(array[0])) {
                            array[0] = '';
                        }
                        // Should be 0 or 9
                        if (!year_2nd_digit.test(array[1])) {
                            array[1] = '';
                        }
                        if (!year_rest_digit.test(array[2])) {
                            array[2] = '';
                        }
                        if (!year_rest_digit.test(array[3])) {
                            array[3] = '';
                        }

                    } else if (type == 'month') {

                        var month_1st_digit = /[0-1]/;
                        var month_2nd_digit = /[0-9]/;

                        // Shouldn't be more than 1 or less than 0
                        if (!month_1st_digit.test(array[0])) {
                            array[0] = '';
                        }

                        // Shouldn't be more than 2 or less than 0
                        if (!month_2nd_digit.test(array[1])) {
                            array[1] = '';
                        }

                        // if the month[0] is undefined and second digit has value change the first digit to 0
                        if (( typeof array[0] == 'undefined' || array[0] == '' ) && parseInt(array[1]) >= 0) {
                            array[0] = 0;
                        }

                        // date.array must have only one digit
                        if (parseInt(array[0], 10) != array[0]) {
                            array[0] = '';
                        }

                        if (parseInt(array[1], 10) != array[1]) {
                            array[1] = '';
                        }


                        if (parseInt(array[0], 10) == array[0] && parseInt(array[1], 10) != array[1]) {
                            array[1] = 0;
                        }


                    } else {

                        var day_1st_digit = /[0-3]/;
                        var day_2nd_digit = /[0-9]/;

                        // Shouldn't be more than 1 or less than 0
                        if (!day_1st_digit.test(array[0])) {
                            array[0] = '';
                        }

                        // Shouldn't be more than 2 or less than 0
                        if (!day_2nd_digit.test(array[1])) {
                            array[1] = '';
                        }

                        // if the day[0] is 3 then second digits must be less than 1
                        if (parseInt(array[0]) == 3 && parseInt(array[1]) > 1) {
                            array[1] = 1;
                        }

                        // if the day[0] is undefined and second digit has value change the first digit to 0
                        if (( typeof array[0] == 'undefined' || array[0] == '' ) && parseInt(array[1]) >= 0) {
                            array[0] = 0;
                        }

                        // date.array must have only one digit
                        if (parseInt(array[0], 10) != array[0]) {
                            array[0] = '';
                        }

                        if (parseInt(array[1], 10) != array[1]) {
                            array[1] = '';
                        }

                        if (parseInt(array[0], 10) == array[0] && parseInt(array[1], 10) != array[1]) {
                            array[1] = 0;
                        }


                    }

                    return array;
                };

                $scope.update_date = function () {

                    var day = '';
                    var month = '';
                    var year = '';

                    if (typeof $scope.date.day != 'undefined') {
                        var dirty_day = $scope.only_one_allowed($scope.date.day);
                        dirty_day = $scope.only_number_allowed(dirty_day, 'day' );
                        $scope.date.day = dirty_day;
                        day = dirty_day.join('');
                    }

                    if (typeof $scope.date.month != 'undefined') {
                        var dirty_month = $scope.only_one_allowed($scope.date.month);
                        dirty_month = $scope.only_number_allowed(dirty_month, 'month' );
                        $scope.date.month = dirty_month;
                        month = dirty_month.join('');
                    }

                    if (typeof $scope.date.year != 'undefined') {
                        var dirty_year = $scope.only_one_allowed($scope.date.year);
                        dirty_year = $scope.only_number_allowed(dirty_year, 'year' );
                        $scope.date.year = dirty_year;
                        year = dirty_year.join('');
                    }

                    $scope.datasource = day + '/' + month + '/' + year
                }
            },
            templateUrl: '/multiSelectDate.html',
            link: function (scope, element, attrs) {

                var start_year = attrs.startYear;
                if (scope.date.year.length != 4 && typeof start_year != 'undefined') {
                    scope.date.year = [start_year[0], start_year[1], start_year[2], start_year[3]];
                }

   scope.$watch('datasource', function(){

                var sources = scope.datasource.split('/');

                if (typeof sources == 'object') {
                    if (sources.length == 3) {
                        scope.date = {
                            day: [sources[0][0], sources[0][1]],
                            month: [sources[1][0], sources[1][1]],
                            year: [sources[2][0], sources[2][1], sources[2][2], sources[2][3]]
                        };
                    }

                }
            })



            }
        }
    });

Here is the template: (/multiSelectDate.html)

<div class="form-inline">
    <input type="text" focus ng-model="date.day[0]" class="dl_float" size="1" ng-keyup="update_date()">
    <input type="text" focus ng-model="date.day[1]" class="dl_float" size="1" ng-keyup="update_date()"> /
    <input type="text" focus ng-model="date.month[0]" class="dl_float" size="1" ng-keyup="update_date()">
    <input type="text" focus ng-model="date.month[1]" class="dl_float" size="1" ng-keyup="update_date()"> /
    <input type="text" focus ng-model="date.year[0]" class="dl_float" size="1" ng-keyup="update_date()">
    <input type="text" focus ng-model="date.year[1]" class="dl_float" size="1" ng-keyup="update_date()">
    <input type="text" focus ng-model="date.year[2]" class="dl_float" size="1" ng-keyup="update_date()">
    <input type="text" focus ng-model="date.year[3]" class="dl_float" size="1" ng-keyup="update_date()">
</div>

Here is the focus:

// <input focus type="text" />

    app.directive('focus', function () {
        return {
            restrict: 'A',
            link: function ($scope, elem, attrs) {
                elem.bind('keyup', function (e) {
                    if (e.keyCode == 8) {
                        if (typeof elem.prev() != 'undefined' && elem.prev().size() > 0) {
                            elem.prev()[0].focus();
                            elem.prev()[0].value = '';
                        }
                    } else {
                        if (typeof elem.next() != 'undefined' && elem.next().size() > 0) {
                            var val = elem[0].value;
                            if (!isNaN(parseFloat(val)) && isFinite(val)) {
                                elem.next()[0].focus();
                            }
                        }
                    }

                });
            }
        }
    });

Here is a sample CSS:

.dl_float {
  font-size: 14px !important;
  width: 19px;
}

Here how to use it:

<multi-select-date datasource="date_of_birth" start-year="1945" ></multi-select-date>

Here how you can see the result

{{date_of_birth}}

Here how initiate it if you need to in your controller:

$scope.date_of_birth = '11/01/1950';
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.