Live Table component

Version 124.1 by Oana Florea on 2009/09/24
Warning: For security reasons, the document is displayed in restricted mode as it is not the current version. There may be differences and errors due to this.

Live Table component

Failed to execute the [velocity] macro. Cause: [The execution of the [velocity] script macro is not allowed in [xwiki:Documentation.DevGuide.FrontendResources.LiveTable.WebHome]. Check the rights of its last author or the parameters if it's rendered from another script.]. Click on this message for details.

Summary

The "Live Table" component is a dynamic table loading data lazily using ajax requests as the user browse the table, in order to scale easily the display of very large amounts of data. Users can browse the table thanks to a pagination system. Filters on columns are available to search for specific entries. Columns can be made sortable in both direction. For a demonstration of the main capabilities of the live table component check out this video.

How to use

The Live Table component is made available in several ways to Applications developers and developers of the XWiki platform and products, depending on their specific needs. The simplest, and most of the times preferred, way to embed a Live Table component is to use the <tt>livetable</tt> velocity macro, available in all pages of your wiki. With only one call to this macro, you will be able to display a live table of the data of your choice! For more specific needs, in the cases you need more control on the table behavior, or to build another component on top of the live table, it is possible to instantiate the live table from JavaScript. In this case, you, as opposed to the velocity macro, you will need to construct the HTML elements the JavaScript component expects yourself, either from JavaScript, either writing the HTML directly in your wiki page

Using the Velocity livetable macro

Please refer Live Table Macro reference.

HTML + JavaScript

This is a dynamic component which must me used carefully because of performance issues. The HTML content of the Live Table is automatically updated using Javascript and JSON code generated with the Live Table Macro.
The Live Table component is build using the Prototype library as a class representing an AJAX-populated live table. The default variable name generated in XWiki Enterprise is ta and you can use it, for example to manipulate the display of the component's rows by calling <tt>ta.showRows()</tt>.

For more details, check the Javascript file livetable.js on your wiki at http://localhost:8080/xwiki/bin/skin/resources/js/xwiki/table/livetable.js

Example

Failed to execute the [velocity] macro. Cause: [The execution of the [velocity] script macro is not allowed in [xwiki:Documentation.DevGuide.FrontendResources.LiveTable.WebHome]. Check the rights of its last author or the parameters if it's rendered from another script.]. Click on this message for details.

The Live Table component could be extended with a special column containing the ratings of some documents from the wiki.
The first step would be to generate the JSON code of the column we want to add. In order to achieve this goal we need to modify the result page of the velocity live table macro with our custom page TutorialsCode.LiveTableRatings:


#set($collist = ["doc.name", "_ratings", "doc.date", "doc.author", "_actions"])

#set($colprops = {
                  "doc.name" : { "type" : "text" , "size" : 30, "sortable":true, "filterable":true},
                  "_ratings" : { "sortable":false},
                  "doc.date" : { "type" : "date" },
                  "doc.author" : { "type" : "text", "link" : "author"},
                  "_actions" : { "actions": ["copy","delete","rename","rights"]}
                })
#set($options = { "resultPage":"TutorialsCode.LiveTableRatings",
                 "tagCloud" : true,
                 "translationPrefix" : "xe.index.",
                 "rowCount": 10 })
#set($ok = $xwiki.ssx.use("TutorialsCode.LiveTableRatings"))
#set($ok = $xwiki.jsx.use("TutorialsCode.LiveTableRatings"))
#livetable("alldocs" $collist $colprops $options

If we want to display the rated documents from a certain space, e.g. Tutorials, the last parameter of the <tt>#gridresultwithfilter</tt> must contain the query we need.

#includeMacros("TutorialsCode.LiveTableResultsMacros")

#gridresultwithfilter("" $request.collist.split(",") "" "doc.space='Tutorials' and doc.name<>'WebHome' and doc.name<>'WebPreferences'")

The page at TutorialsCode.LiveTableResultsMacros should contain a copy of the default code (the page is located at XWiki.LiveTableResultsMacro) for the live table result page. The next step implies extracting the rating information from the wiki pages located the Tutorials space. We add a new velocity macro which will test the presence of the rating object with class XWiki.AverageRatingsClass and extract the rating value.

##
## list ratings
##
#macro(grid_ratings $udoc)
  #set($ratings = "")
  #set($ratingObj = "")
  #set($ratingObj = $udoc.getObject("XWiki.AverageRatingsClass"))
  #if("$!ratingObj" != "")
     #set($ratings = $ratingObj.get("averagevote"))
  #end
#end

The continue our extension of this component, we need to add a test for the presence of our custom column to call the <tt>grid_ratings</tt> macro when generating the JSON: 

...
#elseif($colname=="_images") ,
  #grid_photolist($udoc)
 "${colname}" : "${photolist}"
#elseif($colname=="_ratings"),
  #grid_ratings($udoc)
 "${colname}" : "${ratings}"
#else ,
...

Failed to execute the [velocity] macro. Cause: [The execution of the [velocity] script macro is not allowed in [xwiki:Documentation.DevGuide.FrontendResources.LiveTable.WebHome]. Check the rights of its last author or the parameters if it's rendered from another script.]. Click on this message for details.

Transforming the rating information to a nice star display requires using Javascript to replace the content of that column with the proper HTML. Attach the image below to your TutorialsCode.LiveTableRatings page to change the default white background when hovering on the stars.

star-table.gif

Add an on-demand Javascript Extension with a content which can be parsed and use the code below to enrich your component:

/** Display ratings in the live table on row event */
document.observe("xwiki:livetable:newrow", function(ev) {
  $$('._ratings').each(function (el) {
     // update content
     var avgvote = 0.0;
     if (el.innerHTML !== "") {
       avgvote = parseFloat(el.innerHTML);
      }
     var wstyle = 0;
     if (avgvote > 0) {
       wstyle = avgvote * 20;
       el.innerHTML="<div class='avg-rating'><div class='rating-stars'><ul class='small-star-rating'><li style='width: " + wstyle +"%;' class='current-rating'/><li><a class='one-star' href='#' onclick='return false;'>1</a></li><li><a class='two-stars' href='#'  onclick='return false;'>2</a></li><li><a class='three-stars' href='#'  onclick='return false;'>3</a></li><li><a class='four-stars' href='#'  onclick='return false;'>4</a></li><li><a class='five-stars' href='#'  onclick='return false;'>5</a></li></ul></div></div>";
      } else if(el.innerHTML === ""){
       el.innerHTML="<div class='avg-rating'><div class='rating-stars'><ul class='small-star-rating'><li style='width: 0%;' class='current-rating'/><li><a class='one-star' href='#' onclick='return false;'>1</a></li>    <li><a class='two-stars' href='#'  onclick='return false;'>2</a></li><li><a class='three-stars' href='#'  onclick='return false;'>3</a></li><li><a class='four-stars' href='#'  onclick='return false;'>4</a></li><li><a class='five-stars' href='#'  onclick='return false;'>5</a></li></ul></div></div>";
      }
   });
  document.fire("xwiki:livetable:ready", {
   });
});
/** Update ratings images on hover event aka mouse over and mouse out.*/
document.observe("xwiki:livetable:ready", function(levent) {
  $$('.xwiki-livetable-display-body tr').each(function (elem) {
   Event.observe(elem, 'mouseover', function (ev) {
     var ratings = elem.down('._ratings');
     if(ratings) {
       // update default white stars background
       var elt = ratings.down(2)
       elt.setStyle({
         backgroundImage: 'url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"))',
         backgroundPosition: '0% 0%'
        });
       // update votes background     
       elt = ratings.down(3)
       elt.setStyle({
         backgroundImage: 'url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"))',
         backgroundPosition: '0% 50%'
        });
      }
    });
   Event.observe(elem, 'mouseout', function (ev) {
     var ratings = elem.down('._ratings');
     if(ratings) {
       // restore default white stars background
       var elt = ratings.down(2)
       elt.setStyle({
         backgroundImage: 'url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif"))',
         backgroundPosition: '0% 0%'
        });
       // restore votes background     
       elt = elem.down('._ratings').down(3)
       elt.setStyle({
         backgroundImage: 'url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif"))',
         backgroundPosition: '0% 50%'
        });
      }
    });

  });
});

Also, add some CSS in an on-demand Stylesheet extension with a content which can be parsed to polish the custom column display:

/* ratings for live table */
.small-star-rating,
.small-star-rating .current-rating {
 background: url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif")) left -1000px repeat-x;
}
.small-star-rating{
 position:relative;
 width:125px;
 height:25px;
 overflow:hidden;
 list-style:none;
 margin:0px !important;
 padding:0px !important;
 background-position: left top;
}
.small-star-rating li{
 display: inline;
}
.small-star-rating a,
.small-star-rating .current-rating{
 position:absolute;
 top:0;
 left:0;
 text-indent:-1000em;
 height:25px;
 line-height:25px;
 outline:none;
 overflow:hidden;
 border: none;
}
.small-star-rating .current-rating{
 z-index:1;
 background-position: left center;
}
.small-star-rating:hover,
.small-star-rating:active,
.small-star-rating:focus {
 background-image: url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"));
 background-repeat: repeat-x;
 background-position: top left;
}
.small-star-rating a.one-star{
 width:20%;
 z-index:6;
}
.small-star-rating a.two-stars{
 width:40%;
 z-index:5;
}
.small-star-rating a.three-stars{
 width:60%;
 z-index:4;
}
.small-star-rating a.four-stars{
 width:80%;
 z-index:3;
}
.small-star-rating a.five-stars{
 width:100%;
 z-index:2;
}
.rating-stars {
 display: inline;  
 float: left;
 clear: none;
}

The final result should look like this:

livetabel.png

Get Connected