Add change monitoring to Grid widget
This commit is contained in:
parent
a2e755e439
commit
baec411fd3
|
|
@ -51,20 +51,25 @@ class Grid extends WidgetBase
|
|||
protected $disableToolbar = false;
|
||||
|
||||
/**
|
||||
* @var array Provided data set
|
||||
* @var array Provided data set, cannot use with dataLocker or useDataSource.
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @var boolean Use a remote data source
|
||||
*/
|
||||
protected $useDataSource;
|
||||
|
||||
/**
|
||||
* @var string HTML element that can [re]store the grid data.
|
||||
* @var string HTML element that can [re]store the grid data, cannot use with data or useDataSource.
|
||||
*/
|
||||
protected $dataLocker;
|
||||
|
||||
/**
|
||||
* @var boolean Get data from AJAX callback (onDataSource), cannot use with data or dataLocker.
|
||||
*/
|
||||
protected $useDataSource = false;
|
||||
|
||||
/**
|
||||
* @var boolean Sends an AJAX callback (onDataChanged) any time a field is changed.
|
||||
*/
|
||||
protected $monitorChanges = true;
|
||||
|
||||
/**
|
||||
* Initialize the widget, called by the constructor and free from its parameters.
|
||||
*/
|
||||
|
|
@ -78,6 +83,7 @@ class Grid extends WidgetBase
|
|||
$this->data = $this->getConfig('data', $this->data);
|
||||
$this->dataLocker = $this->getConfig('dataLocker', $this->dataLocker);
|
||||
$this->useDataSource = $this->getConfig('useDataSource', $this->useDataSource);
|
||||
$this->monitorChanges = $this->getConfig('monitorChanges', $this->monitorChanges);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,6 +112,7 @@ class Grid extends WidgetBase
|
|||
$this->vars['data'] = $this->data;
|
||||
$this->vars['dataLocker'] = $this->dataLocker;
|
||||
$this->vars['useDataSource'] = $this->useDataSource;
|
||||
$this->vars['monitorChanges'] = $this->monitorChanges;
|
||||
}
|
||||
|
||||
protected function makeToolbarWidget()
|
||||
|
|
@ -137,6 +144,19 @@ class Grid extends WidgetBase
|
|||
return ['result' => $result];
|
||||
}
|
||||
|
||||
public function onDataChanged()
|
||||
{
|
||||
if (!$this->monitorChanges)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Changes array, each array item will contain:
|
||||
* ['rowData' => [...], 'keyName' => 'changedColumn', 'oldValue' => 'was', 'newValue' => 'is']
|
||||
*/
|
||||
$changes = post('changes');
|
||||
$this->fireEvent('grid.dataChanged', [$changes]);
|
||||
}
|
||||
|
||||
public function onDataSource()
|
||||
{
|
||||
if (!$this->useDataSource)
|
||||
|
|
|
|||
|
|
@ -3,13 +3,16 @@
|
|||
*
|
||||
* Data attributes:
|
||||
* - data-control="datagrid" - enables the plugin on an element
|
||||
* - data-option="value" - an option with a value
|
||||
* - data-allow-remove="true" - allow rows to be removed
|
||||
* - data-autocomplete-handler="onAutocomplete" - AJAX handler for autocomplete values
|
||||
* - data-data-locker="input#locker" - Input element to store and restore grid data as JSON
|
||||
* - data-source-handler="onGetData" - AJAX handler for obtaining grid data
|
||||
*
|
||||
* JavaScript API:
|
||||
* $('a#someElement').dataGrid({ option: 'value' })
|
||||
* $('div#someElement').dataGrid({ option: 'value' })
|
||||
*
|
||||
* Dependences:
|
||||
* - Some other plugin (filename.js)
|
||||
* Dependences:
|
||||
* - Handsontable (handsontable.js)
|
||||
*/
|
||||
|
||||
+function ($) { "use strict";
|
||||
|
|
@ -43,6 +46,19 @@
|
|||
// rowHeaders: false,
|
||||
// manualColumnMove: true,
|
||||
// manualRowMove: true,
|
||||
afterChange: function(changes, source) {
|
||||
if (source === 'loadData')
|
||||
return
|
||||
|
||||
/*
|
||||
* changes - is a 2D array containing information about each of the edited cells
|
||||
* [ [row, prop, oldVal, newVal], ... ].
|
||||
*
|
||||
* source - is one of the strings: "alter", "empty", "edit", "populateFromArray",
|
||||
* "loadData", "autofill", "paste".
|
||||
*/
|
||||
self.$el.trigger('datagrid.change', [changes, source])
|
||||
},
|
||||
fillHandle: false,
|
||||
multiSelect: false,
|
||||
removeRowPlugin: this.options.allowRemove
|
||||
|
|
@ -51,18 +67,24 @@
|
|||
if (this.options.autoInsertRows)
|
||||
handsontableOptions.minSpareRows = 1
|
||||
|
||||
/*
|
||||
* Data provided
|
||||
*/
|
||||
if (this.options.data) {
|
||||
handsontableOptions.data = this.options.data
|
||||
}
|
||||
/*
|
||||
* Data from a data locker
|
||||
*/
|
||||
else if (this.options.dataLocker) {
|
||||
/*
|
||||
* Event to update the data locker
|
||||
*/
|
||||
this.$dataLocker = $(this.options.dataLocker)
|
||||
handsontableOptions.afterChange = function(changes, source) {
|
||||
self.$el.on('datagrid.change', function(event, eventData) {
|
||||
if (!self.gridInstance) return
|
||||
self.$dataLocker.val(JSON.stringify(self.getData()))
|
||||
}
|
||||
})
|
||||
|
||||
/*
|
||||
* Populate existing data
|
||||
|
|
@ -74,10 +96,44 @@
|
|||
delete handsontableOptions.data
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Data from an AJAX data source
|
||||
*/
|
||||
else if (this.options.sourceHandler) {
|
||||
self.refreshDataSource()
|
||||
}
|
||||
|
||||
/*
|
||||
* Monitor for data changes
|
||||
*/
|
||||
if (this.options.changeHandler) {
|
||||
self.$el.on('datagrid.change', function(event, changes, source) {
|
||||
var changeData = [];
|
||||
|
||||
$.each(changes, function(index, change){
|
||||
var changeObj = {}
|
||||
changeObj.keyName = change[1]
|
||||
changeObj.oldValue = change[2]
|
||||
changeObj.newValue = change[3]
|
||||
|
||||
if (changeObj.oldValue == changeObj.newValue)
|
||||
return; // continue
|
||||
|
||||
changeObj.rowData = self.getDataAtRow(change[0])
|
||||
changeData.push(changeObj)
|
||||
})
|
||||
|
||||
if (changeData.length > 0) {
|
||||
self.$el.request(self.options.changeHandler, {
|
||||
data: { changes: changeData }
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Create up Handson table and validate columns
|
||||
*/
|
||||
this.$el.handsontable(handsontableOptions)
|
||||
this.gridInstance = this.$el.handsontable('getInstance')
|
||||
|
||||
|
|
@ -105,6 +161,9 @@
|
|||
return columns
|
||||
}
|
||||
|
||||
/*
|
||||
* Auto complete
|
||||
*/
|
||||
var autocompleteLastQuery = '',
|
||||
autocompleteInterval = 300,
|
||||
autocompleteInputTimer
|
||||
|
|
@ -142,6 +201,7 @@
|
|||
data: null,
|
||||
dataLocker: null,
|
||||
sourceHandler: null,
|
||||
changeHandler: null,
|
||||
startRows: 1,
|
||||
minRows: 1,
|
||||
autoInsertRows: false,
|
||||
|
|
|
|||
|
|
@ -124,9 +124,6 @@
|
|||
.handsontable tbody th:last-of-type {
|
||||
border-right: 1px solid #e2e2e2 !important;
|
||||
}
|
||||
.handsontable tbody td:first-of-type.currentRow {
|
||||
border-left: 3px solid #ff9933;
|
||||
}
|
||||
.handsontable th.active {
|
||||
/*background-color: #CCC;*/
|
||||
color: #666;
|
||||
|
|
|
|||
|
|
@ -147,9 +147,13 @@
|
|||
border-right: 1px solid @color-handsontable-border !important;
|
||||
}
|
||||
|
||||
td:first-of-type.currentRow {
|
||||
border-left: 3px solid @color-list-stripe-active;
|
||||
}
|
||||
//td:first-of-type {
|
||||
// border-left: 3px solid transparent;
|
||||
//}
|
||||
|
||||
// td:first-of-type.currentRow {
|
||||
// border-left: 3px solid @color-list-stripe-active;
|
||||
// }
|
||||
}
|
||||
|
||||
th.active {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
data-autocomplete-handler="<?= $this->getEventHandler('onAutocomplete') ?>"
|
||||
<?php if ($dataLocker): ?>data-data-locker="<?= $dataLocker ?>"<?php endif ?>
|
||||
<?php if ($useDataSource): ?>data-source-handler="<?= $this->getEventHandler('onDataSource') ?>"<?php endif ?>
|
||||
<?php if ($monitorChanges): ?>data-change-handler="<?= $this->getEventHandler('onDataChanged') ?>"<?php endif ?>
|
||||
></div>
|
||||
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue