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>

2 thoughts on “Spring MVC AngularJs Todo List

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s