mleibman / slickgrid Goto Github PK
View Code? Open in Web Editor NEWA lightning fast JavaScript grid/spreadsheet
Home Page: http://wiki.github.com/mleibman/SlickGrid
License: MIT License
A lightning fast JavaScript grid/spreadsheet
Home Page: http://wiki.github.com/mleibman/SlickGrid
License: MIT License
The addition of a Slick.Data.DataView.reverse() method.
Currently toggling between an ascending and descending sort on a column gives you inconsistent results. By doing the reversal in the comparer function (ie - multiplying by -1 for desc) any items which are equal (or empty) won't be reversed. This results in the inconsistent row ordering across sorts.
If the DataView had a function that reversed the items:
function reverse() {
items.reverse();
refresh();
}
Then in the onSort for the grid you would just need to sort the first time and then use the reverse method to toggle between ascending and descending.
This happens when you shrink a column and the mouse is hovering over the column on mouseup. The bug does not occur in Firefox.
The various SlickGrid modules use the '$' shorthand for jQuery, pulling it from the global namespace. This can cause conflicts with other libraries (notably) that may use the same $ variable.
Suggest adding a $ parameter to the wrapper functions for the
various modules, and passing jQuery as the argument.
There's currently no way to access the configuration options for the datepicker since it's buried in the Date editor. Manipulating these options is something that should be possible without replacing the default datepicker implementation.
Here's a patch to expose the datepicker options as an attribute of the editor's prototype:
diff --git a/slick.editors.js b/slick.editors.js
index 1654666..7982463 100644
--- a/slick.editors.js
+++ b/slick.editors.js
@@ -192,12 +192,8 @@ var DateCellEditor = function($container, columnDef, value, dataContext) {
}
$input.appendTo($container);
$input.focus().select();
- $input.datepicker({
- showOn: "button",
- buttonImageOnly: true,
- buttonImage: "../images/calendar.gif"
- });
+ this.dp_options.onClose = function() { this.focus(); };
+ $input.datepicker(this.dp_options);
$input.width($input.width() - 18);
};
@@ -236,6 +232,12 @@ var DateCellEditor = function($container, columnDef, value, dataContext) {
this.init();
};
+DateCellEditor.prototype.dp_options = {
+ showOn: "button",
+ buttonImageOnly: true,
+ buttonImage: "../images/calendar.gif"
+};
+
var YesNoSelectCellEditor = function($container, columnDef, value, dataContext) {
var $select;
var defaultValue = value;
I noticed this yesterday when I was working on my application. I currently need to serve all static content from another URI context than the one that actually generates the page with SlickGrid. It seems like this wouldn't be that unusual a thing to do, so I suggest adding an option that can be used to specify the base location of static resources.
I've currently hacked in this support with the patch below, but you might be able to come up with something more elegant.
Cheers,
ast
diff --git a/slick.editors.js b/slick.editors.js
index 1654666..f67cfdf 100644
--- a/slick.editors.js
+++ b/slick.editors.js
@@ -32,13 +32,13 @@ var YesNoCellFormatter = function(row, cell, value, columnDef, dataContext) {
};
var BoolCellFormatter = function(row, cell, value, columnDef, dataContext) {
- return value ? "<img src='../images/tick.png'>" : "";
+ return value ? "<img src='" + Slick.imageLocation + "/tick.png'>" : "";
};
var TaskNameFormatter = function(row, cell, value, columnDef, dataContext) {
// todo: html encode
var spacer = "<span style='display:inline-block;height:1px;width:" + (2 + 15 * dataContext["indent"]) + "px'></span>";
- return spacer + " <img src='../images/expand.gif'> " + value;
+ return spacer + " <img src='" + Slick.imageLocation + "/expand.gif'> " + value;
};
var ResourcesFormatter = function(row, cell, value, columnDef, dataContext) {
@@ -48,14 +48,14 @@ var ResourcesFormatter = function(row, cell, value, columnDef, dataContext) {
return "";
if (columnDef.width < 50)
- return (resources.length > 1 ? "<center><img src='../images/user_identity_plus.gif' " : "<center><img src='../images/user_identity.gif' ") +
+ return (resources.length > 1 ? "<center><img src='" + Slick.imageLocation + "/user_identity_plus.gif' " : "<center><img src='" + Slick.imageLocation + "/user_identity.gif' ") +
" title='" + resources.join(", ") + "'></center>";
else
return resources.join(", ");
};
var StarFormatter = function(row, cell, value, columnDef, dataContext) {
- return (value) ? "<img src='../images/bullet_star.png' align='absmiddle'>" : "";
+ return (value) ? "<img src='" + Slick.imageLocation + "/bullet_star.png' align='absmiddle'>" : "";
};
@@ -192,13 +192,11 @@ var DateCellEditor = function($container, columnDef, value, dataContext) {
}
$input.appendTo($container);
- $input.focus().select();
- $input.datepicker({
- showOn: "button",
- buttonImageOnly: true,
- buttonImage: "../images/calendar.gif"
- });
+ this.dp_options.onClose = function() { this.focus(); };
+ this.dp_options.buttonImage = Slick.imageLocation + "/calendar.gif"
+ $input.datepicker(this.dp_options);
$input.width($input.width() - 18);
+ $input.focus().select();
};
@@ -236,6 +234,11 @@ var DateCellEditor = function($container, columnDef, value, dataContext) {
this.init();
};
+DateCellEditor.prototype.dp_options = {
+ showOn: "button",
+ buttonImageOnly: true
+};
+
var YesNoSelectCellEditor = function($container, columnDef, value, dataContext) {
var $select;
var defaultValue = value;
@@ -572,7 +575,7 @@ var StarCellEditor = function($container, columnDef, value, dataContext) {
}
this.init = function() {
- $input = $("<IMG src='../images/bullet_star.png' align=absmiddle tabIndex=0 title='Click or press Space to toggle' />");
+ $input = $("<IMG src='" + Slick.imageLocation + "/bullet_star.png' align=absmiddle tabIndex=0 title='Click or press Space to toggle' />");
if (defaultValue)
$input.css("opacity", 1);
diff --git a/slick.grid.js b/slick.grid.js
index ac1d139..b2bb171 100644
--- a/slick.grid.js
+++ b/slick.grid.js
@@ -1339,5 +1339,5 @@
}
// Slick.Grid
- $.extend(true, window, { Slick: { Grid: SlickGrid }});
+ $.extend(true, window, { Slick: { Grid: SlickGrid, imageLocation: "../images" }});
})();
Looks like the jQuery Rule plugin is using the internal jQuery function setArray which was removed in 1.4.2.
Uncaught TypeError: Property 'setArray' of object # is not a function
There is a patch for the rule plugin available here:
http://plugins.jquery.com/node/13311
User can size the column by dragging the resize handle of a header column. Usually the resize handle can be shown again after dragged the header column. However, after dragging a header column with the ellipsis appeared, the resize handle cannot be located any more. It happened in IE.
slickgrid should use jquery ui's theme classes to support themeroller CSS styles.
This has been a problem for some time now, I never got the keyDown handler working unless I comment out the following in handleKeyDown in v1.3.2/mleibman-SlickGrid-e64ff7c:
function handleKeyDown(e) {debugger; //alert("handleKeyDown");
// give registered handler chance to process the keyboard event
var handled = (self.onKeyDown && // a handler must be registered
/*gridDataGetItem(currentRow) &&*/ // grid must be non-empty, have cell navigation enabled and have valid row selected as current
To reproduce, enable "select" behavior for title column in example1 and add a keyDown handler:
{id:"title", name:"Title", field:"title", behavior:"select"},
grid.onKeyDown = function(e) {
// select all rows on ctrl-a
if (e.which != 65 || !e.ctrlKey)
return false;
alert("ctrl-a handler called");
return true;
};
This handler won't be called unless above check is disabled in handleKeyDown. currentRow is always undefined.
Furthermore, handleKeyDown is never called in Firefox (above works for IE). For Firefox, I manually need to set focus in onClick:
if (navigator.appName!="Microsoft Internet Explorer") {
var mycontainer = container.find(".grid-canvas").focus();
}
Is there a better way to do this?
Columns should not use DOM ids as it causes pollution in the DOM ID space. Possibly related to Issue #14.
on line 319, there's special casing for msie browsers that prevents text selection. What's the reason for that prevention?
I'm displaying hyperlinks in the grid, so I don't want editing to start on a single click. However, in this mode, you can't tab between cells in an editing session. Based on other frameworks and what I believe users expect, I think this behavior is incorrect.
I've attached a patch that allows keyboard editing to continue even if editOnDoubleClick is true.
diff --git a/slick.grid.js b/slick.grid.js
index f721d03..b824d4c 100644
--- a/slick.grid.js
+++ b/slick.grid.js
@@ -1000,7 +1000,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////
// Cell switching
- function setSelectedCell(newCell,async) {
+ function setSelectedCell(newCell,async,keynav) {
if (currentCellNode != null) {
makeSelectedCellNormal();
$(currentCellNode).removeClass("selected");
@@ -1016,7 +1016,7 @@
scrollSelectedCellIntoView();
- if (options.editable && !options.editOnDoubleClick && isCellPotentiallyEditable(currentRow,currentCell)) {
+ if (options.editable && (!options.editOnDoubleClick || keynav) && isCellPotentiallyEditable(currentRow,currentCell)) {
clearTimeout(h_editorLoader);
if (async)
@@ -1033,8 +1033,8 @@
}
}
- function setSelectedCellAndRow(newCell,async) {
- setSelectedCell(newCell,async);
+ function setSelectedCellAndRow(newCell,async,keynav) {
+ setSelectedCell(newCell,async,keynav);
if (newCell)
setSelectedRows([currentRow]);
@@ -1134,7 +1134,8 @@
}
function gotoDir(dy, dx, rollover) {
- if (!currentCellNode || !options.enableCellNavigation) return;
+ if (!currentCellNode || !options.enableCellNavigation) return;
+ keynav = (currentEditor != null);
if (!Slick.GlobalEditorLock.commitCurrentEdit()) return;
var nextRow = rowsCache[currentRow + dy];
@@ -1159,7 +1160,7 @@
if (nextRow && nextCell && nextCell.length) {
- setSelectedCellAndRow(nextCell[0],options.asyncEditorLoading);
+ setSelectedCellAndRow(nextCell[0],options.asyncEditorLoading,keynav);
// if no editor was created, set the focus back on the cell
if (!currentEditor)
@@ -1345,4 +1346,4 @@
// Slick.Grid
$.extend(true, window, { Slick: { Grid: SlickGrid }});
-})();
\ No newline at end of file
+})();
Steps to reproduce.
Update "example1-simple.html" data population to loop the creation grid 30 times.
Something like this:
// HTML
<td valign="top" width="50%">
<div id="container"></div>
</td>
// Script
container = $("#container");
for (i = 30; --i > 0;) {
grid = $("<div id='grid".concat(i).concat("' class='grid'></div>"));
container.append(grid);
new Slick.Grid(grid, data, columns, options);
}
Expected.
All grids to display column values the same width as the column headers.
Instead.
In last three grids the column value widths are shrunk to fit while the headers remain the correct width.
The resize handling should disable propagation of the click event so that dragging the resize handle does not also trigger a sort.
Hi , i want to submit the grid data through a form , and am stuck , could you please suggest how we can do this .
This only happened on columns not visible at the initial load. Firefox works, but not IE.
Steps:
Result:
As pointed out on mailing list, after setting height of grid holder div to bigger value, rows are not populated correctly.
To reproduce call
$('#myGrid').height('2000px').trigger('resize')
from Firebug on any of examples (I've tested it on http://mleibman.github.com/SlickGrid/examples/example2-formatters.html)
Here's a different way to get the width that works, but I'm not sure if the license is compatible:
http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels
I would like to see a row selector column, e.g. checkboxes, that would allow a user to select a row(s) by clicking on the first column or a checkbox in the first column.
I have written my own formatter and handlers to provide my users such functionality.
http://groups.google.com/group/slickgrid/browse_thread/thread/b8aab669553996ea
Users that have read-only grids have no need for editors and should not be forced to include slick.globaleditorlock.js or slick.editors.js.
jquery-ui 1.8 is very close to being released, and we should make slickgrid compatible with it.
The grid contains the DOM elements, but it gets rendered blank.
I assume that multiple-header-rows feature is not supported yet.
Basically, I need this feature to implement filters for DataView. This first header row works as normal and the second header row may contain controls to filter data such as text box, check box, drop down select box, date control, etc. This feature replaces the filter controls ('Show tasks with % at least' and 'title including') shown in example5-collapsing.html file.
Thanks,
When a model is set up using setItems, like in Example 4, it creates a mapping from the unique id to its position in the items array called idxById. Whenever deleteItem or insertItem is called on the model, a splice occurs on the items array, so the idxById is no longer accurate for any idx that comes after the inserted/deleted idx.
For example, with some random id numbers:
idxById[99] = 0, idxById[98] = 1, idxById[97] = 2...
and our items array is:
items[0] = {id: 99}, items[1] = {id: 98} and so on.
deleteItem takes in a unique id and gets the position in the items array from idxById, so deleteItem(99) gets idxById[99], which is 0, splices the items array at position 0. After the splice, all subsequent items are moved down a slot, so 98 is now really 0. If you call deleteItem(98) now, it will splice at items[1] instead, which will remove our id of 97 instead of the intended action.
Right now, there is no way to override the overflow-y value using CSS because it's hardcoded into the style property of divMainScroller.
There's another problem in that even if overflow-y is set to auto, lacking slickgrid will not fill the horizontal gap that shows up when the scrollbar is hidden. This means that if overflow-y is set to auto and you don't have enough rows to fill the grid vertically, then the grid looks like it has a scrollbar-width offset on the right.
Slickgrid should automatically widen to fill the scrollbar gap if there are less rows than required to cause a scrollbar to appear.
Scenario 1.
Steps to Reproduce.
Expected.
The grid should render as it normally would.
Instead.
The grid is rendered without any rows or a scrollbar.
Scenario 2.
Steps to reproduce.
Expected.
The grid to disappear and then re-appear in the original state.
Instead.
The grid disappears and then when it re-appears the scroll position is reset and some/all rows are missing.
I need the row style to cover 100% container width when columns do not take up the full width. Part one was covered via style class:
.slick-row.ui-widget-content, .slick-row.ui-state-active {
position: absolute;
border: 0px;
width:100%;
}
But to make this fully work in IE or Chrome and correctly account for vertical scroll bar, we had to modify the script:
resizeCanvas = function resizeCanvasFn() {
...
// IE/Chrome require 100% width when < container width
if(totalWidth > $divMainScroller.get(0).clientWidth)
{
$divMain.width(totalWidth);
}
else
{
$divMain.width('100%');
}
It would be great if this could be fixed so that either it becomes style controllable behavior or a grid option. I personally don't see why the row style should not cover the full canvas width per default!
There are two bugs, which I believe are probably related.
Bug #1:
There is a filtering bug, which can be reproduced easily in Example 4. If the first row is the only row of the filter, it is not displayed if "enableAddRow" is set to "false" and the grid is not scrolled to the bottom before the filter is applied.
Steps to reproduce:
Within the "onPagingInfoChanged" event, change to the following code:
dataView.onPagingInfoChanged.subscribe(function(pagingInfo) {
var isLastPage = pagingInfo.pageSize*(pagingInfo.pageNum+1)-1 >= pagingInfo.totalRows;
grid.setOptions(pagingInfo.pageSize==0);});
Within the "options" declaration, either remove "enableAddRow" or set it to false.
To see bug:
Load page, enter "Task 0" as the filter text. The row containing that task will NOT display but the row count will read 1.
Now, reload the page, scroll to the bottom of the grid, and then enter "Task 0" as the filter text. The row containing that task WILL display and the row count will read 1.
Bug #2
In the current live example 4, if you enter "Task 0" as the filter, the row to add a new row disappears.
Header Columns and Cells are extending are beyond the grid canvas when autosizeColumns is called, causing a wrap around which hides the last column.
Header Columns don't wrap around, but are misaligned with the columns beneath.
I traced the difference in width to the sum of the borders and padding for each cell in a row.
Modifying the .css file to remove the left and right padding and the border makes everything align properly.
Steps to reproduce:
It's easier to think about visibility in the positive, especially since setColumnVisibility is visible-based, not hidden-based.
After displaying data and possibly filtering the results, it would be nice to be able to have a multiple row select using the standard Control-Click or Shift-Click to get numerous rows. This information should then be retrievable to allow a developer to identify the multiple, non-continuous, selected rows.
Two issues:
To fix these issues, slickgrid should:
Simply absolutely positioning the arrow to the right of the column does not work because the text is visible under the sort arrow. The text should elide before the sort arrow and should not be seen under it.
This should be a pretty easy fix if we can stuff the title into a span/div inside the actual column header.
I am very new to the SlickGrid , i have found it very useful , however i want to do a sort on pie chart values created by sparklines , Could you please suggest me how to do this , would really appreciate the help
The slickgrid widget should not have an external css dependency. All necessary layout (non-stylistic) rules should be set within the widget itself. Stylistic rules can be set by user or via jquery ui themes. Lack of stylistic rules should not break slickgrid.
slickgrid should use jQuery's widget framework to implement slickgrid as a widget. Users should be able to instantiate slickgrid using "$(...).slickgrid()" instead of "new SlickGrid()".
for reference: http://bililite.com/blog/understanding-jquery-ui-widgets-a-tutorial/
If you have two grids in one page and reorder a column in one grid, the styles of the other grid gets messed up.
SlickGrid does not look fine under the IE6. Each time updating code from the downloaded source, there will be some amount of time spent to work with IE6. Should I skip the IE6 or continue to work with it or need a better way? I need suggestions regarding IE6 compatibility.
Thanks,
The 96ae851 commit seems to be a workaround for remote_model's non-functional approach to being a dynamic data provider. I think the remote_model should have been changed instead to support explicit gridDataGet* functions.
Right now, we're supplying data, which initializes all three items. I think static data and functional data providers should be separate and explicit. The user can either set data = [], or set the gridDataGet* functions, but not both. In fact, I think we should just keep the functional approach and remove implicit support for arrays. We can then just add a simple array_grid_data.js that wraps the gridDataGet* functions around an array.
Finally, gridDataGet* functions should either be initialized from outside of the data.* scope, or be allowed to change. We're initially get the gridDataGet* from the data object, but lock into the first versions of the function. If the goal of the data object is to be fully dynamic, we should allow the gridDataGet* methods on the data oject to change, and not lock into the first functions. If our intention is to lock into the functions, then the functions should be supplied higher up in the initialization options, not inside the data object.
I don't have control over the data source I'm using with the grid so it would be nice if I could tell DataView which field has the id in it. For example:
dataview.setItems(data, 'contact_id')
maxWidth column options are not applied at first render, but are on drag start. FF 3.6.3 mac
shrink/grow algo seems faulty
If you disable column resizing in the column options force fit columns will not resize the column. This means you can't disable the user from resizing the columns without also disabling force fit columns from doing it's thing.
on line 1094 (of current revision), CSS selector for cell reads:
".c[cell=" + cell + "]"
but should be:
".slick-cell[cell=" + cell + "]"
this causes updateCell to be ineffective since it does not find the cell.
I've got grid with enableCellNavigation=true and autoEdit=false. With such an autoEdit settings i would expect and find more comfortable if navigation by keys is disabled while cell is edited.
Example situation:
I've got an integer cell, navigate to it with keys, hit Enter to edit, value is selected (great when i want to change entire value, but now i want to change only last digit), hit left arrow - cell on the left is selected! (this task can not be done without using a mouse)
Proposed:
hit left arrow - value is deselected and caret moves to left
In a grid with horizontal scrollbar, when you try to move the last column to the first position, the scrollbar won't scroll, have to repeat the drag-n-drop several times.
Setting POSTPROCESSING_DELAY = 0 feels snappier.
Is there a reason why every row rendering has to be delayed 60ms?
To reproduce, update "example1-simple.html" data population loop to go to 100,000 (instead of 500). Now load the HTML file in IE (I tested in v8 and simulated v7). When you use the scrollbar to move to the very end, instead of "Task 99999" you see "Task 47721" in IE8 and "Task 53686" in simulated IE7.
I think this effect is caused by IE handling height of the grid-canvas element incorrectly. If you look at the above grid in Developer Tools, it says "height: 1342177.27px" which is clearly incorrect. This seems to be a limitation of IE and the only way to "fix" it (I think) is to also virtualize the grid-canvas height...
Right now, autosizeColumns is getting called each time setColumnVisibility is called. When you make multiple columns visible via multiple calls to setColumnVisibility, it has the bizarre effect of logrithmically setting the newly visible column widths, since each column goes through autosizeColumns once more than the next.
There should be a way to set the visibility on multiple columns at once so that autosizeColumns is only called once after all the columns' visibility has been changed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.