JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="http://vitalets.github.io/angular-xeditable/dist/js/xeditable.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="http://vitalets.github.io/angular-xeditable/dist/css/xeditable.css">
<script src="http://code.angularjs.org/1.0.8/angular-mocks.js"></script>
<h4>Angular-xeditable Editable form (Bootstrap 3)</h4>
<div ng-app="app">
<form editable-form name="editableForm"
ng-controller="Ctrl"
onaftersave="saveUser()"
ng-mouseenter="showEdit(true)"
ng-mouseleave="showEdit(false)"
>
<div class="buttons">
<!-- button to show form -->
<button type="button" class="btn btn-default" ng-click="editableForm.$show()" ng-show="!editableForm.$visible && editVisible">
<span class="glyphicon glyphicon-pencil" title="edit"></span>
</button>
<!-- buttons to submit / cancel form -->
<span ng-show="editableForm.$visible">
<button type="submit" class="btn btn-primary" ng-disabled="editableForm.$waiting">
<span class="glyphicon glyphicon-ok" title="save"></span>
</button>
<button type="button" class="btn btn-default" ng-disabled="editableForm.$waiting" ng-click="editableForm.$cancel()">
<span class="glyphicon glyphicon-remove" title="cancel"></span>
</button>
</span>
</div>
<div>
<!-- editable username (text with validation) -->
<span class="title">User name: </span>
<span class="editable" editable-text="user.name" e-name="name" onbeforesave="checkName($data)" e-required>{{ user.name || 'empty' }}</span>
</div>
<div>
<!-- editable status (select-local) -->
<span class="title">Status: </span>
<span class="editable" editable-select="user.status" e-name="status"...
CSS
div[ng-app] { margin: 10px; }
form > div {
height: auto;
padding: 5px 0;
vertical-align: middle;
}
form .buttons {
float: right;
}
form .title {
display: inline-block;
font-weight: bold;
padding-top: 5px;
vertical-align: top;
min-width: 90px;
}
form .editable {
display: inline-block;
padding: 7px 13px;
vertical-align: middle;
color: blue;
}
form select {
width: 120px;
}
JavaScript
var app = angular.module("app", ["xeditable", "ngMockE2E"]);
app.run(function(editableOptions) {
editableOptions.theme = 'bs3';
});
app.controller('Ctrl', function($scope, $filter, $http) {
$scope.user = {
id: 1,
name: 'awesome user',
status: 2,
group: 4,
groupName: 'admin'
};
$scope.statuses = [
{value: 1, text: 'status1'},
{value: 2, text: 'status2'},
{value: 3, text: 'status3'},
{value: 4, text: 'status4'}
];
$scope.groups = [];
$scope.editVisible = false;
$scope.showEdit = function(val) {
this.editVisible = val;
};
$scope.loadGroups = function() {
return $scope.groups.length ? null : $http.get('/groups').success(function(data) {
$scope.groups = data;
});
};
$scope.showGroup = function() {
if($scope.groups.length) {
var selected = $filter('filter')($scope.groups, {id: $scope.user.group});
return selected.length ? selected[0].text : 'Not set';
} else {
return $scope.user.groupName;
}
};
$scope.checkName = function(data) {
if (data !== 'awesome' && data !== 'error') {
return "Username should be `awesome` or `error`";
}
};
$scope.saveUser = function() {
// $scope.user already updated!
return $http.post('/saveUser', $scope.user).error(function(err) {
if(err.field && err.msg) {
// err like {field: "name", msg: "Server-side error for this username!"}
$scope.editableForm.$setError(err.field, err.msg);
} else {
// unknown error
$scope.editableForm.$setError('name', 'Unknown error!');
}
});
};
});
// ---------------- mock $http requests --------------------
app.run(function($httpBackend) {
$httpBackend.whenGET('/groups').respond([
{id: 1, text: 'user'},
{id: 2, text: 'customer'},
{id: 3, text: 'vip'},
{id: 4, text: 'admin'}
]);
$httpBackend.whenPOST(/\/saveUser/).respond(function(method, url, data) {
data =...