lexeme
lexeme

Reputation: 2973

What's wrong with my use of ng-class?

I'm using ui-router and the view below accesses the controller using the 'Controller As' syntax. I'm adding the 'invalid' class onto the 'shift'-radios container. When form loads you can see both validation required messages (for requestDate and shift). When requestDate and shift are set validation messages disappear. Form's $valid is true. The only problem is that the 'invalid' class on the radio-wrapper div stays.

What am I doing wrong?

<form novalidate ng-submit="_form.$valid && formCtrl.getFormData()" name="_form">
    <div class="datepicker-wrapper clearfix">
        <datepicker date-format="yyyy-MM-dd">
            <input required ng-model="formCtrl.requestDate" name="requestDate" type="text" />
        </datepicker>                       
    </div>
    <div ng-messages="_form.requestDate.$error" role="alert">
        <div ng-message="required">Введите дату</div>
    </div>
    <div class="radio-wrapper clearfix" ng-class="{invalid: _form.shift.$error}">
        <div ng-repeat="shift in formCtrl.shifts" class="item half-width pull-left">
            <label for="<% shift.name %>">
                <input required ng-model="formCtrl.currentShift" 
                       name="shift" 
                       ng-value="shift" 
                       id="<% shift.name %>" 
                       type="radio" />
                <span class="text"><span ng-bind="shift.text"></span></span>
            </label>
        </div>
    </div>
    <div ng-messages="_form.shift.$error" role="alert">
        <div ng-message="required">Укажите смену</div>
    </div>
    <!-- other inputs... -->
</form>

Upvotes: 1

Views: 95

Answers (3)

Buh Buh
Buh Buh

Reputation: 7546

There is no _form.shift. The input shift is declared inside an ng-repeat so it is a property on the _form.

To fix you could for example, move your ng-class inside the ng-repeat and reference the shift using ng-form to create a sub-grouping:

<div ng-repeat="shift in formCtrl.shifts" ng-form='nestedShiftForm'>
    <div ng-class="{invalid: nestedShiftForm.shift.$error}">
        <input name="shift" />

Upvotes: 0

Matt W
Matt W

Reputation: 476

I think you need to use the $invalid property, which is a boolean, instead of the $error property, which is a hash.

See: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

Upvotes: 3

ryanyuyu
ryanyuyu

Reputation: 6486

Your ng-class definition is checking the wrong property of the form controller. You are checking the truthyness of _form.shift.$error. This object will always exist, even if there are no validation errors. When you don't have any errors, the value of _form.shift.$error is empty object {} which is truthy.

You should instead check the _form.shift.$invalid property which will properly update whether there are any problems with that form field.

Upvotes: 1

Related Questions