VtoCorleone
VtoCorleone

Reputation: 17203

angularjs dynamically change model binding

I have 2 forms - a billing and a shipping. If the user checks a checkbox, the shipping address should be populated with the billing address and turn disabled. If the user unchecks the box, the shipping address should be blank and return to enabled.

I have this working right now with $watch but it feels hacky. I have 2 $watches nested in eachother watching the same element. I want to know if there is a better way to achieve what I am doing.

I tried using a ternary operator in the ng-model like below but that didn't work either.

<input ng-model="isSameAsBilling ? billName : shipName" ng-disabled="isSameAsBilling" />

A plunkr of my "working" code

HTML:

<input ng-model="billName" />

<input type="checkbox" ng-checked="isSameAsBilling" ng-click="sameAsBillingClicked()"/>

<input ng-model="shipName" ng-disabled="isSameAsBilling" />

JavaScript:

$scope.isSameAsBilling = false;

$scope.sameAsBillingClicked = function(){
  $scope.isSameAsBilling = !$scope.isSameAsBilling;
};

$scope.$watch('isSameAsBilling', function(isSame){

  if ($scope.isSameAsBilling) {

    var shipNameWatcher = $scope.$watch('billName', function (newShipName) {
      $scope.shipName = $scope.billName;

      var secondBillWatcher = $scope.$watch('isSameAsBilling', function(isChecked){
        if (!isChecked){
          shipNameWatcher();
          secondBillWatcher();
          $scope.shipName = '';
        }
      });
    });
  }
});

Upvotes: 1

Views: 1228

Answers (1)

jshanley
jshanley

Reputation: 9128

I think I've finally got what you're after here.

When the checkbox is checked, it registers a $watch on the billName and mirrors it to the shipName.

When the checkbox is unchecked, the deregisters the $watch and clears the shipName

angular

  .module('app', [])

  .controller('appController', ['$scope', function($scope){

    $scope.isSameAsBilling = false;

    $scope.isSameChanged = function() {
      if ($scope.isSameAsBilling) {
        // register the watcher when checked
        $scope.nameWatcher = $scope.$watch('billName', function(bName) {
          $scope.shipName = bName
        })
      } else {
        // deregister the watcher and clear the shipName when unchecked
        $scope.nameWatcher();
        $scope.shipName = ''
      }
    }

  }]);

and here is the PLUNK

Upvotes: 2

Related Questions