Spring MVC AngularJs Todo List
Try it: http://cloudsole-angular.herokuapp.com
Clone it: https://github.com/thysmichels/cloudsole-angular
1. Todo Service
2. Todo Service Implementation
3. Todo Spring MVC Controller
4. Angular App.js
5. Angular TodoController
6. Todo html page
1. Todo Service
package com.cloudsole.angular.service;
import java.util.List;
/**
* Created by tmichels on 8/1/14.
*/
public interface TodoService {
public List<String> allTodos();
public void addTodo(String todo);
public void deleteTodo(String todo);
public void deleteAll();
public void updateTodo(int position, String todo);
}
2. Todo Service Implementation
package com.cloudsole.angular.service;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* Created by tmichels on 8/1/14.
*/
@Service
public class TodoServiceImpl implements TodoService {
List<String> todos = new ArrayList<String>();
@Override
public List<String> allTodos() {
return todos;
}
@Override
public void addTodo(String todo) {
todos.add(todo);
}
@Override
public void deleteTodo(String todo) {
if (todos.contains(todo)){
todos.remove(todo);
}
}
@Override
public void deleteAll() {
todos.clear();
}
@Override
public void updateTodo(int position, String todo) {
todos.set(position, todo);
}
}
3. Todo Spring MVC Controller
package com.cloudsole.angular.controller;
import com.cloudsole.angular.service.TodoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* Created by tmichels on 8/1/14.
*/
@Controller
@RequestMapping("/todo")
public class TodoController {
@Autowired
private TodoService todoService;
@RequestMapping(value = "/all.json")
public @ResponseBody List<String> viewAllTodos(){
return todoService.allTodos();
}
@RequestMapping(value = "/add/{todo}", method = RequestMethod.POST)
public @ResponseBody void addTodo(@PathVariable("todo") String todo){
todoService.addTodo(todo);
}
@RequestMapping(value = "/delete/{todo}", method = RequestMethod.DELETE)
public @ResponseBody void deleteTodo(@PathVariable("todo") String todo){
todoService.deleteTodo(todo);
}
@RequestMapping(value = "/deleteAll", method = RequestMethod.DELETE)
public @ResponseBody void deleteAllTodo(){
todoService.deleteAll();
}
@RequestMapping(value="/update/{position}/{todo}", method = RequestMethod.PUT)
public @ResponseBody void updateTodo(@PathVariable("position") String position, @PathVariable("todo") String todo){
todoService.updateTodo(Integer.valueOf(position), todo);
}
@RequestMapping("/layout")
public String getTodoPartialPage() {
return "todo/layout";
}
}
4. Angular App.js
'use strict';
var AngularSpringApp = {};
var App = angular.module('AngularSpringApp', ['AngularSpringApp.filters', 'AngularSpringApp.services', 'AngularSpringApp.directives', 'ngRoute', 'ui.bootstrap', 'ngTable', 'ui.ace', 'angularFileUpload']);
// Declare app level module which depends on filters, and services
App.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/todo', {
templateUrl: 'todo/layout',
controller: TodoController
});
$routeProvider.when('/address', {
templateUrl: 'address/layout',
controller: AddressBookController
});
$routeProvider.when('/table', {
templateUrl: 'table/layout',
controller: TableController
});
$routeProvider.when('/file', {
templateUrl: 'file/layout',
controller: FileController
});
$routeProvider.when('/editor', {
templateUrl: 'editor/layout',
controller: EditorController
});
$routeProvider.when('/rest', {
templateUrl: 'restangular/layout',
controller: RestController
});
$routeProvider.when('/force', {
templateUrl: 'force/layout',
controller: ForceController
});
$routeProvider.otherwise({redirectTo: '/todo'});
}]);
5. Angular TodoController
var TodoController = function($scope, $http){
$scope.editMode = false;
$scope.position = '';
$scope.getAllTodos = function(){
$scope.resetError();
$http.get('todo/all.json').success(function(response){
$scope.todos = response;
}).error(function() {
$scope.setError('Could not display all todos');
});
}
$scope.addTodo = function(newTodo){
$scope.resetError();
$http.post('todo/add/' + newTodo).success(function(response){
$scope.getAllTodos();
}).error(function() {
$scope.setError('Could add todo');
});
$scope.todoName = '';
}
$scope.deleteTodo = function(deleteTodo){
$scope.resetError();
$http.delete('todo/delete/'+deleteTodo).success(function(response){
$scope.getAllTodos();
}).error(function() {
$scope.setError('Could not delete todo');
});
}
$scope.deleteAllTodo = function(){
$scope.resetError();
$http.delete('todo/deleteAll').success(function(response){
$scope.getAllTodos();
}).error(function() {
$scope.setError('Could not delete all todos');
})
}
$scope.editTodo = function(position, todo){
$scope.resetError();
$scope.todoName = todo;
$scope.position = position;
$scope.editMode = true;
}
$scope.updateTodo = function(updateTodo){
$scope.resetError();
$http.put('todo/update/'+ $scope.position +'/'+updateTodo).success(function(response){
$scope.getAllTodos();
$scope.position = '';
$scope.todoName = '';
$scope.editMode = false;
}).error(function(){
$scope.setError('Could not update todo');
})
}
$scope.resetTodoField = function() {
$scope.resetError();
$scope.todoName = '';
$scope.editMode = false;
};
$scope.resetError = function() {
$scope.error = false;
$scope.errorMessage = '';
};
$scope.setError = function(message) {
$scope.error = true;
$scope.errorMessage = message;
};
$scope.getAllTodos();
}
6. Todo html page
<div class="alert alert-error" ng-show="error">{{errorMessage}}</div>
<div class="row">
<form ng-submit="addTodo(todoName)">
<div class="col-lg-8">
<input class="form-control" placeholder="Enter Todo" type="text" ng-model="todoName" required min="1" />
</div>
</form>
<button class="btn btn-primary" ng-disabled="!todoName" ng-hide="editMode" ng-click="addTodo(todoName)">Add Todo</button>
<button type="btn btn-primary" class="btn btn-primary"
ng-disabled="!todoName" ng-show="editMode"
ng-click="updateTodo(todoName)">Save</button>
<button type="btn btn-primary" class="btn btn-primary" ng-click="resetTodoField()">Reset</button>
</div>
<hr />
<div class="row">
<div class="col-lg-8">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" id="search-query-3" ng-model="searchTodo" typeahead="todo for todo in todos | filter:$viewValue | limitTo:8">
<span class="input-group-btn">
<button type="submit" class="btn"><span class="fui-search"></span></button>
</span>
</div>
</div>
</div>
</div>
<hr />
<div class="alert alert-info" style="width:400px;margin-left:100px;" ng-show="todos.length == 0">
No todos found
</div>
<table class="table table-bordered table-striped" ng-show="todos.length > 0">
<thead>
<tr>
<th style="text-align: center; width: 25px;">Delete</th>
<th style="text-align: center; width: 25px;">Update</th>
<th style="text-align: center;">Todo</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todo in todos | filter:searchTodo">
<td style="width:70px;text-align:center;"><button class="btn btn-mini btn-danger" ng-click="deleteTodo(todo)">Delete</button></td>
<td style="width:70px;text-align:center;"><button class="btn btn-mini btn-danger" ng-click="editTodo(todos.indexOf(todo), todo)">Update</button></td>
<td>{{todo}}</td>
</tr>
</tbody>
</table>
<button class="btn btn-danger" ng-show="todos.length >= 1" ng-click="deleteAllTodo()">Delete All Todos</button>
Very Good! I just looking for this!
I want to use it in my project. Can i use?