7

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?

1

2 Answers 2

11

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

Sign up to request clarification or add additional context in comments.

Comments

2

Here's one way.

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

1 Comment

you should use $setDirty() otherwise form.$pristine will still be true

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.