34

I am new to angular js. In my code there is color picker initialized from a text field. User changes the value of color and I want that color to be reflected as a background of a text in a span. It is not working. What is missing?

HTML:

<body ng-app="">
   <input type="button" value="set color" ng-click="myStyle={color:'red'}">
   <input type="button" value="clear" ng-click="myStyle={}">
   <input type="text" name="abc" class="color" ng-change="myStyle={color:'green'}">
   <br/>
   <span ng-style="myStyle">Sample Text</span>
   <pre>myStyle={{myStyle}}</pre>
</body>

Plunker - http://plnkr.co/edit/APrl9Y98Em0d6rxuzRDE?p=preview

However when I change it to ng-click it works.

Ashwin
  • 12,081
  • 22
  • 83
  • 117

6 Answers6

43

ng-change requires ng-model,

<input type="text" name="abc" class="color" ng-model="someName" ng-change="myStyle={color:'green'}">
Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38
  • how can we use the value in the color picker as the style color? – Ashwin Sep 30 '14 at 07:56
  • 2
    One thing that the answer does not mention is the fact that the order actually matters, you NEED to set the ng-model before the ng-change to see this working. – user1336321 Mar 14 '17 at 06:53
  • 5
    @user1336321, it works in any order in current angular (not sure about 1.0 or something). There is no order rule for directives - there is priority... Who on Earth put +1 on this comment... – Petr Averyanov May 10 '17 at 13:05
6

I've got the same issue, my model is binding from another form, I've added ng-change and ng-model and it still doesn't work:

<input type="hidden" id="pdf-url" class="form-control" ng-model="pdfUrl"/>

<ng-dropzone
  dropzone="dropzone"
  dropzone-config="dropzoneButtonCfg"
  model="pdfUrl">
</ng-dropzone>

An input #pdf-url gets data from dropzone (two ways binding), however, ng-change doesn't work in this case. $scope.$watch is a solution for me:

$scope.$watch('pdfUrl', function updatePdfUrl(newPdfUrl, oldPdfUrl) {
  if (newPdfUrl !== oldPdfUrl) {
    // It's updated - Do something you want here.
  }
});

Hope this help.

Sébastien Temprado
  • 1,413
  • 4
  • 18
  • 29
Huy Nguyen
  • 2,025
  • 3
  • 25
  • 37
3

One can also bind a function with ng-change event listener, if they need to run a bit more complex logic.

<div ng-app="myApp" ng-controller="myCtrl">      
        <input type='text' ng-model='name' ng-change='change()'>
        <br/> <span>changed {{counter}} times </span>
 </div>

...

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
      $scope.name = 'Australia';
      $scope.counter = 0;
      $scope.change = function() {
        $scope.counter++;
      };
});

https://jsfiddle.net/as0nyre3/1/

Razan Paul
  • 13,618
  • 3
  • 69
  • 61
2

When you want to edit something in Angular you need to insert an ngModel in your html

try this in your sample:

    <input type="text" name="abc" class="color" ng-model="myStyle.color">

You don't need to watch the change at all!

Sander Elias
  • 754
  • 6
  • 9
2

Maybe you can try something like this:

Using a directive

directive('watchChange', function() {
    return {
        scope: {
            onchange: '&watchChange'
        },
        link: function(scope, element, attrs) {
            element.on('input', function() {
                scope.onchange();
            });
        }
    };
});

http://jsfiddle.net/H2EAB/

avcajaraville
  • 9,041
  • 2
  • 28
  • 37
1

First at all i'm seing your code and you haven't any controller. So i suggest that you use a controller. I think you have to use a controller because your variable {{myStyle}} isn't compile because the 2 curly brace are visible and they shouldn't.

Second you have to use ng-model for your input, this directive will bind the value of the input to your variable.

Mathieu Bertin
  • 1,634
  • 11
  • 11