Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Setting ngModelOptions in Angular

Tags:

angularjs

I've got the following snippet:

<input type="date" ng-model="arrival" ng-model-options="{timezone: 'PST'}" />
<input type="time" ng-model="arrival" ng-model-options="{timezone: 'PST'}" />
{{arrival}}

That works properly (the date is displayed in UTC time converted from PST). I'm now trying to make the 'PST' option dynamic:

<select ng-model="timezone>
  <option value="PST">PST</option>
  <option value="EST">EST</option>
</select>
<input type="date" ng-model="arrival" ng-model-options="{timezone: timezone}" />
<input type="time" ng-model="arrival" ng-model-options="{timezone: timezone}" />
{{arrival}}

However, changing the timezone never update the arrival (it appears that binding doesn't work with nd-model-options). Any way I can force the fields to refresh when the timezone is changed?

Edit

Fiddle: https://jsfiddle.net/10nfqow9/

like image 289
Kevin Sylvestre Avatar asked Mar 04 '16 22:03

Kevin Sylvestre


People also ask

What is Ngmodeloptions in angular?

The ng-model-options directive is used to control the binding of an HTML form element and a variable in the scope. You can specify that the binding should wait for a specific event to occur, or wait a specific number of milliseconds, and more, see the legal values listed in the parameter values below.

Why ngModel?

The ngModel directive is a directive that is used to bind the values of the HTML controls (input, select, and textarea) or any custom form controls, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during form validations.

Which directive is used for non immediate model updates?

In AngularJS, immediate model updates is a default behavior but if we want to persist value in the object after a certain time period has elapsed then we can achieve the same by using “debounce” object in “ng-model-options” directive, which is known as “non-immediate model updates”.

Which property of ngModel is set to true when input value is modified by user?

By setting the allowInvalid property to true, the model will still be updated even if the value is invalid.


1 Answers

Create another directive (attribute type) with a high priority (higher than ng-model /ng-model-option's) that watches the options object for changes and triggers a recompile. My apologies for lack of specifics, I'm on a phone :)

EDIT: Looks like there's a directive called kcd-recompile that does exactly what I described. Here's a working plnkr, with some additional goodies for factoring in DST for american timezones.

HTML:

<div kcd-recompile="data.timezone">
  <div>
    <select ng-model="data.timezone" ng-options="x.offset as x.name for x in timezones">
    </select>
  </div>
  <div>
    <input type="date" ng-model="data.arrival" ng-model-options="{timezone: data.timezone}" />
  </div>
  <div>
    <input type="time" ng-model="data.arrival" ng-model-options="{timezone: data.timezone}" />  
  </div>
</div>

And JS:

Date.prototype.stdTimezoneOffset = function() {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}

Date.prototype.dst = function() {
    return this.getTimezoneOffset() < this.stdTimezoneOffset();
}

angular.module('DemoApp', ['kcd.directives']);
angular.module('DemoApp')
.controller('DemoCtrl', ['$scope', function($scope) {
    var now = new Date(),
        isDst = now.dst();

    $scope.data ={
      arrival: now,
      timezone: null
    };
    $scope.timezones = [
      {
        name: 'PST', 
        offset: isDst ? '-0700' : '-0800'
      },
      {
        name: 'EST', 
        offset: isDst ? '-0400' : '-0500'
      }
    ];
  }]
);
like image 168
Marcel Chastain Avatar answered Sep 22 '22 07:09

Marcel Chastain