Added inline editor container

This commit is contained in:
Dallon Feldner
2012-10-02 15:42:01 -07:00
parent 85dbd0a8b7
commit c0d2ba5c26
5 changed files with 228 additions and 91 deletions

View File

@@ -1,95 +1,102 @@
<div id="data-container">
<div id="data" class="well full-page" data-bind="scrollbarWidth: view.scrollWidth">
<h3>Data</h3>
<div id="table-container" data-bind="scrollY: view.scrollY, scrollX: view.scrollX, screenDimensions: view.dimensions, reflow: properties">
<div id="margin-container" data-bind="style: {top: view.dimensions().top + 'px', left: view.dimensions().left + 'px', height: view.dimensions().height - view.scrollWidth() + 'px'}">
<table id="margin" class="table table-bordered" data-bind="style: {top: -view.scrollY() + 'px'}">
<thead><tr><th class="margin">&nbsp;</th></tr></thead>
<tbody>
<tr class="load-space" data-bind="visible: view.loadSpaceBefore">
<td class="margin" data-bind="style: {height: view.loadSpaceBefore() + 'px'}">&nbsp;</td>
</tr>
<!-- ko foreach: data -->
<tr><td class="margin"><a href="#" class="delete-btn"><i class="icon-white icon-trash"></i></a></td></tr>
<!-- /ko -->
</tbody>
<tfoot>
<tr><td class="margin">&nbsp;</td></tr>
</tfoot>
</table>
<div id="table-viewport">
<div id="inline-editor" data-bind="visible: inlineEdit.editing, if: inlineEdit.editing, click: inlineEdit.dismiss">
<div class="mini-edit" data-bind="style: {top: view.selectedCellY() + 'px', left: view.selectedCellX() + 'px'}">
</div>
</div>
<div id="table-container" data-bind="scrollY: view.scrollY, scrollX: view.scrollX, screenDimensions: view.dimensions, reflow: properties">
<div id="margin-container" data-bind="style: {top: view.dimensions().top + 'px', left: view.dimensions().left + 'px', height: view.dimensions().height - view.scrollWidth() + 'px'}">
<table id="margin" class="table table-bordered" data-bind="style: {top: -view.scrollY() + 'px'}">
<thead><tr><th class="margin">&nbsp;</th></tr></thead>
<tbody>
<tr class="load-space" data-bind="visible: view.loadSpaceBefore">
<td class="margin" data-bind="style: {height: view.loadSpaceBefore() + 'px'}">&nbsp;</td>
</tr>
<!-- ko foreach: data -->
<tr><td class="margin"><a href="#" class="delete-btn"><i class="icon-white icon-trash"></i></a></td></tr>
<!-- /ko -->
</tbody>
<tfoot>
<tr><td class="margin">&nbsp;</td></tr>
</tfoot>
</table>
</div>
<div id="headers-container" data-bind="style: {top: view.dimensions().top + 'px', left: view.dimensions().left + 'px', width: view.dimensions().width - view.scrollWidth() + 'px'}">
<table id="headers" class="table table-bordered" data-bind="style: {left: -view.scrollX() + 'px'}" >
<thead>
<tr>
<th class="margin">&nbsp;</th>
<th class="id-cell"> <i class="icon-custom icon-white string" data-bind="tooltip: 'id'"></i> id</th>
<!-- ko foreach: properties -->
<th> <i class="icon-custom icon-white" data-bind="cssNamed: type, tooltip: typeLabel"></i> <span data-bind="text: name"></span></th>
<!-- /ko -->
</tr>
</thead>
</table>
</div>
<div id="body-table-container">
<table id="body-table" class="table table-bordered" data-bind="element: view.$table">
<thead>
<tr>
<th class="margin">&nbsp;</th>
<th class="id-cell">&nbsp;</th>
<!-- ko foreach: properties -->
<th>&nbsp;</th>
<!-- /ko -->
</tr>
</thead>
<tbody>
<tr class="load-space" data-bind="visible: view.loadSpaceBefore">
<td class="margin"></td>
<td data-bind="attr: {colspan: 2 + properties().length}, style: {height: view.loadSpaceBefore() + 'px'}">
</td>
</tr>
<!-- ko foreach: data -->
<div id="headers-container" data-bind="style: {top: view.dimensions().top + 'px', left: view.dimensions().left + 'px', width: view.dimensions().width - view.scrollWidth() + 'px'}">
<table id="headers" class="table table-bordered" data-bind="style: {left: -view.scrollX() + 'px'}" >
<thead>
<tr>
<td class="margin">
<th class="margin">&nbsp;</th>
<th class="id-cell"> <i class="icon-custom icon-white string" data-bind="tooltip: 'id'"></i> id</th>
<!-- ko foreach: properties -->
<th> <i class="icon-custom icon-white" data-bind="cssNamed: type, tooltip: typeLabel"></i> <span data-bind="text: name"></span></th>
<!-- /ko -->
</tr>
</thead>
</table>
</div>
<div id="body-table-container">
<table id="body-table" class="table table-bordered" data-bind="element: view.$table">
<thead>
<tr>
<th class="margin">&nbsp;</th>
<th class="id-cell">&nbsp;</th>
<!-- ko foreach: properties -->
<th>&nbsp;</th>
<!-- /ko -->
</tr>
</thead>
<tbody>
<tr class="load-space" data-bind="visible: view.loadSpaceBefore">
<td class="margin"></td>
<td data-bind="attr: {colspan: 2 + properties().length}, style: {height: view.loadSpaceBefore() + 'px'}">
</td>
</tr>
<!-- ko foreach: data -->
<tr>
<td class="margin">
</td>
<td class="id-cell">
<div class="value" data-bind="text: id"></div>
</td>
<!-- ko foreach: $root.properties -->
<td data-bind="css: {highlight: $root.selectedRow() === $parent && $root.selectedProp() === $data}, click: $parent._selectCell, event: {dblclick: $parent._editProp}">
<div class="value" data-bind="text: $parent._textFor(name)"></div>
</td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
<tfoot>
<tr>
<th class="margin">&nbsp;</th>
<th class="id-cell">&nbsp;</th>
<!-- ko foreach: properties -->
<th>&nbsp;</th>
<!-- /ko -->
</tr>
</tfoot>
</table>
</div>
<div id="new-row-container" data-bind="style: {bottom: view.dimensions().bottomRelative + view.scrollWidth() + 'px', left: view.dimensions().left + 'px', width: view.dimensions().width - view.scrollWidth() + 'px'}">
<table id="new-row" class="table table-bordered" data-bind="style: {left: -view.scrollX() + 'px'}">
<tr data-bind="with: newRow">
<td class="margin">&nbsp;</td>
<td class="id-cell">
<div class="value" data-bind="text: id"></div>
<div class="hint value">id</div>
</td>
<!-- ko foreach: $root.properties -->
<!-- ko foreach: $parent.properties -->
<td data-bind="css: {highlight: $root.selectedRow() === $parent && $root.selectedProp() === $data}, click: $parent._selectCell">
<div class="value" data-bind="text: $parent.textFor(name)"></div>
<div class="hint value" data-bind="text: name"></div>
</td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
<tfoot>
<tr>
<th class="margin">&nbsp;</th>
<th class="id-cell">&nbsp;</th>
<!-- ko foreach: properties -->
<th>&nbsp;</th>
<!-- /ko -->
</tr>
</tfoot>
</table>
</div>
<div id="new-row-container" data-bind="style: {bottom: view.dimensions().bottomRelative + view.scrollWidth() + 'px', left: view.dimensions().left + 'px', width: view.dimensions().width - view.scrollWidth() + 'px'}">
<table id="new-row" class="table table-bordered" data-bind="style: {left: -view.scrollX() + 'px'}">
<tr data-bind="with: newRow">
<td class="margin">&nbsp;</td>
<td class="id-cell">
<div class="hint value">id</div>
</td>
<!-- ko foreach: $parent.properties -->
<td data-bind="css: {highlight: $root.selectedRow() === $parent && $root.selectedProp() === $data}, click: $parent._selectCell">
<div class="hint value" data-bind="text: name"></div>
</td>
<!-- /ko -->
</tr>
</table>
</table>
</div>
</div>
</div>
</div>

View File

@@ -135,6 +135,10 @@
, selectedRow: ko.observable()
, selectedProp: ko.observable()
, inlineEdit: {
editing: ko.observable(false)
}
, propertiesLoaded: ko.observable(false)
, view: {
@@ -224,6 +228,59 @@
vm.view.scrollToColumn(vm.selectedProp());
};
vm.view.clearSelection = function() {
if(document.selection && document.selection.empty) {
document.selection.empty();
} else if(window.getSelection) {
var sel = window.getSelection();
sel.removeAllRanges();
}
};
vm.view.getSelectedCell = function() {
var $table = vm.view.$table();
if (!$table) return null;
return $table.find('td.highlight');
};
vm.view.selectedCellX = ko.computed(function() {
vm.view.scrollX(); //dependent
vm.selectedProp();
var $cell = vm.view.getSelectedCell();
if ($cell && $cell.length) {
return $cell.position().left;
}
}, vm.view).extend({throttle: 1});
vm.view.selectedCellY = ko.computed(function() {
vm.view.scrollY(); //dependent
vm.selectedRow();
var $cell = vm.view.getSelectedCell();
if ($cell && $cell.length) {
return $cell.position().top;
}
}, vm.view).extend({throttle: 1});
vm.inlineEdit.dismiss = function() {
vm.inlineEdit.editing(false);
};
vm.inlineEdit.start = function() {
vm.inlineEdit.editing(true);
};
vm.inlineEdit.onKeyDown = function(e) {
if (e.which == 27) { // escape
vm.inlineEdit.editing(false);
return false;
}
return true;
};
function createRow(data) {
var rowVm = {};
@@ -235,7 +292,7 @@
rowVm[name] = ko.observable(data[name]);
});
rowVm.textFor = function(prop) {
rowVm._textFor = function(prop) {
var val = rowVm[prop]();
if (typeof val === 'undefined' || val === null) {
return '...';
@@ -246,8 +303,19 @@
}
};
rowVm._selectCell = function(data) {
vm.selectedProp(data);
rowVm._editProp = function(prop, e) {
vm.view.clearSelection();
setTimeout(function() {
if (vm.selectedRow() !== rowVm && vm.selectedProp() !== prop) {
rowVm._selectCell(prop, e);
}
vm.inlineEdit.start();
}, 1);
return false;
};
rowVm._selectCell = function(prop) {
vm.selectedProp(prop);
vm.selectedRow(rowVm);
};
@@ -268,6 +336,10 @@
$(window).keydown(function(e) {
var which = e.which;
if (vm.inlineEdit.editing()) {
return vm.inlineEdit.onKeyDown(e);
}
switch (which) {
case 38: // up/down arrows
case 40:
@@ -281,6 +353,10 @@
case 35:
selectionHorizontal(e);
return false;
case 13: //enter
vm.selectedRow()._editProp(vm.selectedProp());
return false;
}
return true;

View File

@@ -19,6 +19,32 @@
-ms-box-orient: vertical;
-o-box-orient: vertical;
}
#table-viewport {
position: relative;
box-flex: 1;
-moz-box-flex: 1;
-webkit-box-flex: 1;
-ms-box-flex: 1;
-o-box-flex: 1;
}
#table-viewport #inline-editor {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 100;
}
#table-viewport #inline-editor .mini-edit {
position: absolute;
background: url('../../img/outlets-light.png');
height: 38px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
width: 300px;
}
#data {
display: box;
display: -moz-box;
@@ -32,13 +58,11 @@
-o-box-orient: vertical;
}
#table-container {
position: relative;
height: 0;
box-flex: 1;
-moz-box-flex: 1;
-webkit-box-flex: 1;
-ms-box-flex: 1;
-o-box-flex: 1;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: box;
display: -moz-box;
display: -webkit-box;

View File

@@ -1,6 +1,8 @@
@import '../../dashboard/stylesheets/mixins.less';
@background: url('../../img/outlets.png');
@backgroundLight: url('../../img/outlets-light.png');
@cellHeight: 38px;
.unloaded-content {
@@ -16,6 +18,29 @@
}
#table-viewport {
position: relative;
.box-flex(1);
#inline-editor {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 100;
.mini-edit {
position: absolute;
background: @backgroundLight;
height: @cellHeight;
.box-sizing(border-box);
width: 300px;
}
}
}
#data {
// .box-flex(1);
.display-box();
@@ -23,9 +48,12 @@
}
#table-container {
position: relative;
height: 0;
.box-flex(1);
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
.display-box();
.box-orient(vertical);
overflow: scroll;
@@ -138,5 +166,7 @@
background: @background;
margin: 0;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B