mirror of
https://github.com/zhigang1992/deployd.git
synced 2026-05-16 02:57:25 +08:00
Added inline editor container
This commit is contained in:
@@ -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"> </th></tr></thead>
|
||||
<tbody>
|
||||
<tr class="load-space" data-bind="visible: view.loadSpaceBefore">
|
||||
<td class="margin" data-bind="style: {height: view.loadSpaceBefore() + 'px'}"> </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"> </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"> </th></tr></thead>
|
||||
<tbody>
|
||||
<tr class="load-space" data-bind="visible: view.loadSpaceBefore">
|
||||
<td class="margin" data-bind="style: {height: view.loadSpaceBefore() + 'px'}"> </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"> </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"> </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"> </th>
|
||||
<th class="id-cell"> </th>
|
||||
<!-- ko foreach: properties -->
|
||||
<th> </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"> </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"> </th>
|
||||
<th class="id-cell"> </th>
|
||||
<!-- ko foreach: properties -->
|
||||
<th> </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"> </th>
|
||||
<th class="id-cell"> </th>
|
||||
<!-- ko foreach: properties -->
|
||||
<th> </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"> </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"> </th>
|
||||
<th class="id-cell"> </th>
|
||||
<!-- ko foreach: properties -->
|
||||
<th> </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"> </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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
BIN
lib/resources/dashboard/img/outlets-light.png
Normal file
BIN
lib/resources/dashboard/img/outlets-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 175 B |
Reference in New Issue
Block a user