title: Freezing Columns in JQGrid
body: <p>Is there a way to get jqGrid to freeze one or more left-most columns and have the balance of the columns scroll left-and-right?</p>
  
  <p>I did Google up at least one person who claims to have done it here:
  <a href="http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/" rel="nofollow noreferrer">http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/</a></p>
  
  <p>... but the sample code is gone.  (Ironically and painfully, the <a href="http://screencast.com/t/gPdOVPQlRc" rel="nofollow noreferrer">screencast of it working</a> is still up, mocking me.)</p>
  
  <p>It looks like <a href="https://stackoverflow.com/questions/4586924/jqgrid-freeze-columns/5271522#5271522">some here have gotten it working too</a>, but didn't include code.</p>
  
  <p>Has anyone gotten frozen columns with scrolling working in a jqGrid with that plugin or another similar plugin?  Anyone have that code working &amp; handy?</p>
  
  <p>I would have thought you'd include that fellow's code and it would automagically produce the pushpins that you can see in his screencast, and if it didn't you'd make the magic happen with... </p>
  
  <pre><code>$(document).ready(function() {
      //$("#tblImz").jqGrid().freezingSetup(); // initially tried without this line; same error (reporting different function, natch)
      $("#tblImz").jqGrid().freezeColumn(2);
  });
  </code></pre>
  
  <p>... but that gives me...</p>
  
  <blockquote>
    <p>Microsoft JScript runtime error: Object doesn't support property or
    method 'freezeColumn'</p>
  </blockquote>
  
  <p>or</p>
  
  <blockquote>
    <p>Microsoft JScript runtime error: Object doesn't support property or
    method 'freezingSetup'</p>
  </blockquote>
  
  <p>Just for fun, here's the cleaned up code that I <em>think</em> is nearly right, taken from the paste from the <a href="http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/" rel="nofollow noreferrer">post above</a>.  I <em>think</em> this accurately relays what the author had [unintentionally mangled up] in his trirand.com forum post, with the two edits from <a href="http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/#p21071" rel="nofollow noreferrer">here</a> suggested by linoj.  Okay, code dump...  </p>
  
  <pre><code>(function ($) {    
  /**    
  * jqGrid extension    
  * Tim Heckel timheckel@gmail.com    *
  * from here: http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/
  * Dual licensed under the MIT and GPL licenses:    
  * http://www.opensource.org/licenses/mit-license.php    
  * http://www.gnu.org/licenses/gpl-2.0.html    *
  */    
  $.jgrid.extend({
      //overrides existing        
      getCellIndex: function (cell) {
          var c = jQuery(cell);
  
          if (c.is('tr')) { 
              return -1; 
          }
          var index = -1;
  
          if (c.parent().hasClass("ui-jqgrid-frozenColumnHeader")) {
              index = parseInt(c.attr("rel"));
          } else {
              c = (!c.is('td') &amp;&amp; !c.is('th') ? c.closest("td,th") : c)[0];
              if (jQuery.browser.msie) {
                  index = jQuery.inArray(c, c.parentNode.cells);
              } else {
                  index = c.cellIndex;
              }
          }
          return index;        
      }    
  });    
  
  $.jgrid.extend({
      removeFreezeIcons: function () {
          jQuery(".toggleFrozenColumn").remove();
      },
      freezingSetup: function () {
          // [1]
          return this.each(function () {
              var grid = this;
              var colIndex = -1;
              jQuery(".ui-th-column").each(function () {
                  colIndex++;
                  if (colIndex &lt;= grid.p.colModel.length - 1) {
                      if (jQuery(this).is(":visible") &amp;&amp; grid.p.colModel[colIndex].freezing) {
                          if (jQuery(".toggleFrozenColumn[rel=" + colIndex + "]").length === 0) {
                              jQuery(this).children(".ui-jqgrid-sortable").prepend("&lt;img href='javascript:' class='toggleFrozenColumn' rel='" + colIndex + "' src='" + grid.p.imageDir + "/pinup.png'/&gt;");
                          }
                      }
                  } else {
                      return;
                  }
              });
  
  
              jQuery(".toggleFrozenColumn").unbind();
              jQuery(".toggleFrozenColumn").click(function (e) {
                  e.stopPropagation();
                  var img = this;
                  jQuery.extend(grid.p, { currentFrozenIndex: parseInt(jQuery(this).attr("rel")) });
                  process(img);
              });
  
  
              function process(img) {
                  jQuery(".toggleFrozenColumn").hide();
                  jQuery(img).show();
                  var _ci = parseInt(jQuery(img).attr("rel"));
                  var _name = grid.p.colModel[parseInt(jQuery(img).attr("rel"))].name;
                  if (jQuery(img).attr("src").indexOf("pindown") &gt; -1) {
                      jQuery("#" + grid.p.id + "_" + _name).find('.toggleFrozenColumn').attr("src", grid.p.imageDir + "/pinup.png");
                      for (ci = parseInt(jQuery(img).attr("rel")); ci &gt; -1; ci--) {
                          jQuery("#" + grid.p.id).jqGrid("unfreezeColumn", ci);
                      }
                      jQuery(".toggleFrozenColumn").show();
                  } else {
                      jQuery(img).attr("src", grid.p.imageDir + "/pindown.png");
                      for (ci = parseInt(jQuery(img).attr("rel")); ci &gt; -1; ci--) {
                          jQuery("#" + grid.p.id).jqGrid("freezeColumn", ci);
                      }
                  }
              }
  
              if (grid.p.currentFrozenIndex !== undefined) {
                  var img = jQuery(".toggleFrozenColumn[rel=" + grid.p.currentFrozenIndex + "]");
  
                  //unfreeze all
                  process(img[img.length - 1]);
  
                  //freeze all
                  process(img[0]);
              }
          });        
          // [1]
          //
      },        
  
      unfreezeColumn: function (colIndex) {
          return this.each(function () {
          var t = this;
          var _name = t.p.colModel[colIndex].name;
          if (jQuery("#frozenColumn_" + _name).length &gt; 0) {
          jQuery("#frozenColumnHeader_" + _name).remove();
          jQuery("#frozenColumn_" + _name).remove();
          }
          });        
      },        
  
      freezeColumn: function (colIndex) {
          jQuery(".ui-jqgrid-bdiv").scroll(function () {
              jQuery(".ui-jqgrid-frozenColumn").scrollTop(jQuery(this).scrollTop());
          });
  
          return this.each(function () {
              var t = this;
              var _name = t.p.colModel[colIndex].name;
              var _allow = t.p.colModel[colIndex].freezing;
              if (jQuery("#frozenColumn_" + _name).length === 0 &amp;&amp; _allow) {
                  var _id = t.p.id;
                  var c = jQuery("#" + _id + "_" + _name);
                  if (c.is(":visible")) {
                      var th = c.clone(true).css("height", c.height() + "px").css("vertical-align", "middle"); //.css("background-color", t.p.frozenColumnHorizontalBorderColor); //.css("font-weight", c.css("font-weight"));
                      var ct = "";
  
  
  
                      var cell = jQuery('td[aria-describedby=' + _id + '_' + _name + ']');
                      var dimen = { height: 0, top: 0, width: 0, top: 0, left: 0 };
                      dimen.height = jQuery(".ui-jqgrid-bdiv").outerHeight(true) - 16;
  
  
                      jQuery.each(cell, function () {
                          var cls = new Array();
                          var classList = $(this).attr('class').split(/s+/);
                          jQuery.each(classList, function (index, item) {
                          cls.push(item);
                          });
  
                          ct += "&lt;div class='ui-jqgrid-frozenColumnCell " + cls.join(' ') + "' style='border-right:1px solid " + t.p.frozenColumnVerticalBorderColor + ";border-left:1px solid transparent;border-bottom:1px solid " + t.p.frozenColumnHorizontalBorderColor + ";background-color:#FFF;padding-top:1px;height:" + (jQuery(this).height() - 1) + "px;'&gt;" + jQuery(this).html() + "&lt;/div&gt;";
                          // +5 is from here:
                          // http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/#p21071
                          if (dimen.width === 0) dimen.width = jQuery(this).width() + 1 + 5;
                          if (dimen.top === 0) {
                              dimen.top = jQuery(".ui-jqgrid-titlebar").outerHeight(true) + c.outerHeight(true) + 1;
                              dimen.left = jQuery(this).position().left - 1;
                          }
                      });
  
                      var titleBarHeight = jQuery(".ui-jqgrid-titlebar").outerHeight(true);
  
                      // "dimen.width" in first call below replaces c.width() in the original, from same link.
                      // http://www.trirand.com/blog/?page_id=393/discussion/new-freeze-column-plugin/#p21071
                      jQuery(".ui-jqgrid-view").append("&lt;div class='ui-jqgrid-frozenColumnHeader' id='frozenColumnHeader_" + _name 
                          + "' style='height:" + c.height() 
                          + "px;width:" + c.width() 
                          + "px;top:" + titleBarHeight 
                          + "px;left:" + dimen.left 
                          + "px;position:absolute;overflow:hidden;border-right:1px solid " + t.p.frozenColumnVerticalBorderColor + "'&gt;&lt;/div&gt;");
                      jQuery(".ui-jqgrid-view").append("&lt;div class='ui-jqgrid-frozenColumn' id='frozenColumn_" + _name 
                          + "' style=';overflow:hidden;position:absolute;height:" + dimen.height 
                          + "px;width:" + dimen.width 
                          + "px;top:" + dimen.top 
                          + "px;left:" + dimen.left + "px;'&gt;" 
                          + ct 
                      + "&lt;/div&gt;");
  
                      c = (!c.is('td') &amp;&amp; !c.is('th') ? c.closest("td,th") : c)[0];
  
                      if (jQuery.browser.msie) {
                          th.attr("rel", jQuery.inArray(jQuery("#" + _id + "_" + _name), c.parentNode.cells));
                      } else {
                          th.attr("rel", c.cellIndex);
                      }
  
                      jQuery("#frozenColumnHeader_" + _name).append(th);
                  }
              }
          });        
  
      }
  });
  })(jQuery);
  </code></pre>
  
  <p>Any ideas?</p>