spreadsheet directive
by jacobwsmith
HTML
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<link rel="stylesheet" href="https://acadmin.vizu.com/admin/assets/lib/normalize.css/normalize.css">
<link rel="stylesheet" href="https://acadmin.vizu.com/admin/assets/css/_type.css">
<link rel="stylesheet" href="https://acadmin.vizu.com/admin/assets/css/_tables.css">
<link rel="stylesheet" href="https://acadmin.vizu.com/admin/assets/css/_forms.css">
<h1>Setting to Data Example</h1>
<div ng-controller="MyCtrl">
<div class="scrollable">
<table class="sheet header">
<thead>
<tr>
<th></th>
<th>Name1</th>
<th>Name2</th>
<th>Name3</th>
</tr>
<thead>
<tr ng-repeat="item in data">
<td>{{$index+1}}</td>
<td>
<edit-in-place value="item.id"></edit-in-place>
</td>
<td>
<edit-in-place value="item.friendlyName"></edit-in-place>
</td>
<td>
<edit-in-place value="item.groupName"></edit-in-place>
</td>
</tr>
</thead>
</thead>
</table>
</div>
<table class="sheet footer">
<tfoot>
<tr>
<td></td>
</tr>
</tfoot>
</table>
</div>
CSS
.edit-in-place div {
cursor: pointer;
}
/* Excel Like Spread Sheet Table*/
table.sheet {
border-top:1px solid #ccc;
border-left:1px solid #ccc;
width: 100%;
margin: 0;
}
div.scrollable {
border-right:1px solid #ccc;
max-height: 305px;
overflow-x:hidden;
overflow-y: scroll;
width:100%;
}
/*div.scrollable table.sheet {
border-top: none;
}
table.sheet.header th {
}
table.sheet.footer {
}
*/
div.scrollable table {
border-top: 1px solid transparent;
}
table.sheet th:nth-child(1), table.sheet td:nth-child(1) {
text-align: center;
width: 39px;
}
table.sheet th:nth-child(2), table.sheet td:nth-child(2) {
width: 250px;
}
table.sheet th:nth-child(3), table.sheet td:nth-child(3) {
width: auto;
}
table.sheet th:nth-child(4), table.sheet td:nth-child(4) {
width: 250px;
}
table.sheet th:nth-child(5) {
width: 81px;
}
table.sheet td:nth-child(5) {
width: 65px;
}
table.sheet th, table.sheet td {
border-bottom:none;
border: 1px solid #ccc;
box-sizing: border-box;
empty-cells: show;
line-height: 14px;
padding: 0 0;
vertical-align: middle;
}
table.sheet tbody tr td {
min-height:28px;
vertical-align: middle;
position: relative;
background-clip: padding-box;
}
table.sheet tbody tr:first-child td {
border-top: none;
}
table.sheet tbody tr:last-child td {
border-bottom: none;
}
table.sheet th {
text-align: left;
padding: 7px 5px;
}
table.sheet th, table.sheet tr td:first-child {
background-color: #eee;
color: #222;
font-weight:bold;
white-space: nowrap;
}
/* Delete Button */
table.sheet tr th:last-child, table.sheet tr td:last-child {
text-align: center;
padding:4px 0;
}
/* Footer */
table.sheet tfoot tr td {
empty-cells: show;
height:22px;
vertical-align: top;
}
input[type="file"].file {
display:none;
}
/* Input */
table.sheet.body tbody tr td input[type="text"] {
background: transparent;
border:...
JavaScript
var app = angular.module('myApp', []);
function MyCtrl($scope) {
var temp = [];
for (var i = 0; i < 1000; i++) {
temp.push({
id: 'Moe',
friendlyName: 'Curly',
groupName: 'Larry'
})
}
$scope.data = temp;
}
/////////////
app.directive('editInPlace', function () {
return {
restrict: 'E',
scope: {
value: '='
},
template: '<div ng-click="edit()" ng-show="!editing" ng-bind="value"></div><textarea ng-show="editing" ng-model="value" ng-blur="editing = false"></textarea>',
link: function ($scope, element, attrs) {
// Let's get a reference to the input element, as we'll want to reference it.
var inputElement = angular.element(element.children()[1]);
console.log(inputElement);
// This directive should have a set class so we can style it.
element.addClass('edit-in-place');
// Initially, we're not editing.
$scope.editing = false;
// ng-click handler to activate edit-in-place
$scope.edit = function () {
$scope.editing = true;
// We control display through a class on the directive itself. See the CSS.
element.addClass('active');
// And we must focus the element.
// `angular.element()` provides a chainable array, like jQuery so to access a native DOM function,
// we have to reference the first element in the array.
inputElement[0].focus();
};
// When we leave the input, we're done editing.
inputElement.prop('onblur', function () {
$scope.editing = false;
element.removeClass('active');
});
}
};
});