0

is there a simple way to apply a filter to a input? i've found some examples, but all sounds like a Macgyver solution for me. My form is defined dynamically, and when the input type is date, i need to convert date value from 2000-01-01T02:00:00.000Z to mm/dd/yyyy.

<form role="form">
    <div ng-repeat="fld in grid.columns">
        <label>{{fld.label}}</label>
        <input type="text" ng-model="grid.currentRecord[fld.name]">
    </div>
</form>

I could not use that suggestion in my case: (filters on ng-model in an input)

anybody help me, plese?

Community
  • 1
  • 1
Danilo Sampaio
  • 77
  • 1
  • 11
  • i had the same problem, see my question here it was soleved :) might help you http://stackoverflow.com/questions/27141439/ng-model-for-the-custom-directive-angular/27141523?noredirect=1#comment42787454_27141523 – GeekOnGadgets Nov 27 '14 at 00:12
  • @GeekOnGadgets , i've found another way to do that. what do you think? – Danilo Sampaio Nov 27 '14 at 17:29

2 Answers2

0

the simplest way that i found:

i've created a directive called 'dateformatter', that basically, define a $formatter to filter value viewed in input, and a $parser to treat value before set it into model:

app.directive('dateformatter', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {   
            ctrl.$parsers.unshift(function(viewValue) {
                return new Date(viewValue)
            });      
            ctrl.$formatters.push(function(modelValue) {                    
                return modelValue.toDateString()
            });
        }
    };
});

and i added 'dateformatter' attribute in input tag:

<form role="form">
    <div ng-repeat="fld in grid.columns">
        <label>{{fld.label}}</label>
        <input type="text" dateformatter ng-model="grid.currentRecord[fld.name]">
    </div>
</form>

it's working out!

Danilo Sampaio
  • 77
  • 1
  • 11
  • Works only when `Date` constructor can parse the value (which is browser-dependent). It'd be nicer to use [moment.js](http://momentjs.com/) (or some other date manipulation library) and let your directive accept a format as the attribute value and parse/format the Date from/into that format. – hon2a Nov 27 '14 at 17:40
  • yes, but i mean the main code to create a filter, not the implementation of formatter. – Danilo Sampaio Nov 27 '14 at 17:42
  • I'm not sure what you mean by that. – hon2a Nov 27 '14 at 17:44
  • sorry @hon2a :D i was looking for a simple way to apply a filter to input, not only date filter. But all examples seem complicated. I just wanted to share my solution, because I had a hard time understanding how it works, and perhaps other people have the same difficulty. Anyway, thank you. – Danilo Sampaio Nov 27 '14 at 18:01
  • A directive could be written that would allow `ng-model` expression to actually contain a filter (and would cut it out and apply as a formatter). However, that doesn't really make sense, as it would be one-way only (you also need to provide the inverse transformation). – hon2a Nov 27 '14 at 18:09
0

Expanding upon your own answer, you could use moment.js, wrap it into an AngularJS service, and create a really flexible solution:

.directive('dateFormat', ['moment', function (moment) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function ($scope, $element, $attrs, ngModelCtrl) {
            ngModelCtrl.$parsers.unshift(function (viewValue) {
                return moment(viewValue, $attrs.dateFormat).toDate();
            });
            ngModelCtrl.$formatters.push(function (modelValue) {
                return moment(modelValue).format($attrs.dateFormat);
            });
        }
    };
}])

which would be used like this:

<input type="text" ng-model="some.model" date-format="MM/DD/YYYY">
hon2a
  • 7,006
  • 5
  • 41
  • 55