GithubHelp home page GithubHelp logo

frappe / datatable Goto Github PK

View Code? Open in Web Editor NEW
970.0 44.0 150.0 3.2 MB

The Missing Javascript Datatable for the Web

Home Page: https://frappe.io/datatable

License: MIT License

HTML 8.16% JavaScript 87.81% CSS 4.02%
datatable datatables-library modern interactive simple table grid datagrid editable-grid editable-table

datatable's Introduction

Frappe DataTable

A modern datatable library for the web

Test and Release npm version MIT License npm bundle size (minified + gzip) semantic-release

Introduction

Frappe DataTable is a simple, modern and interactive datatable library for displaying tabular data. Originally built for ERPNext, it can be used to render large amount of rows without sacrificing performance and has the basic data grid features like inline editing and keyboard navigation. It does not require jQuery, unlike most data grids out there.

Demo

datatable-demo-2

Features

Cell Features

  • Custom Formatters
  • Inline Editing
  • Mouse Selection
  • Copy Cells
  • Keyboard Navigation
  • Custom Cell Editor

Column Features

  • Reorder Columns
  • Sort by Column
  • Remove / Hide Column
  • Custom Actions
  • Resize Column
  • Flexible Layout

Row Features

  • Row Selection
  • Tree Structured Rows
  • Inline Filters
  • Large Number of Rows
  • Dynamic Row Height

Install

yarn add frappe-datatable
# or
npm install frappe-datatable

Note: sortablejs is required to be installed as well.

Usage

const datatable = new DataTable('#datatable', {
  columns: [ 'First Name', 'Last Name', 'Position' ],
  data: [
    [ 'Don', 'Joe', 'Designer' ],
    [ 'Mary', 'Jane', 'Software Developer' ]
  ]
});

Contribution

  • yarn start - Start dev server
  • Open index.html located in the root folder, and start development.
  • Run yarn lint before committing changes
  • This project uses commitizen for conventional commit messages, use yarn commit command instead of git commit

Read the blog

Making a new datatable for the web

License

MIT

datatable's People

Contributors

achillesrasquinha avatar ankush avatar cgpurbaugh avatar deepeshgarg007 avatar hrwx avatar juliojair avatar mergify[bot] avatar nagariahussain avatar netchampfaris avatar nextchamp-saqib avatar phot0n avatar prssanna avatar raghu-kamath avatar ritviksardana avatar rmehta avatar saifi0102 avatar shariquerik avatar surajshetty3416 avatar webmamba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

datatable's Issues

Cell width is not appropriate and also its not bound with the header

Please see the image below when the report loads at first the cell width is with respect to the header and even its having overflowing values there is no horizontal scrollbar at the bottom.
image
So when I tried to increase the width by dragging it, the horizontal scrollbar appeared but it messed the layout when I dragged it.
image

This may be a temporary fix but I made it work by adding $.scrollbarWidth() to the width for 'bodyScrollable`

const width = $.style(this.header, 'width');

But the horizontal scroll, its still unsolved.

Scrolling and Expand/Collapse issue with DataTable

I encountered multiple issues trying to use Sales/Purchase Analytics. I already created an issue in erpnext's repo but I later realized it has more to do with DataTable so I'm posting it here too.

  • When there are too many rows, another scrolling bar pops up... at around the 150 row mark
    analytics1

  • When you've clicked on a cell in a row that is near the vertical end, you cannot scroll up past a point (maybe the point at which another scrolling bar pops up)
    analytics2

  • When you collapse the last collapsible row, you cannot expand it again. And there is extra scrolling space below that point even though there aren't any more rows.
    analytics3

The first 2 problems can also be analyzed at https://beta.erpnext.com/desk#query-report/General%20Ledger

Filter rows or columns

@netchampfaris Is there a way to filter the datatable based on a value? For example, you have an input in which you can type the search value. Can you then, with JavaScript, use this value to filter the datatable and show only rows and columns containing this search value.
An example would be much appreciated.

Naming Decision

GitHub repo is called datatable and project readme calls it DataTables. Since you probably don't want a conflict with the datatables.net project which calls it DataTables I would suggest just calling this Datatable without the s and withou the capitalized T.

Unexpected Newline Chars In Cell Content

If cell data contains a trailing whitespace character, four (4) additional newline chars will be appended to the text node inside of the dt-cell__content div. This can cause the text-overflow: ellipsis; CSS rule to engage prematurely, and will unnecessarily truncate the content of the cell.

It would seem that this is a result of using a template string to format the cell HTML. I've referenced line 864 of cellmanager.js where this is declared. Collapsing the template string to a single line should fix this issue. If this exceeds max line length, concatenating the variables prior to integrating into the template string may be another option.

return `
<div class="${className}">
${contentHTML}
${sortIndicator}
${resizeColumn}
${dropdown}
</div>
${editCellHTML}
`;

treeview sorting buggy

The treeview does not keep the parent-child relationships when sorting.
Easily observable in the demo.

Suggestion

Hi
please implement rtl direction out of the box for related cultures.(Arabic,Hebr,Persian...)
I think grouping columns based on column_title and summary values based on grouping are necessary features for using this library in frappe and ERPnext.

In function removeStyle() this.stylesheet is null

We are occasionally seeing the following error stack in our app using Frappe datatable:
Screenshot 2020-01-26 at 12 34 17
It seems to be related to the timing when the datatable is rendered on the page because it is not happening every time.
I am wondering if we could add a check here to prevent this.stylesheet to be null and thus preventing the error stack above:

const index = Array.from(this.stylesheet.cssRules)

What is the best way to get data from the selected rows?

I'm guessing I can probably make use of this:

export default function filterRows(rows, filters) {
let filteredRowIndices = [];
if (Object.keys(filters).length === 0) {
return rows.map(row => row.meta.rowIndex);
}
for (let colIndex in filters) {
const keyword = filters[colIndex];
const filteredRows = filteredRowIndices.length ?
filteredRowIndices.map(i => rows[i]) :
rows;
const cells = filteredRows.map(row => row[colIndex]);
let filter = guessFilter(keyword);
let filterMethod = getFilterMethod(filter);
if (filterMethod) {
filteredRowIndices = filterMethod(filter.text, cells);
} else {
filteredRowIndices = cells.map(cell => cell.rowIndex);
}
}
return filteredRowIndices;
};

But it's unclear how I could get the rows that are selected, idiomatically at least, using this library.

It might be a useful addition to the API to add a getSelectedRows function following this one: https://github.com/frappe/datatable/blob/master/src/datatable.js#L174-L176

Any suggestions appreciated.

Support customize visible columns as saved layout

Currently it is possible by drag and drop columns to re-arrange columns and adjust the width, also it is possible to hide or show columns, but unfortunately the changes get lost once re-open the page again. it is desired to allow saving all the customizing: column sequence, width, show or hide, sorting, filtering as saved layout, either save such layout setting as user setting persisted to backend or saved to localstorage, and remember the last setting when next time open the same page.
Here the ALV(active List Viewer, the datatable equivalent) layout feature in SAP
image
Fig 1. Layout toolbar button

image
Fig2. Layout change modal window

image
Fig 3: Layout save

image
Fig4. Saved Layout list

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot 📦🚀

Bulma example

Hello. I am trying out Frappe Datatable in my search for a table without jQuery.
Before I used datatables.net a lot, but this one depends on jQuery. Frappe Datatable looks promising.

I am trying to implement the table in a Bulma hero section. But I would like it to be full-width. Any suggestions?

image

Column Header / Data Widths not aligned

Test on beta.erpnext.com and develop stage locally with areas utilising DataTables.
Column widths between header and data table are out of alignment. Not certain if applicable only to ERPNext / Frappe.

2018-08-17_15-00-13

Paging?

Hi,

Is it possible to add paging to the table?

Thanks

Sorting preferences

Would like to load a datatable with sorting column and type predefined so when user loads view it is setup properly.

Allow opening tree view collapsed

The tree view is a nice feature of datatable, I really like it. However, I'd like to open the tree collapsed by default. (I have a large tree, so it's nicer to expand only the parts that you want to look into.) So it would be nice to have a config option that states whether the tree should initially be expanded or collapsed. (You could even make it more advanced by stating up to what level the tree should be expanded, but for my use case just a boolean would be fine.)

Inline filter improvement ideas

  1. Support filtering multi columns, currently the inline filter only works for each single column by matching the input text like SQL where condition with wildcard, in other word, after filtered on one column, then input filter condition in another column, the previous filtering condition is ignored! it is desired to filter the grid by all active filtering conditions in all columns

  2. Support filtering multi values with delimiter(;) using OR logic, e.g input text "ipad ; ipod" can filter out records with column content contains ipad or ipod.

  3. Support filtering number and date field by range using the operator > and <, e.g input text > 400 can filter out records with number content greater than 400.

  4. Turn the current pure input text field into awesome field with distinct values of the current column as drop down list, allow user to multi select the value, just like how Excel does filtering
    image

  5. Support clearing all active filtering conditions by one click. e.g clearing filters

  6. Support saving the filtering conditions as saved version, can be set as default when next time open the same datatable, also can be selected re-used next time by other user if publicly shared

Fixed header on scroll + Fixed column(s)

First of all, thank you for this awesome library, I searched through issues and did not find any mention of it. I would like to fix 2 columns on my table on the left with fixed headers, my tables have around 30 columns and 100+ rows and want to enable this feature, any suggestions are appreciated

[bug] sorting on a column is broken if some of the cells are `undefined`

Undefined cell breaks the whole column into sorted sequences:

Descending:
image

Ascending:
image

Highlighted cell is undefined in the sample data array:

data = [
	["Tiger Nixon", { content: "System Architect<br>New line", editable: false }, "Edinburgh", 1, "2011/04/25", 320800],
	["Garrett Winters", "Accountant", "Tokyo", 2, "2011/07/25", 170750],
	["Ashton Cox", "Junior Technical Author", "San Francisco", 3, "2009/01/12", 86000],
	["Cedric Kelly", "Senior Javascript Developer", "Edinburgh", undefined, "2012/03/29", 433060],
	["Airi Satou", "Accountant", "Tokyo", 8, "2008/11/28", 162700],
	["Brielle Williamson", "Integration Specialist", "New York", 5, "2012/12/02", 372000],
	["Herrod Chandler", "Sales Assistant", "San Francisco", '', "2012/08/06", 137500]
];

If the 'empty' cell is represented with an emptystring, sorting works correctly.

This is an issue when Datatable is used in the reports infrastructure within Frappe since all of the NULL values in the database are undefined in the table data.

TAB Key control to move to adjacent cell [FEATURE REQUEST]

Current Behavior:
When in edit cell mode, TAB key does not do anything. User must press ENTER, and then tab moves to adjacent cell.

Desired Behavior
User should be able to customize the column with a property named "tab_exits_cell" so that if true, when editing pressing the TAB key moves out of the cell. If false TAB pressing reverts to old behavior.

[BUG] Column Name not showing when using Array of Object Descriptors

Actual Behavior

When creating a datatable in a page on ERPNext, one can specify the column names with the following declaration:

    const options = {
    columns: ['Name', 'Position', 'Country']
}

This works fine.

However, if you wish to use the Array of Object Descriptors method:

const options = {
    columns: [
        {
            name: 'Desired Name',
            id: 'name',
            editable: false,
            resizable: false,
            sortable: false,
            focusable: false,
            dropdown: false,
            width: 32,
            format: (value) => {
                return value.bold();
            }
        },
        ...
    ]
}

The Name does not show up. Nothing is in the column header. No errors on the console show either. Tried with other browsers, and no joy. It must be a bug.

Expected Behavior

Columns defined using Array of Object Descriptors, should show the name simply without any problems.

Source

Unable to override defaults in terms of headerDropdown

These lines seem to force users to have to use the default fields for the headerDropdown, IMO it's less surprising to always override the headerDropdown with whatever is passed in the Datatable object. It's also unclear if there is an idiomatic way around this issue using this library:

options.headerDropdown = options.headerDropdown || [];
this.options.headerDropdown = [
...DEFAULT_OPTIONS.headerDropdown,
...options.headerDropdown
];

Or perhaps my JS knowledge is insufficient and there is an obvious way to do this. In any case, feedback appreciated.

I added an event after field edition, what do you think ?

Hi !
I needed to save data after inline edition. seeing #46 I thought I should try my hand on it.

It's working for me, but I don't know if it's good enough for community, so, what do you think ?

in apps/frappe/node_modules/frappe-datatable/dist/frappe-datatable.cjs.js
from line 2525
class CellManager { constructor(instance) { this.instance = instance; linkProperties(this, this.instance, [ 'wrapper', 'options', 'style', 'header', 'bodyScrollable', 'columnmanager', 'rowmanager', 'datamanager', 'keyboard', 'fireEvent', //<= add this ]); this.bindEvents();

then, from line 3022

` submitEditing() {
if (!this.$editingCell) return;
const $cell = this.$editingCell;
const {
rowIndex,
colIndex
} = $.data($cell);
const col = this.datamanager.getColumn(colIndex);

    if ($cell) {
        const editor = this.currentCellEditor;

        if (editor) {
            let valuePromise = editor.getValue();

            // convert to stubbed Promise
            if (!valuePromise.then) {
                valuePromise = Promise.resolve(valuePromise);
            }

            valuePromise.then((value) => {
                const done = editor.setValue(value, rowIndex, col);
                const oldValue = this.getCell(colIndex, rowIndex).content;

                // update cell immediately
                this.updateCell(colIndex, rowIndex, value);
                $cell.focus();

                // =>add this : BEGINNING OF add edit submit event
                let rowData = this.datamanager.getData(rowIndex);
                this.fireEvent('onSubmitEditing', [rowData, this.getCell(colIndex, rowIndex).column.id, value]);
                // END OF add edit submit event

                if (done && done.then) {
                    // revert to oldValue if promise fails
                    done.catch((e) => {
                        console.log(e);
                        this.updateCell(colIndex, rowIndex, oldValue);
                    });
                }
            });
        }
    }

    this.currentCellEditor = null;
}`

Then in custom JS (associated to a report in my case)

`
frappe.query_reports["my_report"] = {
...
get_datatable_options(options) {

    // loops on each column and make one ore more of them editable
    options.columns.forEach(function(column, i) {
        // column id i want to make editable
        if(column.id == "your_editable_id") {
            column.editable = true
        }
    });

    // change datatable options
    return Object.assign(options, {
        checkboxColumn: true,
        events: {
            onSubmitEditing: function (cell) {
                // rowValues : all cell values from row before edition
                // cellId : key id of cell edited
                // newVal : edited val
                let [rowValues, cellId, newVal] = cell;
                if(cellId == "your_editable_id") {
                    frappe.call({
                        method: "your.method",
                        type: "GET",
                        args: {name: rowValues.id, qty: newVal}, // for example
                        callback: function (r) {
                            if (r.message) {
                                frappe.msgprint(__(r.message));
                            }
                        },
                    });
                }
            },
        }
    });
},

};

`

Question: How to add Actions?

Hi there

How can I add actions for each row, for example have 2 icons / buttons for Edit/Delete with events linked to them so that when I click on one, it actions the appropriate event called?

Thanks

Docs could include a warning about use with bootstrap

Placing a <div id="datatable"></div> within a bootstrap <div class="container"> broke the datatable such that certain view port sizes had no datatable showing. This was confusing, and gotcha note in the docs could be helpful.

[Feature request] Nested headers

Hi,

Thank you for your amazing project, this library looks very promising.

It would be so nice if we could create nested headers, i.e. several levels of headers with headers on top of children headers. See this example in Handsontable.

We could define these nested columns like this, for instance:

columns: [
    {
        name: 'Framework infos',
        nestedColumns: [
            { name: 'Framework name' },
            { name: 'GitHub Stars' },
            { name: 'Forks' }
        ]
    },
    {
        name: 'Actions',
        nestedColumns: [
            { name: 'Project Link', format: value => `<a class="text-primary" href="${value}">${value}</a>` },
            { name: 'Fork', format: value => `<a class="text-primary" href="${value}">${value}</a>` }
        ]
    }
]

Are contributions welcome? I may submit a PR if you think this is an interesting feature.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.