It's just that simple. Turn your simple table into a sophisticated data table and offer your users a nice experience and great features without any effort.

ID Sender Received
10238 eduardo@pingpong.com 14.10.2013
10243 eduardo@pingpong.com 19.10.2013
10248 eduardo@pingpong.com 24.10.2013
10253 eduardo@pingpong.com 29.10.2013
10234 lila@google.com 10.10.2013
10239 lila@google.com 15.10.2013
10244 lila@google.com 20.10.2013
10249 lila@google.com 25.10.2013
10237 robert@bingo.com 13.10.2013
10242 robert@bingo.com 18.10.2013
10247 robert@bingo.com 23.10.2013
10252 robert@bingo.com 28.10.2013
10236 simon@yahoo.com 12.10.2013
10241 simon@yahoo.com 17.10.2013
10246 simon@yahoo.com 22.10.2013
10251 simon@yahoo.com 27.10.2013
10235 tim@microsoft.com 11.10.2013
10240 tim@microsoft.com 16.10.2013
10245 tim@microsoft.com 21.10.2013
10250 tim@microsoft.com 26.10.2013

Code

HTML

<table id="grid-basic" class="table table-condensed table-hover table-striped">
    <thead>
        <tr>
            <th data-column-id="id" data-type="numeric">ID</th>
            <th data-column-id="sender">Sender</th>
            <th data-column-id="received" data-order="desc">Received</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>10238</td>
            <td>eduardo@pingpong.com</td>
            <td>14.10.2013</td>
        </tr>
        ...
    </tbody>
</table>

JavaScript

$("#grid-basic").bootgrid();

ID Sender Received Link

Code

HTML

<table id="grid-data" class="table table-condensed table-hover table-striped">
    <thead>
        <tr>
            <th data-column-id="id" data-type="numeric">ID</th>
            <th data-column-id="sender">Sender</th>
            <th data-column-id="received" data-order="desc">Received</th>
            <th data-column-id="link" data-formatter="link" data-sortable="false">Link</th>
        </tr>
    </thead>
</table>

JavaScript

$("#grid-data").bootgrid({
    ajax: true,
    post: function ()
    {
        /* To accumulate custom parameter with the request object */
        return {
            id: "b0df282a-0d67-40e5-8558-c9e93b7befed"
        };
    },
    url: "/api/data/basic",
    formatters: {
        "link": function(column, row)
        {
            return "<a href=\"#\">" + column.id + ": " + row.id + "</a>";
        }
    }
});

POST Body (Request)

current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed

JSON (Response)

{
  "current": 1,
  "rowCount": 10,
  "rows": [
    {
      "id": 19,
      "sender": "123@test.de",
      "received": "2014-05-30T22:15:00"
    },
    {
      "id": 14,
      "sender": "123@test.de",
      "received": "2014-05-30T20:15:00"
    },
    ...
  ],
  "total": 1123
}

ID Sender Received Link

Ensure that the data attribute data-identifier="true" is set on one column header.

Code

HTML

<table id="grid-selection" class="table table-condensed table-hover table-striped">
    <thead>
        <tr>
            <th data-column-id="id" data-type="numeric" data-identifier="true">ID</th>
            <th data-column-id="sender">Sender</th>
            <th data-column-id="received" data-order="desc">Received</th>
            <th data-column-id="link" data-formatter="link" data-sortable="false">Link</th>
        </tr>
    </thead>
</table>

JavaScript

$("#grid-selection").bootgrid({
    ajax: true,
    post: function ()
    {
        /* To accumulate custom parameter with the request object */
        return {
            id: "b0df282a-0d67-40e5-8558-c9e93b7befed"
        };
    },
    url: "/api/data/basic",
    selection: true,
    multiSelect: true,
    formatters: {
        "link": function(column, row)
        {
            return "<a href=\"#\">" + column.id + ": " + row.id + "</a>";
        }
    }
}).on("selected.rs.jquery.bootgrid", function(e, rows)
{
    var rowIds = [];
    for (var i = 0; i < rows.length; i++)
    {
        rowIds.push(rows[i].id);
    }
    alert("Select: " + rowIds.join(","));
}).on("deselected.rs.jquery.bootgrid", function(e, rows)
{
    var rowIds = [];
    for (var i = 0; i < rows.length; i++)
    {
        rowIds.push(rows[i].id);
    }
    alert("Deselect: " + rowIds.join(","));
});

POST Body (Request)

current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed

JSON (Response)

{
  "current": 1,
  "rowCount": 10,
  "rows": [
    {
      "id": 19,
      "sender": "123@test.de",
      "received": "2014-05-30T22:15:00"
    },
    {
      "id": 14,
      "sender": "123@test.de",
      "received": "2014-05-30T20:15:00"
    },
    ...
  ],
  "total": 1123
}

ID Sender Received Link

Ensure that the data attribute data-identifier="true" is set on one column header.

Code

HTML

<table id="grid-keep-selection" class="table table-condensed table-hover table-striped">
    <thead>
        <tr>
            <th data-column-id="id" data-type="numeric" data-identifier="true">ID</th>
            <th data-column-id="sender">Sender</th>
            <th data-column-id="received" data-order="desc">Received</th>
            <th data-column-id="link" data-formatter="link" data-sortable="false">Link</th>
        </tr>
    </thead>
</table>

JavaScript

$("#grid-keep-selection").bootgrid({
    ajax: true,
    post: function ()
    {
        /* To accumulate custom parameter with the request object */
        return {
            id: "b0df282a-0d67-40e5-8558-c9e93b7befed"
        };
    },
    url: "/api/data/basic",
    selection: true,
    multiSelect: true,
    rowSelect: true,
    keepSelection: true,
    formatters: {
        "link": function(column, row)
        {
            return "<a href=\"#\">" + column.id + ": " + row.id + "</a>";
        }
    }
}).on("selected.rs.jquery.bootgrid", function(e, rows)
{
    var rowIds = [];
    for (var i = 0; i < rows.length; i++)
    {
        rowIds.push(rows[i].id);
    }
    alert("Select: " + rowIds.join(","));
}).on("deselected.rs.jquery.bootgrid", function(e, rows)
{
    var rowIds = [];
    for (var i = 0; i < rows.length; i++)
    {
        rowIds.push(rows[i].id);
    }
    alert("Deselect: " + rowIds.join(","));
});

POST Body (Request)

current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed

JSON (Response)

{
  "current": 1,
  "rowCount": 10,
  "rows": [
    {
      "id": 19,
      "sender": "123@test.de",
      "received": "2014-05-30T22:15:00"
    },
    {
      "id": 14,
      "sender": "123@test.de",
      "received": "2014-05-30T20:15:00"
    },
    ...
  ],
  "total": 1123
}

All setting can be also set via data attributes.

ID Sender Received

Code

HTML

<table id="grid-data-api" class="table table-condensed table-hover table-striped" data-toggle="bootgrid" data-ajax="true" data-url="/api/data/basic">
    <thead>
        <tr>
            <th data-column-id="id" data-type="numeric" data-identifier="true">ID</th>
            <th data-column-id="sender">Sender</th>
            <th data-column-id="received" data-order="desc">Received</th>
        </tr>
    </thead>
</table>

POST Body (Request)

current=1&rowCount=10&sort[sender]=asc&searchPhrase=

JSON (Response)

{
  "current": 1,
  "rowCount": 10,
  "rows": [
    {
      "id": 19,
      "sender": "123@test.de",
      "received": "2014-05-30T22:15:00"
    },
    {
      "id": 14,
      "sender": "123@test.de",
      "received": "2014-05-30T20:15:00"
    },
    ...
  ],
  "total": 1123
}

ID Sender Received Commands

Code

HTML

<table id="grid-data" class="table table-condensed table-hover table-striped">
    <thead>
        <tr>
            <th data-column-id="id" data-type="numeric">ID</th>
            <th data-column-id="sender">Sender</th>
            <th data-column-id="received" data-order="desc">Received</th>
            <th data-column-id="commands" data-formatter="commands" data-sortable="false">Commands</th>
        </tr>
    </thead>
</table>

JavaScript

var grid = $("#grid-command-buttons").bootgrid({
    ajax: true,
    post: function ()
    {
        return {
            id: "b0df282a-0d67-40e5-8558-c9e93b7befed"
        };
    },
    url: "/api/data/basic",
    formatters: {
        "commands": function(column, row)
        {
            return "<button type=\"button\" class=\"btn btn-xs btn-default command-edit\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-pencil\"></span></button> " + 
                "<button type=\"button\" class=\"btn btn-xs btn-default command-delete\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-trash-o\"></span></button>";
        }
    }
}).on("loaded.rs.jquery.bootgrid", function()
{
    /* Executes after data is loaded and rendered */
    grid.find(".command-edit").on("click", function(e)
    {
        alert("You pressed edit on row: " + $(this).data("row-id"));
    }).end().find(".command-delete").on("click", function(e)
    {
        alert("You pressed delete on row: " + $(this).data("row-id"));
    });
});

POST Body (Request)

current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed

JSON (Response)

{
  "current": 1,
  "rowCount": 10,
  "rows": [
    {
      "id": 19,
      "sender": "123@test.de",
      "received": "2014-05-30T22:15:00"
    },
    {
      "id": 14,
      "sender": "123@test.de",
      "received": "2014-05-30T20:15:00"
    },
    ...
  ],
  "total": 1123
}

More examples like manipulation will follow very soon. For experienced developer I recommend to see in code how feature-rich and flexible jQuery Bootgrid is. Here you see only a small set of features.