3

HTML:

<ul>
    <li><a><i class="icon-white icon-save"></i></a></li>
</ul>

<form>
     <input type="text" value="{{ selectedUser.firstname }}" ng-model="selectedUser.firstname">
     <input type="text" value="{{ selectedUser.lastname }}" ng-model="selectedUser.lastname">
</form>

I am dealing with user objects fetched from my REST API. So basically there is a list of users. On click the above form is revealed.

function UserController($scope, User){
    $scope.users = User.query();

    $scope.selectedUser = null;

    $scope.select = function(user){
        $scope.selectedUser = user;
    }
}

I want to display the save link only when form values have changed. Any ideas how to do this with angular.js?

2 Answers 2

11

Give your form a name, such as:

<form name="dataForm">
  <input type="text" name="firstname" ng-model="data.firstname" />
  <input type="text" name="lastname" ng-model="data.lastname" />
</form>

The form will now be a named model in your scope and you can hide/show the save button based on whether the form is pristine:

<ul ng-hide="dataForm.$pristine">
  <li><a><i class="icon-white icon-save"></i></a></li>
</ul>

This approach has the advantage of showing the save button if you change any of the form elements inside the form and the drawback of not checking the input values against their original values, just the fact that they have been edited.

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

1 Comment

I think you can easily fix the 'drawback' by improving the ng-hide condition. Here is one way: dataForm.$pristine || model.origVal === selectedVal.
3

Here is an example of showing your element only when both fields have data:

<div ng-controller="TestCtrl" ng-app>
    <ul ng-show="enableSave(data)">
        <li><a><i class="icon-white icon-save"></i></a></li>
    </ul>

    <form>
        <input type="text" name="firstname" ng-model="data.firstname" />
        <input type="text" name="lastname" ng-model="data.lastname" />
    </form>
</div>

And here is your controller:

function TestCtrl($scope) {
    $scope.data = {firstname: "", lastname: ""};

    $scope.enableSave = function(data) {
         return data.firstname.length > 1 && data.lastname.length > 1;   
    };    
}

You can put any logic you want into enableSave. I've chosen to require that they both have at least two characters... you can do whatever you need.

Here is a jsFiddle that illustrates it: http://jsfiddle.net/nDCXY/1/

EDIT by OP: my solutions

$scope.enableSave = function(user) {
    if(!angular.equals(user, oldUser)){
        return true
    }else{
        return false;
    }
};

5 Comments

Ok thats cool, but imagine there are a lot of fields. And lastname may be empty and firstname changed. The icon will not be displayed...
I just saw your comment about the multiple fields... try this: jsfiddle.net/nDCXY/1 (I've updated my answer to illustrate how to use a model object to watch)
Thanks, my question was a bit unclear. I tried to use your solution but it does not work in my case. Look at my edit.
@artworkadシ You'll have to keep a reference to the old version and the new version of selectedUser. Look at angular.copy() to do this. Then, when the enableSave function gets called, compare it to the original value. Also, you don't need to bind your value attributes in your inputs.
On view init I get "Cannot read property 'firstname' of null" because selectedUser is null until a user is selected.

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.