Wiki source code of Live Table component

Version 107.1 by ElenaOanaTabaranu on 2009/09/14

Show last authors
1 = Live Table component =
2
3 {{velocity filter="indent"}}
4 {{html clean="false" wiki="true"}}
5 #warning("This document is a draft.")
6
7 #warning("This section documents a feature that is only available starting with XWiki Enterprise 1.9M2.")
8
9 {{toc start=2 depth=6 numbered=false scope=page /}}
10
11 == Summary ==
12
13 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>>http://vimeo.com/4474332]].
14
15 == How to use ==
16
17 The Live Table component is made available in several ways to [[Applications>>code:Applications.WebHome]] developers and developers of the [[XWiki platform and products>>dev:Main.WebHome]], 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>>platform:Main.XWikiSyntax]]
18
19 === Using the Velocity livetable macro ===
20
21 Please refer [[Live Table Macro>>code:Macros.LiveTableMacro]] reference.
22
23 === HTML + JavaScript ===
24
25 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>>http://www.json.org]] code generated with the [[Live Table Macro>>code:Macros.LiveTableMacro]].
26
27 === Example ===
28
29 #warning("You need the Ratings plugin in your wiki to make the most of the example below.")
30
31 The Live Table component could be extended with a special column containing the ratings of some documents from the wiki.
32 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**:
33
34 {{code language=html}}
35
36 #set($collist = ["doc.name", "_ratings", "doc.date", "doc.author", "_actions"])
37
38 #set($colprops = {
39 "doc.name" : { "type" : "text" , "size" : 30, "sortable":true, "filterable":true},
40 "_ratings" : { "sortable":false},
41 "doc.date" : { "type" : "date" },
42 "doc.author" : { "type" : "text", "link" : "author"},
43 "_actions" : { "actions": ["copy","delete","rename","rights"]}
44 })
45 #set($options = { "resultPage":"TutorialsCode.LiveTableRatings",
46 "tagCloud" : true,
47 "translationPrefix" : "xe.index.",
48 "rowCount": 10 })
49 #set($ok = $xwiki.ssx.use("TutorialsCode.LiveTableRatings"))
50 #set($ok = $xwiki.jsx.use("TutorialsCode.LiveTableRatings"))
51 #livetable("alldocs" $collist $colprops $options)
52 {{/code}}
53
54 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.
55
56 {{code}}
57 #includeMacros("TutorialsCode.LiveTableResultsMacros")
58
59 #gridresultwithfilter("" $request.collist.split(",") "" "doc.space='Tutorials' and doc.name<>'WebHome' and doc.name<>'WebPreferences'")
60
61 {{/code}}
62
63 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.
64
65 {{code}}
66 ##
67 ## list ratings
68 ##
69 #macro(grid_ratings $udoc)
70 #set($ratings = "")
71 #set($ratingObj = "")
72 #set($ratingObj = $udoc.getObject("XWiki.AverageRatingsClass"))
73 #if("$!ratingObj" != "")
74 #set($ratings = $ratingObj.get("averagevote"))
75 #end
76 #end
77 {{/code}}
78
79 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:
80 {{/html}}
81 {{/velocity}}
82
83 {{code}}
84 ...
85 #elseif($colname=="_images") ,
86 #grid_photolist($udoc)
87 "${colname}" : "${photolist}"
88 #elseif($colname=="_ratings"),
89 #grid_ratings($udoc)
90 "${colname}" : "${ratings}"
91 #else ,
92 ...
93 {{/code}}
94
95 #info("Firebug can be a useful tool when testing the JSON code generated.")
96
97 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.
98
99 Add an on-demand Javascript Extension with a content which can be parsed and use the code below to enrich your component:
100
101 {{code}}
102 /** Display ratings in the live table on row event */
103 document.observe("xwiki:livetable:newrow", function(ev) {
104 $$('._ratings').each(function (el) {
105 // update content
106 var avgvote = 0.0;
107 if (el.innerHTML !== "") {
108 avgvote = parseFloat(el.innerHTML);
109 }
110 var wstyle = 0;
111 if (avgvote > 0) {
112 wstyle = avgvote * 20;
113 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>";
114 } else if(el.innerHTML === ""){
115 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>";
116 }
117 });
118 document.fire("xwiki:livetable:ready", {
119 });
120 });
121 /** Update ratings images on hover event aka mouse over and mouse out.*/
122 document.observe("xwiki:livetable:ready", function(levent) {
123 $$('.xwiki-livetable-display-body tr').each(function (elem) {
124 Event.observe(elem, 'mouseover', function (ev) {
125 var ratings = elem.down('._ratings');
126 if(ratings) {
127 // update default white stars background
128 var elt = ratings.down(2);
129 elt.setStyle({
130 backgroundImage: 'url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"))',
131 backgroundPosition: '0% 0%'
132 });
133 // update votes background
134 elt = ratings.down(3);
135 elt.setStyle({
136 backgroundImage: 'url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"))',
137 backgroundPosition: '0% 50%'
138 });
139 }
140 });
141 Event.observe(elem, 'mouseout', function (ev) {
142 var ratings = elem.down('._ratings');
143 if(ratings) {
144 // restore default white stars background
145 var elt = ratings.down(2);
146 elt.setStyle({
147 backgroundImage: 'url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif"))',
148 backgroundPosition: '0% 0%'
149 });
150 // restore votes background
151 elt = elem.down('._ratings').down(3);
152 elt.setStyle({
153 backgroundImage: 'url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif"))',
154 backgroundPosition: '0% 50%'
155 });
156 }
157 });
158
159 });
160 });
161 {{/code}}
162
163 Also, we should add some CSS in an on-demand Stylesheet extension with a content which can be parsed to polish the custom column display:
164 {{code}}
165 /* ratings for live table */
166 .small-star-rating,
167 .small-star-rating .current-rating {
168 background: url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif")) left -1000px repeat-x;
169 }
170 .small-star-rating{
171 position:relative;
172 width:125px;
173 height:25px;
174 overflow:hidden;
175 list-style:none;
176 margin:0px !important;
177 padding:0px !important;
178 background-position: left top;
179 }
180 .small-star-rating li{
181 display: inline;
182 }
183 .small-star-rating a,
184 .small-star-rating .current-rating{
185 position:absolute;
186 top:0;
187 left:0;
188 text-indent:-1000em;
189 height:25px;
190 line-height:25px;
191 outline:none;
192 overflow:hidden;
193 border: none;
194 }
195 .small-star-rating .current-rating{
196 z-index:1;
197 background-position: left center;
198 }
199 .small-star-rating:hover,
200 .small-star-rating:active,
201 .small-star-rating:focus {
202 background-image: url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"));
203 background-repeat: repeat-x;
204 background-position: top left;
205 }
206 .small-star-rating a.one-star{
207 width:20%;
208 z-index:6;
209 }
210 .small-star-rating a.two-stars{
211 width:40%;
212 z-index:5;
213 }
214 .small-star-rating a.three-stars{
215 width:60%;
216 z-index:4;
217 }
218 .small-star-rating a.four-stars{
219 width:80%;
220 z-index:3;
221 }
222 .small-star-rating a.five-stars{
223 width:100%;
224 z-index:2;
225 }
226 .rating-stars {
227 display: inline;
228 float: left;
229 clear: none;
230 }
231
232 {{/code}}

Get Connected