Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS ng-repeat and form validation

I'm having an issue with form validation in AngularJS and using a ng-repeat of items inside the form.

HTML:

<div ng-app>
    <div ng-controller="EditController">
        <form name="form" novalidate>Name:
            <br/>
            <input type="text" ng-model="model.name" required="" />
            <hr />Products:
            <br/>
            <div ng-repeat="product in model.products">
                <div>
                    <input type="text" ng-model="product.name" required="" />
                    <input type="text" ng-model="product.price" required="" /> <a href="javascript:void(0)" ng-click="remove($index)">Remove</a>

                </div>
            </div>
            <hr />
            <button ng-disabled="form.$invalid || !form.$dirty" ng-click="save()">save</button>
            <div ng-show="form.$invalid && !form.$pristine">There are errors.</div>
            <div ng-show="!form.$dirty && form.$pristine">No changed detected to be saved.</div>
            <div>
                <p>Dirty? {{form.$dirty}}</p>
                <p>Invalid? {{form.$invalid}}</p>
                <p>Pristine? {{form.$pristine}}</p>
            </div>
        </form>
    </div>
</div>

JS:

function EditController($scope) {
    $scope.model = {
        name: "Phil",
        products: [{
            name: "Foo",
            price: 12.99
        }, {
            name: "Bar",
            price: 15.99
        }, {
            name: "FooBar",
            price: 24.99
        }]
    };

    $scope.remove = function(index){
      $scope.model.products.splice(index, 1);  
    };

    $scope.save = function () {
        console.log("saved");
    };
}

Fiddle:

http://jsfiddle.net/66V6m/2/

Replicate:

Remove 1 item by clicking remove, form does not become dirty so the button doesn't enable.

If you edit the name field, the form then becomes dirty.

Any ideas on how to make removing an item from the array make the form dirty?

like image 281
Phil Avatar asked Jun 06 '13 15:06

Phil


2 Answers

Angular provides a $setDirty() function for just the purpose you're trying to accomplish here. Simply add it it in your ng-click attribute like so

<input type="text" ng-model="product.price" required="" /> 
<a href="javascript:void(0)" ng-click="remove($index); form.$setDirty(true);">Remove</a>

I've forked your fiddle and have it working here

like image 142
Mark Meyer Avatar answered Sep 17 '22 12:09

Mark Meyer


Here's one way.

$scope.remove = function (index) {
    $scope.model.products.splice(index, 1);
    $scope.form.$dirty = true;
};
like image 31
jessegavin Avatar answered Sep 17 '22 12:09

jessegavin