Grid save/load
This commit is contained in:
parent
3c510af991
commit
af4d453cb8
|
|
@ -65,6 +65,7 @@ class DataGrid extends FormWidgetBase
|
|||
$this->vars['columnWidths'] = $this->getColumnWidths();
|
||||
$this->vars['size'] = $this->size;
|
||||
$this->vars['toolbarWidget'] = $this->makeToolbarWidget();
|
||||
$this->vars['value'] = json_encode($this->model->{$this->columnName});
|
||||
}
|
||||
|
||||
protected function makeToolbarWidget()
|
||||
|
|
@ -184,6 +185,6 @@ class DataGrid extends FormWidgetBase
|
|||
*/
|
||||
public function getSaveData($value)
|
||||
{
|
||||
return $value;
|
||||
return json_decode($value);
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,27 @@
|
|||
if (this.options.autoInsertRows)
|
||||
handsontableOptions.minSpareRows = 1
|
||||
|
||||
if (this.options.dataLocker) {
|
||||
/*
|
||||
* Event to update the data locker
|
||||
*/
|
||||
this.$dataLocker = $(this.options.dataLocker)
|
||||
handsontableOptions.afterChange = function(changes, source) {
|
||||
if (!self.gridInstance) return
|
||||
self.$dataLocker.val(JSON.stringify(self.getData()))
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate existing data
|
||||
*/
|
||||
try {
|
||||
var existingData = JSON.parse(this.$dataLocker.val())
|
||||
if (existingData) handsontableOptions.data = existingData
|
||||
} catch (e) {
|
||||
delete handsontableOptions.data
|
||||
}
|
||||
}
|
||||
|
||||
this.$el.handsontable(handsontableOptions)
|
||||
this.gridInstance = this.$el.handsontable('getInstance')
|
||||
|
||||
|
|
@ -109,6 +130,7 @@
|
|||
}
|
||||
|
||||
DataGrid.DEFAULTS = {
|
||||
dataLocker: null,
|
||||
startRows: 1,
|
||||
minRows: 1,
|
||||
autoInsertRows: false,
|
||||
|
|
@ -127,11 +149,18 @@
|
|||
}
|
||||
|
||||
DataGrid.prototype.getData = function() {
|
||||
var results = [],
|
||||
var self = this,
|
||||
results = [],
|
||||
dataArray = this.gridInstance.getData()
|
||||
|
||||
$.each(dataArray, function(index, object){
|
||||
results.push($.extend(true, {}, object))
|
||||
var dataObj = {}
|
||||
|
||||
// Prune out unwanted array data
|
||||
$.each(self.columns, function(index, column){
|
||||
dataObj[column.data] = object[column.data]
|
||||
})
|
||||
results.push(dataObj)
|
||||
})
|
||||
return results
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10446,4 +10446,523 @@ if (!Array.prototype.filter) {
|
|||
};
|
||||
}
|
||||
|
||||
})(jQuery, window, Handsontable);
|
||||
})(jQuery, window, Handsontable);
|
||||
|
||||
// numeral.js
|
||||
// version : 1.4.7
|
||||
// author : Adam Draper
|
||||
// license : MIT
|
||||
// http://adamwdraper.github.com/Numeral-js/
|
||||
|
||||
(function () {
|
||||
|
||||
/************************************
|
||||
Constants
|
||||
************************************/
|
||||
|
||||
var numeral,
|
||||
VERSION = '1.4.7',
|
||||
// internal storage for language config files
|
||||
languages = {},
|
||||
currentLanguage = 'en',
|
||||
zeroFormat = null,
|
||||
// check for nodeJS
|
||||
hasModule = (typeof module !== 'undefined' && module.exports);
|
||||
|
||||
|
||||
/************************************
|
||||
Constructors
|
||||
************************************/
|
||||
|
||||
|
||||
// Numeral prototype object
|
||||
function Numeral (number) {
|
||||
this._n = number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of toFixed() that treats floats more like decimals
|
||||
*
|
||||
* Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present
|
||||
* problems for accounting- and finance-related software.
|
||||
*/
|
||||
function toFixed (value, precision, optionals) {
|
||||
var power = Math.pow(10, precision),
|
||||
output;
|
||||
|
||||
// Multiply up by precision, round accurately, then divide and use native toFixed():
|
||||
output = (Math.round(value * power) / power).toFixed(precision);
|
||||
|
||||
if (optionals) {
|
||||
var optionalsRegExp = new RegExp('0{1,' + optionals + '}$');
|
||||
output = output.replace(optionalsRegExp, '');
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/************************************
|
||||
Formatting
|
||||
************************************/
|
||||
|
||||
// determine what type of formatting we need to do
|
||||
function formatNumeral (n, format) {
|
||||
var output;
|
||||
|
||||
// figure out what kind of format we are dealing with
|
||||
if (format.indexOf('$') > -1) { // currency!!!!!
|
||||
output = formatCurrency(n, format);
|
||||
} else if (format.indexOf('%') > -1) { // percentage
|
||||
output = formatPercentage(n, format);
|
||||
} else if (format.indexOf(':') > -1) { // time
|
||||
output = formatTime(n, format);
|
||||
} else { // plain ol' numbers or bytes
|
||||
output = formatNumber(n, format);
|
||||
}
|
||||
|
||||
// return string
|
||||
return output;
|
||||
}
|
||||
|
||||
// revert to number
|
||||
function unformatNumeral (n, string) {
|
||||
if (string.indexOf(':') > -1) {
|
||||
n._n = unformatTime(string);
|
||||
} else {
|
||||
if (string === zeroFormat) {
|
||||
n._n = 0;
|
||||
} else {
|
||||
var stringOriginal = string;
|
||||
if (languages[currentLanguage].delimiters.decimal !== '.') {
|
||||
string = string.replace(/\./g,'').replace(languages[currentLanguage].delimiters.decimal, '.');
|
||||
}
|
||||
|
||||
// see if abbreviations are there so that we can multiply to the correct number
|
||||
var thousandRegExp = new RegExp(languages[currentLanguage].abbreviations.thousand + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$'),
|
||||
millionRegExp = new RegExp(languages[currentLanguage].abbreviations.million + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$'),
|
||||
billionRegExp = new RegExp(languages[currentLanguage].abbreviations.billion + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$'),
|
||||
trillionRegExp = new RegExp(languages[currentLanguage].abbreviations.trillion + '(?:\\)|(\\' + languages[currentLanguage].currency.symbol + ')?(?:\\))?)?$');
|
||||
|
||||
// see if bytes are there so that we can multiply to the correct number
|
||||
var prefixes = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
||||
bytesMultiplier = false;
|
||||
|
||||
for (var power = 0; power <= prefixes.length; power++) {
|
||||
bytesMultiplier = (string.indexOf(prefixes[power]) > -1) ? Math.pow(1024, power + 1) : false;
|
||||
|
||||
if (bytesMultiplier) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do some math to create our number
|
||||
n._n = ((bytesMultiplier) ? bytesMultiplier : 1) * ((stringOriginal.match(thousandRegExp)) ? Math.pow(10, 3) : 1) * ((stringOriginal.match(millionRegExp)) ? Math.pow(10, 6) : 1) * ((stringOriginal.match(billionRegExp)) ? Math.pow(10, 9) : 1) * ((stringOriginal.match(trillionRegExp)) ? Math.pow(10, 12) : 1) * ((string.indexOf('%') > -1) ? 0.01 : 1) * Number(((string.indexOf('(') > -1) ? '-' : '') + string.replace(/[^0-9\.-]+/g, ''));
|
||||
|
||||
// round if we are talking about bytes
|
||||
n._n = (bytesMultiplier) ? Math.ceil(n._n) : n._n;
|
||||
}
|
||||
}
|
||||
return n._n;
|
||||
}
|
||||
|
||||
function formatCurrency (n, format) {
|
||||
var prependSymbol = (format.indexOf('$') <= 1) ? true : false;
|
||||
|
||||
// remove $ for the moment
|
||||
var space = '';
|
||||
|
||||
// check for space before or after currency
|
||||
if (format.indexOf(' $') > -1) {
|
||||
space = ' ';
|
||||
format = format.replace(' $', '');
|
||||
} else if (format.indexOf('$ ') > -1) {
|
||||
space = ' ';
|
||||
format = format.replace('$ ', '');
|
||||
} else {
|
||||
format = format.replace('$', '');
|
||||
}
|
||||
|
||||
// format the number
|
||||
var output = formatNumeral(n, format);
|
||||
|
||||
// position the symbol
|
||||
if (prependSymbol) {
|
||||
if (output.indexOf('(') > -1 || output.indexOf('-') > -1) {
|
||||
output = output.split('');
|
||||
output.splice(1, 0, languages[currentLanguage].currency.symbol + space);
|
||||
output = output.join('');
|
||||
} else {
|
||||
output = languages[currentLanguage].currency.symbol + space + output;
|
||||
}
|
||||
} else {
|
||||
if (output.indexOf(')') > -1) {
|
||||
output = output.split('');
|
||||
output.splice(-1, 0, space + languages[currentLanguage].currency.symbol);
|
||||
output = output.join('');
|
||||
} else {
|
||||
output = output + space + languages[currentLanguage].currency.symbol;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function formatPercentage (n, format) {
|
||||
var space = '';
|
||||
// check for space before %
|
||||
if (format.indexOf(' %') > -1) {
|
||||
space = ' ';
|
||||
format = format.replace(' %', '');
|
||||
} else {
|
||||
format = format.replace('%', '');
|
||||
}
|
||||
|
||||
n._n = n._n * 100;
|
||||
var output = formatNumeral(n, format);
|
||||
if (output.indexOf(')') > -1 ) {
|
||||
output = output.split('');
|
||||
output.splice(-1, 0, space + '%');
|
||||
output = output.join('');
|
||||
} else {
|
||||
output = output + space + '%';
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function formatTime (n, format) {
|
||||
var hours = Math.floor(n._n/60/60),
|
||||
minutes = Math.floor((n._n - (hours * 60 * 60))/60),
|
||||
seconds = Math.round(n._n - (hours * 60 * 60) - (minutes * 60));
|
||||
return hours + ':' + ((minutes < 10) ? '0' + minutes : minutes) + ':' + ((seconds < 10) ? '0' + seconds : seconds);
|
||||
}
|
||||
|
||||
function unformatTime (string) {
|
||||
var timeArray = string.split(':'),
|
||||
seconds = 0;
|
||||
// turn hours and minutes into seconds and add them all up
|
||||
if (timeArray.length === 3) {
|
||||
// hours
|
||||
seconds = seconds + (Number(timeArray[0]) * 60 * 60);
|
||||
// minutes
|
||||
seconds = seconds + (Number(timeArray[1]) * 60);
|
||||
// seconds
|
||||
seconds = seconds + Number(timeArray[2]);
|
||||
} else if (timeArray.lenght === 2) {
|
||||
// minutes
|
||||
seconds = seconds + (Number(timeArray[0]) * 60);
|
||||
// seconds
|
||||
seconds = seconds + Number(timeArray[1]);
|
||||
}
|
||||
return Number(seconds);
|
||||
}
|
||||
|
||||
function formatNumber (n, format) {
|
||||
var negP = false,
|
||||
optDec = false,
|
||||
abbr = '',
|
||||
bytes = '',
|
||||
ord = '',
|
||||
abs = Math.abs(n._n);
|
||||
|
||||
// check if number is zero and a custom zero format has been set
|
||||
if (n._n === 0 && zeroFormat !== null) {
|
||||
return zeroFormat;
|
||||
} else {
|
||||
// see if we should use parentheses for negative number
|
||||
if (format.indexOf('(') > -1) {
|
||||
negP = true;
|
||||
format = format.slice(1, -1);
|
||||
}
|
||||
|
||||
// see if abbreviation is wanted
|
||||
if (format.indexOf('a') > -1) {
|
||||
// check for space before abbreviation
|
||||
if (format.indexOf(' a') > -1) {
|
||||
abbr = ' ';
|
||||
format = format.replace(' a', '');
|
||||
} else {
|
||||
format = format.replace('a', '');
|
||||
}
|
||||
|
||||
if (abs >= Math.pow(10, 12)) {
|
||||
// trillion
|
||||
abbr = abbr + languages[currentLanguage].abbreviations.trillion;
|
||||
n._n = n._n / Math.pow(10, 12);
|
||||
} else if (abs < Math.pow(10, 12) && abs >= Math.pow(10, 9)) {
|
||||
// billion
|
||||
abbr = abbr + languages[currentLanguage].abbreviations.billion;
|
||||
n._n = n._n / Math.pow(10, 9);
|
||||
} else if (abs < Math.pow(10, 9) && abs >= Math.pow(10, 6)) {
|
||||
// million
|
||||
abbr = abbr + languages[currentLanguage].abbreviations.million;
|
||||
n._n = n._n / Math.pow(10, 6);
|
||||
} else if (abs < Math.pow(10, 6) && abs >= Math.pow(10, 3)) {
|
||||
// thousand
|
||||
abbr = abbr + languages[currentLanguage].abbreviations.thousand;
|
||||
n._n = n._n / Math.pow(10, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// see if we are formatting bytes
|
||||
if (format.indexOf('b') > -1) {
|
||||
// check for space before
|
||||
if (format.indexOf(' b') > -1) {
|
||||
bytes = ' ';
|
||||
format = format.replace(' b', '');
|
||||
} else {
|
||||
format = format.replace('b', '');
|
||||
}
|
||||
|
||||
var prefixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
||||
min,
|
||||
max;
|
||||
|
||||
for (var power = 0; power <= prefixes.length; power++) {
|
||||
min = Math.pow(1024, power);
|
||||
max = Math.pow(1024, power+1);
|
||||
|
||||
if (n._n >= min && n._n < max) {
|
||||
bytes = bytes + prefixes[power];
|
||||
if (min > 0) {
|
||||
n._n = n._n / min;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// see if ordinal is wanted
|
||||
if (format.indexOf('o') > -1) {
|
||||
// check for space before
|
||||
if (format.indexOf(' o') > -1) {
|
||||
ord = ' ';
|
||||
format = format.replace(' o', '');
|
||||
} else {
|
||||
format = format.replace('o', '');
|
||||
}
|
||||
|
||||
ord = ord + languages[currentLanguage].ordinal(n._n);
|
||||
}
|
||||
|
||||
if (format.indexOf('[.]') > -1) {
|
||||
optDec = true;
|
||||
format = format.replace('[.]', '.');
|
||||
}
|
||||
|
||||
var w = n._n.toString().split('.')[0],
|
||||
precision = format.split('.')[1],
|
||||
thousands = format.indexOf(','),
|
||||
d = '',
|
||||
neg = false;
|
||||
|
||||
if (precision) {
|
||||
if (precision.indexOf('[') > -1) {
|
||||
precision = precision.replace(']', '');
|
||||
precision = precision.split('[');
|
||||
d = toFixed(n._n, (precision[0].length + precision[1].length), precision[1].length);
|
||||
} else {
|
||||
d = toFixed(n._n, precision.length);
|
||||
}
|
||||
|
||||
w = d.split('.')[0];
|
||||
|
||||
if (d.split('.')[1].length) {
|
||||
d = languages[currentLanguage].delimiters.decimal + d.split('.')[1];
|
||||
} else {
|
||||
d = '';
|
||||
}
|
||||
|
||||
if (optDec && Number(d) === 0) {
|
||||
d = '';
|
||||
}
|
||||
} else {
|
||||
w = toFixed(n._n, null);
|
||||
}
|
||||
|
||||
// format number
|
||||
if (w.indexOf('-') > -1) {
|
||||
w = w.slice(1);
|
||||
neg = true;
|
||||
}
|
||||
|
||||
if (thousands > -1) {
|
||||
w = w.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + languages[currentLanguage].delimiters.thousands);
|
||||
}
|
||||
|
||||
if (format.indexOf('.') === 0) {
|
||||
w = '';
|
||||
}
|
||||
|
||||
return ((negP && neg) ? '(' : '') + ((!negP && neg) ? '-' : '') + w + d + ((ord) ? ord : '') + ((abbr) ? abbr : '') + ((bytes) ? bytes : '') + ((negP && neg) ? ')' : '');
|
||||
}
|
||||
}
|
||||
|
||||
/************************************
|
||||
Top Level Functions
|
||||
************************************/
|
||||
|
||||
numeral = function (input) {
|
||||
if (numeral.isNumeral(input)) {
|
||||
input = input.value();
|
||||
} else if (!Number(input)) {
|
||||
input = 0;
|
||||
}
|
||||
|
||||
return new Numeral(Number(input));
|
||||
};
|
||||
|
||||
// version number
|
||||
numeral.version = VERSION;
|
||||
|
||||
// compare numeral object
|
||||
numeral.isNumeral = function (obj) {
|
||||
return obj instanceof Numeral;
|
||||
};
|
||||
|
||||
// This function will load languages and then set the global language. If
|
||||
// no arguments are passed in, it will simply return the current global
|
||||
// language key.
|
||||
numeral.language = function (key, values) {
|
||||
if (!key) {
|
||||
return currentLanguage;
|
||||
}
|
||||
|
||||
if (key && !values) {
|
||||
currentLanguage = key;
|
||||
}
|
||||
|
||||
if (values || !languages[key]) {
|
||||
loadLanguage(key, values);
|
||||
}
|
||||
|
||||
return numeral;
|
||||
};
|
||||
|
||||
numeral.language('en', {
|
||||
delimiters: {
|
||||
thousands: ',',
|
||||
decimal: '.'
|
||||
},
|
||||
abbreviations: {
|
||||
thousand: 'k',
|
||||
million: 'm',
|
||||
billion: 'b',
|
||||
trillion: 't'
|
||||
},
|
||||
ordinal: function (number) {
|
||||
var b = number % 10;
|
||||
return (~~ (number % 100 / 10) === 1) ? 'th' :
|
||||
(b === 1) ? 'st' :
|
||||
(b === 2) ? 'nd' :
|
||||
(b === 3) ? 'rd' : 'th';
|
||||
},
|
||||
currency: {
|
||||
symbol: '$'
|
||||
}
|
||||
});
|
||||
|
||||
numeral.zeroFormat = function (format) {
|
||||
if (typeof(format) === 'string') {
|
||||
zeroFormat = format;
|
||||
} else {
|
||||
zeroFormat = null;
|
||||
}
|
||||
};
|
||||
|
||||
/************************************
|
||||
Helpers
|
||||
************************************/
|
||||
|
||||
function loadLanguage(key, values) {
|
||||
languages[key] = values;
|
||||
}
|
||||
|
||||
|
||||
/************************************
|
||||
Numeral Prototype
|
||||
************************************/
|
||||
|
||||
|
||||
numeral.fn = Numeral.prototype = {
|
||||
|
||||
clone : function () {
|
||||
return numeral(this);
|
||||
},
|
||||
|
||||
format : function (inputString) {
|
||||
return formatNumeral(this, inputString ? inputString : numeral.defaultFormat);
|
||||
},
|
||||
|
||||
unformat : function (inputString) {
|
||||
return unformatNumeral(this, inputString ? inputString : numeral.defaultFormat);
|
||||
},
|
||||
|
||||
value : function () {
|
||||
return this._n;
|
||||
},
|
||||
|
||||
valueOf : function () {
|
||||
return this._n;
|
||||
},
|
||||
|
||||
set : function (value) {
|
||||
this._n = Number(value);
|
||||
return this;
|
||||
},
|
||||
|
||||
add : function (value) {
|
||||
this._n = this._n + Number(value);
|
||||
return this;
|
||||
},
|
||||
|
||||
subtract : function (value) {
|
||||
this._n = this._n - Number(value);
|
||||
return this;
|
||||
},
|
||||
|
||||
multiply : function (value) {
|
||||
this._n = this._n * Number(value);
|
||||
return this;
|
||||
},
|
||||
|
||||
divide : function (value) {
|
||||
this._n = this._n / Number(value);
|
||||
return this;
|
||||
},
|
||||
|
||||
difference : function (value) {
|
||||
var difference = this._n - Number(value);
|
||||
|
||||
if (difference < 0) {
|
||||
difference = -difference;
|
||||
}
|
||||
|
||||
return difference;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/************************************
|
||||
Exposing Numeral
|
||||
************************************/
|
||||
|
||||
// CommonJS module is defined
|
||||
if (hasModule) {
|
||||
module.exports = numeral;
|
||||
}
|
||||
|
||||
/*global ender:false */
|
||||
if (typeof ender === 'undefined') {
|
||||
// here, `this` means `window` in the browser, or `global` on the server
|
||||
// add `numeral` as a global object via a string identifier,
|
||||
// for Closure Compiler 'advanced' mode
|
||||
this['numeral'] = numeral;
|
||||
}
|
||||
|
||||
/*global define:false */
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define([], function () {
|
||||
return numeral;
|
||||
});
|
||||
}
|
||||
}).call(this);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,16 @@
|
|||
style="width:100%"
|
||||
class="control-datagrid"
|
||||
data-control="datagrid"
|
||||
data-data-locker="#<?= $this->getId('datalocker') ?>"
|
||||
data-autocomplete-handler="<?= $this->getEventHandler('onAutocomplete') ?>"
|
||||
></div>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
id="<?= $this->getId('datalocker') ?>"
|
||||
name="<?= $name ?>"
|
||||
value="<?= e($value) ?>"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue