de

xw-browse: Grid-Control for XML-Data (Javascript)

xw-browse is a lightweight (ca. 26KB) list-control (read-only grid-control) for displaying tabular lists (provided as XML-data). It allows (multi-) selection of rows, sorting, formatting and more; xw-browse is especially suitable for XML-driven "single-page applications", but can also be easily used in conventional websites (like this one).

The xw-browse serves the performant rendering of XML-data; it has a special API  and needs a small helper-plugin for initialization for this reason. At runtime required are the libraries  jQuery  and  jQuery UI . jquery UI-Themes are supported in header and footer, the look can be widely controlled with CSS.

If xw-browse is initialized without resizing of browse and columns and without sortable columns, jQuery UI is not needed.

Demo 1: Standard Features

Script, CSS, browseplaceholder and button

<link href="/css/xw-browse.css" rel="stylesheet"/>
<link href="/css/demo-courses.css" rel="stylesheet"/>
<script src="/js/xw-browse-bundle-1.min.js" ></script>

<div id="demoxwbrowse" class="demo-courses"></div>
<p>
  <button class="demobrowsedouble" >Double entries</button>
</p>

Create browse and initialize Button

var xw = jQuery.fn.xwalk,
    demo_xwbrowse = $("#demoxwbrowse"),
    data = $($.parseXML('<pagexmldata>...</pagexmldata>'));

// format bools as symbols (defined by css-class "xw-bool-true")
xw.formatBool = function (v, opt, row, parent) {
    if (v == "true") { 
        $('<span class="xw-bool-true"></span>').appendTo(parent); 
        return null;
    }
    return "";
};

// initialize the browse
demo_xwbrowse.xwctrl({
    ctrlType: "browse",
    rows: data.find(">pagexmldata>demoBrowseCourses>course"),
    meta: data.find(">pagexmldata>demoBrowseCourses>xwmeta"),
    selectFirstRow: false,
    formatter: xw.format
});

// handle button click-event
$(".demobrowsedouble").click(function () {
    var browseApi = demo_xwbrowse.xwctrl(), 
        newRows = browseApi.cloneRows(),
        ofs = newRows.length + 1;
    
    // set unique primary key values at element "pk"
    newRows.each(function (i) { $(this).find("pk").text(i+ofs) });
    browseApi.insertRows(newRows);
}); 

Column widths and symbols for bool-values

.xw-browse .xw-bool-true:after {
    font-family: FontAwesome;
    content: "\f00c";
    color: #0a0;
}
.demo-courses { font-size:14px }
.demo-courses .pk { width:60px }
.demo-courses .name { width:250px }
.demo-courses .startdate { width:82px }
.demo-courses .fee
{
    text-align:right;
    width:70px;
}
.demo-courses .buchbar, .demo-courses .ab18 {
    text-align:center;
    width:70px;
} 
.demo-courses .ab18 .xw-bool-true:after {
    content: "\f12a";
    color: #e33;
} 

XML-data for the browse

Demo 2: Browse with Buttons

Script, CSS and buttonbrowse (buttons right)

<link href="/css/xw-browse.css" rel="stylesheet"/>
<link href="/css/demo-courses.css" rel="stylesheet"/>
<script src="/js/xw-browse-bundle-1.min.js" ></script>

<div class="buttonbrowse buttons-right" id="demobuttonbrowse">
    <div class="browse demo-courses" />
    <div class="buttons">
        <button id="dbb_show" class="sel1" title="Show">
            <span class="fa fa-eye" />
        </button>
        <button id="dbb_add" title="Add">
            <span class="fa fa-plus" />
        </button>
        <button id="dbb_del" class="sel1n button-sep-big" title="Delete">
            <span class="fa fa-trash" />
        </button>
    </div>
</div> 

Create browse and initialize buttons

var xw = jQuery.fn.xwalk,
    demo_buttonbrowse = $("#demobuttonbrowse"), 
    brws = demo_buttonbrowse.find(">.browse"),
    data = $($.parseXML('<pagexmldata>...</pagexmldata>'));

// format bools as symbols (defined by css-class "xw-bool-true")
xw.formatBool = function (v, opt, row, parent) {
    if (v == "true") { 
        $('<span class="xw-bool-true"></span>').appendTo(parent); 
        return null;
    }
    return "";
};

// make buttons jquery UI - buttons
demo_buttonbrowse.find(">.buttons>button").button();

// init browse
brws.xwctrl({
    ctrlType: "browse",
    rows: data.find(">pagexmldata>demoBrowseCourses>course"),
    meta: data.find(">pagexmldata>demoBrowseCourses>xwmeta"),
    connectButtons: true,
    selectFirstRow: false,
    formatter: xw.format
});

// button-click-events
$("#dbb_show").click(function () {
    alert(brws.xwctrl().selElements().find("name").text());
});

$("#dbb_add").click(function () {
    var browseApi = brws.xwctrl(),
        newRows = browseApi.cloneRows(), ofs = 0;
    if (newRows.length == 0) {
      newRows = data.find(">pagexmldata>demoBrowseCourses>course").clone();
    } 
    else {
      // set unique primary key-values
      newRows.each(function () { 
        var pk = parseInt($(this).find("pk").text()); 
        if (pk > ofs) ofs = pk;
      });
      newRows.each(function (i) { $(this).find("pk").text(i + ofs + 1) });
    }
    browseApi.insertRows(newRows);
});

$("#dbb_del").click(function () { brws.xwctrl().deleteSelected() }); 

Script, CSS and buttonbrowse (buttons top)

<link href="/css/xw-browse.css" rel="stylesheet"/>
<script src="/js/xw-browse-bundle.min.js" ></script>

<div class="buttonbrowse buttons-top" id="demobuttonbrowse">
    <div class="buttons">
        <button id="dbb_show" class="sel1" title="Show">
            <span class="fa fa-eye" />
        </button>
        <button id="dbb_add" title="Add">
            <span class="fa fa-plus" />
        </button>
        <button id="dbb_del" class="sel1n button-sep-big" title="Delete">
            <span class="fa fa-trash" />
        </button>
    </div>
    <div class="browse demo-courses" />
</div> 

CSS and XML is identical to Demo 1.

Buttons can be placed right or top. The CSS-classes "sel1" and "sel1n" control the enabled-status of the buttons, dependent on selection:

Class "sel1": only enabled, if exactly one row is selected.
Class "sel1n": only enabled, if at least one row is selected.

Features and Restrictions

  • XML-data for column definitions and browse content is directly passed.
  • Sortable rows (one or two-tiered, the latter can be achieved by clicking the first sort-arrow to lock the column-sorting and then double click the second column header).
  • Data types for columns allow correct sorting and formatting. With an own formatting-function passed during initialization, cell content can be formatted almost arbitrarily.
  • Optional: order of columns can be changed per drag and drop, columns and/or browse can be configured as resizable.
  • Complete control on styling per CSS (header and footer can be influenced by jQuery UI-Themes), also column widths are set with CSS.
  • Wide support for keydown-events for navigation and selection (arrow and other navigation keys, also with Ctrl- and Shift-Key, Ctrl-A, etc.)
  • (jQuery UI-) buttons can be "connected" to make their enabled-status dependent to the browse selection (controlled by CSS-class at button-element: always enabled, only enabled, if exactly on row is selected or enabled, if at least one row is selected; also, the enabled-status can be programmed per button by passing a function, which can decide the status depending on selected rows content. The first button is defined as the "standard button"; if enabled, it will be "clicked", if return-key is pressed or a row is being double clicked.
  • xw-browse is fast, because only the visible content of XML-data is actually rendered ("virtual scrolling"). However performance decreases with large count of rows, especially, when rows are sorted.
  • xw-browse supports a minimalistic concept of business entities: if a datatype (like "customer") is provided at browse initialization and one or more columns are defined as "key" in column-meta-infos, our XML-events "entities-deleted" and "entity-updated" are getting evaluated by the browse for contained suitable data rows (the xw-browse deletes rows or updates rows content).
  • Restriction: row height can be defined by CSS, but all rows must be defined with same height.
  • Editing of cell content is not possible, xw-browse is a read-only grid-control.

"xw-browse" is provided for download as test-version in the protected area of our website at tab "Media" (exclusively for testing purposes!).

xw-browse was successfully tested with current versions of Mozilla Firefox, MS Internet Explorer, MS Edge and Google Chrome.