Roo/grid/GridView.js
[roojs1] / Roo / grid / GridView.js
index 8dcf196..097b9f7 100644 (file)
@@ -25,12 +25,10 @@ Roo.grid.GridView = function(config){
 
 Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
 
-    /**
-     * Override this function to apply custom css classes to rows during rendering
-     * @param {Record} record The record
-     * @param {Number} index
-     * @method getRowClass
-     */
+    unselectable :  'unselectable="on"',
+    unselectableCls :  'x-unselectable',
+    
+    
     rowClass : "x-grid-row",
 
     cellClass : "x-grid-col",
@@ -119,6 +117,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         if(!tpls.master){
             tpls.master = new Roo.Template(
                '<div class="x-grid" hidefocus="true">',
+                '<a href="#" class="x-grid-focus" tabIndex="-1"></a>',
                   '<div class="x-grid-topbar"></div>',
                   '<div class="x-grid-scroller"><div></div></div>',
                   '<div class="x-grid-locked">',
@@ -130,7 +129,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                       '<div class="x-grid-body">{body}</div>',
                   "</div>",
                   '<div class="x-grid-bottombar"></div>',
-                  '<a href="#" class="x-grid-focus" tabIndex="-1"></a>',
+                 
                   '<div class="x-grid-resize-proxy">&#160;</div>',
                "</div>"
             );
@@ -150,7 +149,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         if(!tpls.hcell){
             tpls.hcell = new Roo.Template(
                 '<td class="x-grid-hd x-grid-td-{id} {cellId}"><div title="{title}" class="x-grid-hd-inner x-grid-hd-{id}">',
-                '<div class="x-grid-hd-text" unselectable="on">{value}<img class="x-grid-sort-icon" src="', Roo.BLANK_IMAGE_URL, '" /></div>',
+                '<div class="x-grid-hd-text ' + this.unselectableCls +  '" ' + this.unselectable +'>{value}<img class="x-grid-sort-icon" src="', Roo.BLANK_IMAGE_URL, '" /></div>',
                 "</div></td>"
              );
              tpls.hcell.disableFormats = true;
@@ -158,7 +157,8 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         tpls.hcell.compile();
 
         if(!tpls.hsplit){
-            tpls.hsplit = new Roo.Template('<div class="x-grid-split {splitId} x-grid-split-{id}" style="{style}" unselectable="on">&#160;</div>');
+            tpls.hsplit = new Roo.Template('<div class="x-grid-split {splitId} x-grid-split-{id}" style="{style} ' +
+                                            this.unselectableCls +  '" ' + this.unselectable +'>&#160;</div>');
             tpls.hsplit.disableFormats = true;
         }
         tpls.hsplit.compile();
@@ -182,7 +182,8 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         if(!tpls.cell){
             tpls.cell = new Roo.Template(
                 '<td class="x-grid-col x-grid-td-{id} {cellId} {css}" tabIndex="0">',
-                '<div class="x-grid-col-{id} x-grid-cell-inner"><div class="x-grid-cell-text" unselectable="on" {attr}>{value}</div></div>',
+                '<div class="x-grid-col-{id} x-grid-cell-inner"><div class="x-grid-cell-text ' +
+                    this.unselectableCls +  '" ' + this.unselectable +'" {attr}>{value}</div></div>',
                 "</td>"
             );
             tpls.cell.disableFormats = true;
@@ -308,25 +309,27 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         var cs = el.childNodes;
 
         this.el = new E(el);
-        this.headerPanel = new E(el.firstChild);
+        
+         this.focusEl = new E(el.firstChild);
+        this.focusEl.swallowEvent("click", true);
+        
+        this.headerPanel = new E(cs[1]);
         this.headerPanel.enableDisplayMode("block");
 
-        this.scroller = new E(cs[1]);
+        this.scroller = new E(cs[2]);
         this.scrollSizer = new E(this.scroller.dom.firstChild);
 
-        this.lockedWrap = new E(cs[2]);
+        this.lockedWrap = new E(cs[3]);
         this.lockedHd = new E(this.lockedWrap.dom.firstChild);
         this.lockedBody = new E(this.lockedWrap.dom.childNodes[1]);
 
-        this.mainWrap = new E(cs[3]);
+        this.mainWrap = new E(cs[4]);
         this.mainHd = new E(this.mainWrap.dom.firstChild);
         this.mainBody = new E(this.mainWrap.dom.childNodes[1]);
 
-        this.footerPanel = new E(cs[4]);
+        this.footerPanel = new E(cs[5]);
         this.footerPanel.enableDisplayMode("block");
 
-        this.focusEl = new E(cs[5]);
-        this.focusEl.swallowEvent("click", true);
         this.resizeProxy = new E(cs[6]);
 
         this.headerSelector = String.format(
@@ -386,7 +389,14 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         this.rowEl.elements = els;
         return this.rowEl;
     },
-
+    /**
+     * Gets the 'td' of the cell
+     * 
+     * @param {Integer} rowIndex row to select
+     * @param {Integer} colIndex column to select
+     * 
+     * @return {Object} 
+     */
     getCell : function(rowIndex, colIndex){
         var locked = this.cm.getLockedCount();
         var source;
@@ -514,7 +524,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
      */
     focusRow : function(row)
     {
-        Roo.log('GridView.focusRow');
+        //Roo.log('GridView.focusRow');
         var x = this.scroller.dom.scrollLeft;
         this.focusCell(row, 0, false);
         this.scroller.dom.scrollLeft = x;
@@ -528,7 +538,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
      */
     focusCell : function(row, col, hscroll)
     {
-        Roo.log('GridView.focusCell');
+        //Roo.log('GridView.focusCell');
         var el = this.ensureVisible(row, col, hscroll);
         this.focusEl.alignTo(el, "tl-tl");
         if(Roo.isGecko){
@@ -546,7 +556,8 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
      */
     ensureVisible : function(row, col, hscroll)
     {
-        Roo.log('GridView.ensureVisible,' + row + ',' + col);
+        //Roo.log('GridView.ensureVisible,' + row + ',' + col);
+        //return null; //disable for testing.
         if(typeof row != "number"){
             row = row.rowIndex;
         }
@@ -569,19 +580,31 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         var cleft = parseInt(el.offsetLeft, 10);
         var cbot = ctop + el.offsetHeight;
         var cright = cleft + el.offsetWidth;
-
+        
         var ch = c.clientHeight - this.mainHd.dom.offsetHeight;
         var stop = parseInt(c.scrollTop, 10);
         var sleft = parseInt(c.scrollLeft, 10);
         var sbot = stop + ch;
         var sright = sleft + c.clientWidth;
-
+        /*
+        Roo.log('GridView.ensureVisible:' +
+                ' ctop:' + ctop +
+                ' c.clientHeight:' + c.clientHeight +
+                ' this.mainHd.dom.offsetHeight:' + this.mainHd.dom.offsetHeight +
+                ' stop:' + stop +
+                ' cbot:' + cbot +
+                ' sbot:' + sbot +
+                ' ch:' + ch  
+                );
+        */
         if(ctop < stop){
-            c.scrollTop = ctop;
+             c.scrollTop = ctop;
+            //Roo.log("set scrolltop to ctop DISABLE?");
         }else if(cbot > sbot){
+            //Roo.log("set scrolltop to cbot-ch");
             c.scrollTop = cbot-ch;
         }
-
+        
         if(hscroll !== false){
             if(cleft < sleft){
                 c.scrollLeft = cleft;
@@ -589,6 +612,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                 c.scrollLeft = cright-c.clientWidth;
             }
         }
+         
         return el;
     },
 
@@ -634,7 +658,9 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         if(s){ // splitters not created yet
             var pos = 0, locked = true;
             for(var i = 0, len = cm.getColumnCount(); i < len; i++){
-                if(cm.isHidden(i)) continue;
+                if(cm.isHidden(i)) {
+                    continue;
+                }
                 var w = cm.getColumnWidth(i); // make sure it's a number
                 if(!cm.isLocked(i) && locked){
                     pos = 0;
@@ -782,7 +808,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
     },
 
     restoreScroll : function(state){
-        Roo.log('GridView.restoreScroll');
+        //Roo.log('GridView.restoreScroll');
         var sb = this.scroller.dom;
         sb.scrollLeft = state.left;
         sb.scrollTop = state.top;
@@ -790,7 +816,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
     },
 
     syncScroll : function(){
-        Roo.log('GridView.syncScroll');
+        //Roo.log('GridView.syncScroll');
         var sb = this.scroller.dom;
         var sh = this.mainHd.dom;
         var bs = this.mainBody.dom;
@@ -831,7 +857,8 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                 name : typeof name == 'undefined' ? ds.fields.get(i).name : name,
                 renderer : cm.getRenderer(i),
                 id : cm.getColumnId(i),
-                locked : cm.isLocked(i)
+                locked : cm.isLocked(i),
+                has_editor : cm.editor ? true : false
             };
         }
 
@@ -863,9 +890,15 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                         p.id = c.id;
                         p.css = p.attr = "";
                         p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
-                        if(p.value == undefined || p.value === "") p.value = "&#160;";
-                        if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
-                            p.css += p.css ? ' x-grid-dirty-cell' : 'x-grid-dirty-cell';
+                        if(p.value == undefined || p.value === "") {
+                            p.value = "&#160;";
+                        }
+                        if(c.has_editor){
+                            Roo.log("adding editable celel css");
+                            p.css += ' x-grid-editable-cell';
+                        }
+                        if(c.dirty && typeof r.modified[c.name] !== 'undefined'){
+                            p.css +=  ' x-grid-dirty-cell';
                         }
                         var markup = ct.apply(p);
                         if(!c.locked){
@@ -891,7 +924,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                             record: r,
                             rowIndex : rowIndex,
                             rowClass : ''
-                        }
+                        };
                         this.grid.fireEvent('rowclass', this, rowcfg);
                         alt.push(rowcfg.rowClass);
                     }
@@ -907,6 +940,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                 // buffers
                 var buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r, rowIndex;
                 var hasListener = this.grid.hasListener('rowclass');
                 var rowcfg = {};
                 for(var j = 0, len = rs.length; j < len; j++){
                     r = rs[j]; cb = []; lcb = []; rowIndex = (j+startRow);
@@ -916,10 +950,18 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                         p.id = c.id;
                         p.css = p.attr = "";
                         p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
-                        if(p.value == undefined || p.value === "") p.value = "&#160;";
+                        if(p.value == undefined || p.value === "") {
+                            p.value = "&#160;";
+                        }
+                        //Roo.log(c);
+                         if(c.has_editor){
+                            Roo.log("adding editable celel css");
+                            p.css += ' x-grid-editable-cell';
+                        }
                         if(r.dirty && typeof r.modified[c.name] !== 'undefined'){
-                            p.css += p.css ? ' x-grid-dirty-cell' : 'x-grid-dirty-cell';
+                            p.css += ' x-grid-dirty-cell' 
                         }
+                        
                         var markup = ct.apply(p);
                         if(!c.locked){
                             cb[cb.length] = markup;
@@ -944,10 +986,11 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                             record: r,
                             rowIndex : rowIndex,
                             rowClass : ''
-                        }
+                        };
                         this.grid.fireEvent('rowclass', this, rowcfg);
                         alt.push(rowcfg.rowClass);
                     }
+                    Roo.log(alt);
                     rp.alt = alt.join(" ");
                     rp.cells = lcb.join("");
                     lbuf[lbuf.length] = rt.apply(rp);
@@ -996,6 +1039,26 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         if(this.enableMoveAnim && Roo.enableFx){
             this.fly(this.getHeaderCell(colIndex).firstChild).highlight(this.hlColor);
         }
+        // if multisort - fix sortOrder, and reload..
+        if (this.grid.dataSource.multiSort) {
+            // the we can call sort again..
+            var dm = this.grid.dataSource;
+            var cm = this.grid.colModel;
+            var so = [];
+            for(var i = 0; i < cm.config.length; i++ ) {
+                
+                if ((typeof(dm.sortToggle[cm.config[i].dataIndex]) == 'undefined')) {
+                    continue; // dont' bother, it's not in sort list or being set.
+                }
+                
+                so.push(cm.config[i].dataIndex);
+            };
+            dm.sortOrder = so;
+            dm.load(dm.lastOptions);
+            
+            
+        }
+        
     },
 
     updateCell : function(dm, rowIndex, dataIndex){
@@ -1014,7 +1077,9 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
         };
         var renderer = cm.getRenderer(colIndex);
         var val = renderer(dm.getValueAt(rowIndex, dataIndex), p, rowIndex, colIndex, dm);
-        if(typeof val == "undefined" || val === "") val = "&#160;";
+        if(typeof val == "undefined" || val === "") {
+            val = "&#160;";
+        }
         cellText.innerHTML = val;
         cell.className = this.cellClass + " " + this.idToCssName(p.cellId) + " " + p.css;
         this.syncRowHeights(rowIndex, rowIndex);
@@ -1142,21 +1207,54 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
     },
 
     updateHeaderSortState : function(){
-        var state = this.ds.getSortState();
-        if(!state){
-            return;
-        }
-        this.sortState = state;
-        var sortColumn = this.cm.findColumnIndex(state.field);
-        if(sortColumn != -1){
-            var sortDir = state.direction;
-            var sc = this.sortClasses;
-            var hds = this.el.select(this.headerSelector).removeClass(sc);
-            hds.item(sortColumn).addClass(sc[sortDir == "DESC" ? 1 : 0]);
+        
+        // sort state can be single { field: xxx, direction : yyy}
+        // or   { xxx=>ASC , yyy : DESC ..... }
+        
+        var mstate = {};
+        if (!this.ds.multiSort) { 
+            var state = this.ds.getSortState();
+            if(!state){
+                return;
+            }
+            mstate[state.field] = state.direction;
+            // FIXME... - this is not used here.. but might be elsewhere..
+            this.sortState = state;
+            
+        } else {
+            mstate = this.ds.sortToggle;
+        }
+        //remove existing sort classes..
+        
+        var sc = this.sortClasses;
+        var hds = this.el.select(this.headerSelector).removeClass(sc);
+        
+        for(var f in mstate) {
+        
+            var sortColumn = this.cm.findColumnIndex(f);
+            
+            if(sortColumn != -1){
+                var sortDir = mstate[f];        
+                hds.item(sortColumn).addClass(sc[sortDir == "DESC" ? 1 : 0]);
+            }
         }
+        
+         
+        
     },
 
-    handleHeaderClick : function(g, index){
+
+    handleHeaderClick : function(g, index,e){
+        
+        Roo.log("header click");
+        
+        if (Roo.isTouch) {
+            // touch events on header are handled by context
+            this.handleHdCtx(g,index,e);
+            return;
+        }
+        
+        
         if(this.headersDisabled){
             return;
         }
@@ -1165,6 +1263,22 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
             return;
         }
         g.stopEditing();
+        
+        if (dm.multiSort) {
+            // update the sortOrder
+            var so = [];
+            for(var i = 0; i < cm.config.length; i++ ) {
+                
+                if ((typeof(dm.sortToggle[cm.config[i].dataIndex]) == 'undefined') && (index != i)) {
+                    continue; // dont' bother, it's not in sort list or being set.
+                }
+                
+                so.push(cm.config[i].dataIndex);
+            };
+            dm.sortOrder = so;
+        }
+        
+        
         dm.sort(cm.getDataIndex(index));
     },
 
@@ -1253,6 +1367,15 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                     cm.setLocked(index, false);
                 }
             break;
+            case 'wider': // used to expand cols on touch..
+            case 'narrow':
+                var cw = cm.getColumnWidth(index);
+                cw += (item.id == 'wider' ? 1 : -1) * 50;
+                cw = Math.max(0, cw);
+                cw = Math.min(cw,4000);
+                cm.setColumnWidth(index, cw);
+                break;
+                
             default:
                 index = cm.getIndexById(item.id.substr(4));
                 if(index != -1){
@@ -1382,6 +1505,15 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                     {id:"unlock", text: this.unlockText, cls: "xg-hmenu-unlock"}
                 );
             }
+            if (Roo.isTouch) {
+                 this.hmenu.add('-',
+                    {id:"wider", text: this.columnsWiderText},
+                    {id:"narrow", text: this.columnsNarrowText }
+                );
+                
+                 
+            }
+            
             if(this.grid.enableColumnHide !== false){
 
                 this.colMenu = new Roo.menu.Menu({id:this.grid.id + "-hcols-menu"});
@@ -1401,6 +1533,7 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
             this.dd = new Roo.grid.GridDragZone(this.grid, {
                 ddGroup : this.grid.ddGroup || 'GridDD'
             });
+            
         }
 
         /*
@@ -1583,7 +1716,10 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
     sortDescText : "Sort Descending",
     lockText : "Lock Column",
     unlockText : "Unlock Column",
-    columnsText : "Columns"
+    columnsText : "Columns",
+    columnsWiderText : "Wider",
+    columnsNarrowText : "Thinner"
 });