JSFiddle - React, Tailwind, and code Playground

by Thomas Bourigault

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>
<div ng-controller="adminsController">

<form name="the-form" novalidate>
    <table class="table table-striped table-hover">
        <thead>
            <tr>
                <th>email</th>
                <th>first name</th>
                <th>last name</th>
            </tr>
        </thead>
        <tbody ng-repeat="(key, admin) in admins">
            <tr ng-form="wsform">
                <td>
                    <input type="email" 
                        name="email"
                        ng-blur="ws.save(this, 'admin', 'email')"
                        class="form-control input-sm"
                        ng-class="wsform.email.css"
                        ng-model="admin.email" 
                    />
                </td>
                <td>
                    <input type="text" 
                        name="fname"
                        ng-blur="ws.save(this, 'admin', 'fname')"
                        class="form-control input-sm"
                        ng-class="wsform.fname.css"
                        ng-model="admin.fname" 
                    />
                </td>
                <td>
                    <input type="text" 
                        name="lname"
                        ng-blur="ws.save(this, 'admin', 'lname')"
                        class="form-control input-sm"
                        ng-class="wsform.lname.css"
                        ng-model="admin.lname"
                    />
                </td>
            </tr>
        </tbody>
    </table>
</form>
    
<p>Form that auto save on blur. Controller "extends" the factory methods as to keep the controller thin. And also possible to share "ws" between many controllers.</p>
    
</div>

CSS

.field-success {
	border-color: #00CC00;
	box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;
}
body {
    padding: 15px;
}

JavaScript

angular.module('dashboard',[])

.factory('ws', function($http, $timeout) {

    var ws = {
        save: function (that, model_name, field_name) {
            
            console.log(' -- ws save()');
            console.log(that);
            console.log(model_name);
            console.log(field_name);  
           
            // $http restful
            
            that.wsform[field_name]['css'] = 'field-success';
            
            that['delay_success' + field_name] = $timeout(function(){
					that.wsform[field_name]['css'] = undefined;
			},3000);
            
        }
    }
    
    return ws;
    
})

.controller('adminsController', function($scope, $http, ws) {
    
    console.log($scope);
    
    $scope.ws = ws;
    
    $scope.admins = [
        {
        fname: 'user',
        lname: 'one',
        email: '[email protected]'
        },
       {
        fname: 'user',
        lname: 'two',
        email: '[email protected]'
        },
        {
        fname: 'user',
        lname: 'three',
        email: '[email protected]'
        },
    ];
        
});