diff --git a/.docs/actions.md b/.docs/actions.md index bfe8e3453..241bc17f0 100644 --- a/.docs/actions.md +++ b/.docs/actions.md @@ -1,24 +1,24 @@ Table of contents - [Actions](#actions) - - [Api](#api) - - [Parameters](#parameters) - - [Icon](#icon) - - [Class](#class) - - [Title](#title) - - [Confirmation](#confirmation) - - [Ajax](#ajax) - - [Redrawing the data](#redrawing-the-data) - - [Redrawing one row](#redrawing-one-row) - - [Sortable](#sortable) - - [Sorting handler](#sorting-handler) - - [MultiAction](#multiaction) - - [Item detail](#item-detail) - - [Item detail form](#item-detail-form) - - [Item detail template variables](#item-detail-template-variables) - - [Item detail render condition](#item-detail-render-condition) - - [ActionCallback](#actioncallback) - - [Toolbar button](#toolbar-button) + - [Api](#api) + - [Parameters](#parameters) + - [Icon](#icon) + - [Class](#class) + - [Title](#title) + - [Confirmation](#confirmation) + - [Ajax](#ajax) + - [Redrawing the data](#redrawing-the-data) + - [Redrawing one row](#redrawing-one-row) + - [Sortable](#sortable) + - [Sorting handler](#sorting-handler) + - [MultiAction](#multiaction) + - [Item detail](#item-detail) + - [Item detail form](#item-detail-form) + - [Item detail template variables](#item-detail-template-variables) + - [Item detail render condition](#item-detail-render-condition) + - [ActionCallback](#actioncallback) + - [Toolbar button](#toolbar-button) # Actions @@ -105,7 +105,7 @@ All links are by default not-ajax. Do you see the bold `ajax` class in previous ```php public function handleDelete($id) { - $this->connection->delete('ublaboo_example') + $this->connection->delete('example') ->where('id = ?', $id) ->execute(); @@ -127,7 +127,7 @@ When you are updating row data (i.e. status), you can send only one row as snipp ```php public function handleSetStatus($id, $status) { - $this->connection->update('ublaboo_example', ['status' => $satatus]) + $this->connection->update('example', ['status' => $satatus]) ->where('id = ?', $id) ->execute(); @@ -242,7 +242,7 @@ The name of the handler used for sorting can be changed: $grid->setSortableHandler('foo!'); ``` -Also when you are using datagrid in component, you have to alter the name a bit: +Also, when you are using datagrid in component, you have to alter the name a bit: ```php $grid->setSortableHandler('myComponent:sort!'); @@ -250,7 +250,7 @@ $grid->setSortableHandler('myComponent:sort!'); ## MultiAction -Same as there is column status with pretty dropdown menu, ublaboo datagrid comes with similar dropdown menu for actions. It is called MultiAction: +Same as there is column status with pretty dropdown menu, the datagrid comes with similar dropdown menu for actions. It is called MultiAction: ```php /** @@ -261,7 +261,7 @@ $grid->addMultiAction('multi_action', 'MultiAction') ->addAction('blah2', 'Blahblah2', 'blah!', ['name']); ``` -Sure you can alter multiaction class, icons, etc. Same you can change icon, class, etc of nested actions: +Sure you can alter multiaction class, icons, etc. Same you can change icon, class, etc. of nested actions: ```php $grid->getAction('multi_blah') @@ -312,7 +312,7 @@ $grid->setItemsDetailForm(function(Nette\Forms\Container $container) use ($grid, }); ``` -DataGrid user template: +Datagrid user template: ```latte {extends $originalTemplate} @@ -361,7 +361,7 @@ $grid->addActionCallback('custom_callback', '') }; ``` -You treat `ActionCallback` same as `Action`, except for some arguments passed to the `DataGrid::addActionCallback` method. +You treat `ActionCallback` same as `Action`, except for some arguments passed to the `Datagrid::addActionCallback` method. ## Toolbar button diff --git a/.docs/assets.md b/.docs/assets.md index 541d991db..d51a304a7 100644 --- a/.docs/assets.md +++ b/.docs/assets.md @@ -6,116 +6,103 @@ Table of contents # Assets -DataGrid needs for its precise functionality some third party scripts and styles. Install all required assets with NPM. +There are prepare JS/TS and CSS files for precise functionality. The best way is to use some frontend bundler, for example [Vite](https://vitejs.dev). -**CSS (external)** +## Installation -- bootstrap -- bootstrap datepicker -- bootstrap select - -**CSS** - -- datagrid.css -- datagrid-spinners.css - -**JS (external)** - -- jquery -- nette forms -- nette ajax / naja -- bootstrap -- bootstrap datepicker -- bootstrap select - -**JS** - -- datagrid.js -- datagrid-instant-url-refresh.js -- datagrid-spinners.js - -**Icons** - -You will probably want to use some icon font, but that is in your command. -On this project website we use font awesome (you can change the icon prefix by setting new value to static property `DataGrid::$iconPrefix = 'fa fa-';`). - -**Spinners** - -As you can see, there is also a `datagrid-spinners.js` script in a datagrid repository. If you include this file within you project layout, there are some actions, that will show spinner/some other animation when waiting for ajax response. Actions, that has somehow animated spinner: - -- Group actions -- Pagination -- Changing items per page -- Toggling item detail - loading the detail for the first time - -## NPM - -``` -npm install --save ublaboo-datagrid -``` - -package.json: +You need to install datagrid's assets. For example this way. ```json { - "dependencies": { - "bootstrap-datepicker": "^1.9", - "bootstrap-select": "^1.13", - "bootstrap": "^4.4.1", - "happy-inputs": "^2.0", - "jquery": "^3.4.1", - "jquery-ui-sortable": "^1.0", - "nette-forms": "^3.0", - "nette.ajax.js": "^2.3", - "popper.js": "^1.14.7", - "ublaboo-datagrid": "^6.2" - } + "dependencies": { + "@contributte/datagrid": "git+ssh://git@github.com:contributte/datagrid.git#next" + } } ``` -## Example html when not using NPM - -```html - - -
- - - - - - - - - - +## - - +## Demo - - - - - - - - - - +**package.json** - - - - - +```json +{ + "dependencies": { + "@contributte/datagrid": "git+ssh://git@github.com:contributte/datagrid.git#next", + "@fortawesome/fontawesome-free": "^6.3.0", + "bootstrap": "^5.3.0-alpha3", + "naja": "^2.5.0", + "nette-forms": "^3.3.1", + "prismjs": "^1.29.0", + "sortablejs": "^1.15.0", + "tom-select": "^2.2.2", + "vanillajs-datepicker": "^1.3.1" + }, + "devDependencies": { + "@types/bootstrap-select": "^1.13.4", + "@types/jquery": "^3.5.16", + "@types/jqueryui": "^1.12.16", + "@types/sortablejs": "^1.15.1", + "@types/vanillajs-datepicker": "^1.2.1", + "autoprefixer": "^10.4.0", + "typescript": "^4.9.5", + "vite": "^2.6.10" + }, + "scripts": { + "watch": "vite build --watch --mode=development", + "build": "vite build --mode=production" + } +} +``` - - - - +**vite.config.js** + +```js +import { defineConfig } from 'vite'; +import { resolve } from 'path'; + +export default defineConfig(({ mode }) => { + const DEV = mode === 'development'; + + return { + publicDir: './assets/public', + resolve: { + alias: { + '@': resolve(__dirname, 'assets/js'), + '~': resolve(__dirname, 'node_modules'), + }, + }, + base: '/dist/', + server: { + open: false, + hmr: false, + }, + css: { + postcss: [ + "autoprefixer" + ] + }, + build: { + manifest: true, + assetsDir: '', + outDir: './www/dist/', + emptyOutDir: true, + minify: DEV ? false : 'esbuild', + rollupOptions: { + output: { + manualChunks: undefined, + chunkFileNames: '[name].js', + entryFileNames: '[name].js', + assetFileNames: '[name].[ext]', + }, + input: { + app: './assets/js/main.js' + } + } + }, + } +}); ``` diff --git a/.docs/columns.md b/.docs/columns.md index cd4f9f6e2..fe40b157d 100644 --- a/.docs/columns.md +++ b/.docs/columns.md @@ -1,35 +1,35 @@ Table of contents - [Columns](#columns) - - [Api](#api) - - [Parameters](#parameters) - - [Templates](#templates) - - [Renderers](#renderers) - - [Replacement](#replacement) - - [Escaping values](#escaping-values) - - [Sorting](#sorting) - - [Resetting pagination after sorting](#resetting-pagination-after-sorting) - - [Default sort](#default-sort) - - [Resetting default sort](#resetting-default-sort) - - [Multiple columns sort](#multiple-columns-sort) - - [Default per page](#default-per-page) - - [Custom sorting Callback](#custom-sorting-callback) - - [Align](#align) - - [Removing column](#removing-column) - - [Column Text](#column-text) - - [Column Number](#column-number) - - [Column DateTime](#column-datetime) - - [Column Link](#column-link) - - [Open in new tab](#open-in-new-tab) - - [Column Status](#column-status) - - [Hideable columns](#hideable-columns) - - [Default hide](#default-hide) - - [Columns Summary](#columns-summary) - - [Aggregation Function](#aggregation-function) - - [Single column](#single-column) - - [Multiple columns](#multiple-columns) - - [Column \(th>, td>\) attributes](#column-th-td-attributes) - - [Column callback](#column-callback) + - [Api](#api) + - [Parameters](#parameters) + - [Templates](#templates) + - [Renderers](#renderers) + - [Replacement](#replacement) + - [Escaping values](#escaping-values) + - [Sorting](#sorting) + - [Resetting pagination after sorting](#resetting-pagination-after-sorting) + - [Default sort](#default-sort) + - [Resetting default sort](#resetting-default-sort) + - [Multiple columns sort](#multiple-columns-sort) + - [Default per page](#default-per-page) + - [Custom sorting Callback](#custom-sorting-callback) + - [Align](#align) + - [Removing column](#removing-column) + - [Column Text](#column-text) + - [Column Number](#column-number) + - [Column DateTime](#column-datetime) + - [Column Link](#column-link) + - [Open in new tab](#open-in-new-tab) + - [Column Status](#column-status) + - [Hideable columns](#hideable-columns) + - [Default hide](#default-hide) + - [Columns Summary](#columns-summary) + - [Aggregation Function](#aggregation-function) + - [Single column](#single-column) + - [Multiple columns](#multiple-columns) + - [Column \(th>, td>\) attributes](#column-th-td-attributes) + - [Column callback](#column-callback) # Columns @@ -39,7 +39,7 @@ There are several column classes and they all have some common behaviour and pro ### Parameters -Lets add a simple text column like we've done before: +Let's add a simple text column like we've done before: ```php $grid->addColumnText('name', 'Name'); @@ -55,7 +55,7 @@ $grid->addColumnText('name3', 'Name', 'name'); ### Templates -Column may have it's own template. I will add one more parameter (optional) to the method `::setTemplate()`, just for fun: +Columns may have it's own template. I will add one more parameter (optional) to the method `::setTemplate()`, just for fun: ```php $grid->addColumnText('name', 'Name') @@ -76,7 +76,7 @@ $grid->addColumnText('name', 'Name') }); ``` -But hey, what if i want to replace **just some** rows? No problem, the second optional argument tells me (callback again) whether the datagrid should use your renderer or not. Example: +But hey, what if I want to replace **just some** rows? No problem, the second optional argument tells me (callback again) whether the datagrid should use your renderer or not. Example: ```php $grid->addColumnText('name', 'Name') @@ -117,7 +117,7 @@ $grid->addColumnText('name', 'Name') ->setSortable(); ``` -When using doctrine as data source, you can output data the object way using dot-notaion and property accessor. But when you are using collumn of related table for sorting, you probably want to use alias for sorting: +When using doctrine as data source, you can output data the object way using dot-notation and property accessor. But when you are using column of related table for sorting, you probably want to use alias for sorting: ```php $grid->addColumnText('role', 'User role', 'role.name') @@ -134,7 +134,7 @@ $grid->addColumnText('name', 'Name') ### Default sort -`DataGrid` implements default sorting mechanism: +`Datagrid` implements default sorting mechanism: ```php $grid->setDefaultSort(['name' => 'DESC']); @@ -142,7 +142,7 @@ $grid->setDefaultSort(['name' => 'DESC']); ### Resetting default sort -By default, once you reset the filter, default sort is applied. If you don't want to apply it after resetting the filter, pass FALSE as a second parameter to `DataGrid::setDefaultSort()`: +By default, once you reset the filter, default sort is applied. If you don't want to apply it after resetting the filter, pass FALSE as a second parameter to `Datagrid::setDefaultSort()`: ```php $grid->setDefaultSort(['id' => 'DESC'], FALSE); @@ -150,7 +150,7 @@ $grid->setDefaultSort(['id' => 'DESC'], FALSE); ### Multiple columns sort -Sorting by multiple columns is disabled by default. But can be enaled: +Sorting by multiple columns is disabled by default. But can be enabled: ```php $grid->setMultiSortEnabled($enabled = TRUE); // Pass FALSE to disable @@ -266,7 +266,7 @@ $grid->addColumnLink('name', 'Name', 'edit') ![Status 1](https://github.com/contributte/datagrid/blob/master/.docs/assets/status1.gif?raw=true) ![Status 1](https://github.com/contributte/datagrid/blob/master/.docs/assets/status2.gif?raw=true) -Once your item keep some "status" flag, it is appropriate to show user the status in highlighted form. Also there could be a dropdown with available statuses: +Once your item keep some "status" flag, it is appropriate to show user the status in highlighted form. Also, there could be a dropdown with available statuses: ```php $grid->addColumnStatus('status', 'Status') @@ -347,7 +347,7 @@ $grid->getColumn('status')->getOption(2) ![Columns Hiding](https://github.com/contributte/datagrid/blob/master/.docs/assets/hideable_columns.gif?raw=true) -In example datargid above, you can hide columns and then reveal them again. This feature is disabled by default. You can enable it like this: +In example datagrid above, you can hide columns and then reveal them again. This feature is disabled by default. You can enable it like this: ```php $grid->setColumnsHideable(); @@ -370,7 +370,7 @@ If default hide is used, new button is shown in that settings (gear) dropdown - ## Columns Summary -Datagrid implements a feature that allows you to display **sum** of column of displayed items at the bootom of the grid. Try it out: +Datagrid implements a feature that allows you to display **sum** of column of displayed items at the bottom of the grid. Try it out: ```php $grid->addColumnNumber('in', 'Income') @@ -422,11 +422,11 @@ $grid->addAggregationFunction('status', new FunctionSum('id')); This will render a sum of ids under the `"status"` column. -As mentioned above, there is one aggregation function prepared: `Ublaboo\DataGrid\AggregationFunction\FunctionSum`. You can implement whatever function you like, it just have to implement `Ublaboo\DataGrid\AggregationFunction\ISingleColumnAggregationFunction`. +As mentioned above, there is one aggregation function prepared: `Contributte\Datagrid\AggregationFunction\FunctionSum`. You can implement whatever function you like, it just have to implement `Contributte\Datagrid\AggregationFunction\ISingleColumnAggregationFunction`. ### Multiple columns -In case you want to make the aggreagation directly using SQL by your domain, you will probably use interface `IMultipleAggregationFunction` (instead of `ISingleColumnAggregationFunction`): +In case you want to make the aggregation directly using SQL by your domain, you will probably use interface `IMultipleAggregationFunction` (instead of `ISingleColumnAggregationFunction`): ```php $grid->setMultipleAggregationFunction( @@ -476,7 +476,7 @@ $grid->setMultipleAggregationFunction( ); ``` -This aggregatin is used along with `Dibi` in the demo. +This aggregating is used along with `Dibi` in the demo. ## Column (th>, td>) attributes @@ -499,7 +499,7 @@ $grid->addColumnText('name', 'Name') ## Column callback -When you need to modify columns just before rendering (meybe remove some status options or completely change renderer for partucular items), you can create column callback, that will be called with `$column` and `$item` in parameter: +When you need to modify columns just before rendering (maybe remove some status options or completely change renderer for particular items), you can create column callback, that will be called with `$column` and `$item` in parameter: ```php $grid->addColumnLink('link', 'Link', 'this#demo', 'name', ['id', 'surname' => 'name']); @@ -531,7 +531,7 @@ $grid->addColumnCallback('link', function($column, $item) { }); ``` -That is the code of the demove shown above. As you can see, item with id == 1 does have a empty link column and only 2 options in `ColumnStatus`. +That is the code of the demo shown above. As you can see, item with id == 1 does have an empty link column and only 2 options in `ColumnStatus`. ```php diff --git a/.docs/data-source.md b/.docs/data-source.md index 63fd00fcf..7887299b1 100644 --- a/.docs/data-source.md +++ b/.docs/data-source.md @@ -1,10 +1,10 @@ Table of contents - [Data sources](#data-sources) - - [ORM Relations](#orm-relations) - - [ApiDataSource](#apidatasource) - - [NextrasDataSource](#nextrasdatasource) - - [NetteDatabaseTableDataSource](#nettedatabasetabledatasource) + - [ORM Relations](#orm-relations) + - [ApiDataSource](#apidatasource) + - [NextrasDataSource](#nextrasdatasource) + - [NetteDatabaseTableDataSource](#nettedatabasetabledatasource) # Data sources @@ -44,7 +44,7 @@ Once you have set a data source, you can add columns to the datagrid. ## ORM Relations -When you are using for example Doctrine as a data source, you can easily access another related entites for rendering in column. Let's say you have an entity `User` and each instance can have a property `$name` and `$grandma`. `$grandma` is also an instance of `User` class. Displaying people and their grandmas is very simple then - just use this dot notation: +When you are using for example Doctrine as a data source, you can easily access another related entities for rendering in column. Let's say you have an entity `User` and each instance can have a property `$name` and `$grandma`. `$grandma` is also an instance of `User` class. Displaying people and their grandmas is very simple then - just use this dot notation: ```php $grid->addColumnText('name', 'Name', 'name'); @@ -59,7 +59,7 @@ Basic usage: ```php $grid->setDataSource( - new Ublaboo\DataGrid\DataSource\ApiDataSource('http://my.remote.api') + new Contributte\Datagrid\DataSource\ApiDataSource('http://my.remote.api') ); ``` @@ -67,7 +67,7 @@ The idea is simply to forward filtering/sorting/limit/... to remote api. Feel fr ## NextrasDataSource -There is one specific behaviour when using Netras ORM. When custom filter conditions are used, user has to work not with given `Collection` instance, but with `Collection::getQueryBuilder()`. That snippet of code will not work correctly, because `DbalCollection` calls clone on each of it's methods: +There is one specific behaviour when using Nextras ORM. When custom filter conditions are used, user has to work not with given `Collection` instance, but with `Collection::getQueryBuilder()`. That snippet of code will not work correctly, because `DbalCollection` calls clone on each of it's methods: ```php $grid->getFilter('name') diff --git a/.docs/export.md b/.docs/export.md index 4de88b390..ccdc97226 100644 --- a/.docs/export.md +++ b/.docs/export.md @@ -1,17 +1,17 @@ Table of contents - [Exports](#exports) - - [ExportCallback](#exportcallback) - - [CSV export](#csv-export) - - [\(Not\) Using templates in CSV export](#not-using-templates-in-csv-export) - - [Export columns](#export-columns) - - [Export encoding, delimiter](#export-encoding-delimiter) + - [ExportCallback](#exportcallback) + - [CSV export](#csv-export) + - [\(Not\) Using templates in CSV export](#not-using-templates-in-csv-export) + - [Export columns](#export-columns) + - [Export encoding, delimiter](#export-encoding-delimiter) # Exports ## ExportCallback -DataGrid allows you to export the data via `$grid->addExportCallback()`. The parameters are: +Datagrid allows you to export the data via `$grid->addExportCallback()`. The parameters are: ```php /** @@ -38,15 +38,15 @@ $grid->addExportCsv('Csv export (filtered)', 'examples.csv') ### (Not) Using templates in CSV export -ExportCsv ignores column template, because i don't like the idea Latte (tempalting engine for HTML) exporting data for CSV format. Using custom renderer sounds better to me in that case. +ExportCsv ignores column template, because i don't like the idea Latte (templating engine for HTML) exporting data for CSV format. Using custom renderer sounds better to me in that case. ## Export columns -When you exporting the data, you can have different columns in export and in the datagrid. Or differently rendered. So there is another method `Ublaboo\DataGrid\Export\Export::setColumns()`. You can create instances of another columns and pass them in array to this method. These will be rendered in export: +When you're exporting the data, you can have different columns in export and in the datagrid. Or differently rendered. So there is another method `Contributte\Datagrid\Export\Export::setColumns()`. You can create instances of another columns and pass them in array to this method. These will be rendered in export: ```php -$column_name = new Ublaboo\DataGrid\Column\ColumnText($grid, 'name', 'name', 'Name'); -$column_even = (new Ublaboo\DataGrid\Column\ColumnText($grid, 'name', 'even', 'Even ID (yes/no)')) +$column_name = new Contributte\Datagrid\Column\ColumnText($grid, 'name', 'name', 'Name'); +$column_even = (new Contributte\Datagrid\Column\ColumnText($grid, 'name', 'even', 'Even ID (yes/no)')) ->setRenderer(function(array $item): string { return $item['id'] % 2 ? 'No' : 'Yes'; }); @@ -61,7 +61,7 @@ $grid->addExportCsv('Csv export', 'examples_all.csv') ## Export encoding, delimiter -By default, DataGrid exports data in `utf-8` with semicolon delimiter `;`. This can be changed: +By default, Datagrid exports data in `utf-8` with semicolon delimiter `;`. This can be changed: ```php /** diff --git a/.docs/filters.md b/.docs/filters.md index 5cb530f43..c14061ffb 100644 --- a/.docs/filters.md +++ b/.docs/filters.md @@ -1,27 +1,27 @@ Table of contents - [Filters](#filters) - - [Api](#api) - - [Placeholder](#placeholder) - - [Custom where condition](#custom-where-condition) - - [Templates:](#templates) - - [Filter blocks](#filter-blocks) - - [Filter type blocks](#filter-type-blocks) - - [Removing filter](#removing-filter) - - [FilterText](#filtertext) - - [FilterSelect](#filterselect) - - [FilterMultiSelect](#filtermultiselect) - - [FilterDate](#filterdate) - - [FilterRange](#filterrange) - - [FilterDateRange](#filterdaterange) - - [Default filter values](#default-filter-values) - - [Resetting filter to default values](#resetting-filter-to-default-values) - - [Filters rendering](#filters-rendering) - - [Outer filters rendering](#outer-filters-rendering) - - [Session - remeber state](#session---remeber-state) - - [Session - filters / filter values changed](#session---filters--filter-values-changed) - - [URL refreshing - history API](#url-refreshing---history-api) - - [Auto submit](#auto-submit) + - [Api](#api) + - [Placeholder](#placeholder) + - [Custom where condition](#custom-where-condition) + - [Templates:](#templates) + - [Filter blocks](#filter-blocks) + - [Filter type blocks](#filter-type-blocks) + - [Removing filter](#removing-filter) + - [FilterText](#filtertext) + - [FilterSelect](#filterselect) + - [FilterMultiSelect](#filtermultiselect) + - [FilterDate](#filterdate) + - [FilterRange](#filterrange) + - [FilterDateRange](#filterdaterange) + - [Default filter values](#default-filter-values) + - [Resetting filter to default values](#resetting-filter-to-default-values) + - [Filters rendering](#filters-rendering) + - [Outer filters rendering](#outer-filters-rendering) + - [Session - remeber state](#session---remeber-state) + - [Session - filters / filter values changed](#session---filters--filter-values-changed) + - [URL refreshing - history API](#url-refreshing---history-api) + - [Auto submit](#auto-submit) # Filters @@ -111,7 +111,7 @@ There is how the default FilterText template looks like:, EventDetail & NajaPayload;
+ response: AjaxResponse & Response;
+}
+
+export interface ErrorEventDetail<
+ E extends Error = Error,
+> extends BaseErrorEventDetail {
+ return await this.client.makeRequest(args.method, args.url, args.data) as P;
+ }
+
+ async submitForm {
+ return await this.client.uiHandler.submitForm(element) as P;
+ }
+
+ dispatch<
+ K extends string, M extends BaseAjaxEventMap = AjaxEventMap
+ >(type: K, detail: K extends keyof M ? EventDetail
', '\n');
- if (cell.attr('data-datagrid-editable-value')) {
- valueToEdit = String(cell.data('datagrid-editable-value'));
- } else {
- valueToEdit = cellValue;
- }
- cell.data('originalValue', cellValue);
- cell.data('valueToEdit', valueToEdit);
- if (cell.data('datagrid-editable-type') === 'textarea') {
- input = $('');
- cell_padding = parseInt(cell.css('padding').replace(/[^-\d\.]/g, ''), 10);
- cell_height = cell.outerHeight();
- line_height = Math.round(parseFloat(cell.css('line-height')));
- cell_lines = (cell_height - (2 * cell_padding)) / line_height;
- input.attr('rows', Math.round(cell_lines));
- } else if (cell.data('datagrid-editable-type') === 'select') {
- input = $(cell.data('datagrid-editable-element'));
- input.find("option[value='" + valueToEdit + "']").prop('selected', true);
- } else {
- input = $('');
- input.val(valueToEdit);
- }
- attrs = cell.data('datagrid-editable-attrs');
- for (attr_name in attrs) {
- attr_value = attrs[attr_name];
- input.attr(attr_name, attr_value);
- }
- cell.removeClass('edited');
- cell.html(input);
- submit = function(cell, el) {
- var value;
- value = el.val();
- if (value !== cell.data('valueToEdit')) {
- dataGridRegisterAjaxCall({
- url: cell.data('datagrid-editable-url'),
- data: {
- value: value
- },
- type: 'POST',
- success: function(payload) {
- if (cell.data('datagrid-editable-type') === 'select') {
- cell.html(input.find("option[value='" + value + "']").html());
- } else {
- if (payload._datagrid_editable_new_value) {
- value = payload._datagrid_editable_new_value;
- }
- cell.html(value);
- }
- return cell.addClass('edited');
- },
- error: function() {
- cell.html(cell.data('originalValue'));
- return cell.addClass('edited-error');
- }
- });
- } else {
- cell.html(cell.data('originalValue'));
- }
- return setTimeout(function() {
- return cell.removeClass('editing');
- }, 1200);
- };
- cell.find('input,textarea,select').focus().on('blur', function() {
- return submit(cell, $(this));
- }).on('keydown', function(e) {
- if (cell.data('datagrid-editable-type') !== 'textarea') {
- if (e.which === 13) {
- e.stopPropagation();
- e.preventDefault();
- return submit(cell, $(this));
- }
- }
- if (e.which === 27) {
- e.stopPropagation();
- e.preventDefault();
- cell.removeClass('editing');
- return cell.html(cell.data('originalValue'));
- }
- });
- return cell.find('select').on('change', function() {
- return submit(cell, $(this));
- });
- }
-});
-
-dataGridRegisterExtension('datagrid.after_inline_edit', {
- success: function(payload) {
- var grid = $('.datagrid-' + payload._datagrid_name);
-
- if (payload._datagrid_inline_edited) {
- grid.find('tr[data-id="' + payload._datagrid_inline_edited + '"] > td').addClass('edited');
- return grid.find('.datagrid-inline-edit-trigger').removeClass('hidden');
- } else if (payload._datagrid_inline_edit_cancel) {
- return grid.find('.datagrid-inline-edit-trigger').removeClass('hidden');
- }
- }
-});
-
-$(document).on('mouseup', '[data-datagrid-cancel-inline-add]', function(e) {
- var code = e.which || e.keyCode || 0;
- if (code === 1) {
- e.stopPropagation();
- e.preventDefault();
- return $('.datagrid-row-inline-add').addClass('datagrid-row-inline-add-hidden');
- }
-});
-
-dataGridRegisterExtension('datagrid-toggle-inline-add', {
- success: function(payload) {
- var grid = $('.datagrid-' + payload._datagrid_name);
-
- if (payload._datagrid_inline_adding) {
- var row = grid.find('.datagrid-row-inline-add');
-
- if (row.hasClass('datagrid-row-inline-add-hidden')) {
- row.removeClass('datagrid-row-inline-add-hidden');
- }
-
- row.find('input:not([readonly]),textarea:not([readonly])').first().focus();
- }
- }
-});
-
-datagridFitlerMultiSelect = function() {
- var select = $('.selectpicker').first();
-
- if ($.fn.selectpicker) {
- return $.fn.selectpicker.defaults = {
- countSelectedText: select.data('i18n-selected'),
- iconBase: '',
- tickIcon: select.data('selected-icon-check')
- };
- }
-};
-
-$(function() {
- return datagridFitlerMultiSelect();
-});
-
-datagridGroupActionMultiSelect = function() {
- var selects;
-
- if (!$.fn.selectpicker) {
- return;
- }
-
- selects = $('[data-datagrid-multiselect-id]');
-
- return selects.each(function() {
- var id;
- if ($(this).hasClass('selectpicker')) {
- $(this).removeAttr('id');
- id = $(this).data('datagrid-multiselect-id');
- $(this).on('loaded.bs.select', function(e) {
- $(this).parent().attr('style', 'display:none;');
- return $(this).parent().find('.hidden').removeClass('hidden').addClass('btn-default btn-secondary');
- });
- return $(this).on('rendered.bs.select', function(e) {
- return $(this).parent().attr('id', id);
- });
- }
- });
-};
-
-$(function() {
- return datagridGroupActionMultiSelect();
-});
-
-dataGridRegisterExtension('datagrid.fitlerMultiSelect', {
- success: function() {
- datagridFitlerMultiSelect();
- if ($.fn.selectpicker) {
- return $('.selectpicker').selectpicker({
- iconBase: 'fa'
- });
- }
- }
-});
-
-dataGridRegisterExtension('datagrid.groupActionMultiSelect', {
- success: function() {
- return datagridGroupActionMultiSelect();
- }
-});
-
-dataGridRegisterExtension('datagrid.inline-editing', {
- success: function(payload) {
- var grid;
- if (payload._datagrid_inline_editing) {
- grid = $('.datagrid-' + payload._datagrid_name);
- return grid.find('.datagrid-inline-edit-trigger').addClass('hidden');
- }
- }
-});
-
-dataGridRegisterExtension('datagrid.redraw-item', {
- success: function(payload) {
- var row;
- if (payload._datagrid_redraw_item_class) {
- row = $('tr[data-id="' + payload._datagrid_redraw_item_id + '"]');
- return row.attr('class', payload._datagrid_redraw_item_class);
- }
- }
-});
-
-dataGridRegisterExtension('datagrid.reset-filter-by-column', {
- success: function(payload) {
- var grid, href, i, key, len, ref;
- if (!payload._datagrid_name) {
- return;
- }
- grid = $('.datagrid-' + payload._datagrid_name);
- grid.find('[data-datagrid-reset-filter-by-column]').addClass('hidden');
- if (payload.non_empty_filters && payload.non_empty_filters.length) {
- ref = payload.non_empty_filters;
- for (i = 0, len = ref.length; i < len; i++) {
- key = ref[i];
- grid.find('[data-datagrid-reset-filter-by-column="' + key + '"]').removeClass('hidden');
- }
- href = grid.find('.reset-filter').attr('href');
- return grid.find('[data-datagrid-reset-filter-by-column]').each(function() {
- var new_href;
- key = $(this).attr('data-datagrid-reset-filter-by-column');
- new_href = href.replace('do=' + payload._datagrid_name + '-resetFilter', 'do=' + payload._datagrid_name + '-resetColumnFilter');
- new_href += '&' + payload._datagrid_name + '-key=' + key;
- return $(this).attr('href', new_href);
- });
- }
- }
-});
diff --git a/assets/datagrid.ts b/assets/datagrid.ts
new file mode 100644
index 000000000..de36fcaa0
--- /dev/null
+++ b/assets/datagrid.ts
@@ -0,0 +1,145 @@
+import { defaultDatagridNameResolver, isEnter } from "./utils";
+import type { Ajax, DatagridEventMap, DatagridOptions, EventDetail, EventListener, } from "./types";
+
+export class Datagrid extends EventTarget {
+ private static readonly defaultOptions: DatagridOptions = {
+ confirm: confirm,
+ resolveDatagridName: defaultDatagridNameResolver,
+ plugins: [],
+ };
+
+ public readonly name: string;
+
+ public readonly ajax: Ajax;
+
+ private readonly options: DatagridOptions;
+
+ constructor(
+ public readonly el: HTMLElement,
+ ajax: Ajax | ((grid: Datagrid) => Ajax),
+ options: Partial