Tag Archives: jQuery

Use jQuery FreezeTable to build a scrollable table

Here we’ll use jQuery FreezeTable plugin to freeze the header and add a vertical scroll bar to a lengthly table.

The end result will look like this:
freezetableexample

Step 1: The HTML

<table id="mytable">
  <colgroup>
    <col class="column-make" />
    <col class="column-display" />
    <col class="column-country" />       
  </colgroup>
  <thead>
    <tr>
      <th>make_id</th>
      <th>make_display</th>
      <th>make_country</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>abarth</td>
      <td>Abarth</td>
      <td>Italy</td>
    </tr>
  </tbody>
</table>

The table markup needs to adhere to the HTML 4.01 Specification for Tables. The row groups THEAD and TBODY are used to determine which sections of the table should be frozen. jquery.freezetable clones the table and removes the TBODY from the cloned copy to ‘freeze’ the header. It then removes the THEAD from the original table to make the scrollable portion of the table. jquery.freezetable also depends on COLGROUP to maintain consistent column styling between the orginal and cloned header table.

Step 2: The JavaScript

$(document).ready(function () {
    $('#mytable').freezeTable({
        'autoHeight': false,
        'height': 160
    });
});

Demo
AutoHeight Demo
Fixed height Demo
Interactive Demo on JSFIDDLE

Download
Download FreezeTable from GitHub

Formatting Dates with Knockout.js

I am working on a couple of Silverlight projects using Microsoft Prism and found the MVVM pattern very powerful. The team at work is developing a single page HTML/Javascript application that is using Knockout as the MVVM framework. I wanted to bind a date using a custom format ‘dddd, MMMM dd, yyyy’. Since JavaScript doesn’t have great support for formatting dates I pulled in Date.js.

I am familiar with using IValueConverter in Silverlight to convert values during binding. I was really happy to find a the custom binding feature in Knockout called ‘bindingHandlers‘. I was able to write a quick bindingHandler to format the date using date.js.

Checkout the Demo

Here is the custom binding for formatting dates using date.js:

ko.bindingHandlers.dateString = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor(),
            allBindings = allBindingsAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        var pattern = allBindings.datePattern || 'MM/dd/yyyy';
        $(element).text(valueUnwrapped.toString(pattern));
    }
}

Here is the binding in page:

Thursday, April 05, 2012
0.00

Quick Tip: Use JQuery to submit a TextBox.

imageSubmitting a search box when <Enter> is pressed is a nice usability feature to provide.  Unfortunately, ASP.NET Web Forms and its requirement for a single <form> tag breaks this expected behavior when there is more than one submit button on the page.   This can be easily fixed with a JavaScript and JQuery.   Listening to the keydown event on the TextBox the Go submit button can be triggered when <Enter> is pressed.

jQuery("#searchTextBox").keydown(function (event) {
    if (event.keyCode && event.keyCode == '13') {
        jQuery("#searchButton").click();
        return false;
    } else {
        return true;
    }
});

jQuery dialog with tabs font-size fix

While developing AspNetInfo I ran into a styling problem when using jQuery tabs nested in a dialog.  Notice in the dialog how the tab font-size is slightly larger than the tag font-size in the page.

jquery-font-size-example 

This is because the dialog and tab widgets are decorated with the jQuery style .ui-widget, which specifies a relative font-size of 1.3em.

.ui-widget { 
    font-family: Arial,sans-serif; 
    font-size: 1.3em; 
}

The font-size of the nested tab widget ends up being larger due to CSS inheritance and relative font-size.  The tab widget inherits the dialog widget’s relative font-size making the nested tab widget items 1.69em in size (1.3em X 1.3em = 1.69em).

This can be fixed by specifying a more specific rule for the nested tab widget to bring all of it’s items back to 1.3em.  This rule can be applied to just the tabs by specifying the tab id or to all instances of nested widgets.

Fix for email tab only:

#emailTabs.ui-widget {
    font-size: 1em;
}

Fix for all widgets:

.ui-widget .ui-widget {
    font-size: 1em;
}

JavaScript Variable Pattern

To help make writing and maintaining JavaScript easier in ASP.NET I have started to use a pattern that isolates the JavaScript variables away from the core script.  By doing this I can avoid a bunch of string concatenation in my server side code and embedded code blocks in my .aspx page when rendering dynamic JavaScript.  The core JavaScript can be placed into a .js file.  The ASP.NET page is now only responsible for rendering a list of updated variables that the core script expects.

To demonstrate consider a set of jQuery tabs that contains forms on each tab.  When a form is submitted from a particular tab the tab should be selected after the form posts back.  Using embedded code blocks the JavaScript would be. 

<script type="text/javascript">
    jQuery(function($) {
        $("#tabs").tabs();
        $("#tabs").tabs('select', <%=selectedTab %>);
    });
</script>

While this looks pretty clean it prevents us from putting this JavaScript into a .js file.  Applying the variable pattern the JavaScript can be refactored to the following and placed into a .js file.

jQuery(function($) {
    $("#tabs").tabs();
    $("#tabs").tabs('select', selectedTab);
});

The page is now only responsible for rendering the ‘selectedTab’ variable.

<script type="text/javascript">
    var selectedTab = 3;
</script>

I have created a JavaScriptVariable class to assist in rendering the JavaScript variables.   The JavaScript block is rendered to the page using ScriptManager.RegisterStartupScript to ensure the variable are available to scripts.  In addition, the ‘JavaScriptVariables’ member variable and the RenderJavaScriptVaraibles() method could be added to a base Paqe class.  Here is an example using JavaScriptVariable to render the variables for example above.

    IList<JavaScriptVariable> JavaScriptVariables = new List<JavaScriptVariable>();
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        JavaScriptVariables.Add(new JavaScriptVariable("selectedTab", selectedTab.ToString(), "{0}"));
        ScriptManager.RegisterStartupScript(this, typeof(AspNetDiag), "AspNetDiagVars.js", RenderJavaScriptVariables(), true);
    }

    private string RenderJavaScriptVariables()
    {
        StringBuilder js = new StringBuilder();
        foreach (var jsVar in JavaScriptVariables)
        {
            js.AppendFormat("var {0} = {1};", jsVar.Name, jsVar.GetFormatedValue());
        }
        return js.ToString();
    }

Finally the source for JavaScriptVariable.  

class JavaScriptVariable
{
    public string Name { get; set; }
    public string Value { get; set; }
    public string Format { get; set; }

    public JavaScriptVariable(string name, string value) : this(name, value, "\"{0}\"") { }
    public JavaScriptVariable(string name, string value, string format)
    {
        Name = name;
        Value = value;
        Format = format;
    }

    public string GetFormatedValue()
    {
        return String.Format(Format, Value);
    }
}