Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use ngChange on a div (or something similar)

I had an input that had ng-change on it, then I changed it to a contenteditable div, so I can have a little more control over what I can do with the input. But the thing is that when I changed from an input to a div, I am no longer able to use ng-change. What can I do obtain the same effect/result?

Here is how I am using it in my template:

<div class="form-control" ng-model="search" ng-change="searchChanged()" contenteditable="true">{{seach}}</div>
like image 204
Get Off My Lawn Avatar asked Jun 19 '15 20:06

Get Off My Lawn


2 Answers

Inorder to support ng-model with ng-change for anything other than form element, you would need to create a custom directive. For example a simple implementation as below directive named contenteditable (much similar to angular having internal directives for input, form etc), have it require ng-model and on keyup event set the viewvalue and render the ng-model. When you setViewValue for the ng-model and values are different than prev value angular will evaluate the ng-change expression.

.directive('contenteditable', function() {
      return {
        require: 'ngModel',
        restrict: 'A',
        link: function(scope, elm, attr, ngModel) {

          function updateViewValue() {
            ngModel.$setViewValue(this.innerHTML);
          }
          //Binding it to keyup, lly bind it to any other events of interest 
          //like change etc..
          elm.on('keyup', updateViewValue);

          scope.$on('$destroy', function() {
            elm.off('keyup', updateViewValue);
          });

          ngModel.$render = function(){
             elm.html(ngModel.$viewValue);
          }

        }
    }
});

and do:

<div class="form-control" type="search" 
      ng-model="seach" ng-change="searchChanged()" 
      contenteditable="true"></div>

angular.module('app', []).controller('ctrl', function($scope) {
  $scope.seach = "Initial";
  $scope.searchChanged = function() {
    console.log('changed', $scope.seach);
  }
}).directive('contenteditable', function() {
  return {
    require: 'ngModel',
    restrict: 'A',
    link: function(scope, elm, attr, ngModel) {

      function updateViewValue() {
        ngModel.$setViewValue(this.innerHTML);
      }

      //Or bind it to any other events
      elm.on('keyup', updateViewValue);

      scope.$on('$destroy', function() {
        elm.off('keyup', updateViewValue);
      });

      ngModel.$render = function() {
        elm.html(ngModel.$viewValue);
      }

    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  Edit
  <div class="form-control" type="search" ng-model="seach" ng-change="searchChanged()" contenteditable="true"></div>
  {{seach}}
</div>
like image 99
PSL Avatar answered Oct 02 '22 15:10

PSL


ng-change only works on an input not a div. Try ng-click.

For an example of implementing a custom directive to bind a model to a contenteditable div, see here.

like image 29
Donal Avatar answered Oct 02 '22 14:10

Donal