From f6fffad37d887f17c38edd01122475e69bc1cf62 Mon Sep 17 00:00:00 2001 From: Sam Georges Date: Wed, 16 Jul 2014 18:48:18 +1000 Subject: [PATCH] Convert DataGrid form widget in to Grid widget (no longer exclusive to forms) --- modules/backend/formwidgets/DataGrid.php | 166 +++---------- .../datagrid/partials/_datagrid.htm | 17 +- .../datagrid/partials/_toolbar.htm | 6 - modules/backend/widgets/Grid.php | 226 ++++++++++++++++++ modules/backend/widgets/Toolbar.php | 2 +- .../grid}/assets/css/datagrid.css | 0 .../grid}/assets/js/datagrid.js | 13 +- .../grid}/assets/less/datagrid.less | 0 .../vendor/handsontable/columnautosize.js | 0 .../assets/vendor/handsontable/columnmove.js | 0 .../vendor/handsontable/columnresize.js | 0 .../vendor/handsontable/columnsorting.js | 0 .../handsontable/jquery.handsontable.css | 0 .../handsontable/jquery.handsontable.js | 0 .../handsontable/jquery.handsontable.less | 0 .../vendor/handsontable/removebutton.js | 0 .../assets/vendor/handsontable/rowmove.js | 0 .../backend/widgets/grid/partials/_grid.htm | 23 ++ .../widgets/grid/partials/_toolbar.htm | 20 ++ 19 files changed, 316 insertions(+), 157 deletions(-) delete mode 100644 modules/backend/formwidgets/datagrid/partials/_toolbar.htm create mode 100644 modules/backend/widgets/Grid.php rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/css/datagrid.css (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/js/datagrid.js (96%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/less/datagrid.less (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/columnautosize.js (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/columnmove.js (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/columnresize.js (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/columnsorting.js (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/jquery.handsontable.css (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/jquery.handsontable.js (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/jquery.handsontable.less (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/removebutton.js (100%) rename modules/backend/{formwidgets/datagrid => widgets/grid}/assets/vendor/handsontable/rowmove.js (100%) create mode 100644 modules/backend/widgets/grid/partials/_grid.htm create mode 100644 modules/backend/widgets/grid/partials/_toolbar.htm diff --git a/modules/backend/formwidgets/DataGrid.php b/modules/backend/formwidgets/DataGrid.php index 249b7f0e3..1b405ca8c 100644 --- a/modules/backend/formwidgets/DataGrid.php +++ b/modules/backend/formwidgets/DataGrid.php @@ -1,5 +1,6 @@ columns = $this->getConfig('columns', []); $this->size = $this->getConfig('size', $this->size); + $this->grid = $this->makeGridWidget(); + $this->grid->bindToController(); } /** @@ -59,125 +52,10 @@ class DataGrid extends FormWidgetBase */ public function prepareVars() { + $this->vars['grid'] = $this->grid; $this->vars['name'] = $this->formField->getName(); - $this->vars['columnHeaders'] = $this->getColumnHeaders(); - $this->vars['columnDefinitions'] = $this->getColumnDefinitions(); - $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() - { - $toolbarConfig = $this->makeConfig([ - 'alias' => $this->alias . 'Toolbar', - 'buttons' => $this->getViewPath('_toolbar.htm'), - ]); - - $toolbarWidget = $this->makeWidget('Backend\Widgets\Toolbar', $toolbarConfig); - return $toolbarWidget; - } - - // - // Getters - // - - protected function getColumnHeaders() - { - $headers = []; - foreach ($this->columns as $key => $column) { - $headers[] = isset($column['title']) ? $column['title'] : '???'; - } - return $headers; - } - - protected function getColumnWidths() - { - $widths = []; - foreach ($this->columns as $key => $column) { - $widths[] = isset($column['width']) ? $column['width'] : '0'; - } - return $widths; - } - - protected function getColumnDefinitions() - { - $definitions = []; - foreach ($this->columns as $key => $column) { - $item = []; - $item['data'] = $key; - - if (isset($column['readOnly'])) - $item['readOnly'] = $column['readOnly']; - - $item = $this->evalColumnType($column, $item); - $definitions[] = $item; - } - return $definitions; - } - - protected function evalColumnType($column, $item) - { - if (!isset($column['type'])) - return $item; - - switch ($column['type']) { - case 'number': - $item['type'] = 'numeric'; - break; - - case 'currency': - $item['type'] = 'numeric'; - $item['format'] = '$0,0.00'; - break; - - case 'checkbox': - $item['type'] = 'checkbox'; - break; - - case 'autocomplete': - $item['type'] = 'autocomplete'; - if (isset($column['options'])) $item['source'] = $column['options']; - if (isset($column['strict'])) $item['strict'] = $column['strict']; - break; - } - - return $item; - } - - // - // AJAX - // - - public function onAutocomplete() - { - if (!$this->model->methodExists('getGridAutocompleteValues')) - throw new ApplicationException('Model :model does not contain a method getGridAutocompleteValues()'); - - $field = post('autocomplete_field'); - $value = post('autocomplete_value'); - $data = post('autocomplete_data', []); - $result = $this->model->getGridAutocompleteValues($field, $value, $data); - if (!is_array($result)) - $result = []; - - return ['result' => $result]; - } - - // - // Internals - // - - /** - * {@inheritDoc} - */ - public function loadAssets() - { - $this->addCss('vendor/handsontable/jquery.handsontable.css', 'core'); - $this->addCss('css/datagrid.css', 'core'); - $this->addJs('vendor/handsontable/jquery.handsontable.js', 'core'); - $this->addJs('js/datagrid.js', 'core'); + $this->vars['value'] = json_encode($this->formField->value); } /** @@ -187,4 +65,28 @@ class DataGrid extends FormWidgetBase { return json_decode($value); } + + protected function makeGridWidget() + { + $config = $this->makeConfig((array) $this->config); + $config->dataLocker = '#'.$this->getId('dataLocker'); + + $grid = new Grid($this->controller, $config); + $grid->alias = $this->alias . 'Grid'; + $grid->bindEvent('grid.autocomplete', [$this, 'getAutocompleteValues']); + + return $grid; + } + + public function getAutocompleteValues($field, $value, $data) + { + if (!$this->model->methodExists('getGridAutocompleteValues')) + throw new ApplicationException('Model :model does not contain a method getGridAutocompleteValues()'); + + $result = $this->model->getGridAutocompleteValues($field, $value, $data); + if (!is_array($result)) + $result = []; + + return $result; + } } \ No newline at end of file diff --git a/modules/backend/formwidgets/datagrid/partials/_datagrid.htm b/modules/backend/formwidgets/datagrid/partials/_datagrid.htm index f8cb23918..7ec6fe954 100644 --- a/modules/backend/formwidgets/datagrid/partials/_datagrid.htm +++ b/modules/backend/formwidgets/datagrid/partials/_datagrid.htm @@ -2,16 +2,7 @@ id="getId() ?>" class="field-datagrid size-"> - render() ?> - -
+ render() ?> - \ No newline at end of file diff --git a/modules/backend/formwidgets/datagrid/partials/_toolbar.htm b/modules/backend/formwidgets/datagrid/partials/_toolbar.htm deleted file mode 100644 index ffa217aff..000000000 --- a/modules/backend/formwidgets/datagrid/partials/_toolbar.htm +++ /dev/null @@ -1,6 +0,0 @@ -
- Insert Row - Delete Row - - -
\ No newline at end of file diff --git a/modules/backend/widgets/Grid.php b/modules/backend/widgets/Grid.php new file mode 100644 index 000000000..8105149fd --- /dev/null +++ b/modules/backend/widgets/Grid.php @@ -0,0 +1,226 @@ +columns = $this->getConfig('columns', []); + $this->showHeader = $this->getConfig('showHeader', $this->showHeader); + $this->allowInsert = $this->getConfig('allowInsert', $this->allowInsert); + $this->allowRemove = $this->getConfig('allowRemove', $this->allowRemove); + $this->disableToolbar = $this->getConfig('disableToolbar', $this->disableToolbar); + $this->dataLocker = $this->getConfig('dataLocker', $this->dataLocker); + $this->dataSource = $this->getConfig('dataSource', $this->dataSource); + } + + /** + * Renders the widget. + */ + public function render() + { + $this->prepareVars(); + return $this->makePartial('grid'); + } + + /** + * Prepares the view data + */ + public function prepareVars() + { + $this->vars['columnHeaders'] = $this->getColumnHeaders(); + $this->vars['columnDefinitions'] = $this->getColumnDefinitions(); + $this->vars['columnWidths'] = $this->getColumnWidths(); + $this->vars['toolbarWidget'] = $this->makeToolbarWidget(); + + $this->vars['showHeader'] = $this->showHeader; + $this->vars['allowInsert'] = $this->allowInsert; + $this->vars['allowRemove'] = $this->allowRemove; + $this->vars['disableToolbar'] = $this->disableToolbar; + $this->vars['dataLocker'] = $this->dataLocker; + } + + protected function makeToolbarWidget() + { + if ($this->disableToolbar) + return; + + $toolbarConfig = $this->makeConfig([ + 'alias' => $this->alias . 'Toolbar', + 'buttons' => $this->getViewPath('_toolbar.htm'), + ]); + + $toolbarWidget = $this->makeWidget('Backend\Widgets\Toolbar', $toolbarConfig); + $toolbarWidget->vars['allowInsert'] = $this->allowInsert; + $toolbarWidget->vars['allowRemove'] = $this->allowRemove; + return $toolbarWidget; + } + + // + // AJAX + // + + public function onAutocomplete() + { + $field = post('autocomplete_field'); + $value = post('autocomplete_value'); + $data = post('autocomplete_data', []); + $result = $this->fireEvent('grid.autocomplete', [$field, $value, $data], true); + return ['result' => $result]; + } + + public function onDataSource() + { + if ($this->dataLocker) + return; + + $result = $this->dataSource; + return ['result' => $result]; + } + + // + // Getters + // + + protected function getColumnHeaders() + { + if (!$this->showHeader) + return false; + + $headers = []; + foreach ($this->columns as $key => $column) { + $headers[] = isset($column['title']) ? $column['title'] : '???'; + } + return $headers; + } + + protected function getColumnWidths() + { + $widths = []; + foreach ($this->columns as $key => $column) { + $widths[] = isset($column['width']) ? $column['width'] : '0'; + } + return $widths; + } + + protected function getColumnDefinitions() + { + $definitions = []; + foreach ($this->columns as $key => $column) { + $item = []; + $item['data'] = $key; + + if (isset($column['readOnly'])) + $item['readOnly'] = $column['readOnly']; + + $item = $this->evalColumnType($column, $item); + $definitions[] = $item; + } + return $definitions; + } + + protected function evalColumnType($column, $item) + { + if (!isset($column['type'])) + return $item; + + switch ($column['type']) { + case 'number': + $item['type'] = 'numeric'; + break; + + case 'currency': + $item['type'] = 'numeric'; + $item['format'] = '$0,0.00'; + break; + + case 'checkbox': + $item['type'] = 'checkbox'; + break; + + case 'autocomplete': + $item['type'] = 'autocomplete'; + if (isset($column['options'])) $item['source'] = $column['options']; + if (isset($column['strict'])) $item['strict'] = $column['strict']; + break; + } + + return $item; + } + + // + // Internals + // + + /** + * {@inheritDoc} + */ + public function loadAssets() + { + $this->addCss('vendor/handsontable/jquery.handsontable.css', 'core'); + $this->addCss('css/datagrid.css', 'core'); + $this->addJs('vendor/handsontable/jquery.handsontable.js', 'core'); + $this->addJs('js/datagrid.js', 'core'); + } + +} \ No newline at end of file diff --git a/modules/backend/widgets/Toolbar.php b/modules/backend/widgets/Toolbar.php index 57f75a6fe..e2abfb0b2 100644 --- a/modules/backend/widgets/Toolbar.php +++ b/modules/backend/widgets/Toolbar.php @@ -83,6 +83,6 @@ class Toolbar extends WidgetBase if (!isset($this->config->buttons)) return false; - return $this->controller->makePartial($this->config->buttons); + return $this->controller->makePartial($this->config->buttons, $this->vars); } } \ No newline at end of file diff --git a/modules/backend/formwidgets/datagrid/assets/css/datagrid.css b/modules/backend/widgets/grid/assets/css/datagrid.css similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/css/datagrid.css rename to modules/backend/widgets/grid/assets/css/datagrid.css diff --git a/modules/backend/formwidgets/datagrid/assets/js/datagrid.js b/modules/backend/widgets/grid/assets/js/datagrid.js similarity index 96% rename from modules/backend/formwidgets/datagrid/assets/js/datagrid.js rename to modules/backend/widgets/grid/assets/js/datagrid.js index 83dfd2971..b625d5629 100644 --- a/modules/backend/formwidgets/datagrid/assets/js/datagrid.js +++ b/modules/backend/widgets/grid/assets/js/datagrid.js @@ -37,12 +37,12 @@ startRows: this.options.startRows, minRows: this.options.minRows, currentRowClassName: 'currentRow', - // rowHeaders: true, + // rowHeaders: false, // manualColumnMove: true, // manualRowMove: true, fillHandle: false, multiSelect: false, - removeRowPlugin: true + removeRowPlugin: this.options.allowRemove } if (this.options.autoInsertRows) @@ -68,6 +68,13 @@ delete handsontableOptions.data } } + else if (this.options.sourceHandler) { + $.request(self.options.sourceHandler, { + success: function(data, textStatus, jqXHR){ + self.gridInstance.loadData(data.result) + } + }) + } this.$el.handsontable(handsontableOptions) this.gridInstance = this.$el.handsontable('getInstance') @@ -138,6 +145,8 @@ columnWidths: null, columns: null, autocompleteHandler: null, + sourceHandler: null, + allowRemove: true, confirmMessage: 'Are you sure?' } diff --git a/modules/backend/formwidgets/datagrid/assets/less/datagrid.less b/modules/backend/widgets/grid/assets/less/datagrid.less similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/less/datagrid.less rename to modules/backend/widgets/grid/assets/less/datagrid.less diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnautosize.js b/modules/backend/widgets/grid/assets/vendor/handsontable/columnautosize.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnautosize.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/columnautosize.js diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnmove.js b/modules/backend/widgets/grid/assets/vendor/handsontable/columnmove.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnmove.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/columnmove.js diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnresize.js b/modules/backend/widgets/grid/assets/vendor/handsontable/columnresize.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnresize.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/columnresize.js diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnsorting.js b/modules/backend/widgets/grid/assets/vendor/handsontable/columnsorting.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/columnsorting.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/columnsorting.js diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/jquery.handsontable.css b/modules/backend/widgets/grid/assets/vendor/handsontable/jquery.handsontable.css similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/jquery.handsontable.css rename to modules/backend/widgets/grid/assets/vendor/handsontable/jquery.handsontable.css diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/jquery.handsontable.js b/modules/backend/widgets/grid/assets/vendor/handsontable/jquery.handsontable.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/jquery.handsontable.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/jquery.handsontable.js diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/jquery.handsontable.less b/modules/backend/widgets/grid/assets/vendor/handsontable/jquery.handsontable.less similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/jquery.handsontable.less rename to modules/backend/widgets/grid/assets/vendor/handsontable/jquery.handsontable.less diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/removebutton.js b/modules/backend/widgets/grid/assets/vendor/handsontable/removebutton.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/removebutton.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/removebutton.js diff --git a/modules/backend/formwidgets/datagrid/assets/vendor/handsontable/rowmove.js b/modules/backend/widgets/grid/assets/vendor/handsontable/rowmove.js similarity index 100% rename from modules/backend/formwidgets/datagrid/assets/vendor/handsontable/rowmove.js rename to modules/backend/widgets/grid/assets/vendor/handsontable/rowmove.js diff --git a/modules/backend/widgets/grid/partials/_grid.htm b/modules/backend/widgets/grid/partials/_grid.htm new file mode 100644 index 000000000..149c01f65 --- /dev/null +++ b/modules/backend/widgets/grid/partials/_grid.htm @@ -0,0 +1,23 @@ +
+ + render() ?> + + +
data-data-locker="" + data-autocomplete-handler="getEventHandler('onAutocomplete') ?>" + data-source-handler="getEventHandler('onDataSource') ?>" + >
+ +
+ diff --git a/modules/backend/widgets/grid/partials/_toolbar.htm b/modules/backend/widgets/grid/partials/_toolbar.htm new file mode 100644 index 000000000..88a64a12e --- /dev/null +++ b/modules/backend/widgets/grid/partials/_toolbar.htm @@ -0,0 +1,20 @@ +
+ + + Insert Row + + + + + Delete Row + + + + +
\ No newline at end of file