The options can now be set with the PHP configuration. Minor updates in the scrollbar widget. Implemented scrolling. Updated documentation.

This commit is contained in:
alekseybobkov 2014-12-17 22:07:49 -08:00
parent f2e2862b06
commit 1480303c4f
9 changed files with 148 additions and 23 deletions

View File

@ -205,6 +205,7 @@
Scrollbar.DEFAULTS = {
vertical: true,
scrollSpeed: 2,
animation: true,
start: function() {},
drag: function() {},
stop: function() {}
@ -308,14 +309,24 @@
} else {
offset = $el.get(0).offsetTop - this.$el.scrollTop()
if (offset < 0) {
this.$el.animate({'scrollTop': $el.get(0).offsetTop}, params)
animated = true
} else {
offset = $el.get(0).offsetTop - (this.$el.scrollTop() + this.$el.outerHeight())
if (offset > 0) {
this.$el.animate({'scrollTop': $el.get(0).offsetTop + $el.outerHeight() - this.$el.outerHeight()}, params)
if (this.options.animation) {
if (offset < 0) {
this.$el.animate({'scrollTop': $el.get(0).offsetTop}, params)
animated = true
} else {
offset = $el.get(0).offsetTop - (this.$el.scrollTop() + this.$el.outerHeight())
if (offset > 0) {
this.$el.animate({'scrollTop': $el.get(0).offsetTop + $el.outerHeight() - this.$el.outerHeight()}, params)
animated = true
}
}
} else {
if (offset < 0) {
this.$el.scrollTop($el.get(0).offsetTop)
} else {
offset = $el.get(0).offsetTop - (this.$el.scrollTop() + this.$el.outerHeight())
if (offset > 0)
this.$el.scrollTop($el.get(0).offsetTop + $el.outerHeight() - this.$el.outerHeight())
}
}
}
@ -326,6 +337,13 @@
return this
}
Scrollbar.prototype.dispose = function() {
this.$el = null
this.$scrollbar = null
this.$track = null
this.$thumb = null
}
// SCROLLBAR PLUGIN DEFINITION
// ============================

View File

@ -12,10 +12,11 @@
<script src="<?= Backend::skinAsset('assets/js/vendor/jquery-2.0.3.min.js') ?>"></script>
<script src="<?= URL::asset('modules/system/assets/js/framework.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/vendor/modernizr.min.js') ?>"></script>
<!--
<script src="<?= Backend::skinAsset('assets/js/vendor/mousewheel.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/vendor/jquery.touchwipe.min.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/vendor/moment.min.js') ?>"></script>
<!--
<script src="<?= Backend::skinAsset('assets/js/vendor/raphael-min.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/vendor/jquery.autoellipsis.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/vendor/jquery.waterfall.js') ?>"></script>
@ -48,9 +49,10 @@
<script src="<?= Backend::skinAsset('assets/js/october.tab.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/october.popover.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/october.popup.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/october.goalmeter.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/october.goalmeter.js') ?>"></script> -->
<script src="<?= Backend::skinAsset('assets/js/october.scrollbar.js') ?>"></script>
<!--
<script src="<?= Backend::skinAsset('assets/js/october.filelist.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/october.hotkey.js') ?>"></script>
<script src="<?= Backend::skinAsset('assets/js/october.loadindicator.js') ?>"></script>

View File

@ -96,6 +96,13 @@ class Table extends WidgetBase
$this->vars['columns'] = $this->prepareColumnsArray();
$this->vars['recordsKeyColumn'] = $this->recordsKeyColumn;
$this->vars['recordsPerPage'] = $this->getConfig('records_per_page', false) ?: 'false';
$this->vars['postbackHandlerName'] = $this->getConfig('postback_handler_name', 'onSave');
$this->vars['adding'] = $this->getConfig('adding', true);
$this->vars['deleting'] = $this->getConfig('deleting', true);
$this->vars['toolbar'] = $this->getConfig('toolbar', true);
$this->vars['height'] = $this->getConfig('height', false) ?: 'false';
$isClientDataSource = $this->isClientDataSource();
$this->vars['clientDataSourceClass'] = $isClientDataSource ? 'client' : 'server';

View File

@ -83,6 +83,7 @@ The options below are listed in the JavaScript notation. Corresponding data attr
- `adding` - determines whether users can add new records. Default value is **true**.
- `deleting` - determines whether users can delete records. Default value is **true**.
- `toolbar` - determines whether the toolbar is visible. The default value is **true**.
- `height` - specifies the maximum height of the data table (not including the header, toolbar and pagination). If the table contains more rows than the height could fit, the data table becomes scrollable. The default value is **false** (height is not limited).
## Client-side helper classes
@ -168,6 +169,12 @@ The widget is configured with YAML file. Required parameters:
* `columns` - the columns definitions, see below
* `data_source` - The data source class. Should specify the full qualified data source class name or alias. See the data source aliases below.
* `key_column` - name of the key column. The default value is **id**.
* `records_per_page` - number of records per page. If not specified, the pagination will be disabled.
* `postback_handler_name` - AJAX data handler name for the automatic data postback. The data will be posted only when the AJAX requests posts data to this handler. The default value is **onSave**. This parameter is applicable only with client-memory data sources.
* `adding` - indicates if record deleting is allowed, default is **true**.
* `deleting` - indicates if record deleting is allowed, default is **true**.
* `toolbar` - specifies if the toolbar should be visible, default is **true**.
* `height` - specifies the data table height, in pixels. The default value is **false** - the height is not limited.
The `data_source` parameter can take aliases for some data source classes for the simpler configuration syntax. Known aliases are:

View File

@ -1,9 +1,6 @@
/*
* General control styling
*/
.table-control {
/* TODO: this should be applied only when the control is active */
}
.table-control .table-container {
border: 1px solid #808c8d;
-webkit-border-radius: 4px;
@ -37,6 +34,7 @@
position: absolute;
left: 1px;
right: 1px;
margin-top: -1px;
border-bottom: 1px solid #bdc3c7;
}
.table-control table.headers th {
@ -51,18 +49,22 @@
overflow: hidden;
text-overflow: ellipsis;
}
.table-control table.headers th [data-view-container] {
padding-bottom: 6px;
}
.table-control table.headers th:last-child {
border-right: none;
}
.table-control table.data td {
border: 1px solid #ecf0f1;
/* TODO: this should be applied only when the control is active */
}
.table-control table.data td .content-container {
position: relative;
padding: 1px;
}
.table-control table.data td.active {
border-color: #5fb6f5;
border-color: #5fb6f5 !important;
}
.table-control table.data td.active .content-container {
padding: 0;
@ -90,6 +92,9 @@
.table-control table.data tr:nth-child(2n) {
background-color: #fbfbfb;
}
.table-control table.data tr:first-child td {
border-top: none;
}
.table-control table.data tr:last-child td {
border-bottom: none;
}
@ -99,6 +104,14 @@
.table-control table.data td:last-child {
border-right: none;
}
.table-control .control-scrollbar > div {
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
overflow: hidden;
}
.table-control .control-scrollbar table.data tr:last-child td {
border-bottom: 1px solid #ecf0f1;
}
.table-control .toolbar {
background: white;
border-bottom: 1px solid #bdc3c7;

View File

@ -1,5 +1,8 @@
/*
* Table control class
*
* Dependences:
* - Scrollbar (october.scrollbar.js)
*/
+function ($) { "use strict";
@ -40,6 +43,9 @@
// A reference to the tables container
this.tableContainer = null
// A reference to the data table container
this.dataTableContainer = null
// The key of the row which is being edited at the moment.
// This key corresponds the data source row key which
// uniquely identifies the row in the data set. When the
@ -195,6 +201,11 @@
// Append the table container to the element
this.el.insertBefore(this.tableContainer, this.el.children[0])
if (!this.options.height)
this.dataTableContainer = this.tableContainer
else
this.dataTableContainer = this.buildScrollbar()
// Build the data table
this.updateDataTable()
}
@ -239,6 +250,21 @@
this.tableContainer.appendChild(this.toolbar)
}
Table.prototype.buildScrollbar = function() {
var scrollbar = document.createElement('div'),
scrollbarContent = document.createElement('div')
scrollbar.setAttribute('class', 'control-scrollbar')
scrollbar.setAttribute('style', 'height: ' + this.options.height + 'px')
scrollbar.appendChild(scrollbarContent)
this.tableContainer.appendChild(scrollbar)
$(scrollbar).scrollbar({animation: false})
return scrollbarContent
}
Table.prototype.buildHeaderTable = function() {
var headersTable = document.createElement('table'),
row = document.createElement('tr')
@ -336,15 +362,18 @@
// Inject the data table to the DOM or replace the existing table
if (this.dataTable !== null)
this.tableContainer.replaceChild(dataTable, this.dataTable)
this.dataTableContainer.replaceChild(dataTable, this.dataTable)
else
this.tableContainer.appendChild(dataTable)
this.dataTableContainer.appendChild(dataTable)
this.dataTable = dataTable
// Update column widths
this.updateColumnWidth()
// Update the scrollbar
this.updateScrollbar()
// Update the pagination links
this.navigation.buildPagination(totalCount)
}
@ -356,6 +385,28 @@
onSuccess)
}
Table.prototype.updateScrollbar = function() {
if (!this.options.height)
return
$(this.dataTableContainer.parentNode).data('oc.scrollbar').update()
}
Table.prototype.scrollCellIntoView = function() {
if (!this.options.height || !this.activeCell)
return
$(this.dataTableContainer.parentNode).data('oc.scrollbar').gotoElement(this.activeCell)
}
Table.prototype.disposeScrollbar = function() {
if (!this.options.height)
return
$(this.dataTableContainer.parentNode).data('oc.scrollbar').dispose()
$(this.dataTableContainer.parentNode).data('oc.scrollbar', null)
}
/*
* Makes a cell processor active and hides the previously
* active editor.
@ -443,6 +494,8 @@
this.editedRowKey = rowKey
processor.onFocus(cellElement, isClick)
this.scrollCellIntoView()
}
Table.prototype.markCellRowDirty = function(cellElement) {
@ -668,9 +721,11 @@
// we only make sure that the table widget doesn't hold
// references to the detached DOM tree so that the garbage
// collector can delete the elements if needed.
this.disposeScrollbar()
this.el = null
this.tableContainer = null
this.$el = null
this.dataTableContainer = null
// Delete references to other DOM elements
this.activeCell = null
@ -793,7 +848,8 @@
adding: true,
deleting: true,
toolbar: true,
rowSorting: false
rowSorting: false,
height: false
}
// TABLE PLUGIN DEFINITION

View File

@ -250,7 +250,8 @@
left = 0
do {
top += element.offsetTop || 0;
top += element.offsetTop || 0;
top -= element.scrollTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while(element)

View File

@ -40,6 +40,7 @@
position: absolute;
left: 1px;
right: 1px;
margin-top: -1px;
border-bottom: 1px solid #bdc3c7;
}
@ -51,6 +52,9 @@
color: #333333;
background: white;
border-right: 1px solid #ecf0f1;
[data-view-container] {
padding-bottom: 6px;
}
white-space: nowrap;
overflow: hidden;
@ -71,8 +75,9 @@
padding: 1px;
}
/* TODO: this should be applied only when the control is active */
&.active {
border-color: @color-focus;
border-color: @color-focus!important;
.content-container {
padding: 0;
@ -108,9 +113,9 @@
}
}
/* TODO: this should be applied only when the control is active */
table.data {
tr:first-child td {
border-top: none;
}
tr:last-child td {
@ -126,6 +131,19 @@
}
}
.control-scrollbar {
> div {
.border-bottom-radius(4px);
overflow: hidden;
}
table.data {
tr:last-child td {
border-bottom: 1px solid #ecf0f1;
}
}
}
.toolbar {
background: white;
border-bottom: 1px solid #bdc3c7;

View File

@ -1,11 +1,14 @@
<!-- <div data-control="table" data-row-sorting="1" data-columns="<?= e(json_encode($columns)) ?>" data-data="<?= e(json_encode($data)) ?>"></div> -->
<div
data-control="table"
class="table-control"
data-columns="<?= e(json_encode($columns)) ?>"
data-data="<?= e($data) ?>"
data-records-per-page="10"
data-postback-handler-name="<?= e($postbackHandlerName) ?>"
data-adding="<?= e($adding) ?>"
data-deleting="<?= e($deleting) ?>"
data-toolbar="<?= e($toolbar) ?>"
data-height="<?= e($height) ?>"
data-records-per-page="<?= e($recordsPerPage) ?>"
data-key-column="<?= e($recordsKeyColumn) ?>"
data-client-data-source-class="<?= e($clientDataSourceClass) ?>"
data-alias="<?= e($this->alias) ?>"></div>