zoukankan      html  css  js  c++  java
  • SlickGrid资料

    SlickGrid简单介绍 : https://github.com/mleibman/SlickGrid/wiki

    快速入门 : https://github.com/mleibman/SlickGrid/wiki/Getting-Started

    使用示例 : https://github.com/mleibman/SlickGrid/wiki/Examples

    API文档: https://github.com/mleibman/SlickGrid/wiki/API-Reference

    处理选择模式: https://github.com/mleibman/SlickGrid/wiki/Handling-selection

    Welcome to the SlickGrid!

    UPDATE: March 5th, 2014 – I have too many things going on in my life right now to really give SlickGrid support and development the time and attention it deserves. I am not stopping it, but I will most likely be unresponsive for some time. Sorry.

    UPDATE: This repo hasn’t been updated in a while. https://github.com/6pac/SlickGrid/wikiseems to be the most active fork at the moment.

    Do you use SlickGrid? Add your site to the Used By!

    Want to show your appreciation? Hit Donate! :)

    What it is

    Quite simply, SlickGrid is a JavaScript grid/spreadsheet component.
    It is an advanced component and is going to be a bit more difficult to learn and configure, but once you realize its full potential, it will blow your mind!

    Some highlights:

    • Adaptive virtual scrolling (handle hundreds of thousands of rows with extreme responsiveness)
    • Extremely fast rendering speed
    • Supports jQuery UI Themes
    • Background post-rendering for richer cells
    • Configurable & customizable
    • Column resize/reorder/show/hide
    • Column autosizing & force-fit
    • Pluggable cell formatters & editors
    • Support for editing and creating new rows.
    • Grouping, filtering, custom aggregators, and more!
    • Advanced detached & multi-field editors with undo/redo support.
    • “GlobalEditorLock” to manage concurrent edits in cases where multiple Views on a page can edit the same data.

    Resources

    Dependencies

    • jQuery
    • jQueryUI Sortable (optional, only if column reordering is enabled)
    • jquery.event.drag – http://threedubmedia.com/code/event/drag
    • jquery.event.drop – http://threedubmedia.com/code/event/drop

    Documentation

    Contact/Support

    GitHub Issues are for bug reports only. Please use the appropriate forum.
    Please see Rules of conduct

    When reporting bugs, please be specific (details are described in the above “Rules of conduct”):

    1. Include the version of SlickGrid.
    2. Include the reproduction steps. Describe about expected behavior & actual behavior.
    (If possible, post code on jsfiddle.net).
    3. Use proper English that everybody can understand.

    What makes it different

    Virtual rendering

    SlickGrid utilizes virtual rendering to enable you to easily work with hundreds of thousands of items without any drop in performance. In fact, there is no difference in performance between working with a grid with 10 rows versus a 100’000 rows. This is achieved through virtual rendering where only what’s visible on the screen plus a small buffer is rendered. As the user scrolls, DOM nodes are continuously being created and removed. These operations are highly tuned to provide optimal performance under all browsers. The grid also adapts to the direction and speed of scroll to minimize the number of rows that need to be swapped out and to dynamically switch between synchronous and asynchronous rendering.

    It does a few other things to maximize performance, such as dynamically generating and updatingCSS rules, so that resizing a column does not change the grid DOM tree and only causes one reflow, and loading cell editors asynchronously to maximize keyboard navigation speed.

    Grid vs Data

    The key difference is between SlickGrid and other grid implementation I have seen is that they focus too much on being able to understand and work with data (search, sort, parse, ajax load, etc.) and not enough on being a better “grid” (or, in case of editable grids, a spreadsheet). It’s great if all you want to do is “spruce up” an HTML TABLE or slap a front end onto a simple list, but too inflexible for anything else.

    Data is complicated. It has business rules. It has non-intrinsic properties. Editing one property of an element can lead to cascading changes modifying other properties or even other elements. It has dependencies. What I’m saying, is that dealing with data is best left to the developer using the grid control. Trying to fit all of that into the grid implementation and API will only limit its applicability and add considerable bloat.

    SlickGrid takes a different approach. In the simplest scenario, it accesses data through an array interface (i.e. using “dataitem” to get to an item at a given position and “data.length” to determine the number of items), but the API is structured in such a way that it is very easy to make the grid react to any possible changes to the underlying data.

    Responding to data source changes

    While this may not be immediately obvious from what you see in the examples and in the code, the key use of the grid is in MVC applications where the grid is wired to respond to events in the Model. In our application we have spreadsheet component of a Gantt chart, and the Model is a “filtered” view of the tasks (rows) in the original datasource. Suppose you collapse or expand a parent task or enter some text in a Quick Filter textbox. The Model then recalculates which rows are now visible, compares that with what was visible before and fires two events – onRowCountChanged & onRowsChanged. The latter one tells all subscribed Views, such as the grid, that the rows in specific positions changed. The grid then only has to invalidate/remove those rows and call grid.renderViewport() to make sure that whatever is in the viewport is visible. The onRowCountChanged event triggers the recalculation of the virtual canvas – grid.resizeCanvas(). Together, this pattern makes for an incredibly efficient, flexible and, most importantly, scalable implementation.

    Unsupported browsers

    Rather than listing all the browsers that SlickGrid works on, I will concentrate on the ones that don’t.

    IE6 is explicitly NOT supported. While some people have made SlickGrid work with IE6, I am not going to merge those changes in or spend any time testing on IE6 and trying to make it work. If you have to support it, I feel your pain, but I don’t want to share it.

    Opera seems to be having some issues with synchronized scrolling of column headers and a vertical page scrollbar appearing when scrolling the grid content vertically. I haven’t been able to figure out why in the amount of time I was willing to spend on it. If you have an idea, let me know.

    Thanks

    Big thanks to JetBrains who have supported SlickGrid and other open-source projects by providing a free license for their awesome WebStorm IDE.

    This is the API reference for SlickGrid.

    Slick.Grid

    • Constructor - Slick.Grid constructor
    • Core - Core grid functionality
    • Columns - Initializing and customizing columns
    • Cells - Manipulating cell data and styling
    • Rendering - Rendering methods
    • Headers - Column header methods

    DataView

    Slick.Data.RemoteModel

    Slick.Event

    Slick.EventData

    Slick.EditorLock

    Slick.GlobalEditorLock

    Slick.Range

    Slick.CellRangeDecorator

    Slick.CellRangeSelector

    Table of Contents

    # Constructor

    # var grid = new Slick.Grid(container, data, columns, options);

    container - Container node to create the grid in. This can be a DOM Element, a jQuery node, or a jQuery selector.

    data - Databinding source. This can either be a regular JavaScript array or a custom object exposing getItem(index) and getLength() functions.

    columns - An array of column definition objects. See Column Options for a list of options that can be included on each column definition object.

    options - Additional options. See Grid Options for a list of options that can be included.

    Create an instance of the grid.

    Example usage, taken from the basic Slickgrid example:

      var grid;

      var columns = [

        {id: "title", name: "Title", field: "title"},

        {id: "duration", name: "Duration", field: "duration"},

        {id: "%", name: "% Complete", field: "percentComplete"},

        {id: "start", name: "Start", field: "start"},

        {id: "finish", name: "Finish", field: "finish"},

        {id: "effort-driven", name: "Effort Driven", field: "effortDriven"}

      ];

     

      var options = {

        enableCellNavigation: true,

        enableColumnReorder: false

      };

     

      $(function () {

        var data = [];

        for (var i = 0; i < 500; i++) {

          data[i] = {

            title: "Task " + i,

            duration: "5 days",

            percentComplete: Math.round(Math.random() * 100),

            start: "01/01/2009",

            finish: "01/05/2009",

            effortDriven: (i % 5 == 0)

          };

        }

     

        grid = new Slick.Grid("#myGrid", data, columns, options);

    # Core

    # grid.init()

    Initializes the grid. Called after plugins are registered. Normally, this is called by the constructor, so you don't need to call it. However, in certain cases you may need to delay the initialization until some other process has finished. In that case, set the explicitInitialization option to true and call the grid.init() manually.

    # grid.getData()

    Returns an array of every data object, unless you're using DataView in which case it returns a DataView object.

    # grid.getDataItem(index)

    index - Item index.

    Returns the databinding item at a given position.

    // Get the id of the 15th item

    var id15 = grid.getDataItem(14).id;

    # grid.setData(newData, scrollToTop)

    data - New databinding source. This can either be a regular JavaScript array or a custom object exposing getItem(index) and getLength() functions.

    scrollToTop - If true, the grid will reset the vertical scroll position to the top of the grid.

    Sets a new source for databinding and removes all rendered rows. Note that this doesn't render the new rows - you can follow it with a call to render() to do that.

    # grid.getDataLength()

    Returns the size of the databinding source.

    // Create an array of just the ids from every data item

    var ids = [];

    for (var i=0; i<grid.getDataLength() ; i++) {

      ids.push(grid.getDataItem(i).id);

    }

    # grid.getOptions()

    Returns an object containing all of the Grid options set on the grid. See a list of Grid Options here.

    // Find all elements that are currently selected

    var $selectedCells = $('.' + grid.getOptions().selectedCellCssClass);

    # grid.getSelectedRows()

    Returns an array of row indices corresponding to the currently selected rows.

    # grid.getSelectionModel()

    Returns the current SelectionModel. See here for more information about SelectionModels.

    # grid.setOptions(options)

    options - An object with configuration options.

    Extends grid options with a given hash. If there is an active edit, the grid will attempt to commit the changes and only continue if the attempt succeeds.

    // set a new CSS class for selected cells

    grid.setOptions( { selectedCellCssClass: "newSelection" } );

     

    // Select the first row

    grid.setSelectedRows([0]);

     

    // get the elements for the selected cells

    $('.newSelection');

    # grid.setSelectedRows(rowsArray)

    rowsArray - An array of row numbers.

    Accepts an array of row indices and applies the current selectedCellCssClass to the cells in the row, respecting whether cells have been flagged as selectable.

    // Select the first three rows

    grid.setSelectedRows([0, 1, 2]);

    # grid.setSelectionModel(selectionModel)

    selectionModel - A SelectionModel.

    Unregisters a current selection model and registers a new one. See the definition of SelectionModelfor more information.

    # Columns

    # grid.autosizeColumns()

    Proportionately resizes all columns to fill available horizontal space. This does not take the cell contents into consideration.

    # grid.getColumnIndex(id)

    id - A column id.

    Returns the index of a column with a given id. Since columns can be reordered by the user, this can be used to get the column definition independent of the order:

    var column = grid.getColumns()[grid.getColumnIndex("title")]

    # grid.getColumns()

    Returns an array of column definitions, containing the option settings for each individual column.

    // Log to console whether the first column is sortable

    var cols = grid.getColumns();

    var sortable = cols[0].sortable;

    sortable ? console.log("It's sortable!") : console.log("It's not sortable!");

    # grid.setColumns(columnDefinitions)

    columnDefinitions - An array of column definitions.

    Sets grid columns. Column headers will be recreated and all rendered rows will be removed. To re-render the grid (if necessary), call render().

    // Change the name of the first column to "First"

    var data = grid.getColumns();

    data[0].name = "First";

    grid.setColumns(data);

    # grid.setSortColumn(columnId, ascending)

    Accepts a columnId string and an ascending boolean. Applies a sort glyph in either ascending or descending form to the header of the column. Note that this does not actually sort the column. It only adds the sort glyph to the header.

    # grid.setSortColumns(cols)

    Accepts an array of objects in the form [ { columnId: [string], sortAsc: [boolean] }, ... ]. When called, this will apply a sort glyph in either ascending or descending form to the header of each column specified in the array. Note that this does not actually sort the column. It only adds the sort glyph to the header

    # grid.updateColumnHeader(columnId, title, toolTip)

    id - Column id.

    title - New column name.

    toolTip - New column tooltip.

    Updates an existing column definition and a corresponding header DOM element with the new title and tooltip.

    // Change the column with an id of 'FirstName' to have the name "A First Name", and no tooltip.

    grid.updateColumnHeader("FirstName", "A First Name");

    # Cells

    # grid.addCellCssStyles(key, hash)

    key - A unique key you can use in calls to setCellCssStyles and removeCellCssStyles. If a hash with that key has already been set, an exception will be thrown.

    hash - A hash of additional cell CSS classes keyed by row number and then by column id. Multiple CSS classes can be specified and separated by space.

    Example:

    {

        0:    {

            "number_column":    "cell-bold",

            "title_column":     "cell-title cell-highlighted"

        },

        4:    {

            "percent_column":    "cell-highlighted"

        }

    }

    Adds an "overlay" of CSS classes to cell DOM elements. SlickGrid can have many such overlays associated with different keys and they are frequently used by plugins. For example, SlickGrid uses this method internally to decorate selected cells with selectedCellCssClass (see options).

    # grid.canCellBeActive(row, col)

    row - A row index.

    col - A column index.

    Returns true if you can click on a given cell and make it the active focus.

    # grid.canCellBeSelected(row, col)

    row - A row index.

    col - A column index.

    Returns true if selecting the row causes this particular cell to have the selectedCellCssClassapplied to it. A cell can be selected if it exists and if it isn't on an empty / "Add New" row and if it is not marked as "unselectable" in the column definition.

    # grid.editActiveCell(editor)

    editor - A SlickGrid editor (see examples in slick.editors.js).

    Attempts to switch the active cell into edit mode. Will throw an error if the cell is set to be not editable. Uses the specified editor, otherwise defaults to any default editor for that given cell.

    // Assuming slick.editors.js is included...

    // Set the first cell in the first row to be active

    grid.setActiveCell(0,0);

     

    // Invoke the Date editor on that cell

    grid.editActiveCell(Slick.Editors.Date);

    # grid.flashCell(row, cell, speed)

    row - A row index.

    cell - A column index.

    speed (optional) - The milliseconds delay between the toggling calls. Defaults to 100 ms.

    Flashes the cell twice by toggling the CSS class 4 times.

    # grid.getActiveCell()

    Returns an object representing the coordinates of the currently active cell:

    {

      row: activeRow,

      cell: activeCell

    }

    # grid.getActiveCellNode()

    Returns the DOM element containing the currently active cell. If no cell is active, null is returned.

    // Get the element for the active cell

    var $active = $(grid.getActiveCellNode())

     

    // Add a new class to the active cell

    $active.addClass('myClass');

    # grid.getActiveCellPosition()

    Returns an object representing information about the active cell's position. All coordinates are absolute and take into consideration the visibility and scrolling position of all ancestors. The object takes the form:

    {

      bottom:  [numPixels],

      height:  [numPixels],

      left:    [numPixels],

      right:   [numPixels],

      top:     [numPixels],

      visible: [boolean],

         [numPixels]

    }

    # grid.getCellCssStyles(key)

    key - A string.

    Accepts a key name, returns the group of CSS styles defined under that name. SeesetCellCssStyles for more info.

    # grid.getCellEditor()

    Returns the active cell editor. If there is no actively edited cell, null is returned.

    # grid.getCellFromEvent(e)

    e - A standard W3C/jQuery event.

    Returns a hash containing row and cell indexes from a standard W3C/jQuery event.

    # grid.getCellFromPoint(x, y)

    x - An x coordinate.

    y - A y coordinate.

    Returns a hash containing row and cell indexes. Coordinates are relative to the top left corner of the grid beginning with the first row (not including the column headers).

    # grid.getCellNode(row, cell)

    row - A row index.

    cell - A column index.

    Returns a DOM element containing a cell at a given row and cell.

    # grid.getCellNodeBox(row, cell)

    row - A row index.

    cell - A column index.

    Returns an object representing information about a cell's position. All coordinates are absolute and take into consideration the visibility and scrolling position of all ancestors. The object takes the form:

    {

      bottom:  [numPixels],

      height:  [numPixels],

      left:    [numPixels],

      right:   [numPixels],

      top:     [numPixels],

      visible: [boolean],

         [numPixels]

    }

    # grid.gotoCell(row, cell, forceEdit)

    Accepts a row integer and a cell integer, scrolling the view to the row where row is its row index, and cell is its cell index. Optionally accepts a forceEdit boolean which, if true, will attempt to initiate the edit dialogue for the field in the specified cell.

    Unlike setActiveCell, this scrolls the row into the viewport and sets the keyboard focus.

    # grid.navigateDown()

    Switches the active cell one row down skipping unselectable cells. Returns a boolean saying whether it was able to complete or not.

    # grid.navigateLeft()

    Switches the active cell one cell left skipping unselectable cells. Unline navigatePrev,navigateLeft stops at the first cell of the row. Returns a boolean saying whether it was able to complete or not.

    # grid.navigateNext()

    Tabs over active cell to the next selectable cell. Returns a boolean saying whether it was able to complete or not.

    # grid.navigatePrev()

    Tabs over active cell to the previous selectable cell. Returns a boolean saying whether it was able to complete or not.

    # grid.navigateRight()

    Switches the active cell one cell right skipping unselectable cells. Unline navigateNext,navigateRight stops at the last cell of the row. Returns a boolean saying whether it was able to complete or not.

    # grid.navigateUp()

    Switches the active cell one row up skipping unselectable cells. Returns a boolean saying whether it was able to complete or not.

    # grid.removeCellCssStyles(key)

    key - A string key.

    Removes an "overlay" of CSS classes from cell DOM elements. See setCellCssStyles for more.

    # grid.resetActiveCell()

    Resets active cell.

    # grid.setActiveCell(row, cell)

    row - A row index.

    cell - A column index.

    Sets an active cell.

    # grid.setCellCssStyles(key, hash)

    key - A string key. Will overwrite any data already associated with this key.

    hash - A hash of additional cell CSS classes keyed by row number and then by column id. Multiple CSS classes can be specified and separated by space.

    Example:

    {

        0:    {

            "number_column":    "cell-bold",

            "title_column":     "cell-title cell-highlighted"

        },

        4:    {

            "percent_column":    "cell-highlighted"

        }

    }

    Sets CSS classes to specific grid cells by calling removeCellCssStyles(key) followed byaddCellCssStyles(key, hash). key is name for this set of styles so you can reference it later - to modify it or remove it, for example. hash is a per-row-index, per-column-name nested hash of CSS classes to apply.

    Suppose you have a grid with columns:

    ["login", "name", "birthday", "age", "likes_icecream", "favorite_cake"]

    ...and you'd like to highlight the "birthday" and "age" columns for people whose birthday is today, in this case, rows at index 0 and 9. (The first and tenth row in the grid).

       .highlight{ background: yellow }

    grid.setCellCssStyles("birthday_highlight", {

       0: {

            birthday: "highlight",

            age: "highlight"

           },

     

       9: {

             birthday: "highlight",

             age: "highlight"

           }

    })

    # Rendering

    # grid.getCanvasNode()

    Returns the DIV element matching class grid-canvas, which contains every data row currently being rendered in the DOM.

    // Get the total number of data rows being rendered in the DOM.

    var numRenderedRows = $(grid.getCanvasNode()).children().length;

    # grid.getGridPosition()

    Returns an object representing information about the grid's position on the page. The object takes the form:

    {

      bottom:  [numPixels],

      height:  [numPixels],

      left:    [numPixels],

      right:   [numPixels],

      top:     [numPixels],

      visible: [boolean],

         [numPixels]

    }

    # grid.getRenderedRange(viewportTop, viewportLeft)

    viewportTop (optional) - The number of pixels offset from the top of the grid.

    viewportLeft (optional) - The number of pixels offset from the left of the grid.

    If passed no arguments, returns an object that tells you the range of rows (by row number) currently being rendered, as well as the left/right range of pixels currently rendered. { top: [rowIndex], bottom: [rowIndex], leftPx: [numPixels], rightPx: [numPixels] }

    The options viewportTop and viewportLeft are optional, and tell what what would be rendered at a certain scroll top/left offset. For example, grid.getRenderedRange(1000) would essentially be asking: "if I were to scroll 1000 pixels down, what rows would be rendered?"

    # grid.getViewport(viewportTop, viewportLeft)

    viewportTop (optional) - The number of pixels offset from the top of the grid.

    viewportLeft (optional) - The number of pixels offset from the left of the grid.

    Returns an object telling you which rows are currently being displayed on the screen, and also the pixel offsets for left/right scrolling. { top: [rowIndex], bottom: [rowIndex], leftPx: [numPixels], rightPx: [numPixels] }

    Also accepts viewportTop and viewportLeft offsets to tell you what would be shown to the user if you were to scroll to that point.

    # grid.invalidate()

    Redraws the grid. Invalidates all rows and calls render().

    // Change the name property of the first row

    var data = grid.getData();

    data[0].name = "New name!"

     

    // Call invalidate to render the data again. No need to call render, as this calls it for you.

    grid.invalidate();

    # grid.invalidateAllRows()

    Tells the grid that all rows in the table are invalid. (If render() is called after this, it will redraw the entire grid.)

    # grid.invalidateRow(row)

    row - A row index.

    Tells the grid that the row specified by row is invalid. (If render() is called after this, it will redraw the contents of that row.)

    # grid.invalidateRows(rows)

    rows - An array of row indices.

    Accepts an array of row indices, and tells the grid that those rows are invalid. (If render() is called after this, it will redraw the contents of those rows.)

    // Change the name property of the first row

    var data = grid.getData();

    data[0].name = "New name!"

    data[1].name = "Another new name!"

     

    // Call invalidateRows to invalidate the first two rows

    grid.invalidateRows([0,1]);

     

    // Call render to render them again

    grid.render();

    # grid.render()

    Rerenders rows in the DOM.

    # grid.resizeCanvas()

    Resizes the canvas to fit the current DIV container. (For example, to resize the grid, you would first change the size of the div, then call resizeCanvas().)

    # grid.scrollCellIntoView(row, cell)

    row - A row index.

    cell - A column index.

    Scrolls the indicated cell into view.

    Note that this does nothing unless the indicated column is already not in view. For example, if the grid is scrolled to the far left and you were looking at row 0, calling scrollCellIntoView(100,0) would not simply scroll you to row 100. But if column 8 were out of view and you calledscrollCellIntoView(100,8), then it would scroll down and to the right.

    # grid.scrollRowIntoView(row, doPaging)

    row - A row index.

    doPaging - A boolean. If false, the grid will scroll so the indicated row is at the top of the view. If true, the grid will scroll so the indicated row is at the bottom of the view. Defaults to false.

    Scrolls the view to the indicated row.

    # grid.scrollRowToTop(row)

    row - A row index.

    Scrolls the view to the indicated row, placing the row at the top of the view.

    # grid.updateCell(row, cell)

    TODO

    // put stuff here

    # grid.updateRow(row)

    TODO

    // put stuff here

    # grid.updateRowCount()

    TODO

    // put stuff here

    # Headers

    # grid.getHeaderRow()

    Returns the element of a DIV row beneath the actual column headers. For an example of how you might use this, see the header row quick filter example, which grabs the element, appends inputs, and delegates events to the inputs.

    # grid.getHeaderRowColumn(columnId)

    columnId - The id string of a column.

    If a header row is implemented and has one child for each column, as seen in the header row quick filter example, you may use this function to pass a columnId and get the individual cell from that header row. Returns a DIV element.

    # grid.getSortColumns()

    Returns an array of objects representing columns that have a sort glyph in the header:

    {

      columnId: [string],

      sortAsc:  [boolean]

    }

    # grid.getTopPanel()

    Returns the DIV element of the top panel. The panel is hidden by default, but you can show it by initializing the grid with showTopPanel set to true, or by callinggrid.setTopPanelVisibility(true).

    // Create a subheader and attach it to the top panel

    $("<div>Here is a subheader!</div>")

      .appendTo(grid.getTopPanel());

    // Show the top panel

    grid.setTopPanelVisibility(true);

    # grid.setHeaderRowVisibility(visible)

    Note: Earlier Versions used grid.showTopPanel() and grid.hideTopPanel() these have now been replaced with grid.setTopPanelVisibility(true) andgrid.setTopPanelVisibility(false); TODO

    // put stuff here

     

    DataView

    Core concepts

    SlickGrid is very flexible in how it consumes the data. The data is passed to the grid via the constructor and can also be accessed using the setData(data) and getData() methods. Data itself can be either an array-like object with a length property and an indexer (data[index]) or a custom data provider implementing the following interface:

    • getLength() - returns the number of data items in the set
    • getItem(index) - returns the item at a given index
    • getItemMetadata(index) - returns the metadata for the item at a given index (optional)

    DataView (Slick.Data.DataView included in slick.dataview.js) is one such data provider and it is part of the SlickGrid package.

    If all of the data is available on the client (i.e. in a JavaScript array), DataView can provide many useful features that the grid itself doesn't have. (This fact that the grid lacks these features is by design - SlickGrid tries to keep the core lean and simple while encouraging modular design and data abstraction in its API.)

    DataView works by taking in your data and acting as a data provider that you pass to SlickGrid instead of your original data array. For example, if you make DataView group data, it makes the grid think that the "group" rows are just regular data items, so the grid doesn't need to be aware of them. DataView tells the grid that those items have a custom display and behavior and provides implementations of both. You then wire up DataView's onRowCountChanged and onRowsChangedevents to update the grid and voila.

    Here's a rough list of features that DataView adds to the grid:

    • Paging.
    • Multi-column sorting.
    • Search.
    • Multi-level grouping with totals.
    • Expand/collapse groups.

    DataView also enables very efficient updates in response to the changing data. Whenever something changes, it detects which rows need updating, and passes them in the onRowCountChanged andonRowsChanged events that it fires, so instead of rerendering the entire grid, you can simply invalidate the updated rows.

    Getting started

    To use the DataView, include slick.dataview.js:

    // Create the DataView.

    var dataView = new Slick.Data.DataView();

     

    //Create columns

    var columns = [

      {id: "column1", name: "ID", field: "id"},

      {id: "column2", name: "Language", field: "lang"},

      {id: "column3", name: "Year", field: "year"}

    ];

     

    // Pass it as a data provider to SlickGrid.

    var grid = new Slick.Grid(containerEl, dataView, columns, options);

     

    // Make the grid respond to DataView change events.

    dataView.onRowCountChanged.subscribe(function (e, args) {

      grid.updateRowCount();

      grid.render();

    });

     

    dataView.onRowsChanged.subscribe(function (e, args) {

      grid.invalidateRows(args.rows);

      grid.render();

    });

    Now we're ready to initialize it with some data. One important requirement that DataView imposes on the data it consumes is that every item has a unique identifier. DataView uses it to uniquely identify items and compare them to each other. By default, DataView uses the id property of the data item, but you can specify a different one by passing it in via an optional second argument in thesetItems(data, [objectIdProperty]). The id value must be serializable to a string.

    var data = [

      {'id': 'l1', 'lang': 'Java', 'year': 1995},

      {'id': 'l2', 'lang': 'JavaScript', 'year': 1995},

      {'id': 'l3', 'lang': 'C#', 'year': 2000},

      {'id': 'l4', 'lang': 'Python', 'year': 1991}];

     

    // This will fire the change events and update the grid.

    dataView.setItems(data);

    You can call getItems() to get the data array back.

    Mapping rows vs items

    Ok, let's reiterate - DataView takes in a data array as an input, manipulates it, and presents the results to the grid by acting as a data provider, i.e. exposing the data provider methods getItem(index),getLength() and getItemMetadata(index). In handling grid events, it's important to always keep in mind that the row indexes the grid refers to are, in fact, the indexes into the output of the DataView! For example, if you're handling a grid onClick event and it's giving you a row index, to look up the data item, you need to call dataView.getItem(rowIndex) and not data[rowIndex].

    In general, whenever we talk about rows, we mean the data as the grid sees it, so, if you're using a DataView, that would be the output of the DataView (dataView.getItem(index)). Whenever we talk about items, we mean the input of the DataView (data[index] or dataView.getItems()[index]). You'll notice that it is somewhat confusing that getItem(index) returns a row while getItems()returns items. Unfortunately, it's this way for historical reasons. getItem(index) is part of the data provider interface. In retrospect, it would be better if the DataView exposed a getDataProvider()method.

    DataView Methods

    Since each item has a unique id, they are often used to keep track of ids/items/rows/indices and to map one to another.

    These methods are exposed by the DataView as part of the data provider interface:

    • getItems() - Returns the original data array.
    • getItem(row) - With a row index of an item in the grid, return the item.
    • getItemMetadata(idx) - Returns the item metadata at a given index.
    • getLength() - Returns the number of rows in the grid.

    DataView exposes several methods in order to map ids to items to rows in the grid to indices in the original data array:

    • getItemById(id) - With an item's id, return the item.
    • getIdxById(id) - With an item's id, return the index of the item in the original data array.
    • getRowById(id) - With an item's id, return the row of the item in the grid.
    • getItemByIdx(idx) - With an index of an item in the original data array, return the item. Equivalent to getItems()[index].
    • mapIdsToRows(idArray) - Maps an array of item ids into rows in the grid.
    • mapRowsToIds(rowArray) - Maps an array of rows in the grid into item ids.

    Synchronizing selection & cell CSS styles

    One of the most common questions about DataView is how to synchronize the selection or cell CSS styles state on DataView changes. Let's say that the user selected a row. If they then change the filter on the DataView to hide some items, the grid gets a call to invalidate all changed rows, including the selected one, but it doesn't know that the item that was displayed there has moved somewhere else. What we need to do, is to store the ids of items that were selected, and to update the selection on the grid any time the DataView is modified.

    Luckily, there is a helper method on the DataView that can take care of that:

    • syncGridSelection(grid, preserveHidden) - Synchronizes grid's selected rows with the DataView by subscribing to the grid's onSelectedRowsChanged event as well as the DataView'sonRowsChanged & onRowCountChanged events. If preserveHidden is true, it will preserve selected items even if they are not visible as rows. For example, if you select an item, change the DataView filter so that that item is no longer presented to the grid and then change it back, the item will remain selected. If preserveHidden is false, all selected items that can't be mapped onto rows are dropped.

    The implementation is really simple, and I'll include it here for the reference:

    function syncGridSelection(grid, preserveHidden) {

      var self = this;

      var selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());;

      var inHandler;

     

      function update() {

        if (selectedRowIds.length > 0) {

          inHandler = true;

          var selectedRows = self.mapIdsToRows(selectedRowIds);

          if (!preserveHidden) {

            selectedRowIds = self.mapRowsToIds(selectedRows);

          }

          grid.setSelectedRows(selectedRows);

          inHandler = false;

        }

      }

     

      grid.onSelectedRowsChanged.subscribe(function(e, args) {

        if (inHandler) { return; }

        selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());

      });

     

      this.onRowsChanged.subscribe(update);

     

      this.onRowCountChanged.subscribe(update);

    }

    NOTE: This only works with the RowSelectionModel. CellSelectionModel isn't supported yet (I'm open to pull requests!).

    There is a similar helper method to synchronize the cell CSS styles:

    function syncGridCellCssStyles(grid, key) {

      var hashById;

      var inHandler;

     

      // since this method can be called after the cell styles have been set,

      // get the existing ones right away

      storeCellCssStyles(grid.getCellCssStyles(key));

     

      function storeCellCssStyles(hash) {

        hashById = {};

        for (var row in hash) {

          var id = rows[row][idProperty];

          hashById[id] = hash[row];

        }

      }

     

      function update() {

        if (hashById) {

          inHandler = true;

          ensureRowsByIdCache();

          var newHash = {};

          for (var id in hashById) {

            var row = rowsById[id];

            if (row != undefined) {

              newHash[row] = hashById[id];

            }

          }

          grid.setCellCssStyles(key, newHash);

          inHandler = false;

        }

      }

     

      grid.onCellCssStylesChanged.subscribe(function(e, args) {

        if (inHandler) { return; }

        if (key != args.key) { return; }

        if (args.hash) {

          storeCellCssStyles(args.hash);

        }

      });

     

      this.onRowsChanged.subscribe(update);

     

      this.onRowCountChanged.subscribe(update);

    }

    Sorting

    Sorting is pretty simple:

    // Subscribe to the grid's onSort event.

    // It only gets fired for sortable columns, so make sure your column definition has `sortable = true`.

    grid.onSort.subscribe(function(e, args) {

      // args.multiColumnSort indicates whether or not this is a multi-column sort.

      // If it is, args.sortCols will have an array of {sortCol:..., sortAsc:...} objects.

      // If not, the sort column and direction will be in args.sortCol & args.sortAsc.

     

      // We'll use a simple comparer function here.

      var comparer = function(a, b) {

        return (a[args.sortCol.field] > b[args.sortCol.field]) ? 1 : -1;

      }

     

      // Delegate the sorting to DataView.

      // This will fire the change events and update the grid.

      dataView.sort(comparer, args.sortAsc);

    });

    Note that calling sort() on the DataView modifies the original data array that was passed in tosetItems(data)!

    There's also a fastSort(field, isAscending) method on the DataView to do a fast lexicographic search that is especially handy for older versions of IE.

    Updating data

    Since DataView can't automatically detect when you're changing the data, you'll need to make these updates via the DataView. These updates will be applied directly to the original data array.

    // Delete item with id 'l3' ('C#').

    dataView.deleteItem('l3');

     

    // Append item to the end.

    dataView.addItem({'id': 'l5', 'lang': 'CoffeeScript'});

     

    // Insert item at the beginning.

    dataView.insertItem(0, {'id': 'l6', 'lang': 'TypeScript'});

     

    // Update an existing item.

    var item = dataView.getItemById('l4');

    item['lang'] = 'Clojure';

    dataView.updateItem('l4', item);

    Each one of these updates will fire change events and the grid will get updated automatically.

    Batching updates

    Notice that in the example above, each update will result in the DataView recalculating its data and firing change events, resulting in the grid rerendering affected rows. If you need to make multiple changes, you should batch them up to avoid unnecessary operations:

    // Suspend recalculations until endUpdate() is called.

    dataView.beginUpdate();

     

    dataView.addItem(...);

    dataView.addItem(...);

    dataView.sort(...);

     

    // Indicate that we're done updating.

    dataView.endUpdate();

    Filtering

    Paging

    Grouping

    Advanced topics

    API reference

    Grid Options

    As included in the examples or described in stable releases:

    Option

    Default

    Description

    asyncEditorLoading

    false

    Makes cell editors load asynchronously after a small delay. This greatly increases keyboard navigation speed.

    asyncEditorLoadDelay

    100

    Delay after which cell editor is loaded. Ignored unless asyncEditorLoading is true.

    asyncPostRenderDelay

    50

     

    autoEdit

    true

    Cell will not automatically go into edit mode when selected.

    autoHeight

    false

    This disables vertical scrolling.

    cellFlashingCssClass

    “flashing”

    A CSS class to apply to flashing cells via flashCell().

    cellHighlightCssClass

    “selected”

    A CSS class to apply to cells highlighted via setHighlightedCells().

    dataItemColumnValueExtractor

    null

     

    defaultColumnWidth

    80

     

    defaultFormatter

    defaultFormatter

     

    editable

    false

     

    editCommandHandler

    queueAndExecuteCommand

    Not listed as a default under options in slick.grid.js

    editorFactory

    null

    A factory object responsible to creating an editor for a given cell. Must implement getEditor(column).

    editorLock

    Slick.GlobalEditorLock

    A Slick.EditorLock instance to use for controlling concurrent data edits.

    enableAddRow

    false

    If true, a blank row will be displayed at the bottom - typing values in that row will add a new one. Must subscribe to onAddNewRow to save values.

    enableAsyncPostRender

    false

    If true, async post rendering will occur and asyncPostRender delegates on columns will be called.

    enableCellRangeSelection

    null

    **WARNING**: Not contained in SlickGrid 2.1, may be deprecated

    enableCellNavigation

    true

    Appears to enable cell virtualisation for optimised speed with large datasets

    enableColumnReorder

    true

     

    enableRowReordering

    null

    **WARNING**: Not contained in SlickGrid 2.1, may be deprecated

    enableTextSelectionOnCells

    false

     

    explicitInitialization

    false

    See: Example: Explicit Initialization

    forceFitColumns

    false

    Force column sizes to fit into the container (preventing horizontal scrolling). Effectively sets column width to be 1/Number of Columns which on small containers may not be desirable

    forceSyncScrolling

    false

     

    formatterFactory

    null

    A factory object responsible to creating a formatter for a given cell. Must implement getFormatter(column).

    fullWidthRows

    false

    Will expand the table row divs to the full width of the container, table cell divs will remain aligned to the left

    headerRowHeight

    25

     

    leaveSpaceForNewRows

    false

     

    multiColumnSort

    false

    See: Example: Multi-Column Sort

    multiSelect

    true

     

    rowHeight

    25

     

    selectedCellCssClass

    “selected”

     

    showHeaderRow

    false

     

    syncColumnCellResize

    false

    If true, the column being resized will change its width as the mouse is dragging the resize handle. If false, the column will resize after mouse drag ends.

    topPanelHeight

    25

     

    Column Options

    Options which you can apply to the columns objects.

    Option

    Default

    Description

    asyncPostRender

    null

    This accepts a function of the form function(cellNode, row, dataContext, colDef) and is used to post-process the cell’s DOM node / nodes

    behavior

    null

    Used by the the slick.rowMoveManager.js plugin for moving rows. Has no effect without the plugin installed.

    cannotTriggerInsert

    null

    In the “Add New” row, determines whether clicking cells in this column can trigger row addition. If true, clicking on the cell in this column in the “Add New” row will not trigger row addition.

    cssClass

    ””

    Accepts a string as a class name, applies that class to every row cell in the column.

    defaultSortAsc

    true

    When set to true, the first user click on the header will do a ascending sort. When set to false, the first user click on the header will do an descending sort.

    editor

    null

    The editor for cell edits {TextEditor, IntegerEditor, DateEditor…} See slick.editors.js

    field

    ””

    The property name in the data object to pull content from. (This is assumed to be on the root of the data object.)

    focusable

    true

    When set to false, clicking on a cell in this column will not select the row for that cell. The cells in this column will also be skipped during tab navigation.

    formatter

    null

    This accepts a function of the form function(row, cell, value, columnDef, dataContext) and returns a formatted version of the data in each cell of this column. For example, settingformatter to function(r, c, v, cd, dc) { return “Hello!”; } would overwrite every value in the column with “Hello!” SeedefaultFormatter in slick.grid.js for an example formatter.

    headerCssClass

    null

    Accepts a string as a class name, applies that class to the cell for the column header.

    id

    ””

    A unique identifier for the column within the grid.

    maxWidth

    null

    Set the maximum allowable width of this column, in pixels.

    minWidth

    30

    Set the minimum allowable width of this column, in pixels.

    name

    ””

    The text to display on the column heading.

    rerenderOnResize

    false

    If set to true, whenever this column is resized, the entire table view will rerender.

    resizable

    true

    If false, column can no longer be resized.

    selectable

    true

    If false, when a row is selected, the CSS class for selected cells (“selected” by default) is not applied to the cell in this column.

    sortable

    false

    If true, the column will be sortable by clicking on the header.

    toolTip

    ””

    If set to a non-empty string, a tooltip will appear on hover containing the string.

    width

     

    Width of the column in pixels. (May often be overridden by things like minWidth, maxWidth, forceFitColumns, etc.)

    Grid Events

    SlickGrid exposes the following events:

    • onScroll ({ scrollLeft: number, scrollTop: number })
    • onSort ({ multiColumnSort: boolean, sortCol: Object, sortCols: Object[], sortAsc: boolean })
    • onHeaderContextMenu ({ column: Object })
    • onHeaderClick ({ column: Object })
    • onMouseEnter ({})
    • onMouseLeave ({})
    • onClick ({ row: number, cell: number })
    • onDblClick ({ row: number, cell: number })
    • onContextMenu ({})
    • onKeyDown ({ row: number, cell: number })
    • onAddNewRow ({ item: any, column: Object })
    • onValidationError ({ editor: Object, cellNode: Object, validationResult: Object, row: number, cell: number, column: Object })
    • onViewportChanged ({})
    • onColumnsReordered ({})
    • onColumnsResized ({})
    • onCellChange ({ row: number, cell: number, item: any })
    • onBeforeEditCell ({ row: number, cell: number, item: any, column: Object })
    • onBeforeCellEditorDestroy ({ editor: Object })
    • onHeaderCellRendered ({ node: Object, column: Object })
    • onBeforeHeaderCellDestroy ({ node: Object, column: Object })
    • onBeforeDestroy ({})
    • onActiveCellChanged ({ row: number, cell: number }|null)
    • onActiveCellPositionChanged ({})
    • onDragInit
    • onDragStart
    • onDrag
    • onDragEnd
    • onSelectedRowsChanged ({ rows: number[] })
    • onCellCssStylesChanged ({ key: string, hash: Object })

    You can subscribe to the above events using a syntax similar to:

    gridInstance.onXYZEvent.subscribe(function(e, args){

        //event handling code.

    });

    The handler is called with these arguments:
    e: Slick.EventData, which mimics the jQuery EventData.
    args: event specific data

    Event handlers can also be removed with

    gridInstance.onXYZEvent.unsubscribe(fn);

    Providing data to the grid

    Overview

    The data is passed to the grid via the constructor and can also be accessed using thesetData(data) and getData() methods. Data itself can be either an array-like object with alength property and an indexer (data[index]) or a custom data provider implementing the following interface:

    • getLength() - returns the number of data items in the set
    • getItem(index) - returns the item at a given index
    • getItemMetadata(index) - returns the metadata for the item at a given index (optional)

    Item Metadata

    getItemMetadata provides a powerful way of specifying additional information about a data item that let the grid customize the appearance and handling of a particular data item. The method should returnnull if the item requires no special handling, or an object in the following general format:

    {

      // properties describing metadata related to the item (i.e. grid row) itself

      "<property>": value,

      "<property>": value,

     

      // properties describing metadata related to individual columns

      "columns":  {

        "<column index>":  {

          // metadata indexed by column index

          "<property>": value,

          "<property>": value

        },

     

        "<column id>":  {

          // metadata indexed by column id

          "<property>": value,

          "<property>": value

        }

      }

    }

    Row-level properties

    • cssClasses (string) - One or more (space-separated) CSS classes to be added to the entire row.
    • focusable (boolean) - Whether or not any cells in the row can be set as "active".
    • selectable (boolean) - Whether or not a row or any cells in it can be selected.

    Column-level properties

    • focusable (boolean) - Whether or not a cell can be set as "active".
    • selectable (boolean) - Whether or not a cell can be selected.
    • formatter (Function) - A custom cell formatter.
    • editor (Function) - A custom cell editor.
    • colspan (number|string) - Number of columns this cell will span. Can also contain "*" to indicate that the cell should span the rest of the row.

    Order of checks

    When looking up a property, the grid checks in the following order:

    1. Row-level item metadata.
    2. Column-level item metadata by column id.
    3. Column-level item metadata by column index.
    4. Column definition.
    5. Grid options.
    6. Grid defaults.

    Examples

    See colspan example.

  • 相关阅读:
    linux下netstat命令详解
    linux下strace命令详解
    /proc/uptime
    趣味理解网关、路由等概念
    OPENCV运行的问题,自带的程序可以运行,但是自己制作的QT报错
    第九章 MIZ702 ZYNQ片上ADC的使用
    第四章 MIZ701 ZYNQ制作UBOOT固化程序
    第三章 VIVADO 自定义IP 流水灯实验
    第一章 MIZ701 VIVADO 搭建SOC最小系统HelloWorld
    Zynq-7000 MiZ701 SOC硬件使用手册
  • 原文地址:https://www.cnblogs.com/zfc2201/p/3800164.html
Copyright © 2011-2022 走看看