3

I am using angularJs (and I am new with it) to validate some fields on a form. This is the particular input that I am having problem with.

<input type="text" ng-required="!isWPPOnly" name="grades"
    ng-class="{error:frmTestingDates.grades.$invalid}"
    ng-model="date.grades" style="display:;"/>

If I press some keys like 1,2,3 the validation fires. However if I set the value of that input control using javascript in the controller like

$("[name=grades]").val('1');

angularJs does not know that the value of the control has changed. I guess that it listens to keydown or keyup event.

Anyway, how can I fire that validation manually from the controller after I set the value?

This is the code that gets fired in the controller when I click on a button

$scope.togglegrade = function (obj) {                   
        var checkedGrades = [];
        $("[name=grades]").val('');
        $("input:checkbox[name=chkGrades]:checked").each(function()
        {                                
            checkedGrades.push($(this).val());          
            $("[name=grades]").val(checkedGrades);      

        });

    };

I tried this but it does not work

$scope.togglegrade = function (obj) {
        $scope.apply(function () {
            alert(1);
            var checkedGrades = [];
            $("[name=grades]").val('');
            $("input:checkbox[name=chkGrades]:checked").each(function()
            {                                
                checkedGrades.push($(this).val());          
                $("[name=grades]").val(checkedGrades);                  
            });
        });                             
    };

You can see the complete html payment.html here http://pastebin.com/9wesxaVd complete controler payment.js here http://pastebin.com/1FWJKYyy

Notice I have commented out the ng-required="!isWPPOnly" line 454 in payment.html for a while until I find out how to fix the issue. One other thing I need to mention is that this application has no definition of date.grades in it's controller nor in any other place in the entire application. It has to be generated automatically somehow

2
  • 1
    It is a bad practice to use jQuery together with Angularjs without using directives. Angularjs is model driven, you really don't need to use jQuery to do what you did. Commented Aug 1, 2013 at 14:42
  • I am very new in angularJs.I understand your point though\ Commented Aug 1, 2013 at 14:45

2 Answers 2

4

first of all, you should NEVER use jQuery and any kind of DOM manipulation in your view. The only place you could do that are directives (and some specific kinds of services, very, very rare). Think declarative instead of imperative.

Also, forget binding via events, just change the model value, for instance:

$scope.$apply(function(){
  $scope.date.grades  = 'foo bar';
})

I don't have access to any text editor or IDE atm, so please let me know if there are any typos.

EDIT

I've created a simple example with good practices regarding to ng-model and data binding in AngularJS in general. Code is based the source, you've provided.

View Plunkr

http://embed.plnkr.co/bOYsO4/preview

Source:

View
<!DOCTYPE html>
<html ng-app="app">

  <!-- ... -->
  <body ng-controller="test">
    <!--Note that the form creates its own controller instance-->
    <form name="testForm" class="form form-horizontal">

      <label><input type="checkbox" ng-model="model.isWPPOnly"> isWPPOnly</label>


      <!-- element name CANNOT contain a dot, since it's used as a form controller property  -->
      <input type="text" ng-required="!model.isWPPOnly" name="date_grades" ng-model="date.grades" />

      <h3>Result</h3>
      <pre>{{date | json}}</pre>
      <pre>{{model | json}}</pre>
    </form>
  </body>

</html>
Controller
angular.module('app', []).controller('test', function($scope){
  // Create object to store bindings via references
  // In javascript simple types (Number, String, Boolean) are passed via value 
  // and complex ones ([], {}) via reference (1)
  $scope.model = {}
  $scope.model.isWPPOnly = true;
  $scope.date = {};
  $scope.date.grades = 'foo';


  // (1) I know, I've oversimplified it a little bit, since everything's and object in JS.

})
CSS
/* Note that there's no need to create an .error class, since angular provides you with default ones */
.error, .ng-invalid{
  border: 1px solid red;
  box-shadow: 0 0 10px red;
}

form{
  padding: 10px;
}
Sign up to request clarification or add additional context in comments.

11 Comments

I am sorry, I don't understand the answer on how to use $scope.$apply
Sure, no problem. In angular.js you don't need to care about binding DOM and data, you can just work on plain javascript objects. Internally it uses dirty checking (docs.angularjs.org/guide/scope) to handle that. $scope.$apply notifies angular that you've made changes that should be reflected in the ui. Usually angular is smart enough to detect them, but might want to force dirty checking explicitly. By the way, egghead.io is a very good starting point for new angular.js devs.
I am having some tutorials now. One thing you are mentioning is that I can directly reference to the control textbox by $scope.date.grades? date confuses me. I think you meant $scope.grades='foo'; so this will directly change the value of that control? If this is the case apply will inform angular that changes are made so this will cause to fire all the validations or just that particular validation of that control? thank you again
oh ng-model="date.grades" so you are referring to the model. I am actually typing in the controller $scope.date.grades = 'foo bar'; but I don't see any effects when I fire the method
Can you post fiddle with your code? I'll take a look at it when I'm back home
|
0
$scope.$apply(function () {
  $('[name=grades]').val('1');
});

5 Comments

Nope this is not working. I have added that to the controller and called it from a method
Hey, using jQuery in views is not a very a good idea. You should work on the model data instead.
jQuery is bad Idea to be used together with angular? why?
It's not a bad idea to use it with angular in general, but you should follow suggested practices: the point is - angular controller should only deal with data. Most of the ui logic should be implemented in directives and templates.
I agree that using jQuery to do this is not a good idea - I was mainly giving a suggestion, although I'm confused why this wouldn't work. The better approach IMO would be just to set $scope.date.grades = '1' - I think there was less information when I originally posted this though. Ideally though, this whole code would be best served by a complete overhaul

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.