Quantcast
Channel: Recent Discussions — DataTables forums
Viewing all articles
Browse latest Browse all 82017

New Plugin: Fill Available Width

$
0
0
Here is a plugin that I created to force datatables to fill the available width. The advantage of this plugin over setting "width: 100% !important" in CSS is that the latter will cause columns to shrink to the minimum width required to show the content, ignoring "sWidth" altogether. With this plugin, you can specify a sMinWidth, which will enforce a minimum column width even if it requires a horizontal scrollbar.

I offer this code with no support or guarantees whatsoever. Just thought it might be useful. See JavaDoc for details and recipes.

Instructions:
1. Copy the code below into "datatables.fillwidth.js"
2. Include the script on your page
3. Add an "F" to "sDom" when creating the datatable

/**
 * Forces the data table to fill the available width.
 * 
 * If the available width is larger than the width of the datatable, then the
 * remaining width will be allocated according to the relative weight (sWidth)
 * of columns. If one or more columns contains a percentage, then the remaining
 * width is distributed only to those columns. See recipes below for more
 * details.
 * 
 * If the available width is smaller than the width of the datatable, then the
 * datatable will overflow the width and a horizontal scrollbar will appear.
 * 
 * This plugin introduces a new column attribute "sMinWidth", which sets the
 * minimum width of the column. If not specified, the "sWidth" is used as the
 * minimum width. "sMinWidth" is useful if you want a column to have a minimum
 * width AND get a portion of the available width.
 * 
 * NOTE: If the content of a column is wider than the minimum width, the column
 * will be stretched anyway. That is, content is not truncated by sMinWidth.
 * 
 * NOTE: If you resize the table, you must call fnDraw() to resize the columns
 * using this plugin.
 * 
 * USAGE:
 * 
 * <code>
 * $("#myGrid").dataTable({
 *   "sDom" : "tF", // "F" enabled the fillwidth plugin
 * });
 * </code>
 * 
 * RECIPES:
 * <dl>
 * <dt>Allocate extra space to a single column</dt>
 * <dd>Set the sWidth of the column to "100%", and set the sWidth of other
 * columns in px.
 * 
 * <code>
 * { sWidth: "50px" },
 * { sWidth: "100%" }, // Takes all remainining space
 * { sWidth: "200px" } 
 * </code>
 * 
 * <dt>Split extra space between multiple columns</dt>
 * <dd>Set the sWidth of the columns in percentages (weights), and set the
 * sWidth of other columns in px.
 * 
 * <code>
 * { sWidth: "50px" },
 * { sWidth: "60%" }, // Takes 60% of remaining space
 * { sWidth: "40%" }, // Takes 40% of remaining space
 * { sWidth: "200px" } 
 * </code>
 * 
 * <dt>Assign extra space to a column and also require a minimum width</dt>
 * <dd>
 * 
 * <code>
 * { sWidth: "50px" },
 * { sWidth: "60%" }, // Takes 60% of remaining space
 * { 
 *   sMinWidth: "200px", // Starts out at a minimum 200px 
 *   sWidth: "40%"       // Takes 40% of remaining space
 * },
 * { sWidth: "200px" } 
 * </code>
 * 
 * </dd>
 * 
 * </dl>
 * If you want to set all columns to
 * 
 * @author John LaBanca
 */
function __fillwidthPlugin(dtSettings) {
  this.dtSettings = dtSettings; // DataTable settings.
}

__fillwidthPlugin.prototype = {

  ondraw : function() {
    /*
     * Add a sizer div to each header. The sizer forces the TH (and thus the
     * column) to have the minimum width because a cell will expand to fit its
     * content even if it means ignoring the cell's width.
     */
    for ( var i = 0; i < this.dtSettings.aoColumns.length; i++) {
      var column = this.dtSettings.aoColumns[i];
      var sizer = this._ensureSizer(column);

      // Set the width of the sizer to the minimum width.
      var minWidth = this._calculateMinWidth(column);
      if (minWidth) {
        sizer.width(minWidth);
      }
    }

    /*
     * Set the tbody to 100% width. Setting the width here is better than
     * setting it in CSS because datatable will be able to override the setting
     * after calculations are complete. If we set the width in CSS, it will
     * override anything that datatables does.
     */
    var tbody = $(this.dtSettings.nTBody);
    var tbodyTable = tbody.parent();
    tbodyTable.width("100%");
  },

  /**
   * Ensures that the column contains a sizer div and returns it.
   * 
   * @param aoColumn the column
   * @return the sizer div
   */
  _ensureSizer : function(aoColumn) {
    var th = $(aoColumn.nTh);
    var sizer = th.children(".__fillwidthPluginSizer");

    // Create the sizer if it doesn't exist.
    if (sizer.size() == 0) {
      sizer = $('<div class="__fillwidthPluginSizer" style="height:0px;"></div>');
      th.append(sizer);
    }

    return sizer;
  },

  /**
   * Calculates the minimum column width.
   */
  _calculateMinWidth : function(aoColumn) {
    // Default minimum width is the sWidth.
    var minWidth = aoColumn.sWidth;

    // Calculate the min width if it is provided separately.
    if (typeof aoColumn.sMinWidth != "undefined") {
      var iTmpWidth = this.dtSettings.oInstance.oApi._fnConvertToWidth(aoColumn.sMinWidth,
          this.dtSettings.nTable.parentNode);
      if (iTmpWidth !== null) {
        minWidth = iTmpWidth;
      }
    }

    return minWidth;
  }
};

$.fn.dataTableExt.aoFeatures.push({
  "fnInit" : function(oDTSettings) {
    var plugin = new __fillwidthPlugin(oDTSettings);
    oDTSettings.aoDrawCallback.push({
      "fn" : function() {
        plugin.ondraw();
      },
      "sName" : "FillWidth"
    });

    // Return void because we do not require a DOM element.
    return;
  },
  "cFeature" : "F",
  "sFeature" : "FillWidth"
});

Viewing all articles
Browse latest Browse all 82017

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>