New version Angular 9
AngularJS Tutorial - 4, CUD
In this part we will setup the create, delete and update forms.

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,
- If you have Python 2.x: python -m SimpleHTTPServer 8000
- If you have Python 3.x: python -m http.server 8000
- If you have Perl:
- cpan HTTP::Server::Brick # install dependency
- perl -MHTTP::Server::Brick -e '$s=HTTP::Server::Brick->new(port=>8000); $s->mount("/"=>{path=>"."}); $s->start'
- If you are under windows: "C:\Program Files (x86)\IIS Express\iisexpress.exe" /path:%CD% /port:8000
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:
- ng-disabled: takes in charge an expression or value on the scope.
In this example use the FormName.$invalid, a special value that tells
if there are validators on the input fields that are giving erros - bg-submit: intercept the submit of the form and execute the given
expression initialized on the scope, preventing the real post.
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>