SrinivasNaidu
SrinivasNaidu

Reputation: 519

Two way binding is not working in AngularJS 1.x

I'm implementing a directive in such a way that it is accessible in multiple pages. My requirement is that when I hold down any key (as of now) I need to show the password. The password details will be coming from controller. I need to update the password in the directive.

On keydown event I want to show the password as hello and on keyup i want to show the password as ********.

Below is the code for that:

HTML View

<div ng-app="myApp" ng-controller="Ctrl1">
   <a class="f-mrgn-left-4px" 
      key-hold 
      password="statusMessage" 
      generatedpassword="selfgeneratedpassword" 
      tabindex="0" 
      ng-mousedown="ShowPassword()" 
      ng-mouseup="HidePassword()">Show</a>
   <span>{{selfgeneratedpassword}}</span>
</div> 

JavaScript

function Ctrl1($scope) {
    $scope.selfgeneratedpassword = '******';
    $scope.statusMessage = "Password";

    $scope.ShowPassword = function () {
    console.log('show passwo', $scope.statusMessage);
        $scope.selfgeneratedpassword = $scope.statusMessage;
    }

    $scope.HidePassword = function () {
      $scope.selfgeneratedpassword = "********";
    }
}

angular.module('myApp', []).directive('keyHold', function() {
    return {
        restrict: 'A',
        scope: {
            'password': '=',
            'generatedpassword': '='
        },
        link: function(scope, element, attrs) {
                    console.log('self generated password', scope.password,scope.generatedpassword, element);               
          element.bind('keydown', function () {           
            $timeout(function () {
                console.log('after timeout');
                scope.selfgeneratedpassword = scope.password;
            }, 100);
          });

          element.bind('keyup', function () {
             scope.generatedpassword = "*******";
          });
        }
    }

Attached fiddler will explain how I'm implementing it. Fiddler Link. In the fiddler i am unable to get the two way binding working. Can anybody help me on this. I lost a day working on this.

Upvotes: 2

Views: 97

Answers (1)

lin
lin

Reputation: 18392

You cannot use ng-mousedown or ng-mouseup in AngularJS 1.0.x because its not implement in this version. Just switch to AngularJS 1.4.x or higher to make it work like in this Demo Fiddle.

Switch to the latest version of AngularJS -> https://github.com/angular/angular.js/releases

View

<div ng-app="myApp" ng-controller="MyCtrl">
  <a class="f-mrgn-left-4px" 
     tabindex="0" 
     ng-mousedown="ShowPassword()" 
     ng-mouseup="HidePassword()">Show</a>
  <span>{{selfgeneratedpassword}}</span>
</div>

AngularJS application

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {

  $scope.selfgeneratedpassword = '******';
  $scope.statusMessage = "Password";

  $scope.ShowPassword = function() {
    $scope.selfgeneratedpassword = $scope.statusMessage;
  }

  $scope.HidePassword = function() {
    $scope.selfgeneratedpassword = "********";
  }
});

Update

Now, if you click the "Show" element once (a click does set it active so it can listen to "keyup" and keydown" event) and you press a key the password will be diplayed for 1 seconds like in this Demo fiddle. The logic is now placed in a directive:

View

<div ng-app="myApp" ng-controller="MyCtrl">
  <a class="f-mrgn-left-4px" tabindex="0" 
      key-hold 
      password="statusMessage" 
      generatedpassword="generatedpassword">Show</a>
  <span>{{generatedpassword}}</span>
</div>

AngularJS Application

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {
  $scope.generatedpassword = '******';
  $scope.statusMessage = "Password";
});

myApp.directive('keyHold', function($timeout) {
  return {
    restrict: 'A',
    scope: {
      'password': '=',
      'generatedpassword': '='
    },
    link: function(scope, element, attrs) {
      element.bind('keydown', function() {
          scope.generatedpassword = scope.password;
          scope.$apply();
      });

      element.bind('keyup', function() {
       $timeout(function () {
          scope.generatedpassword = "*******";
          scope.$apply();
        }, 1000);
      });
    }
  }
});

Upvotes: 1

Related Questions