On May 24, 2012 In Coding User interface with , , , tags

Responsive Data Tables with jQuery

On October 2011, we wrote a article called Responsive and SEO Friendly Data Tables which caught a lot of attention. now they are request asking for a plugin to convert the html table into a div based responsive table in real time using JavaScript. So, i started my hand getting in dirt.

i really don’t know how well it goes, this is my jQuery plugin. So, feel free to report bugs. before continuing please consider reading previous article for all the HTML and CSS stuff.

Basic HTML Table which we will convert into a div based table

<table>
        <thead>
		<tr>
			<td>Employee No</td>
			<td>User Name</td>
			<td>Real Name</td>
			<td>Age</td>
			<td>Profession</td>
			<td>Contact</td>
		<tr>
        </thead>
        <tr>
            <td>2311</td>
            <td>Lorem</td>
            <td>Ipsum dolor</td>
            <td>22</td>
            <td>Web designer</td>
            <td>1234567890</td>
	</tr>
        <tr>
            <td>4542</td>
            <td>Viverra</td>
            <td>Nam non viverra</td>
            <td>22</td>
            <td>Web developer</td>
            <td>2345678901</td>
        </tr>
        <tr>
            <td>5643</td>
            <td>Sed</td>
            <td>Donec sed volutpat</td>
            <td>25</td>
            <td>Editor</td>
            <td>3456789012</td>
        </tr>
        <tr>
            <td>5464</td>
            <td>Orci</td>
            <td>Phasellus eu orci nunc</td>
            <td>32</td>
            <td>User Interface</td>
            <td>4567890123</td>
        </tr>
    </table>

This basic table will be converted into div based table after jQuery

Step 1: Include jQuery Library

We are using jquery-1.7.1.min.js for real time table conversion grab you copy

<script src="js/jquery-1.7.1.min.js"></script>

If you can grab a copy don’t worry. we have included all the files in the source

Step 2: Adding the jQuery

We will start from the begining i.e from variables

var head_col_count = $('thead td').size();
var head_col_label = $('thead td:nth-child('+ i +')').text();
head_col_count
Returns total number of td’s inside thead
head_col_label
Extracts the value of td inside thead and then stores it to data-label

Now, the remaining tutorial will be followed inside the program through comments

<script>
	// counts total number of td in a head so that we can can use it for label extraction
	var head_col_count =  $('thead td').size();
	// loop which replaces td
	for ( i=0; i <= head_col_count; i++ )  {
		// head column label extraction
		var head_col_label = $('thead td:nth-child('+ i +')').text();
		// replaces td with <div class="column" data-label="label">
		$('tr td:nth-child('+ i +')').replaceWith(
			function(){
				return $('<div class="column" data-label="'+ head_col_label +'">').append($(this).contents());
			}
		);
	}	
	// replaces table with <div class="table">
	$('table').replaceWith(
		function(){
			return $('<div class="table">').append($(this).contents());
		}
	);	
	// replaces thead with <div class="table-head">
	$('thead').replaceWith(
		function(){
			return $('<div class="table-head">').append($(this).contents());
		}
	);	
	// replaces tr with <div class="row">
	$('tr').replaceWith(
		function(){
			return $('<div class="row">').append($(this).contents());
		}
	);	
	// replaces th with <div class="column">
	$('th').replaceWith(
		function(){
			return $('<div class="column">').append($(this).contents());
		}
	);
</script>

And it works. I hope you got a clean understanding on this little jQuery plugin. please use our comments section for a thanking message, a bug report etc,.. Any kind of spreading the word is appreciated and its time to bed

I would like to thank useyourfred

  • gmclelland

    Thanks again for posting this.  I made a few changes.  
    http://jsfiddle.net/gmclelland/4EPYW/
    - Your demo works with td in the thead, but most of time you will see th inside of thead.
    - I also added alternating class odd_row class for styling.
    - the tbody expands full width when in mobileI think this needs to be turned into a proper plugin.  See http://jqueryboilerplate.com/  I will try my hand at converting this.

    Just curious why are you using data attributes in the script?  http://www.useyourfred.com/2012/01/js-in-my-sexy-responsive-data-tables/ doesn’t use them.  By using data attributes, you make it only work with html5 pages, right?

    • http://www.mobifreaks.com Munawar Ahmed Mohammed

      i’ll update this as per your suggestion, like removing thead and adding odd columns can be dine with css no need create a class we can do that with nth-child
      now about jquery boiler plate am not sure, will try to make it compact and conflict free

      before i wrote our previous responsive data tables article we read Chris choyers. articles, which was based on tables and repeative css nth-childs for the data to be look like mobile chart then we prototyped with div’s and data-attributes at that time,i haven’t thought of why am using this.
      however it will work on all smartphones which support css3, but if we really got a need to avoid a data-attributes, we can try any semantic attribute

      • gmclelland

        Your right about the odd row styling.  If possible, I would suggest not using the data attributes so that you can use this plugin on any preexisting html4 and html5 pages.

        I’m trying out http://jqueryboilerplate.com, there is also http://starter.pixelgraphics.us/ as a plugin generator.

        The other thing you might want to think about it preserving all the attributes on the original tags instead of replacing them completely.  For example, if the tables have preexisting classes or data attributes you will want to keep that.

        Looking forward to it

        • http://www.mobifreaks.com Munawar Ahmed Mohammed

          i’ll be replacing data-label with title attribute which is a semantic way.
          and am replacing thead with tr athen call it in jQuery as tr:first-child.keeping preexisting classes is a good idea will try in the evening

          • gmclelland

            Now that I think about it some more, why should we be converting table elements(tr,td,thead) into divs? That’s a lot of DOM manipulation that would slow down mobile devices.  I know Chris Coyier said that IE doesn’t play nice with tables elements set to display:block.  Maybe we can make to where IE styling is ignored?
            Why not simply insert the values of TH from the THEAD at the top of a TR into a TH? This would be more performant as there would be a lot less DOM manipulation.

            What do you think?

          • http://www.mobifreaks.com Munawar Ahmed Mohammed

            i convert table element to div’s, div’s are way faster than the table, while comparing the load time. One more thing retrieving values from thead td or thead th are both same both cause same amount of data manipulation.

            how ever over plugin works on mobile which supports js i.e IOS, Android, Bada, Windows Mango etc,..

            i removed thead and replaced it with tr and used titles instead of data attribute will update the script after jQuery plugin implementation

      • http://twitter.com/frederickweiss Frederick P Weiss

        I (useyourfred.com) just have the code rely on a basic table that the client will input, no extra code; a client will just be adding tables without any extra markup, unless you have a custom table node template(drupal) created.

        • http://www.mobifreaks.com Munawar Ahmed Mohammed

          Am trying to remove extra markup. by the way thanks for stopping by

  • gmclelland

    Currently we take table rows and table cells and convert them into a bunch of divs with classes.  That part requires a lot of DOM manipulation.  Why don’t we just skip that part and keep tables as tables.  No need to replace anything.  No need to worry about keeping preexisting attributes like classes, id, etc. because we aren’t replacing anything.  This would be much simpler.

    In a new plugin you could simply take the value from the thead>td and insert it as a th inside each table row.  Then still use media queries to change the look of the table into a stacked layout on the mobile.

    Hopefully, I’m explaining this clearly.

    • http://www.mobifreaks.com Munawar Ahmed Mohammed

      i can do that

  • gmclelland

    I created a jquery plugin proof of concept at 
    http://jsfiddle.net/gmclelland/wAbuW/  

    • http://www.mobifreaks.com Munawar Ahmed Mohammed

      yah it works. i think adding a class or id to the table element will do the magic and stops other tables from converting. am little busy may be i will post the plugin tomarrow

  • gmclelland

    I activated the plugin like this 
    $(‘table’).responsiveTables();​ which works for all tables, but you could also call it like this 
    $(‘table.nameOfClass’).responsiveTables(); to only activate on all tables with the class=”nameOfClass”.

    Hope that helps.

    Thank you for all your help.​

  • Gfw

    Love your code. 

    Question… Assuming that some of the columns are styles left (typically text) and others to the right (typically currency), how would you maintain the column styles when you move the table to the div format?

    • http://www.mobifreaks.com Munawar Ahmed Mohammed

      Text would be on top and currency would be on bottom of text. i guess

  • http://www.facebook.com/julian.pustkuchen Julian Pustkuchen

    Here you can find another alternative:

    https://github.com/JPustkuchen/jquery.webks-responsive-table