Login Register

Dojo Grid 1.1

Now that everyone has had a chance to take the grid for a test drive, I'd like to work on the Dojo Grid development road map.

Please comment here, file tickets, or send me e-mails, or find me on irc, and tell me what you like and dislike about the grid.

Auto Filter

Haven't used Grid much yet - plan to though. I know one thing I'd like is to be able to setup a persistent row on the top (or wherever), under the header row that would allow for filtering similar to Excel's auto-filter feature. I know filtering grid data is doable with some code, but ideally it'd be nice to be able to have this functionality built in.

Some wishes for Christmas

Hello,
To Have the possibility to remove the Edit option.
To Have the possibility to hide the scrollbars.
To Have the possibility to create subrows easily from the same datastore.
Thx Santa
Kilroy

Two words: Tree Grid

*

A hacky way to remove scrollbars

It's not great but it seems to work for me

dojo.addOnLoad(
    function()
    {
        var nl = dojo.query(".dojoxGrid-scrollbox");
        dojo.forEach(nl, function (n) { n.style.overflow = "auto"; });
       
    }
);

It would be nice if Grid

It would be nice if Grid will acts as any other widget. I mean sizing problems (see bug #4900). Also out-of-box support for formatters which returns widgets instead of html code would be nice (I mean formatters, not editors).

server paging, sorting and filtering

First, thanks for the great grid widget.

Requests:

* Maybe this is more about the model than the grid itself, but making server paging, sorting and filtering easy is the biggest thing for me. For a lot of applications, it's really required. See the post and comments on http://dojotoolkit.org/book/dojo-book-0-9-1-0/part-2-dijit-dojo-widget-l...

* Resolving the sizing issue mentioned above would also be greatly appreciated.

Rhyme & Reason
Online tools for poets and lyricists

dojox.grid.cell constructor + more

Hi,

Love the grid.

Could we change the cell constructor to the following so we can specify editors as strings instead of functions? I'm generating the structure/layout server side and things need to be quoted...

constructor: function(inProps){
	dojo.mixin(this, inProps);
	if (this.editor) {
		var e = this.editor;
		if (dojo.isString(e)) {
			e = dojo.getObject(e);
		}
		this.editor = (dojo.isFunction(e)) ? new e(this) : e;
	}
 },

A couple of other things would be:
o Column selection (Ctrl+Click or Shift+Click)
o A grid loading sprite to show while waiting for server side data
o A built in grid counter

Cheers

Filtering + dojo Grid foot

Hello,

This is a very nice grid,

but I want take a foot in the Dojo Grid and i don't know how I could do this.
And I want to do filtering special items. For example name of a person.
I have 1000 persons in a database and I want to see only persons starting with an 'A' (or so).
I hope you can help me and this comment are not to silly for you.

so far
mikrama

Christmas wishes

hi dylan,

My wishes for christmas:
* More examples for the celleditors!
* Use all kinds of form-elements from dijit as cell-editors(especially filtering-select and dropdownbutton).

Keep up the good work, I really appreciate the work you dojo-guys have laid down in this framework!

Selected row css

Thia is a minor thing and easy enough for me to change, but I would suggest changing the default color of selected rows to be darker. Right now they are hardly darker than the regular rowes (or at least every second one...). There also seems to be a little funkiness with the selection. Sometimes (with non-editable cells) the cursur changes to an insert caret and you end up selecting in the HTML DOM sense rather than at the grid/row level. Not sure how else to explain it...

Rhyme & Reason
Online tools for poets and lyricists

show selection when selected, not after leaving row.

When a row is clicked & gets selected the color does not change until the cursor is moved off the row.

I noticed this & a client has commented on it. Not a big deal, but if you're at the polishing stage it'd be nice to smooth this out.

This may just be a CSS issue.

Thanks

Wishes

Dear Santa

I would love a grid where the user can:

  • Resize column
  • Add/remove column usign right click in header - like in windows file explorer(with XML/json feed)
  • reorder column (drag a column left/right to reorder the column display)
  • Idealy a row can be dragable (eg. catalogue search result to be dragged in a shopping basket)
  • managed select and multiple select (where multiselections using CTR key would be supported)
  • Live grid - No pagination - load data as the user scroll - eg.openrico , new Yahoo email grid.(that would be awesome)
  • keyboard key up/down supported to got up and down in the list.

Babas

Virtual scrolling already supported

Well, Christmas came early for you, because the grid already supports virtual scrolling. See discussion about implementing grid sorting, paging and virtual scrolling.

Embeddable Widgets

I did some work last month that involved embedding fairly simple widgets into the grid and it was quite painful. I had to end taking the approach of embedding the markup for a widget, manually parsing it, and then hacking away a lot of the core features of the grid (mostly stuff that triggers redraws, which would hose the whole situation since the widget markup in the model is different from the widget that i created via the manual parse that lives in the grid. IOW, all of the cool grid features.) So, in the end, I basically ended up with a really heavy table...but I keep telling myself that the effort of making the grid work for my situation will be worth it if widgets become first class citizens as part of the data model. At that point, I'd get back the pieces of it that I stripped away.

Regardless of how you do it though, it seems to me that this is one feature that is really crucial for introducing. In the meantime, any hints Bryan might offer on the blog as workarounds would be much appreciated.

grid improvement ideas

Here's some things I'd like to see implemented in the grid/datastore...

  • Modify the datastore read api to include a count method that accepts the same input parameters as the fetch. Currently the count of the total result set has to be returned with the fetch request which means a count has to be performed for every page retrieved in the result set. This is inefficient and can slow down the response time on the server side. You only really need to do a count once at the start and when a filter applied to a fetch changes.
  • Provide a metadata api for the datastore so the grid headers can be created from datastore metadata instead of needing to be defined explicitely in the model.
  • Improve the performance of rendering a page. When scrolling down in a result set there is a noticeable and annoying lag in rendering the page.
  • Make it easy to add widgets to cells, in particular column headers. For example it would be great to be able to add a drop down menu to a column header to provide options for sorting and filtering.
  • The rico live grid has a nice resize feature where the grid will only display the number of rows that can be displayed on the page, even if the user resizes the browser. This feature would be nice to have.
  • I believe your last bullet

    I believe your last bullet is rowsPerPage="X"... it should force the Grid to only load X rows of data at a time, and loads more as you scroll....

    -Karl

    I don't think its the same

    The rico grid is smarter because it will automatically adjust the rowsPerPage value based on the viewport. So if the user resizes the browser, the rows per page will be adjusted automatically to avoid having more scrollbars.

    dojox.grid.editors.FilteringSelect (solved / peer review ?)

    A dojox.grid.editors.FilteringSelect would be great. I ended up needing 1) a regular filtering select that ran off of static data from the page and 2) a filtering select that could look up a name from a list of > 9K remotely.

    So, I ended up doing this -- would be great to see something like this included.

    I'm new to dojo -- if there's something whacky below, please set me straight -- otherwise, maybe others can use this?

    // this is the formatting function when using a dojox.grid.editors.DLFilteringSelect
    //  - datastore.js has been tweaked to know about column names (subject for another post) 
    formatFilteringSelect = function(inDatum, inRow) {
        if (inDatum != dojox.grid.na) {
            var col = this.editorProps.display_field;
            return this.grid.model.getDatumCx(inRow, col);
        }
        else 
            return dojox.grid.na;		
    }
    
    
    
    dojo.declare(
    	"dijit.form.DLFilteringSelect",
    	[dijit.form.FilteringSelect],
    	{
    // fix dijit.form.FilteringSelect to behave in a grid -- see below
    
    	setDisplayedValue:function(/*String*/ label){
    	// summary:
    
    	//	dijit.form.FilteringSelect.setDisplayedValue is public and insists on doing a reverse lookup
            // (it would be sweet if this could be optional)
            // but grid stuff wants to call this to just tell the thing what to display before a lookup is done.
    
    	//  anyway, override that just assume that this is only being called by dojox.grid.editors.DLFilteringSelect
        // and assume that when this gets called something else is setting the value
        
    	this.textbox.value=label;
    	this._lastDisplayedValue=label;
    
    }
    
    
    });
    
    
    
    dojo.declare("dojox.grid.editors.DLFilteringSelect", dojox.grid.editors.Dijit, {
    	editorClass: "dijit.form.DLFilteringSelect",
    
        // grid cell editor provides a Filtering select (modified from dojox.grid.editors.ComboBox class
        // use like in the dojox.grid.editors.Select example
    
        // options: text of each item
    	// values: value for each item   (both like dojox.grid.editors.Select) 
     
        // or
        
        // storeClass : class name of an alternate store to use 
        // storeProps : properties passed to the store constructor   
        
        // e.g.
        // storeClass : 'dojox.data.QueryReadStore'
        // ,storeProps : {url: 'EV_RemoteCall.php'}
    
    
    	constructor: function(inCell){
    		this.searchDelay = this.cell.searchDelay;
    		this.values = this.cell.query;
    	},
    
    	createEditor: function(inNode, inDatum, inRowIndex){
    		return new this.editorClass(this.getEditorProps(inDatum, inRowIndex), inNode);
    	},
    
    	attachEditor: function(inNode, inDatum, inRowIndex){
    		inNode.appendChild(this.editor.domNode);
    		this.editor.cellRow = inRowIndex;
    		// stash the grid row in the editor 
    		// when it is done updating (getValue() below) we'll use it to 
            //  updated the display value back in the store.  
            // the formatSelect function will use this displayValue to put the name in the cell 
    
    		var model = this.cell.grid.model;
            var v = '';
            var dv = '';
            
            if (this.cell.editorProps && this.cell.editorProps.storeClass) {
                // this is to make the optional use of QueryReadStore.js work
                // below is unique to the datastore -- 
                //  e.g. this field is always the value -- e.g. PERSON_ID 
                //   -- the display_field might be PERSON_NAME
        		var col = this.cell.editorProps.display_field;
                dv = model.getDatumCx(inRowIndex, col);
                }
    
            // get the VALUE and set it in the editor
            v = model.getDatum(inRowIndex, this.cell.fieldIndex);
            this.editor._isvalid = true;         
            this.editor._setValue(v, dv);
    		
    	},
    	
    	getEditorProps: function(inDatum, inRowIndex){
            // this is modeled after dojox.grid.editors.Select 
            
            var store;	
            if (this.cell.editorProps && this.cell.editorProps.storeClass) {
                // if we have a store class & props create that
                 
    		    var _ctr = dojo.getObject(this.cell.editorProps.storeClass);
                store = new _ctr(this.cell.editorProps.storeProps || {});
                //var store = new dojox.data.QueryReadStore({url: "EV_RemoteCall.php"});
            }
    	    else {
    	       // otherwise, do it like dojox.grid.editors.Select
            	var items=[];
            	for (var i=0, o, v; (o=this.cell.options[i])&&(v=this.cell.values[i]); i++){
            		items.push({name: o, value: v});
            	}
            	store = new dojo.data.ItemFileReadStore({data: {identifier:"value", items: items}});
            }
    
            // eitherway, now we have a store withwhich to do our lookups -- mix it in...
    		
            return dojo.mixin({}, this.cell.editorProps||{}, {
    			value: inDatum,
    			store: store,
    			cell: this.cell,
                cellRow : inRowIndex			
    		});
    	},
    	
    	getValue: function(){
    
    		var e = this.editor;
    
            // now set the display value up in the data model, that's where it comes from 
            //  via formatSelect
            if (this.cell.editorProps && this.cell.editorProps.display_field) {
        		var model = this.cell.grid.model;
        		var col = this.cell.editorProps.display_field;
        		var row = e.cellRow;
        		var disp_val = e.getDisplayedValue();
                model.setDatumCx(disp_val, row, col);
        		model.rowChange();
            }         
    
            // now get the actual value
            var v = e.getValue(); // model.getDatum(row, this.cell.fieldIndex);
    		return v;
    	}
    	
    });
    
    
    // oh - and then there was this -- not sure why the value was commented out in dojox.grid.editors.Select
    
    //dojo.declare("dojox.grid.editors.DLSelect", dojox.grid.editors.Input, {
    dojo.declare("dojox.grid.editors.DLSelect", dojox.grid.editors.Select, {
    	format: function(inDatum, inRowIndex){
    		this.needFormatNode(inDatum, inRowIndex);
    		var h = [ '' ];
    		for (var i=0, o, v; (o=this.options[i])&&(v=this.values[i]); i++){
    			h.push("", o, "");
    			//-DL -- this was commented out -- due to something about ID not returning a value
    			// if IE gives grief may need to change the getValue function to return this.values[i]
    		}
    		h.push('');
    		return h.join('');
    	}
    });

    i'm not sure to understand everything

    Hi,
    I'm trying to use your DLFilteringSelect.
    It works fine with options and values directly passed trought the structure declaration.
    But I have to load them dynamically.
    I tried to use "storeClass", but getDatumCx is not fund... and I don't know what it is and how it works.
    But I know, i'm a newby and don't understand everything about dojo.data and stores.
    Thanks in advance.

    getDatumCx / sorry

    Hi -- sorry -- I'm new to all this and not sure if I should have posted all that. Anyway, I modified dojox.grid.test.dataModel.js and added support for dealing w/ column names, so you'll have to do the same for any datamodel you use.

    getDatumCx: function (iRow, col) {

    Unfortunately, in my experience you don't get very far with dojo without being willing to to wade through and try to understand and modify the underlying code. Dojo's amazing, but it's super-young. It's great if your a committed hacker and think face-time w/ your computer is cool; it's not so great if you're trying to run a business, keep up on your sports, etc., and used to just dropping something like this in and having it work off the bat. :-) But it will get there....

    i'm not sure to understand everything

    Hi,
    I'm trying to use your DLFilteringSelect.
    It works fine with options and values directly passed trought the structure declaration.
    But I have to load them dynamically.
    I tried to use "storeClass", but getDatumCx is not fund... and I don't know what it is and how it works.
    But I know, i'm a newby and don't understand everything about dojo.data and stores.
    Thanks in advance.

    I second the request for a

    I second the request for a tree grid, with support for deferred fetching of collapsed node content and no limits on nesting levels.

    I'd also like to see better support for dynamically changing stores. Currently, if you press Ctrl+End or drag the scrollbar to the bottom of the range, the grid navigates to the end of the data as determined by the last reported size rather than the current size when the request is made (think of a mail inbox with new mail constantly arriving). The grid should be able to navigate to the current end of the store at the time that the request is made without having to make extra requests to the server to determine the new store size. This would probably require an enhancement to the dojo.data.fetch API to support a start count of -1 (last item) or the addition of a fromEnd option to indicate that the start offset is relative to the end of the store rather than the beginning (I'd prefer to see the latter but could settle for the former).

    What I'd like to see

    1. From the get or formatter code for the cell, I'd like to be able to return a domNode. right now, to do markup, I have to return an html string. that means I can't really hang events off that node easily. I'd love to be able to create a domNode, attach events to it, etc

    2. It would be great as part of the data model to pass in html or domNode for a specific cell. Right now, if you need to do custom cell rendering (where not all rows in a given column do the same thing) you need to override the get or formatter. The problem is, if the html is static after being created once, the formatter still gets called whenever the row gets updated. So, I may need to set special colors, etc on individual cells, but I only need to do that once. It seems like if all the rows in a column are not the same, the only way to do this is dynamically, and then it gets called all the time.

    3. I'd like to see a model where you separate the current view row id from the original rowId passed in. That way, when sorting happens, you can get the current rowId, but there is also the concept of a "original" row Id. Right now, I add an extra cell taht doesn't get displayed for this "primary" key, which is essentially what this is.

    4. A store implementation that isn't as broken. right now, with sorting the store implementation is essentially broken.

    Couple of request

    1. A simple method to persist the changes a user makes to the layout of the grid I.E. column widths and the sort order

    2. An event when a page has been completely render to the screen. At the moment it's not really possible to tell when the rendering has been completed (I have a work around but it would be nice to have a proper solution)

    1. A simple method to

    1. A simple method to persist the changes a user makes to the layout of the grid I.E. column widths and the sort order <= I agree this would be a great function!

    -------------------------------------------------
    Webdesign Köln

    Bunches of stuff.

    1. If I provide an editor, clientSort="true" does not appear to work. Is this a known bug?

    2. My users need to 'shift' rows -- e.g., if row 4 really belongs between rows 1 and 2, shift it up (swap places with row 3) then shift it up again -- and this appears to be quite hard. Is it easier to enable the user to drag-n-drop rows into their right places?

    3. In my rows, there are 5 columns that have multiple, synchronized values -- e.g., a book with several authors with each author having his own address/phone. I don't see how to cleanly display multiple values in one cell (...nor how to keep multiple values aligned across cells, nor how to enable a reasonable editor interface for multiple values in multiple cells). Can the grid handle a sub-grid or multi-line text widget of any kind?

    4. I'd like the following click paradigm: user clicks anywhere in a row to select it, user clicks on any already-selected text to enter edit mode in that cell, user clicks on any already-selected cell (outside the text) to de-select. Is this possible?

    5. I also want to remove the default scrollbars from the grid presentation. I'll check out the hack, above.

    Finally, if this message is really more forums-y than roadmap-y, please accept my apologies, and, if you wish, I will remove/repost.

    Thank you.

    cell drag / drop / mouse events?

    Here is another vote (plea) for grid cell drag and drop. Or even mousedown/mouseup events so that someone could roll their own?

    Export to CSV

    If this already exists, please excuse my post... I would like an easy option to export the grid data to a CSV, perhaps a dynamically generated CSV file that streams as a download to the user when clicked.

    I second this.

    I second this. (Export to CSV)

    Most asked for features

    In our recent grid evaluations, on which we ultimately chose Turbo Grid, prior to it being added to Dojo 1.0 we did some extensive usability testing inside a large financial institution. The features that users liked the most from other grid packages or most commonly asked for were:

    Re-Ordering columns with drag and drop.
    Block Select / Cut or copy selected block.
    Right click to hide a column (I think this could be done with context menu and layout manipulation, but it would be nice to have an api call for show and hide columns)
    Multi-column sort - I know this can be done, but it is difficult and a simple api call would be nice.
    Subtotal rows for groups.

    Thanks,
    Mike

    Getting Changes

    It seems when using the Store as the underlying data, the original store remains unchanged, and I have to write code like this to extract a row that I changed with a cell editor. I query the store and then have to go into the model to get the real changed object. Then I have to set _data to null to avoid recursion in creating JSON payload

    getSelected:function(event)
    {
    console.debug(event);
    var uerr = dojo.byId('updateError');
    uerr.innerHTML = "";
    this.incentiveid = event.id.substring(6);
    var incUpdateCheck = dojo.byId("incentiveUpdateValue");
    incUpdateCheck.innerHTML = "Updating incentiveId " + this.incentiveid + "";
    incentiveHandler.incentiveStore.fetch({query:{incentiveid:this.incentiveid}, onComplete: incentiveUpdater.extractContent});
    },
    extractContent:function(content,request)
    {
    incentiveUpdater.content = incentiveHandler.incentiveModel.getRow(content[0]._0);
    incentiveUpdater.content.__dojo_data_item = null;
    dijit.byId('updateDialog').show();
    }

    Widgets in Cells

    That's all I need, at present.
    Nice dojo Buttons, comboboxes, trees or what have you.

    You could do it simple, by adding something like "executeScripts=true" for ContentPanes, or the like.

    Cheers,
    PS

    Where can one get Grid 1.1?

    -

    Grid 1.1

    You can get Grid 1.1 when Dojo 1.1 ships in early March. At this point, we're just brainstorming and discussing features and adding them to the roadmap.

    Widgets in cells

    Just wanted to place my vote (even though already mentioned twice above) -- would like it if the Grid could easily support widgets in cells. The workarounds are painful!

    re: Widgets in cells

    My vote for widgets in cells too. I have to implement FilteringSelect in grid column with DWR provided store. It looks nice, but when I make some choose, every cells changes displayed value to same. I dont know if it is because I don't have unique ID for every cell's editor or I need unique store for each cell's editor? Has anybody some workarounds, or any idea how to provide unique ID for FilteringSelect inside grid cell?
    Here is my column declaration :

    aColumn = { name:"Column name", width:"110px",
                                       editor: dojox.grid.editors.ComboBox,
                                 editorClass: "dijit.form.FilteringSelect",
                                 store: dwrStore,
                                 searchAttr:"value",
           
               header.push(aColumn);

    Thanks in advance for any help.

    grid is the greatest

    The dojo gird is very cool. I'm trying to use it in several application efforts. The hard work that went into it is really an inspiration for what's possible via Javascript. Like Turbogrid and like dozens of great stuff in the Dojo toolkit - wow.

    I do have trouble getting desired results from grid and column width parameters. I'm trying to build pages that use the entire browser width with a percentage of that width designated to the gird. I would like to be able to set column widths to percentages of the available grid width. The width parameter of the each cell in a grid view seem to only accept number values which I believe are character column units!? That's kinda cool, but I'd like to use percentages here as well. I've seen people use 'auto' and "*" for cell width - but those do not work as I expect.

    Or maybe instead of using a view cell's 'width' attribute - use the width attribute from within the view cell's "styles" attribute?

    "view cell" does that make sense? Mine look like this:
    var view = {
    defaultCell: { width: 15, styles: 'text-align: left;' },
    cells:[columns]
    };

    Thanks again for sharing the gird with us mortals!
    -cs-

    fwiw, if you know your

    fwiw, if you know your number of columns, and it's static, doing what you want is fairly easy:

    var overallSize = dojo.coords(grid.domNode.parentNode).w;
    var eachSize = overallSize/cols;
    for(var i = 0; i
    
    it _should_ spread each of the coloums evenly across the view.  evenly isn't something everybody wants, so its a lot more difficult to include in the widget, but you can easily get what you want out of it.

    subgrid help

    I am posting this duplicated with the dojox grid support forum topic . I am using the subgrid and am facing a problem where the selections or other operations on the subgrid are affecting the parent grid. This issue is also visible in the test samples with DOJO toolkit. I want the subgrid to behave independant of the parent grid but for only some data dependence that is handled in the model. The selection , deletion and events should be seperate. Currently , the subgrid event triggers and then the the parent grid event triggers with the rowIndex and column indexes of the subgrid.

    I have got no response in the last 2 days . I would appreciate any pointers on how to resolve this.

    Thanks

    columns with get cells not sortable

    Just because they're calculated doesn't mean they shouldn't sort.

    Thanks

    Status?

    What can we expect from grid 1.1 now that it's early March and 1.1 is in beta? I don't see anything about the grid here:

    http://www.dojotoolkit.org/book/dojo-1-1-release-notes

    Thx,

    Josh