Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple angularjs date input

Tags:

angularjs

I have an edit page for an event and one of my fields is a date. In some browsers it seems to act like a plain text box (IE8), however in chrome it displays "dd/mm/yyyy" and if you click on it it has some additional options for setting the date.

My issue though is on the edit page it's not populating the existing date (I imagine because it's not in the correct format?). The MVC controller returns the data in this format "2014-03-08T00:00:00" (just using basic CRUD controller actions).

<form name="form" class="form-horizontal">
<div class="control-group" ng-class="{error: form.EventDate.$invalid}">
        <label class="control-label" for="EventDate">Event Date</label>
        <div class="controls">
            <input type="date" ng-model="item.EventDate" id="EventDate">
        </div>
    </div>
<div class="form-actions">
        <button ng-click="save()" class="btn btn-primary">
            {{action}}
        </button>
        <a href="#/" class="btn">Cancel</a>
    </div>
</form>

I've seen quite a few posts on using directives and watches, but that seems complicated. I would have thought there would have been a relatively simple way of formatting the model data so that it displays in the right format and works as expected. I don't mind if Chrome gives a different experience than other browsers - it's just a simple internal user website. I just don't like that it's not prepopulating the date when I edit a record.

like image 647
Jen Avatar asked Jul 04 '14 02:07

Jen


People also ask

How to set date inputs in angular forms?

set the form inputs. However, Angular forms set inputs via the value property. We have to convert to and from the yyyy-dd-mm date string format if we are working with date objects in our application. Fortunately, we have a couple of workarounds to make it easier to use Date objects and HTML5 date inputs in Angular.

How do I map a string to a date in angular?

We can work around this limitation by creating a custom Angular Form Control Directive to intercept and map to a Date object or string dynamically. We can enable date objects on our native date inputs by creating an Angular Form Directive that will select an input [type=date] selectors.

How to get the date from a date picker in angular?

But if we only have a date picker and want to get the date once the user selects it, we can use the onChange event to get the value. Let’s create a new application by using the following command. After creating our new application in Angular, we will go to our application directory using this command.

Is there a way to convert string to date?

I've created a date parser that converts string to Date objects. You can also provide date formats you're using, as well as your date locale. It returns a Date object, valid or otherwise depending on the input. There's also a directive that implements this parser so you can use it on an input field, for example.


1 Answers

If you want to populate the field with an initial value, then the following will work

//Controller:
$scope.myDate = new Date('2014-03-08T00:00:00');

//HTML:
<input type="date" ng-init="model=(myDate | date:'yyyy-MM-dd')" ng-model="model" />

However, I strongly recommend creating a custom date field directive.

A custom input field directive offers the following benefits:

  1. Two-way binding between the model and the view. For example, when you enter a valid date in the input field, it will automatically assign a javascript date to the model; and when you assign a valid javascript date as the model, it will automatically format it in the text field.
  2. Form validation support. When you enter an invalid date, you can set an $error flag, which can be used in your view bindings (i.e. displaying an error message). Setting an error flag will also set form.$valid to false so that you can conditionally submit the form to the server.

There are three basic things to consider when implementing a custom date directive:

  1. A parser that will parse the input text and return the model (in this case, a javascript date).
  2. A formatter that will format the model and display it in the text field.
  3. Setting of an optional validation flag which can be used in the UI for custom form validation.

Date Directive:

myApp.directive('dateField', function($filter) {
  return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModelController) {
           ngModelController.$parsers.push(function(data) {

              //View -> Model
              var date = Date.parseExact(data,'yyyy-MM-dd');

              // if the date field is not a valid date 
              // then set a 'date' error flag by calling $setValidity
              ngModelController.$setValidity('date', date!=null);
              return date == null ? undefined : date;
           });
           ngModelController.$formatters.push(function(data) {
              //Model -> View
              return $filter('date')(data, "yyyy-MM-dd");
           });    
       }
    }
});

Note: For parsing dates, this directive uses Date.js (an external library).

CSS:

.error {
  color:red;
}
.error-border {
  border: solid 2px red;
}

HTML:

<form name="myForm">
     <input ng-class="{'error-border': myForm.myDate.$error.date}" type="date"
            name="myDate" ng-model="myDate" date-field />
              <span ng-show="myForm.myDate.$error.date" class="error">
                  Please enter a valid date!!!
              </span>             
         <br /> Raw Date: {{myDate}} 
         <br /> Formatted Nicely: {{ myDate | date:'yyyy, MMMM dd'}}    
         <br /> Is Valid Date? {{ !myForm.myDate.$error.date}}
         <br /> Is Form Valid? {{ myForm.$valid }}
</form>

Controller:

myApp.controller('ctrl', function($scope) {
    $scope.myDate = new Date('2014-03-08T00:00:00');
});

Demo JS Fiddle with Date.js
Demo JS Fiddle with Moment.js

like image 146
pixelbits Avatar answered Oct 06 '22 17:10

pixelbits