Start a series of posts how to code apps. First ever app with AngularJS and Yii was very simple. We'll talk about a few topics. Demos find here Simple Single Page app with list of todos - u can browse, add and delete without reloading the page ;) Folder with all oof the front (AngularJS files) looked like this:

Pix with folders

This article doesn't proveide info on creating yii REST - it's reaally simple. Acting the Usual way - gen app, models and CRUD. I had the next view:

<p>API test :id - http://proserge.kh.ua/yiiangular/index.php/api/todo/1<br />
    API test all - http://localhost:8084/yiiangular/index.php/api/todo/<br />
    JSON doc - {
                            "id":"1",
                            "descr":"Task #0-1",
                            "active":"1"
                            }
   </p>
<?php
//TEXT in origin todo._id & todo.text CHANGE to id &descr
$url = Yii::app()->request->baseUrl;
//<link rel="stylesheet" type="text/css" href="'.$url.'/front/NodeToDo/common/todo.css" />
echo '<script src="'.$url.'/front/NodeToDo/js/core.js"></script>
 
    <script src="'.$url.'/front/NodeToDo/js/controllers/main.js"></script>
    <script src="'.$url.'/front/NodeToDo/js/services/todos.js"></script> 
    <!-- ASSIGN OUR ANGULAR MODULE -->
    <div ng-app="scotchTodo" class="html-ex">
 
    <!-- SET THE CONTROLLER AND GET ALL TODOS WITH INITIALIZE FUNCTION -->
    <div class="body-ex" ng-controller="mainController" ng-init="initialize()">
        <div class="container">
 
            <!-- HEADER AND TODO COUNT -->
            <div class="jumbotron text-center">
                <h1>I\'m a Todo-aholic <span class="label label-info">{{ todos.length }}</span></h1>
            </div>
 
            <!-- TODO LIST -->
            <div id="todo-list" class="row">
                <div class="col-sm-4 col-sm-offset-4">
 
                    <!-- LOOP OVER THE TODOS IN $scope.todos -->
                    <div class="checkbox" ng-repeat="todo in todos">
                        <label>
                            <input type="checkbox" ng-click="deleteTodo(todo.id)"> {{ todo.descr }}
                        </label>
                    </div>
 
                </div>
            </div>
 
            <!-- FORM TO CREATE TODOS -->
            <div id="todo-form" class="row">
                <div class="col-sm-8 col-sm-offset-2 text-center">
                    <form>
                        <div class="form-group">
 
                            <!-- BIND THIS VALUE TO formData.text IN ANGULAR -->
                            <input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.descr">
                        </div>
 
                        <!-- createToDo() WILL CREATE NEW TODOS -->
                        <button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button>
                    </form>
                </div>
            </div>
 
            <div class="text-center text-muted">
                <p>A demo by <a href="#">Me</a>.</p>
                <p>Read the <a href="http://scotch.io/tutorials/javascript/creating-a-single-page-todo-app-with-node-and-angular">tutorial</a>.</p>
            </div>
 
        </div>
 
    </div>
    </div>';

That's all on the back. I separated Back & Front to different folders. core.js:

var scotchTodo = angular.module('scotchTodo', []);
 
function mainController($scope, $http) {
    $scope.formData = {};
 
    // when landing on the page, get all todos and show them
    $scope.initialize = function() {
        $http.get('/api/todos')
            .success(function(data) {
                $scope.todos = data;
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };
 
    // when submitting the add form, send the text to the node API
    $scope.createTodo = function() {
        $http.post('/api/todos', $scope.formData)
            .success(function(data) {
                $('input').val('');
                $scope.todos = data;
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };
 
    // delete a todo after checking it
    $scope.deleteTodo = function(id) {
        $http.delete('/api/todos/' + id)
            .success(function(data) {
                $scope.todos = data;
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };
 
}

AngularJS controller file - main.js

angular.module('todoController', [])
 
    // inject the Todo service factory into our controller
    .controller('mainController', function($scope, $http, Todos) {
        $scope.formData = {};
        $scope.loading = true;
 
        // GET =====================================================================
        // when landing on the page, get all todos and show them
        // use the service to get all the todos
        Todos.get()
            .success(function(data) {
                $scope.todos = data;
                $scope.loading = false;
            });
 
        // CREATE ==================================================================
        // when submitting the add form, send the text to the node API
        $scope.createTodo = function() {
            $scope.loading = true;
 
            // validate the formData to make sure that something is there
            // if form is empty, nothing will happen
            if ($scope.formData.descr != undefined) {
 
                // call the create function from our service (returns a promise object)
                $scope.formData.active = 1;
                Todos.create($scope.formData)
 
                    // if successful creation, call our get function to get all the new todos
                    .success(function(data) {
                        $scope.loading = false;
                        $scope.formData = {}; // clear the form so our user is ready to enter another
                        //$scope.todos = data; // assign our new list of todos
                        $scope.todos.push((data));
                    });
            }
        };
 
        // DELETE ==================================================================
        // delete a todo after checking it
        $scope.deleteTodo = function(id) {
            $scope.loading = true;
 
            Todos.delete(id)
                // if successful creation, call our get function to get all the new todos
                .success(function(data) {
                    var id = (data)["id"];
                    for (var i = 0; i < $scope.todos.length; i++) {
                        if ($scope.todos[i]['id'] == id ){$scope.todos.splice(i, 1); break;}
                    }
                    //$scope.todos = data; // assign our new list of todos
                    $scope.loading = false;
                });
        };
    });

AngularJS routes - todos.js

angular.module('todoService', [])
 
    // super simple service
    // each function returns a promise object 
    .factory('Todos', function($http) {
        var baseUrl = "http://localhost:8084/yiiangular/index.php/api/";
        return {
            get : function() {
                return $http.get(baseUrl + 'todo/');
            },
            create : function(todoData) {
                return $http.post(baseUrl + 'todo', todoData);
            },
            delete : function(id) {
                return $http.delete(baseUrl + 'todo/' + id);
            }
        }
    });

One comment

#170
Wednesday, October 1, 2014 12:37 PM
Appreciate this post. Will try it out.

Leave a Comment

Fields with * are required.

Please enter the letters as they are shown in the image above.
Letters are not case-sensitive.