AngularJS Tutorial - 4, CUD

In this part we will setup the create, delete and update forms.

Screenshot

Download

The source for this part is here: 04_cud.zip.

The samples can be run with Firefox, in general or by running, into the directory,

Create

First we will add the route for the creation. AFTER THE LIST and BEFORE THE DETAIL. If we place it after the detail, the detail will be intercepted first and the 'new' will be considered as a customer id.

    when('/customers/', {
        templateUrl: 'app/customers/list.html',
        controller: 'CustomersController'
    }).
    when('/customers/new', {
        templateUrl: 'app/customers/new.html',
        controller: 'CustomerNewController'
    }).

Then the new controller must be created. As usual, the single customer is pre initialized. In this situation we will add the save method to the scope. This will receive the model to send to the api. We use the post method, that takes two parameters: the api address and the json object to send. On success the api will return the object just inserted, so we could redirect to the detail page for the given object.

customers.controller('CustomerNewController',['$scope','$http','$location',
    function($scope,$http,$location){
        $scope.customer = {};
        
        $scope.save = function(data){
            $http.post('/customers',data).
                success(function(result, status, headers, config) {
                    $location.path('/customers/'+result.id);
                });
        }
}]);

The template must then call the save. Note the new directives:

Note even that the form does not contains any method or action: all is managed by the function in ng-submit

<a class="btn btn-default" href="#customers">Back to list</a><br>
<form novalidate name="addNewForm" id="add-new-form" ng-submit="save(customer)">
    <table>
    <tr><td><label for="first_name">First Name </label></td><td><input type="text" ng-model="customer.first_name" required /></td></tr>
    <tr><td><label for="last_name">Last Name </label></td><td><input type="text" ng-model="customer.last_name" required /></td></tr>
    </table>
    <button ng-disabled="addNewForm.$invalid" class="btn btn-primary" >Save</button>
</form>

Update

First we will add the route right after the "new" route. The customerId is not optional! It has no question marks in it!

    when('/customers/new', {
        templateUrl: 'app/customers/list.html',
        controller: 'CustomersController'
    }).
    when('/customers/edit/:customerId', {
        templateUrl: 'app/customers/edit.html',
        controller: 'CustomerEditController'
    }).

Then the controller. In which we will mix the edit and update. First the customer data must be preloaded. Then the update function is created.

customers.controller('CustomerEditController',['$scope','$http','$location','$routeParams',
    function($scope,$http,$location,$routeParams){
        $scope.customer = {};
        
        $http.get('/customers/'+$routeParams.customerId).
            success(function(data, status, headers, config) {
                $scope.customer=data;
            });
            
        $scope.update = function(data){
            $http.put('/customers/'+data.id,data).
                success(function(result, status, headers, config) {
                    $location.path('/customers/'+result.id);
                });
        }
}]);

Finally the edit template. Here we added the hidden customer.id and renamed the form with editForm. Nothing else change from the add.

<a class="btn btn-default" href="#customers">Back to list</a><br>
<form novalidate name="editForm" id="add-new-form" ng-submit="update(customer)">
    <input type="hidden" ng-model="customer.id"/>
    <table>
    <tr><td><label for="first_name">First Name </label></td><td><input type="text" ng-model="customer.first_name" required /></td></tr>
    <tr><td><label for="last_name">Last Name </label></td><td><input type="text" ng-model="customer.last_name" required /></td></tr>
    </table>
    <button ng-disabled="editForm.$invalid" class="btn btn-primary" >Update</button>
</form>

To enable it we will add the button on the detail page

    <a class="btn btn-default" ng-href="#customers/edit/{{customer.id}}">Edit</a><br>

Delete

For this we will modify the detail controller adding a new scope function. Nothing new here. Only the "confirm" javascript that returns true if ok is pressed or false if cancel is pressed.

If the delete was made we redirect to the list of customers. We should remember to add $location to the dependencies

    $scope.delete = function(data){
        if(confirm("You want to delete customer n."+data.id+"?")){
            $http.delete('/customers/'+$routeParams.customerId).
                success(function(data, status, headers, config) {
                    $location.path('/customers');
                });
        }
    }

To enable it we will add the button on the detail page

    <a class="btn btn-default" ng-click="delete(customer)">Delete</a><br>

Last modified on: April 08, 2015