Salal Aslam
Salal Aslam

Reputation: 1377

AngularJS ngSubmit only dirty fields

I was wondering if there is a way to submit the form with only $dirty fields, currently I am using ng-change to manually add every field to the request on change. But the problem with that is, its not very reusable.

in form.html

<input name="status" id="status" ng-model="campaign.status" ng-change="change('status')">

in controller.js

$scope.updates = {};
$scope.change = function (field) {
    $scope.updates[field] = $scope.campaign[field];
};
Campaign.update({id: $scope.campaign.id}, $scope.updates).$promise.then(function () {
    // success
}, function () {
    //error
});

I am looking for a better way to do this, maybe for example without the updates variable.

Upvotes: 0

Views: 2049

Answers (3)

Travis
Travis

Reputation: 5061

It appears to me that you only want to send fields that have been updated. I'm not quite sure what the reasoning is for this, but if the problem you want to solve is only submitting changed values, I would like to suggest an alternate approach.

If you can use a library like lodash or underscore, my suggestion would be to do a diff of an original copy and the current instance of $scope.campaigns before submitting.

The reasons are as follows:

  • The listener function of $scope.$watch is not flexible enough to easily use to create your $scope.updates object object.

  • The $dirty state of your form will be a bit fragile because the $dirty property requires that you use the name property of the form field, not the name of the ng-model attribute. This can cause naming conflicts and tends to not be very portable or update friendly.

If you were using lodash you might do something like:

//as soon as you create $scope.campaign, copy it to $scope.original
$scope.original = angular.copy($scope.campaign);

//in your update function
$scope.updates = _.pick($scope.campaign, function(value, key, object){ return $scope.campaign[key] != $scope.original[key] });

Campaign.update({id: $scope.campaign.id}, $scope.updates).$promise.then(function () {
        // success
    }, function () {
        //error
    });

Upvotes: 2

michelem
michelem

Reputation: 14590

You can also invalid it until every fields are dirty:

JSFiddle

<form name="test">
    <input name="status" id="status" ng-model="campaign.status" ng-change="change('status')">
    <button type="submit" ng-disabled="!test.status.$dirty">Send</button>
</form>

Upvotes: 0

Joy
Joy

Reputation: 9550

For each field in the form, there is a property $dirty on it. When submitting the form, you can iterate through the fields and pick those $dirty.

Try console.log($scope.formName.status) to check those properties.

Upvotes: 1

Related Questions