0

I am building an SPA using AngularJS and Bootstrap. I have a form which has a "Back" link on the navigation bar and 2 buttons (Save and Cancel). When the form is launched I want to display only the "Back" link (Save and Cancel should be hidden). However when the user starts inputting values into any of the form fields I want to hide the "Back" link & the Save & Cancel buttons should be shown to the user.

My controller logic is as shown below:

app.controller('TestController', function ($scope, $stateParams, testService) {
    debugger;
    $scope.id = $stateParams.id;
    $scope.modeldata = null;

    testService.getDetails($scope.id).success(function (data) {
        $scope.modeldata = data;
        $scope.beforeImage = angular.copy(data);
    });

    $scope.isUnchanged = function(formData){
        debugger;
        return angular.equals(formData, $scope.beforeImage);
    };
....    

I have the isUnchanged function that checks the data between the current state of the form and the initial state of the form. This function is then used in the actual ng-show / ng-hide directive as shown below:

<script type="text/ng-template" id="/testDetails.html">
    <div class="navbar navbar-default navbar-fixed-top">
        <div class="container-fluid">
            <div class="navbar-left">
                <a ui-sref="TestList" class="btn-link btn navbar-btn y-back" ng-show="isUnchanged(modeldata)">
                    <span class="caret left"></span>
                    Back
                </a>
            </div>
            <div class="navbar-right">
                <button ng-click="cancel()" class="btn btn-default navbar-btn" ng-hide="isUnchanged(modeldata)">Cancel</button>
                <button ng-click="updateTest()" class="btn btn-warning navbar-btn" ng-hide="isUnchanged(modeldata)">Save</button>    
            </div>
        </div>
    </div>
    <form class="form-horizontal" role="form">
       <legend>Test Details</legend>
       <div class="col-sm-12">
       <div class="row">
          <div class="panel panel-default">
             <div class="panel-heading">Basic Data</div>
             <div class="panel-body">
                <div class="col-sm-6">
                   <div class="form-group">
                      <label class="col-sm-2 control-label">Id</label>
                      <div class="col-sm-10">
                         <p class="form-control-static">{{ modeldata.testId }}</p>
                      </div>
                   </div>
                   <div class="form-group">
                      <label class="col-sm-2 control-label" for="testName">Name</label>
                      <div class="col-sm-10">
                         <input class="form-control" type="text" id="testName" ng-model="modeldata.name" required>
                      </div>
                   </div>
                   <div class="form-group">
                      <label class="col-sm-2 control-label" for="testDescription">Description</label>
                      <div class="col-sm-10">
                         <input class="form-control" type="text" id="testDescription" ng-model="modeldata.description">
                      </div>
                   </div>          

.....

Initial launch of the partial template correctly shows only the "Back" link and hides the Save & Cancel buttons. However when values are input into the editable form fields the switch does not happen.

Any ideas as to what could be going wrong ?

mithrandir
  • 1,323
  • 4
  • 18
  • 39
  • Model data isn't changing so that is unchanged function always returns true. I think you want to bind that model Data to something – dchhetri Oct 19 '14 at 06:19
  • Sorry, I didn't include a larger snippet. I have edited the HTML partial view code above to show the usage of the model. Is there anything that needs to be set at the
    itself ?
    – mithrandir Oct 19 '14 at 06:26
  • 1
    It will be helpful if you provide a running code sample. – Alborz Oct 19 '14 at 06:34
  • you can use form.$dirty for show/hide – harishr Oct 19 '14 at 07:29

1 Answers1

0

You can use myForm.$pristine or myForm.$dirty. $pristine means user has not interacted with the form, $dirty is the opposite.

<a ui-sref="TestList" class="btn-link btn navbar-btn y-back" ng-show="myForm.$pristine">
<span class="caret left"></span>
Back
</a>

<button ng-click="cancel()" class="btn btn-default navbar-btn" ng-hide="myForm.$pristine">Cancel</button>
<button ng-click="updateTest()" class="btn btn-warning navbar-btn" ng-hide="myForm.$pristine">Save</button>    

<form class="form-horizontal" name="myForm" role="form">

Btw, with Angular 1.3 you can also use $touched and $untouched. $touched means form has lost focus. They are quite useful for from validation.

s.alem
  • 12,579
  • 9
  • 44
  • 72
  • I tried this out however the directive seems to work only when the partial is loaded. So the "Back" shows up correctly. However when I input value into a form field, the "Save / Cancel" are not showing up. – mithrandir Oct 20 '14 at 02:56
  • No the "Back" button still remains. I can provide a scrubbed version of the code in Plunkr.. – mithrandir Oct 20 '14 at 16:15