Wiki source code of Live Table

Last modified by Sergei Kulagin on 2024/04/23

Hide last authors
Manuel Smeria 134.3 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
Vincent Massol 125.2 4
Manuel Smeria 134.3 5 = Summary =
fkorteby 27.1 6
Vincent Massol 131.2 7 The **"Livetable"** 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, check out the [[XWiki livetable component video>>http://vimeo.com/4474332]].
ElenaOanaTabaranu 65.1 8
Manuel Smeria 134.3 9 = How to use =
fkorteby 27.1 10
Sergei Kulagin 138.3 11 The Livetable component is made available in several ways to [[Extensions>>extensions:Main.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 Livetable component is to use the ##livetable## velocity macro, available in all pages of your wiki. With only one call to this macro you will be able to display a Livetable 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 Livetable, it is possible to instantiate the Livetable from JavaScript. In this case you, as opposed to the velocity macro, will need to construct the HTML elements yourself that the JavaScript component expects, either from JavaScript or writing the [[HTML directly in your wiki page>>xwiki:Documentation.UserGuide.Features.XWikiSyntax]].
fkorteby 27.1 12
Manuel Smeria 134.3 13 == Using the Velocity Livetable macro ==
fkorteby 27.1 14
Vincent Massol 131.2 15 Please refer to [[XWiki Livetable Macro>>extensions:Extension.Livetable Macro]] reference.
fkorteby 27.1 16
Manuel Smeria 134.3 17 == HTML + JavaScript ==
fkorteby 27.1 18
Manuel Smeria 134.3 19 This is a dynamic component which must be used carefully because of performance issues. The HTML content of the Livetable is automatically updated using Javascript and [[JSON>>http://www.json.org]] code generated with the [[Livetable Macro>>extensions:Extension.Livetable Macro]].
Vincent Massol 131.2 20 The Livetable component is build using the Prototype library as a class representing an AJAX-populated Livetable:
Manuel Smeria 134.3 21
Ecaterina Moraru (Valica) 136.1 22 * The default variable name generated in XWiki is **livetable** and you can use it, for example to manipulate the display of the component's rows by calling ##livetable.showRows()## or to refresh it ##livetable.refresh()##(older versions of the livetable use the default variable name **ta**).
Guillaume Delhumeau 135.1 23 {{comment}}FIXME: Page has been moved/removed.
24 * Take a look at the [[code snippet>>extensions:Extension.Refresh Livetable With Changed URL]] for refreshing the Livetable.{{/comment}}
Mathieu Pace 138.1 25 * For more details, check the Javascript file **livetable.js** [[on your wiki>>http://localhost:8080/xwiki/bin/skin/resources/js/xwiki/table/livetable.js]] or {{scm path="xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/table/livetable.js"}}on GitHub{{/scm}}.
fkorteby 27.1 26
Manuel Smeria 134.3 27 == Example ==
Oana Florea 123.1 28
Manuel Smeria 134.3 29 {{warning}}
30 You need the [[Ratings Application>>extensions:Extension.Ratings Application]] in your wiki to make the most of the example below.
31 {{/warning}}
ElenaOanaTabaranu 103.1 32
Vincent Massol 131.2 33 The Livetable component could be extended with a special column containing the ratings of some documents from the wiki.
34 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 Livetable macro with our custom page **TutorialsCode.LiveTableRatings**:
ElenaOanaTabaranu 32.1 35
Vincent Massol 125.2 36 {{code language="none"}}
ElenaOanaTabaranu 55.1 37 #set($collist = ["doc.name", "_ratings", "doc.date", "doc.author", "_actions"])
ElenaOanaTabaranu 57.1 38 #set($colprops = {
ElenaOanaTabaranu 32.1 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"},
ElenaOanaTabaranu 51.1 43 "_actions" : { "actions": ["copy","delete","rename","rights"]}
ElenaOanaTabaranu 57.1 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"))
Oana Florea 122.1 51 #livetable("alldocs" $collist $colprops $options)
ElenaOanaTabaranu 58.1 52 {{/code}}
ElenaOanaTabaranu 32.1 53
Vincent Massol 125.2 54 If we want to display the rated documents from a certain space, e.g. **Tutorials**, the last parameter of the ###gridresultwithfilter## must contain the query we need.
ElenaOanaTabaranu 34.1 55
Vincent Massol 125.2 56 {{code language="none"}}
ElenaOanaTabaranu 34.1 57 #includeMacros("TutorialsCode.LiveTableResultsMacros")
ElenaOanaTabaranu 59.1 58
Raluca Stavro 126.1 59 #gridresultwithfilter("" $request.collist.split(",") "" "and doc.space='Tutorials' and doc.name<>'WebHome' and doc.name<>'WebPreferences'")
ElenaOanaTabaranu 60.1 60 {{/code}}
ElenaOanaTabaranu 73.1 61
Vincent Massol 131.2 62 The page at **TutorialsCode.LiveTableResultsMacros** should contain a copy of the default code (the page is located at **XWiki.LiveTableResultsMacro**) for the Livetable 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.
ElenaOanaTabaranu 90.1 63
Vincent Massol 125.2 64 {{code language="none"}}
ElenaOanaTabaranu 81.1 65 ##
66 ## list ratings
67 ##
ElenaOanaTabaranu 73.1 68 #macro(grid_ratings $udoc)
69 #set($ratings = "")
70 #set($ratingObj = "")
71 #set($ratingObj = $udoc.getObject("XWiki.AverageRatingsClass"))
72 #if("$!ratingObj" != "")
73 #set($ratings = $ratingObj.get("averagevote"))
74 #end
75 #end
ElenaOanaTabaranu 74.1 76 {{/code}}
ElenaOanaTabaranu 90.1 77
Manuel Smeria 134.3 78 To continue our extension of this component, we need to add a test for the presence of our custom column to call the ##grid_ratings## macro when generating the JSON:
ElenaOanaTabaranu 93.1 79
Vincent Massol 125.2 80 {{code language="none"}}
ElenaOanaTabaranu 75.1 81 ...
Eduard Moraru 134.2 82 #elseif($colname == '_images') ,
83 #livetable_getImagesList($itemDoc)
84 "$escapetool.javascript(${colname})" : "$escapetool.javascript(${imagesList})"
ElenaOanaTabaranu 75.1 85 #elseif($colname=="_ratings"),
Eduard Moraru 134.2 86 #grid_ratings($itemDoc)
ElenaOanaTabaranu 75.1 87 "${colname}" : "${ratings}"
ElenaOanaTabaranu 79.1 88 #else ,
ElenaOanaTabaranu 75.1 89 ...
90 {{/code}}
ElenaOanaTabaranu 87.1 91
Manuel Smeria 134.3 92 {{info}}
93 Firebug can be a useful tool when testing the JSON code generated.
94 {{/info}}
Eduard Moraru 134.2 95
ElenaOanaTabaranu 107.1 96 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.
ElenaOanaTabaranu 75.1 97
Mathieu Pace 138.1 98 [[image:star-table.gif||style="margin-right:1em"]]
ElenaOanaTabaranu 108.1 99
ElenaOanaTabaranu 107.1 100 Add an on-demand Javascript Extension with a content which can be parsed and use the code below to enrich your component:
101
Vincent Massol 125.2 102 {{code language="javascript"}}
Vincent Massol 131.2 103 /** Display ratings in the Livetable on row event */
ElenaOanaTabaranu 98.1 104 document.observe("xwiki:livetable:newrow", function(ev) {
105 $$('._ratings').each(function (el) {
106 // update content
107 var avgvote = 0.0;
108 if (el.innerHTML !== "") {
109 avgvote = parseFloat(el.innerHTML);
110 }
111 var wstyle = 0;
112 if (avgvote > 0) {
113 wstyle = avgvote * 20;
114 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>";
115 } else if(el.innerHTML === ""){
116 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>";
117 }
118 });
119 document.fire("xwiki:livetable:ready", {
120 });
121 });
122 /** Update ratings images on hover event aka mouse over and mouse out.*/
123 document.observe("xwiki:livetable:ready", function(levent) {
124 $$('.xwiki-livetable-display-body tr').each(function (elem) {
125 Event.observe(elem, 'mouseover', function (ev) {
126 var ratings = elem.down('._ratings');
127 if(ratings) {
128 // update default white stars background
129 var elt = ratings.down(2);
130 elt.setStyle({
131 backgroundImage: 'url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"))',
132 backgroundPosition: '0% 0%'
133 });
134 // update votes background
135 elt = ratings.down(3);
136 elt.setStyle({
137 backgroundImage: 'url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"))',
138 backgroundPosition: '0% 50%'
139 });
140 }
141 });
142 Event.observe(elem, 'mouseout', function (ev) {
143 var ratings = elem.down('._ratings');
144 if(ratings) {
145 // restore default white stars background
146 var elt = ratings.down(2);
147 elt.setStyle({
148 backgroundImage: 'url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif"))',
149 backgroundPosition: '0% 0%'
150 });
151 // restore votes background
152 elt = elem.down('._ratings').down(3);
153 elt.setStyle({
154 backgroundImage: 'url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif"))',
155 backgroundPosition: '0% 50%'
156 });
157 }
158 });
ElenaOanaTabaranu 75.1 159
ElenaOanaTabaranu 98.1 160 });
161 });
162 {{/code}}
163
ElenaOanaTabaranu 110.1 164 Also, add some CSS in an on-demand Stylesheet extension with a content which can be parsed to polish the custom column display:
Vincent Massol 121.2 165
Vincent Massol 125.2 166 {{code language="none"}}
Vincent Massol 131.2 167 /* ratings for Livetable */
ElenaOanaTabaranu 98.1 168 .small-star-rating,
169 .small-star-rating .current-rating {
170 background: url($xwiki.getDocument("XWiki.Ratings").getAttachmentURL("star.gif")) left -1000px repeat-x;
171 }
172 .small-star-rating{
173 position:relative;
174 width:125px;
175 height:25px;
176 overflow:hidden;
177 list-style:none;
178 margin:0px !important;
179 padding:0px !important;
180 background-position: left top;
181 }
182 .small-star-rating li{
183 display: inline;
184 }
185 .small-star-rating a,
186 .small-star-rating .current-rating{
187 position:absolute;
188 top:0;
189 left:0;
190 text-indent:-1000em;
191 height:25px;
192 line-height:25px;
193 outline:none;
194 overflow:hidden;
195 border: none;
196 }
197 .small-star-rating .current-rating{
198 z-index:1;
199 background-position: left center;
200 }
201 .small-star-rating:hover,
202 .small-star-rating:active,
203 .small-star-rating:focus {
204 background-image: url($xwiki.getDocument("TutorialsCode.LiveTableRatings").getAttachmentURL("star-table.gif"));
205 background-repeat: repeat-x;
206 background-position: top left;
207 }
208 .small-star-rating a.one-star{
209 width:20%;
210 z-index:6;
211 }
212 .small-star-rating a.two-stars{
213 width:40%;
214 z-index:5;
215 }
216 .small-star-rating a.three-stars{
217 width:60%;
218 z-index:4;
219 }
220 .small-star-rating a.four-stars{
221 width:80%;
222 z-index:3;
223 }
224 .small-star-rating a.five-stars{
225 width:100%;
226 z-index:2;
227 }
228 .rating-stars {
229 display: inline;
230 float: left;
231 clear: none;
232 }
233 {{/code}}
ElenaOanaTabaranu 111.1 234
235 The final result should look like this:
ElenaOanaTabaranu 114.1 236
Mathieu Pace 138.1 237 [[image:livetabel.png||style="margin-right:1em"]]

Get Connected