Browse Source

HUE-913 [core] Convert new jump to column to jQuery plugin and test it

Refactored HUE-899 to jQuery plugin
Added plugin to the 'sample' tab of a table
Added basic infrastructure for jQuery plugins Jasmine tests
Improved usability of the plugin (fixed headers, toggable tooltip with row identifier)
Enrico Berti 13 năm trước cách đây
mục cha
commit
ce6d541

+ 31 - 5
apps/beeswax/src/beeswax/templates/describe_table.mako

@@ -61,10 +61,14 @@ ${layout.menubar(section='tables')}
 					<li class="nav-header">${_('Actions')}</li>
 					<li><a href="#importData" data-toggle="modal">${_('Import Data')}</a></li>
 					<li><a href="${ url("beeswax.views.read_table", table=table_name) }">${_('Browse Data')}</a></li>
-			        <li><a href="#dropTable" data-toggle="modal">${_('Drop')} ${view_or_table_noun}</a></li>
-			        <li><a href="${hdfs_link}" rel="${ table.sd.location }">${_('View File Location')}</a></li>
+			    <li><a href="#dropTable" data-toggle="modal">${_('Drop')} ${view_or_table_noun}</a></li>
+			    <li><a href="${hdfs_link}" rel="${ table.sd.location }">${_('View File Location')}</a></li>
 				</ul>
 			</div>
+      <div id="jumpToColumnAlert" class="alert hide">
+        <button type="button" class="close" data-dismiss="alert">&times;</button>
+        <strong>${_('Did you know?')}</strong> ${_('You can click on a row to select a column you want to jump to.')}
+      </div>
 		</div>
 		<div class="span9">
 			% if table.parameters.get("comment", False):
@@ -93,11 +97,11 @@ ${layout.menubar(section='tables')}
 		        % endif
 				% if top_rows is not None:
 					<div class="tab-pane" id="sample">
-						<table class="table table-striped table-condensed datatables">
+						<table class="table table-striped table-condensed sampleTable">
 			              <thead>
 			                <tr>
 			                  % for col in table.sd.cols:
-			                    <th>${col.name}</th>
+			                    <th style="white-space: nowrap">${col.name}</th>
 			                  % endfor
 			                </tr>
 			              </thead>
@@ -105,7 +109,7 @@ ${layout.menubar(section='tables')}
 			                % for i, row in enumerate(top_rows):
 			                  <tr>
 			                    % for item in row:
-			                      <td>${ item }</td>
+			                      <td style="white-space: nowrap">${ item }</td>
 			                    % endfor
 			                  </tr>
 			                % endfor
@@ -200,6 +204,10 @@ ${layout.menubar(section='tables')}
         overflow-y:scroll;
         margin-top:10px;
     }
+
+    .sampleTable td, .sampleTable th {
+      white-space: nowrap;
+    }
 </style>
 
 <script type="text/javascript" charset="utf-8">
@@ -228,6 +236,24 @@ ${layout.menubar(section='tables')}
         $(".loadPath").click(function(){
             $("#filechooser").slideDown();
         });
+
+      $('a[data-toggle="tab"]').on('shown', function () {
+        $(".sampleTable").not('.initialized').addClass('initialized').dataTable({
+          "bPaginate": false,
+          "bLengthChange": false,
+          "bInfo": false,
+          "bFilter": false,
+          "fnInitComplete": function () {
+            $(".sampleTable").parent().jHueTableScroller();
+            $(".sampleTable").jHueTableExtender({
+              hintElement: "#jumpToColumnAlert",
+              fixedHeader: true
+            });
+          }
+        });
+      })
+
+
     });
 </script>
 

+ 12 - 111
apps/beeswax/src/beeswax/templates/watch_results.mako

@@ -50,52 +50,10 @@ ${layout.menubar(section='query')}
     left: 0;
   }
 
-  .noLeftMargin {
-    margin-left: 0 !important;
-  }
-
-  .rowSelected {
-    background-color: #EEEEEE !important;
-  }
-
-  .columnSelected {
-    background-color: #EEEEEE !important;
-  }
-
-  .cellSelected {
-    background-color: #DDDDDD !important;
-  }
-
-  #suggestColumns {
-    position: absolute;
-    left: 0;
-    z-index: 1000;
-    display: none;
-    min-width: 160px;
-    padding: 10px 20px 2px 10px;
-    margin: 2px 0 0;
-    background-color: #ffffff;
-    border: 1px solid #ccc;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-    *border-right-width: 2px;
-    *border-bottom-width: 2px;
-    -webkit-border-radius: 6px;
-    -moz-border-radius: 6px;
-    border-radius: 6px;
-    -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-    -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-    -webkit-background-clip: padding-box;
-    -moz-background-clip: padding;
-    background-clip: padding-box;
+  .resultTable td, .resultTable th {
     white-space: nowrap;
   }
 
-  #suggestColumns a {
-    margin-left: 10px;
-    margin-right: -14px;
-    margin-top: -12px;
-  }
 </style>
 
 <div class="container-fluid">
@@ -130,6 +88,10 @@ ${layout.menubar(section='query')}
 					% endif
 				</ul>
 			</div>
+      <div id="jumpToColumnAlert" class="alert hide">
+        <button type="button" class="close" data-dismiss="alert">&times;</button>
+        <strong>${_('Did you know?')}</strong> ${_('You can click on a row to select a column you want to jump to.')}
+      </div>
 		</div>
 		<div class="span9">
       <ul class="nav nav-tabs">
@@ -167,9 +129,9 @@ ${layout.menubar(section='query')}
             <tbody>
               % for i, row in enumerate(results):
               <tr>
-                <td style="white-space: nowrap">${start_row + i}</td>
+                <td>${start_row + i}</td>
               % for item in row:
-                  <td style="white-space: nowrap">${ item }</td>
+                  <td>${ item }</td>
               % endfor
               </tr>
               % endfor
@@ -185,10 +147,6 @@ ${layout.menubar(section='query')}
               % endif
               </ul>
             </div>
-            <div id="jumpToColumnAlert" class="alert hide" style="float:left;margin: 20px 0;">
-              <button type="button" class="close" data-dismiss="alert">&times;</button>
-              <strong>${_('Did you know?')}</strong> ${_('You can click on a row to select a column you want to jump to.')}
-            </div>
             % endif
         </div>
         <div class="tab-pane" id="query">
@@ -241,10 +199,7 @@ ${layout.menubar(section='query')}
   </div>
 %endif
 
-<div id="suggestColumns">
-  <a href="#" class="pull-right">&times;</a>
-  <label>${_('Go to column:')} <input type="text" placeholder="${_('column name...')}" /></label>
-</div>
+
 
 
 <script type="text/javascript" charset="utf-8">
@@ -324,66 +279,12 @@ ${layout.menubar(section='query')}
         $(".sidebar-nav").parent().css("margin-left", "0");
       });
 
-      $("[rel='tooltip']").tooltip();
-
-      $(".resultTable tbody").click(function (event) {
-        $(".rowSelected").removeClass("rowSelected");
-        $(".columnSelected").removeClass("columnSelected");
-        $(".cellSelected").removeClass("cellSelected");
-        $(event.target.parentNode).addClass("rowSelected");
-        $(event.target.parentNode).find("td").each(function () {
-          $(this).addClass("rowSelected");
-          $(this).attr("rel", "tooltip").attr("title", $(this).parents("table").find("th").eq($(this).prevAll().length).text()).tooltip();
-        });
-        $("#suggestColumns")
-                .css("left", (event.clientX + $("#suggestColumns").width() > $(window).width() - 10 ? event.clientX - $("#suggestColumns").width() - 10 : event.clientX))
-                .css("top", event.clientY + 10).show();
-        $("#suggestColumns input").focus();
-      });
-
-      $.expr[":"].econtains = function (obj, index, meta, stack) {
-        return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
-      }
-
-      var source = [];
-      $(".resultTable th").each(function () {
-        source.push($(this).text());
-      });
-
-      $("#suggestColumns input").typeahead({
-        source:source,
-        updater:function (item) {
-          $("#suggestColumns").hide();
-          $(".resultTable tr td:nth-child(" + ($(".resultTable th:econtains(" + item + ")").index() + 1) + ")").addClass("columnSelected");
-          $(".dataTables_wrapper").animate({
-            scrollLeft:$(".resultTable th:econtains(" + item + ")").position().left + $(".dataTables_wrapper").scrollLeft() - $(".dataTables_wrapper").offset().left - 30
-          }, 300);
-          $(".resultTable tr.rowSelected td:nth-child(" + ($(".resultTable th:econtains(" + item + ")").index() + 1) + ")").addClass("cellSelected");
-        }
+      $(".resultTable").jHueTableExtender({
+        hintElement: "#jumpToColumnAlert",
+        fixedHeader: true,
+        firstColumnTooltip: true
       });
 
-      $("#suggestColumns a").click(function (e) {
-        e.preventDefault();
-        $("#suggestColumns").hide();
-      });
-
-      $(window).resize(function () {
-        $("#suggestColumns").hide();
-      });
-
-      var showAlertTimeout = -1;
-      $(".resultTable tbody").mousemove(function () {
-        window.clearTimeout(showAlertTimeout);
-        if ($("#jumpToColumnAlert").data("show") == null || $("#jumpToColumnAlert").data("show")) {
-          showAlertTimeout = window.setTimeout(function () {
-            $("#jumpToColumnAlert").fadeIn();
-          }, 1300);
-        }
-      });
-
-      $("#jumpToColumnAlert .close").click(function () {
-        $("#jumpToColumnAlert").data("show", false);
-      });
     });
 </script>
 

+ 18 - 10
desktop/core/src/desktop/templates/common_header.mako

@@ -61,18 +61,25 @@ from django.utils.translation import ugettext as _
 
       // jHue plugins global configuration
       jHueFileChooserGlobals = {
-          labels: {
-              BACK: "${_('Back')}",
-              SELECT_FOLDER: "${_('Select this folder')}",
-              CREATE_FOLDER: "${_('Create folder')}",
-              FOLDER_NAME: "${_('Folder name')}",
-              CANCEL: "${_('Cancel')}",
-              FILE_NOT_FOUND: "${_('The file has not been found')}",
-              UPLOAD_FILE: "${_('Upload a file')}",
-              FAILED: "${_('Failed')}"
-          }
+        labels:{
+          BACK:"${_('Back')}",
+          SELECT_FOLDER:"${_('Select this folder')}",
+          CREATE_FOLDER:"${_('Create folder')}",
+          FOLDER_NAME:"${_('Folder name')}",
+          CANCEL:"${_('Cancel')}",
+          FILE_NOT_FOUND:"${_('The file has not been found')}",
+          UPLOAD_FILE:"${_('Upload a file')}",
+          FAILED:"${_('Failed')}"
+        }
       };
 
+      jHueTableExtenderGlobals = {
+        labels:{
+          GO_TO_COLUMN: "${_('Go to column:')}",
+          PLACEHOLDER: "${_('column name...')}"
+        }
+      }
+
   </script>
 
   <script src="/static/ext/js/jquery/jquery-1.8.1.min.js"></script>
@@ -82,6 +89,7 @@ from django.utils.translation import ugettext as _
   <script src="/static/js/Source/jHue/jquery.rowselector.js"></script>
   <script src="/static/js/Source/jHue/jquery.notify.js"></script>
   <script src="/static/js/Source/jHue/jquery.tablescroller.js"></script>
+  <script src="/static/js/Source/jHue/jquery.tableextender.js"></script>
   <script src="/static/ext/js/jquery/plugins/jquery.cookie.js"></script>
   <script src="/static/ext/js/jquery/plugins/jquery.simpleplaceholder.js"></script>
   <script src="/static/ext/js/jquery/plugins/jquery.dataTables.1.8.2.min.js"></script>

+ 35 - 0
desktop/core/src/desktop/templates/jasmine.mako

@@ -0,0 +1,35 @@
+## Licensed to Cloudera, Inc. under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  Cloudera, Inc. licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+##
+## no spaces in this method please; we're declaring a CSS class, and ART uses this value for stuff, and it splits on spaces, and
+## multiple spaces and line breaks cause issues
+
+<%inherit file="common_jasmine.mako"/>
+
+<%block name="specs">
+  <link href="/static/css/hue2.css" rel="stylesheet">
+
+  <script src="/static/ext/js/jquery/plugins/jquery.dataTables.1.8.2.min.js"></script>
+  <script src="/static/ext/js/bootstrap.min.js"></script>
+
+  <script src="/static/js/Source/jHue/jquery.selector.js"></script>
+  <script src="static/jasmine/jHueSelectorSpec.js"></script>
+
+  <script src="/static/js/Source/jHue/jquery.tableextender.js"></script>
+  <script src="static/jasmine/jHueTableExtenderSpec.js"></script>
+</%block>
+

+ 4 - 0
desktop/core/src/desktop/urls.py

@@ -60,6 +60,10 @@ dynamic_patterns = patterns('',
   (r'^debug/check_config$', 'desktop.views.check_config'),
   (r'^debug/check_config_ajax$', 'desktop.views.check_config_ajax'),
   (r'^log_frontend_event$', 'desktop.views.log_frontend_event'),
+
+  # Jasmine
+  (r'^jasmine', 'desktop.views.jasmine'),
+
   # Top level web page!
   (r'^$', 'desktop.views.index'),
 )

+ 3 - 0
desktop/core/src/desktop/views.py

@@ -202,6 +202,9 @@ def threads(request):
     out.append("")
   return HttpResponse("\n".join(out), content_type="text/plain")
 
+def jasmine(request):
+  return render('jasmine.mako', request, None)
+
 @login_notrequired
 def index(request):
   return render("index.mako", request, dict(

+ 46 - 1
desktop/core/static/css/hue2.css

@@ -1015,4 +1015,49 @@ a#advanced-btn:hover {
 
 .modal form {
   margin: 0;
-}
+}
+
+/*
+ * jHueTableExtender
+ */
+
+.rowSelected {
+  background-color: #EEEEEE !important;
+}
+
+.columnSelected {
+  background-color: #EEEEEE !important;
+}
+
+.cellSelected {
+  background-color: #DDDDDD !important;
+}
+
+#jHueTableExtenderNavigator {
+  position: absolute;
+  left: 0;
+  top: 0;
+  z-index: 1000;
+  display: none;
+  min-width: 160px;
+  padding: 10px 20px 2px 10px;
+  margin: 2px 0 0;
+  background-color: #ffffff;
+  border: 1px solid #ccc;
+  -webkit-border-radius: 6px;
+  -moz-border-radius: 6px;
+  border-radius: 6px;
+  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+  -webkit-background-clip: padding-box;
+  -moz-background-clip: padding;
+  background-clip: padding-box;
+  white-space: nowrap;
+}
+
+#jHueTableExtenderNavigator a {
+  margin-left: 10px;
+  margin-right: -14px;
+  margin-top: -12px;
+}

+ 6 - 0
desktop/core/static/jasmine/jHueSelectorFixture.html

@@ -0,0 +1,6 @@
+<select id="sampleList">
+  <option value="aaa">Aaa</option>
+  <option value="bbb">Bbb</option>
+  <option value="ccc">Ccc</option>
+  <option value="zzz">Zzz</option>
+</select>

+ 13 - 0
desktop/core/static/jasmine/jHueSelectorSpec.js

@@ -0,0 +1,13 @@
+describe("jHueSelector plugin", function () {
+
+  beforeEach(function () {
+    jasmine.getFixtures().fixturesPath = 'static/jasmine/';
+    loadFixtures('jHueSelectorFixture.html');
+    $("#sampleList").jHueSelector();
+  });
+
+  it("should hide the original element", function () {
+    expect($("#sampleList")).toBeHidden();
+  });
+
+});

+ 1221 - 0
desktop/core/static/jasmine/jHueTableExtenderFixture.html

@@ -0,0 +1,1221 @@
+<style>
+  .resultTable td, .resultTable th {
+    white-space: nowrap;
+  }
+</style>
+
+<table class="table table-striped table-condensed resultTable" cellpadding="0" cellspacing="0">
+  <thead>
+    <tr>
+      <th>&nbsp;</th>
+      <th>column0</th>
+      <th>column1</th>
+      <th>column2</th>
+      <th>column3</th>
+      <th>column4</th>
+      <th>column5</th>
+      <th>column6</th>
+      <th>column7</th>
+      <th>column8</th>
+      <th>column9</th>
+      <th>column10</th>
+      <th>column11</th>
+      <th>column12</th>
+      <th>column13</th>
+      <th>column14</th>
+      <th>column15</th>
+      <th>column16</th>
+      <th>column17</th>
+      <th>column18</th>
+      <th>column19</th>
+      <th>column20</th>
+      <th>column21</th>
+      <th>column22</th>
+      <th>column23</th>
+      <th>column24</th>
+      <th>column25</th>
+      <th>column26</th>
+      <th>column27</th>
+      <th>column28</th>
+      <th>column29</th>
+      <th>column30</th>
+      <th>column31</th>
+      <th>column32</th>
+      <th>column33</th>
+      <th>column34</th>
+      <th>column35</th>
+      <th>column36</th>
+      <th>column37</th>
+      <th>column38</th>
+      <th>column39</th>
+      <th>column40</th>
+      <th>column41</th>
+      <th>column42</th>
+      <th>column43</th>
+      <th>column44</th>
+      <th>column45</th>
+      <th>column46</th>
+      <th>column47</th>
+      <th>column48</th>
+      <th>column49</th>
+      <th>column50</th>
+      <th>column51</th>
+      <th>column52</th>
+      <th>column53</th>
+      <th>column54</th>
+      <th>column55</th>
+      <th>column56</th>
+      <th>column57</th>
+      <th>column58</th>
+      <th>column59</th>
+      <th>column60</th>
+      <th>column61</th>
+      <th>column62</th>
+      <th>column63</th>
+      <th>column64</th>
+      <th>column65</th>
+      <th>column66</th>
+      <th>column67</th>
+      <th>column68</th>
+      <th>column69</th>
+      <th>column70</th>
+      <th>column71</th>
+      <th>column72</th>
+      <th>column73</th>
+      <th>column74</th>
+      <th>column75</th>
+      <th>column76</th>
+      <th>column77</th>
+      <th>column78</th>
+      <th>column79</th>
+      <th>column80</th>
+      <th>column81</th>
+      <th>column82</th>
+      <th>column83</th>
+      <th>column84</th>
+      <th>column85</th>
+      <th>column86</th>
+      <th>column87</th>
+      <th>column88</th>
+      <th>column89</th>
+      <th>column90</th>
+      <th>column91</th>
+      <th>column92</th>
+      <th>column93</th>
+      <th>column94</th>
+      <th>column95</th>
+      <th>column96</th>
+      <th>column97</th>
+      <th>column98</th>
+      <th>column99</th>
+      <th>column100</th>
+      <th>column101</th>
+      <th>column102</th>
+      <th>column103</th>
+      <th>column104</th>
+      <th>column105</th>
+      <th>column106</th>
+      <th>column107</th>
+      <th>column108</th>
+      <th>column109</th>
+      <th>column110</th>
+      <th>column111</th>
+      <th>column112</th>
+      <th>column113</th>
+      <th>column114</th>
+      <th>column115</th>
+      <th>column116</th>
+      <th>column117</th>
+      <th>column118</th>
+      <th>column119</th>
+      <th>column120</th>
+      <th>column121</th>
+      <th>column122</th>
+      <th>column123</th>
+      <th>column124</th>
+      <th>column125</th>
+      <th>column126</th>
+      <th>column127</th>
+      <th>column128</th>
+      <th>column129</th>
+      <th>column130</th>
+      <th>column131</th>
+      <th>column132</th>
+      <th>column133</th>
+      <th>column134</th>
+      <th>column135</th>
+      <th>column136</th>
+      <th>column137</th>
+      <th>column138</th>
+      <th>column139</th>
+      <th>column140</th>
+      <th>column141</th>
+      <th>column142</th>
+      <th>column143</th>
+      <th>column144</th>
+      <th>column145</th>
+      <th>column146</th>
+      <th>column147</th>
+      <th>column148</th>
+      <th>column149</th>
+      <th>column150</th>
+      <th>column151</th>
+      <th>column152</th>
+      <th>column153</th>
+      <th>column154</th>
+      <th>column155</th>
+      <th>column156</th>
+      <th>column157</th>
+      <th>column158</th>
+      <th>column159</th>
+      <th>column160</th>
+      <th>column161</th>
+      <th>column162</th>
+      <th>column163</th>
+      <th>column164</th>
+      <th>column165</th>
+      <th>column166</th>
+      <th>column167</th>
+      <th>column168</th>
+      <th>column169</th>
+      <th>column170</th>
+      <th>column171</th>
+      <th>column172</th>
+      <th>column173</th>
+      <th>column174</th>
+      <th>column175</th>
+      <th>column176</th>
+      <th>column177</th>
+      <th>column178</th>
+      <th>column179</th>
+      <th>column180</th>
+      <th>column181</th>
+      <th>column182</th>
+      <th>column183</th>
+      <th>column184</th>
+      <th>column185</th>
+      <th>column186</th>
+      <th>column187</th>
+      <th>column188</th>
+      <th>column189</th>
+      <th>column190</th>
+      <th>column191</th>
+      <th>column192</th>
+      <th>column193</th>
+      <th>column194</th>
+      <th>column195</th>
+      <th>column196</th>
+      <th>column197</th>
+      <th>column198</th>
+      <th>column199</th>
+      <th>column200</th>
+      <th>column201</th>
+      <th>column202</th>
+      <th>column203</th>
+      <th>column204</th>
+      <th>column205</th>
+      <th>column206</th>
+      <th>column207</th>
+      <th>column208</th>
+      <th>column209</th>
+      <th>column210</th>
+      <th>column211</th>
+      <th>column212</th>
+      <th>column213</th>
+      <th>column214</th>
+      <th>column215</th>
+      <th>column216</th>
+      <th>column217</th>
+      <th>column218</th>
+      <th>column219</th>
+      <th>column220</th>
+      <th>column221</th>
+      <th>column222</th>
+      <th>column223</th>
+      <th>column224</th>
+      <th>column225</th>
+      <th>column226</th>
+      <th>column227</th>
+      <th>column228</th>
+      <th>column229</th>
+      <th>column230</th>
+      <th>column231</th>
+      <th>column232</th>
+      <th>column233</th>
+      <th>column234</th>
+      <th>column235</th>
+      <th>column236</th>
+      <th>column237</th>
+      <th>column238</th>
+      <th>column239</th>
+      <th>column240</th>
+      <th>column241</th>
+      <th>column242</th>
+      <th>column243</th>
+      <th>column244</th>
+      <th>column245</th>
+      <th>column246</th>
+      <th>column247</th>
+      <th>column248</th>
+      <th>column249</th>
+      <th>column250</th>
+      <th>column251</th>
+      <th>column252</th>
+      <th>column253</th>
+      <th>column254</th>
+      <th>column255</th>
+      <th>column256</th>
+      <th>column257</th>
+      <th>column258</th>
+      <th>column259</th>
+      <th>column260</th>
+      <th>column261</th>
+      <th>column262</th>
+      <th>column263</th>
+      <th>column264</th>
+      <th>column265</th>
+      <th>column266</th>
+      <th>column267</th>
+      <th>column268</th>
+      <th>column269</th>
+      <th>column270</th>
+      <th>column271</th>
+      <th>column272</th>
+      <th>column273</th>
+      <th>column274</th>
+      <th>column275</th>
+      <th>column276</th>
+      <th>column277</th>
+      <th>column278</th>
+      <th>column279</th>
+      <th>column280</th>
+      <th>column281</th>
+      <th>column282</th>
+      <th>column283</th>
+      <th>column284</th>
+      <th>column285</th>
+      <th>column286</th>
+      <th>column287</th>
+      <th>column288</th>
+      <th>column289</th>
+      <th>column290</th>
+      <th>column291</th>
+      <th>column292</th>
+      <th>column293</th>
+      <th>column294</th>
+      <th>column295</th>
+      <th>column296</th>
+      <th>column297</th>
+      <th>column298</th>
+      <th>column299</th>
+      <th>column300</th>
+      <th>column301</th>
+      <th>column302</th>
+      <th>column303</th>
+      <th>column304</th>
+      <th>column305</th>
+      <th>column306</th>
+      <th>column307</th>
+      <th>column308</th>
+      <th>column309</th>
+      <th>column310</th>
+      <th>column311</th>
+      <th>column312</th>
+      <th>column313</th>
+      <th>column314</th>
+      <th>column315</th>
+      <th>column316</th>
+      <th>column317</th>
+      <th>column318</th>
+      <th>column319</th>
+      <th>column320</th>
+      <th>column321</th>
+      <th>column322</th>
+      <th>column323</th>
+      <th>column324</th>
+      <th>column325</th>
+      <th>column326</th>
+      <th>column327</th>
+      <th>column328</th>
+      <th>column329</th>
+      <th>column330</th>
+      <th>column331</th>
+      <th>column332</th>
+      <th>column333</th>
+      <th>column334</th>
+      <th>column335</th>
+      <th>column336</th>
+      <th>column337</th>
+      <th>column338</th>
+      <th>column339</th>
+      <th>column340</th>
+      <th>column341</th>
+      <th>column342</th>
+      <th>column343</th>
+      <th>column344</th>
+      <th>column345</th>
+      <th>column346</th>
+      <th>column347</th>
+      <th>column348</th>
+      <th>column349</th>
+      <th>column350</th>
+      <th>column351</th>
+      <th>column352</th>
+      <th>column353</th>
+      <th>column354</th>
+      <th>column355</th>
+      <th>column356</th>
+      <th>column357</th>
+      <th>column358</th>
+      <th>column359</th>
+      <th>column360</th>
+      <th>column361</th>
+      <th>column362</th>
+      <th>column363</th>
+      <th>column364</th>
+      <th>column365</th>
+      <th>column366</th>
+      <th>column367</th>
+      <th>column368</th>
+      <th>column369</th>
+      <th>column370</th>
+      <th>column371</th>
+      <th>column372</th>
+      <th>column373</th>
+      <th>column374</th>
+      <th>column375</th>
+      <th>column376</th>
+      <th>column377</th>
+      <th>column378</th>
+      <th>column379</th>
+      <th>column380</th>
+      <th>column381</th>
+      <th>column382</th>
+      <th>column383</th>
+      <th>column384</th>
+      <th>column385</th>
+      <th>column386</th>
+      <th>column387</th>
+      <th>column388</th>
+      <th>column389</th>
+      <th>column390</th>
+      <th>column391</th>
+      <th>column392</th>
+      <th>column393</th>
+      <th>column394</th>
+      <th>column395</th>
+      <th>column396</th>
+      <th>column397</th>
+      <th>column398</th>
+      <th>column399</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>0</td>
+      <td>vestibulum ipsum</td>
+      <td>Fusce eleifend.</td>
+      <td>nec, Quisque</td>
+      <td>id ipsum</td>
+      <td>vehicula diam,</td>
+      <td>Fusce lacus</td>
+      <td>ipsum nibh.</td>
+      <td>sit dolor</td>
+      <td>sodales nec</td>
+      <td>dolor sit</td>
+      <td>Quisque Pellentesque</td>
+      <td>dui Pellentesque</td>
+      <td>Pellentesque Quisque</td>
+      <td>ac dignissim</td>
+      <td>accumsan pulvinar.</td>
+      <td>leo a</td>
+      <td>Pellentesque neque.</td>
+      <td>sit hendrerit</td>
+      <td>amet, tincidunt</td>
+      <td>purus, est</td>
+      <td>purus, adipiscing</td>
+      <td>sit Fusce</td>
+      <td>gravida. a</td>
+      <td>nibh. gravida.</td>
+      <td>luctus, vulputate</td>
+      <td>potenti. felis</td>
+      <td>vestibulum adipiscing</td>
+      <td>sapien sodales</td>
+      <td>imperdiet potenti.</td>
+      <td>dictum Pellentesque</td>
+      <td>dignissim neque.</td>
+      <td>magna imperdiet</td>
+      <td>eleifend. Lorem</td>
+      <td>sit dictum</td>
+      <td>vulputate nibh.</td>
+      <td>Aenean vulputate</td>
+      <td>urna neque.</td>
+      <td>at tellus</td>
+      <td>in mattis</td>
+      <td>amet, imperdiet</td>
+      <td>mattis fermentum</td>
+      <td>mi consectetur</td>
+      <td>elit. vel</td>
+      <td>ipsum amet</td>
+      <td>arcu. gravida.</td>
+      <td>vehicula Pellentesque</td>
+      <td>tempus sem</td>
+      <td>dolor dignissim</td>
+      <td>ligula luctus,</td>
+      <td>dignissim pulvinar.</td>
+      <td>ipsum convallis</td>
+      <td>Lorem luctus,</td>
+      <td>lacus tincidunt,</td>
+      <td>neque. Nam</td>
+      <td>molestie. nisi</td>
+      <td>mauris, Quisque</td>
+      <td>sed velit</td>
+      <td>iaculis, dignissim</td>
+      <td>eleifend. a</td>
+      <td>quis consectetur</td>
+      <td>nibh. sem</td>
+      <td>at consectetur</td>
+      <td>pharetra risus</td>
+      <td>elit. ac</td>
+      <td>tincidunt pulvinar.</td>
+      <td>Pellentesque consectetur</td>
+      <td>diam, nec</td>
+      <td>leo elit.</td>
+      <td>risus, tincidunt</td>
+      <td>Proin Suspendisse</td>
+      <td>Suspendisse sit</td>
+      <td>ipsum mattis</td>
+      <td>vehicula orci,</td>
+      <td>Fusce Aenean</td>
+      <td>nec sed</td>
+      <td>Fusce ut</td>
+      <td>quam diam</td>
+      <td>massa tempor,</td>
+      <td>a consectetur</td>
+      <td>sed amet</td>
+      <td>luctus, elit.</td>
+      <td>iaculis, mi</td>
+      <td>massa feugiat</td>
+      <td>amet elit.</td>
+      <td>amet, quis</td>
+      <td>Suspendisse a</td>
+      <td>ipsum magna</td>
+      <td>Pellentesque est</td>
+      <td>vulputate nec</td>
+      <td>eleifend. posuere</td>
+      <td>feugiat Pellentesque</td>
+      <td>Pellentesque enim.</td>
+      <td>sem dui</td>
+      <td>velit a</td>
+      <td>tempus dictum</td>
+      <td>amet, magna</td>
+      <td>ipsum sed</td>
+      <td>dignissim Pellentesque</td>
+      <td>Aenean amet,</td>
+      <td>nisl nec,</td>
+      <td>at dictum</td>
+      <td>diam, leo</td>
+      <td>Morbi ligula</td>
+      <td>tincidunt leo</td>
+      <td>nec imperdiet</td>
+      <td>sodales convallis</td>
+      <td>dui vel</td>
+      <td>ac pharetra</td>
+      <td>nec, tempus</td>
+      <td>hendrerit nec,</td>
+      <td>vitae accumsan</td>
+      <td>nibh. pharetra</td>
+      <td>Proin dictum</td>
+      <td>adipiscing at</td>
+      <td>adipiscing quam</td>
+      <td>vulputate fermentum</td>
+      <td>amet, imperdiet</td>
+      <td>amet, Pellentesque</td>
+      <td>sit pharetra</td>
+      <td>Lorem accumsan</td>
+      <td>sem imperdiet</td>
+      <td>purus, posuere</td>
+      <td>sit pharetra</td>
+      <td>orci, lacus</td>
+      <td>fermentum nulla</td>
+      <td>urna Pellentesque</td>
+      <td>turpis felis</td>
+      <td>Aenean sed</td>
+      <td>enim. diam,</td>
+      <td>nibh. velit</td>
+      <td>leo potenti.</td>
+      <td>dolor sit</td>
+      <td>sapien nisl</td>
+      <td>purus, Lorem</td>
+      <td>Aenean pharetra</td>
+      <td>sit blandit</td>
+      <td>sem gravida.</td>
+      <td>vitae pulvinar.</td>
+      <td>sit sit</td>
+      <td>ipsum sed</td>
+      <td>vulputate magna</td>
+      <td>Proin sit</td>
+      <td>hendrerit ante</td>
+      <td>amet mauris,</td>
+      <td>ipsum quam</td>
+      <td>sem mattis</td>
+      <td>posuere. Pellentesque</td>
+      <td>diam nulla</td>
+      <td>Pellentesque tincidunt,</td>
+      <td>pulvinar. leo</td>
+      <td>at blandit</td>
+      <td>a imperdiet</td>
+      <td>mi nec</td>
+      <td>sit odio</td>
+      <td>blandit vestibulum</td>
+      <td>diam, massa</td>
+      <td>risus, consectetur</td>
+      <td>Aenean pellentesque</td>
+      <td>sem tempor,</td>
+      <td>nec sed</td>
+      <td>in adipiscing</td>
+      <td>eleifend. diam</td>
+      <td>massa risus</td>
+      <td>pellentesque Aenean</td>
+      <td>orci, Nam</td>
+      <td>ante tempus</td>
+      <td>hendrerit diam</td>
+      <td>vulputate ante</td>
+      <td>enim. risus</td>
+      <td>a vitae</td>
+      <td>vestibulum ligula</td>
+      <td>Proin dolor</td>
+      <td>posuere. tempor,</td>
+      <td>enim. odio</td>
+      <td>orci, neque.</td>
+      <td>fermentum a</td>
+      <td>in Quisque</td>
+      <td>potenti. Morbi</td>
+      <td>mi consectetur</td>
+      <td>sapien dui</td>
+      <td>ipsum sem</td>
+      <td>dolor at</td>
+      <td>felis mi</td>
+      <td>ipsum Morbi</td>
+      <td>ut arcu.</td>
+      <td>amet Fusce</td>
+      <td>diam ante</td>
+      <td>dolor adipiscing</td>
+      <td>Lorem Nam</td>
+      <td>ipsum pharetra</td>
+      <td>amet, est</td>
+      <td>posuere nisl</td>
+      <td>amet a</td>
+      <td>diam, tincidunt</td>
+      <td>est pellentesque</td>
+      <td>lacus Pellentesque</td>
+      <td>magna Morbi</td>
+      <td>nulla Fusce</td>
+      <td>tempor, Fusce</td>
+      <td>nec dignissim</td>
+      <td>dolor urna</td>
+      <td>ut nec</td>
+      <td>mi ante</td>
+      <td>molestie. at</td>
+      <td>a Lorem</td>
+      <td>amet at</td>
+      <td>adipiscing iaculis,</td>
+      <td>dui Aenean</td>
+      <td>sit Proin</td>
+      <td>Fusce dignissim</td>
+      <td>tempor, diam,</td>
+      <td>dui a</td>
+      <td>sed Fusce</td>
+      <td>nisl ac</td>
+      <td>convallis pharetra</td>
+      <td>ante dolor</td>
+      <td>quis posuere</td>
+      <td>amet, ipsum</td>
+      <td>vestibulum accumsan</td>
+      <td>mattis elit.</td>
+      <td>diam dolor</td>
+      <td>leo imperdiet</td>
+      <td>a pharetra</td>
+      <td>Proin dignissim</td>
+      <td>nisl posuere</td>
+      <td>Morbi mi</td>
+      <td>Aenean feugiat</td>
+      <td>leo ligula</td>
+      <td>orci, sit</td>
+      <td>risus eleifend.</td>
+      <td>sit arcu.</td>
+      <td>est sit</td>
+      <td>diam posuere</td>
+      <td>pharetra adipiscing</td>
+      <td>dignissim Lorem</td>
+      <td>sit feugiat</td>
+      <td>Morbi nisi</td>
+      <td>lacus at</td>
+      <td>a Aenean</td>
+      <td>pulvinar. quam</td>
+      <td>est sem</td>
+      <td>blandit dui</td>
+      <td>pharetra purus,</td>
+      <td>Pellentesque tempor,</td>
+      <td>dignissim ligula</td>
+      <td>pharetra purus,</td>
+      <td>ac dui</td>
+      <td>pharetra a</td>
+      <td>neque. neque.</td>
+      <td>arcu. sed</td>
+      <td>turpis amet,</td>
+      <td>amet turpis</td>
+      <td>mi nec</td>
+      <td>sit pulvinar.</td>
+      <td>dolor elit.</td>
+      <td>sit Fusce</td>
+      <td>vel Aenean</td>
+      <td>vehicula tempor,</td>
+      <td>Aenean iaculis,</td>
+      <td>Morbi potenti.</td>
+      <td>massa orci,</td>
+      <td>lacus adipiscing</td>
+      <td>nec, nec</td>
+      <td>feugiat pulvinar.</td>
+      <td>luctus, vitae</td>
+      <td>ipsum consectetur</td>
+      <td>leo. Aenean</td>
+      <td>ac leo.</td>
+      <td>est vel</td>
+      <td>est Pellentesque</td>
+      <td>nisi tempus</td>
+      <td>non, molestie.</td>
+      <td>Fusce diam,</td>
+      <td>nec nibh.</td>
+      <td>sit purus,</td>
+      <td>at est</td>
+      <td>luctus, Fusce</td>
+      <td>in Lorem</td>
+      <td>dolor vitae</td>
+      <td>Quisque Lorem</td>
+      <td>feugiat Pellentesque</td>
+      <td>mi leo.</td>
+      <td>a sapien</td>
+      <td>fermentum in</td>
+      <td>luctus, nulla</td>
+      <td>gravida. Nam</td>
+      <td>gravida. sit</td>
+      <td>Aenean fermentum</td>
+      <td>risus, leo</td>
+      <td>nulla tempor,</td>
+      <td>orci, sit</td>
+      <td>potenti. ipsum</td>
+      <td>tincidunt, Quisque</td>
+      <td>sit sit</td>
+      <td>amet, leo</td>
+      <td>dui mattis</td>
+      <td>tincidunt, Pellentesque</td>
+      <td>magna turpis</td>
+      <td>dolor dictum</td>
+      <td>dui non,</td>
+      <td>purus, sed</td>
+      <td>luctus, nibh.</td>
+      <td>dictum id</td>
+      <td>quis pulvinar.</td>
+      <td>Pellentesque vitae</td>
+      <td>mauris, vehicula</td>
+      <td>Aenean vestibulum</td>
+      <td>purus. consectetur</td>
+      <td>pulvinar. velit</td>
+      <td>Pellentesque amet,</td>
+      <td>non, Fusce</td>
+      <td>quam mattis</td>
+      <td>sapien leo</td>
+      <td>mi nec</td>
+      <td>nec a</td>
+      <td>Morbi urna</td>
+      <td>dignissim Fusce</td>
+      <td>sit a</td>
+      <td>tellus amet,</td>
+      <td>dolor nulla</td>
+      <td>molestie. dolor</td>
+      <td>Lorem diam</td>
+      <td>pharetra pharetra</td>
+      <td>nec at</td>
+      <td>sit id</td>
+      <td>nec sit</td>
+      <td>quam ac</td>
+      <td>tincidunt sed</td>
+      <td>posuere magna</td>
+      <td>amet, Pellentesque</td>
+      <td>pellentesque nisl</td>
+      <td>vel non,</td>
+      <td>vestibulum at</td>
+      <td>at Suspendisse</td>
+      <td>sit at</td>
+      <td>tempor, adipiscing</td>
+      <td>nec Aenean</td>
+      <td>urna gravida.</td>
+      <td>mattis Pellentesque</td>
+      <td>quam ipsum</td>
+      <td>diam sit</td>
+      <td>dignissim urna</td>
+      <td>consectetur amet,</td>
+      <td>sit sed</td>
+      <td>amet, in</td>
+      <td>nisi blandit</td>
+      <td>ac Morbi</td>
+      <td>consectetur leo.</td>
+      <td>at massa</td>
+      <td>vestibulum dui</td>
+      <td>lacus vitae</td>
+      <td>Aenean orci,</td>
+      <td>tincidunt, sit</td>
+      <td>tincidunt, quam</td>
+      <td>dolor leo</td>
+      <td>in leo</td>
+      <td>dolor convallis</td>
+      <td>id mattis</td>
+      <td>potenti. id</td>
+      <td>ligula convallis</td>
+      <td>iaculis, diam</td>
+      <td>est tempor,</td>
+      <td>ut purus.</td>
+      <td>id feugiat</td>
+      <td>sodales pharetra</td>
+      <td>ut nisi</td>
+      <td>ac massa</td>
+      <td>fermentum accumsan</td>
+      <td>eleifend. neque.</td>
+      <td>mattis sed</td>
+      <td>sem Proin</td>
+      <td>elit. ipsum</td>
+      <td>quis ut</td>
+      <td>Suspendisse id</td>
+      <td>sapien Proin</td>
+      <td>potenti. posuere</td>
+      <td>tempor, purus.</td>
+      <td>dignissim sapien</td>
+      <td>ante tempus</td>
+      <td>nec convallis</td>
+      <td>Proin pharetra</td>
+      <td>pellentesque luctus,</td>
+      <td>molestie. amet,</td>
+      <td>Proin sit</td>
+      <td>Pellentesque enim.</td>
+      <td>ipsum nulla</td>
+      <td>a velit</td>
+      <td>a a</td>
+      <td>at lacus</td>
+      <td>feugiat elit.</td>
+      <td>massa potenti.</td>
+      <td>feugiat pulvinar.</td>
+      <td>felis feugiat</td>
+      <td>eleifend. vulputate</td>
+      <td>quis diam,</td>
+      <td>a tellus</td>
+      <td>amet, Fusce</td>
+      <td>Fusce id</td>
+      <td>Fusce neque.</td>
+      <td>tincidunt, risus,</td>
+    </tr>
+    <tr>
+      <td>1</td>
+      <td>vestibulum ipsum</td>
+      <td>Fusce eleifend.</td>
+      <td>nec, Quisque</td>
+      <td>id ipsum</td>
+      <td>vehicula diam,</td>
+      <td>Fusce lacus</td>
+      <td>ipsum nibh.</td>
+      <td>sit dolor</td>
+      <td>sodales nec</td>
+      <td>dolor sit</td>
+      <td>Quisque Pellentesque</td>
+      <td>dui Pellentesque</td>
+      <td>Pellentesque Quisque</td>
+      <td>ac dignissim</td>
+      <td>accumsan pulvinar.</td>
+      <td>leo a</td>
+      <td>Pellentesque neque.</td>
+      <td>sit hendrerit</td>
+      <td>amet, tincidunt</td>
+      <td>purus, est</td>
+      <td>purus, adipiscing</td>
+      <td>sit Fusce</td>
+      <td>gravida. a</td>
+      <td>nibh. gravida.</td>
+      <td>luctus, vulputate</td>
+      <td>potenti. felis</td>
+      <td>vestibulum adipiscing</td>
+      <td>sapien sodales</td>
+      <td>imperdiet potenti.</td>
+      <td>dictum Pellentesque</td>
+      <td>dignissim neque.</td>
+      <td>magna imperdiet</td>
+      <td>eleifend. Lorem</td>
+      <td>sit dictum</td>
+      <td>vulputate nibh.</td>
+      <td>Aenean vulputate</td>
+      <td>urna neque.</td>
+      <td>at tellus</td>
+      <td>in mattis</td>
+      <td>amet, imperdiet</td>
+      <td>mattis fermentum</td>
+      <td>mi consectetur</td>
+      <td>elit. vel</td>
+      <td>ipsum amet</td>
+      <td>arcu. gravida.</td>
+      <td>vehicula Pellentesque</td>
+      <td>tempus sem</td>
+      <td>dolor dignissim</td>
+      <td>ligula luctus,</td>
+      <td>dignissim pulvinar.</td>
+      <td>ipsum convallis</td>
+      <td>Lorem luctus,</td>
+      <td>lacus tincidunt,</td>
+      <td>neque. Nam</td>
+      <td>molestie. nisi</td>
+      <td>mauris, Quisque</td>
+      <td>sed velit</td>
+      <td>iaculis, dignissim</td>
+      <td>eleifend. a</td>
+      <td>quis consectetur</td>
+      <td>nibh. sem</td>
+      <td>at consectetur</td>
+      <td>pharetra risus</td>
+      <td>elit. ac</td>
+      <td>tincidunt pulvinar.</td>
+      <td>Pellentesque consectetur</td>
+      <td>diam, nec</td>
+      <td>leo elit.</td>
+      <td>risus, tincidunt</td>
+      <td>Proin Suspendisse</td>
+      <td>Suspendisse sit</td>
+      <td>ipsum mattis</td>
+      <td>vehicula orci,</td>
+      <td>Fusce Aenean</td>
+      <td>nec sed</td>
+      <td>Fusce ut</td>
+      <td>quam diam</td>
+      <td>massa tempor,</td>
+      <td>a consectetur</td>
+      <td>sed amet</td>
+      <td>luctus, elit.</td>
+      <td>iaculis, mi</td>
+      <td>massa feugiat</td>
+      <td>amet elit.</td>
+      <td>amet, quis</td>
+      <td>Suspendisse a</td>
+      <td>ipsum magna</td>
+      <td>Pellentesque est</td>
+      <td>vulputate nec</td>
+      <td>eleifend. posuere</td>
+      <td>feugiat Pellentesque</td>
+      <td>Pellentesque enim.</td>
+      <td>sem dui</td>
+      <td>velit a</td>
+      <td>tempus dictum</td>
+      <td>amet, magna</td>
+      <td>ipsum sed</td>
+      <td>dignissim Pellentesque</td>
+      <td>Aenean amet,</td>
+      <td>nisl nec,</td>
+      <td>at dictum</td>
+      <td>diam, leo</td>
+      <td>Morbi ligula</td>
+      <td>tincidunt leo</td>
+      <td>nec imperdiet</td>
+      <td>sodales convallis</td>
+      <td>dui vel</td>
+      <td>ac pharetra</td>
+      <td>nec, tempus</td>
+      <td>hendrerit nec,</td>
+      <td>vitae accumsan</td>
+      <td>nibh. pharetra</td>
+      <td>Proin dictum</td>
+      <td>adipiscing at</td>
+      <td>adipiscing quam</td>
+      <td>vulputate fermentum</td>
+      <td>amet, imperdiet</td>
+      <td>amet, Pellentesque</td>
+      <td>sit pharetra</td>
+      <td>Lorem accumsan</td>
+      <td>sem imperdiet</td>
+      <td>purus, posuere</td>
+      <td>sit pharetra</td>
+      <td>orci, lacus</td>
+      <td>fermentum nulla</td>
+      <td>urna Pellentesque</td>
+      <td>turpis felis</td>
+      <td>Aenean sed</td>
+      <td>enim. diam,</td>
+      <td>nibh. velit</td>
+      <td>leo potenti.</td>
+      <td>dolor sit</td>
+      <td>sapien nisl</td>
+      <td>purus, Lorem</td>
+      <td>Aenean pharetra</td>
+      <td>sit blandit</td>
+      <td>sem gravida.</td>
+      <td>vitae pulvinar.</td>
+      <td>sit sit</td>
+      <td>ipsum sed</td>
+      <td>vulputate magna</td>
+      <td>Proin sit</td>
+      <td>hendrerit ante</td>
+      <td>amet mauris,</td>
+      <td>ipsum quam</td>
+      <td>sem mattis</td>
+      <td>posuere. Pellentesque</td>
+      <td>diam nulla</td>
+      <td>Pellentesque tincidunt,</td>
+      <td>pulvinar. leo</td>
+      <td>at blandit</td>
+      <td>a imperdiet</td>
+      <td>mi nec</td>
+      <td>sit odio</td>
+      <td>blandit vestibulum</td>
+      <td>diam, massa</td>
+      <td>risus, consectetur</td>
+      <td>Aenean pellentesque</td>
+      <td>sem tempor,</td>
+      <td>nec sed</td>
+      <td>in adipiscing</td>
+      <td>eleifend. diam</td>
+      <td>massa risus</td>
+      <td>pellentesque Aenean</td>
+      <td>orci, Nam</td>
+      <td>ante tempus</td>
+      <td>hendrerit diam</td>
+      <td>vulputate ante</td>
+      <td>enim. risus</td>
+      <td>a vitae</td>
+      <td>vestibulum ligula</td>
+      <td>Proin dolor</td>
+      <td>posuere. tempor,</td>
+      <td>enim. odio</td>
+      <td>orci, neque.</td>
+      <td>fermentum a</td>
+      <td>in Quisque</td>
+      <td>potenti. Morbi</td>
+      <td>mi consectetur</td>
+      <td>sapien dui</td>
+      <td>ipsum sem</td>
+      <td>dolor at</td>
+      <td>felis mi</td>
+      <td>ipsum Morbi</td>
+      <td>ut arcu.</td>
+      <td>amet Fusce</td>
+      <td>diam ante</td>
+      <td>dolor adipiscing</td>
+      <td>Lorem Nam</td>
+      <td>ipsum pharetra</td>
+      <td>amet, est</td>
+      <td>posuere nisl</td>
+      <td>amet a</td>
+      <td>diam, tincidunt</td>
+      <td>est pellentesque</td>
+      <td>lacus Pellentesque</td>
+      <td>magna Morbi</td>
+      <td>nulla Fusce</td>
+      <td>tempor, Fusce</td>
+      <td>nec dignissim</td>
+      <td>dolor urna</td>
+      <td>ut nec</td>
+      <td>mi ante</td>
+      <td>molestie. at</td>
+      <td>a Lorem</td>
+      <td>amet at</td>
+      <td>adipiscing iaculis,</td>
+      <td>dui Aenean</td>
+      <td>sit Proin</td>
+      <td>Fusce dignissim</td>
+      <td>tempor, diam,</td>
+      <td>dui a</td>
+      <td>sed Fusce</td>
+      <td>nisl ac</td>
+      <td>convallis pharetra</td>
+      <td>ante dolor</td>
+      <td>quis posuere</td>
+      <td>amet, ipsum</td>
+      <td>vestibulum accumsan</td>
+      <td>mattis elit.</td>
+      <td>diam dolor</td>
+      <td>leo imperdiet</td>
+      <td>a pharetra</td>
+      <td>Proin dignissim</td>
+      <td>nisl posuere</td>
+      <td>Morbi mi</td>
+      <td>Aenean feugiat</td>
+      <td>leo ligula</td>
+      <td>orci, sit</td>
+      <td>risus eleifend.</td>
+      <td>sit arcu.</td>
+      <td>est sit</td>
+      <td>diam posuere</td>
+      <td>pharetra adipiscing</td>
+      <td>dignissim Lorem</td>
+      <td>sit feugiat</td>
+      <td>Morbi nisi</td>
+      <td>lacus at</td>
+      <td>a Aenean</td>
+      <td>pulvinar. quam</td>
+      <td>est sem</td>
+      <td>blandit dui</td>
+      <td>pharetra purus,</td>
+      <td>Pellentesque tempor,</td>
+      <td>dignissim ligula</td>
+      <td>pharetra purus,</td>
+      <td>ac dui</td>
+      <td>pharetra a</td>
+      <td>neque. neque.</td>
+      <td>arcu. sed</td>
+      <td>turpis amet,</td>
+      <td>amet turpis</td>
+      <td>mi nec</td>
+      <td>sit pulvinar.</td>
+      <td>dolor elit.</td>
+      <td>sit Fusce</td>
+      <td>vel Aenean</td>
+      <td>vehicula tempor,</td>
+      <td>Aenean iaculis,</td>
+      <td>Morbi potenti.</td>
+      <td>massa orci,</td>
+      <td>lacus adipiscing</td>
+      <td>nec, nec</td>
+      <td>feugiat pulvinar.</td>
+      <td>luctus, vitae</td>
+      <td>ipsum consectetur</td>
+      <td>leo. Aenean</td>
+      <td>ac leo.</td>
+      <td>est vel</td>
+      <td>est Pellentesque</td>
+      <td>nisi tempus</td>
+      <td>non, molestie.</td>
+      <td>Fusce diam,</td>
+      <td>nec nibh.</td>
+      <td>sit purus,</td>
+      <td>at est</td>
+      <td>luctus, Fusce</td>
+      <td>in Lorem</td>
+      <td>dolor vitae</td>
+      <td>Quisque Lorem</td>
+      <td>feugiat Pellentesque</td>
+      <td>mi leo.</td>
+      <td>a sapien</td>
+      <td>fermentum in</td>
+      <td>luctus, nulla</td>
+      <td>gravida. Nam</td>
+      <td>gravida. sit</td>
+      <td>Aenean fermentum</td>
+      <td>risus, leo</td>
+      <td>nulla tempor,</td>
+      <td>orci, sit</td>
+      <td>potenti. ipsum</td>
+      <td>tincidunt, Quisque</td>
+      <td>sit sit</td>
+      <td>amet, leo</td>
+      <td>dui mattis</td>
+      <td>tincidunt, Pellentesque</td>
+      <td>magna turpis</td>
+      <td>dolor dictum</td>
+      <td>dui non,</td>
+      <td>purus, sed</td>
+      <td>luctus, nibh.</td>
+      <td>dictum id</td>
+      <td>quis pulvinar.</td>
+      <td>Pellentesque vitae</td>
+      <td>mauris, vehicula</td>
+      <td>Aenean vestibulum</td>
+      <td>purus. consectetur</td>
+      <td>pulvinar. velit</td>
+      <td>Pellentesque amet,</td>
+      <td>non, Fusce</td>
+      <td>quam mattis</td>
+      <td>sapien leo</td>
+      <td>mi nec</td>
+      <td>nec a</td>
+      <td>Morbi urna</td>
+      <td>dignissim Fusce</td>
+      <td>sit a</td>
+      <td>tellus amet,</td>
+      <td>dolor nulla</td>
+      <td>molestie. dolor</td>
+      <td>Lorem diam</td>
+      <td>pharetra pharetra</td>
+      <td>nec at</td>
+      <td>sit id</td>
+      <td>nec sit</td>
+      <td>quam ac</td>
+      <td>tincidunt sed</td>
+      <td>posuere magna</td>
+      <td>amet, Pellentesque</td>
+      <td>pellentesque nisl</td>
+      <td>vel non,</td>
+      <td>vestibulum at</td>
+      <td>at Suspendisse</td>
+      <td>sit at</td>
+      <td>tempor, adipiscing</td>
+      <td>nec Aenean</td>
+      <td>urna gravida.</td>
+      <td>mattis Pellentesque</td>
+      <td>quam ipsum</td>
+      <td>diam sit</td>
+      <td>dignissim urna</td>
+      <td>consectetur amet,</td>
+      <td>sit sed</td>
+      <td>amet, in</td>
+      <td>nisi blandit</td>
+      <td>ac Morbi</td>
+      <td>consectetur leo.</td>
+      <td>at massa</td>
+      <td>vestibulum dui</td>
+      <td>lacus vitae</td>
+      <td>Aenean orci,</td>
+      <td>tincidunt, sit</td>
+      <td>tincidunt, quam</td>
+      <td>dolor leo</td>
+      <td>in leo</td>
+      <td>dolor convallis</td>
+      <td>id mattis</td>
+      <td>potenti. id</td>
+      <td>ligula convallis</td>
+      <td>iaculis, diam</td>
+      <td>est tempor,</td>
+      <td>ut purus.</td>
+      <td>id feugiat</td>
+      <td>sodales pharetra</td>
+      <td>ut nisi</td>
+      <td>ac massa</td>
+      <td>fermentum accumsan</td>
+      <td>eleifend. neque.</td>
+      <td>mattis sed</td>
+      <td>sem Proin</td>
+      <td>elit. ipsum</td>
+      <td>quis ut</td>
+      <td>Suspendisse id</td>
+      <td>sapien Proin</td>
+      <td>potenti. posuere</td>
+      <td>tempor, purus.</td>
+      <td>dignissim sapien</td>
+      <td>ante tempus</td>
+      <td>nec convallis</td>
+      <td>Proin pharetra</td>
+      <td>pellentesque luctus,</td>
+      <td>molestie. amet,</td>
+      <td>Proin sit</td>
+      <td>Pellentesque enim.</td>
+      <td>ipsum nulla</td>
+      <td>a velit</td>
+      <td>a a</td>
+      <td>at lacus</td>
+      <td>feugiat elit.</td>
+      <td>massa potenti.</td>
+      <td>feugiat pulvinar.</td>
+      <td>felis feugiat</td>
+      <td>eleifend. vulputate</td>
+      <td>quis diam,</td>
+      <td>a tellus</td>
+      <td>amet, Fusce</td>
+      <td>Fusce id</td>
+      <td>Fusce neque.</td>
+      <td>tincidunt, risus,</td>
+    </tr>
+  </tbody>
+</table>

+ 22 - 0
desktop/core/static/jasmine/jHueTableExtenderSpec.js

@@ -0,0 +1,22 @@
+describe("jHueTableExtender plugin", function () {
+
+  beforeEach(function () {
+    jasmine.getFixtures().fixturesPath = 'static/jasmine/';
+    loadFixtures('jHueTableExtenderFixture.html');
+    $(".resultTable").dataTable({
+      "bPaginate":false,
+      "bLengthChange":false,
+      "bInfo":false
+    });
+    $(".resultTable").jHueTableExtender({
+      fixedHeader:true,
+      firstColumnTooltip:true
+    });
+  });
+
+  it("should create the hidden navigator element", function () {
+    expect($("#jHueTableExtenderNavigator")).toExist();
+    expect($("#jHueTableExtenderNavigator")).toBeHidden();
+  });
+
+});

+ 177 - 0
desktop/core/static/js/Source/jHue/jquery.tableextender.js

@@ -0,0 +1,177 @@
+/*
+ * jHue table extender plugin
+ *
+ */
+;
+(function ($, window, document, undefined) {
+
+  var pluginName = "jHueTableExtender",
+      defaults = {
+        fixedHeader:false,
+        firstColumnTooltip:false,
+        hintElement:null,
+        labels:{
+          GO_TO_COLUMN:"Go to column:",
+          PLACEHOLDER:"column name..."
+        }
+      };
+
+  function Plugin(element, options) {
+    this.element = element;
+    if (typeof jHueTableExtenderGlobals != 'undefined') {
+      var extendedDefaults = $.extend({}, defaults, jHueFileChooserGlobals);
+      extendedDefaults.labels = $.extend({}, defaults.labels, jHueFileChooserGlobals.labels);
+      this.options = $.extend({}, extendedDefaults, options);
+      if (options != null) {
+        this.options.labels = $.extend({}, extendedDefaults.labels, options.labels);
+      }
+    }
+    else {
+      this.options = $.extend({}, defaults, options);
+      if (options != null) {
+        this.options.labels = $.extend({}, defaults.labels, options.labels);
+      }
+    }
+    this._defaults = defaults;
+    this._name = pluginName;
+    this.previousPath = "";
+    this.init();
+  }
+
+  Plugin.prototype.setOptions = function (options) {
+    this.options = $.extend({}, defaults, options);
+  };
+
+  Plugin.prototype.init = function () {
+
+    $.expr[":"].econtains = function (obj, index, meta, stack) {
+      return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
+    }
+
+    var _this = this;
+
+    var jHueTableExtenderNavigator = $("<div>").attr("id", "jHueTableExtenderNavigator");
+    $("<a>").attr("href", "#").addClass("pull-right").html("&times;").click(function (e) {
+      e.preventDefault();
+      $(this).parent().hide();
+    }).appendTo(jHueTableExtenderNavigator);
+    $("<label>").html(_this.options.labels.GO_TO_COLUMN + " <input type=\"text\" placeholder=\"" + _this.options.labels.PLACEHOLDER + "\" />").appendTo(jHueTableExtenderNavigator);
+
+    jHueTableExtenderNavigator.appendTo($("body"));
+
+    $(_this.element).find("tbody").click(function (event) {
+      $(".rowSelected").removeClass("rowSelected");
+      $(".columnSelected").removeClass("columnSelected");
+      $(".cellSelected").removeClass("cellSelected");
+      $(event.target.parentNode).addClass("rowSelected");
+      $(event.target.parentNode).find("td").addClass("rowSelected");
+      jHueTableExtenderNavigator
+          .css("left", (event.clientX + jHueTableExtenderNavigator.width() > $(window).width() - 10 ? event.clientX - jHueTableExtenderNavigator.width() - 10 : event.clientX) + "px")
+          .css("top", (event.clientY + 10) + "px").show();
+      jHueTableExtenderNavigator.find("input").focus();
+    });
+
+    var source = [];
+    $(_this.element).find("th").each(function () {
+      source.push($(this).text());
+    });
+
+    jHueTableExtenderNavigator.find("input").typeahead({
+      source:source,
+      updater:function (item) {
+        jHueTableExtenderNavigator.hide();
+        $(_this.element).find("tr td:nth-child(" + ($(_this.element).find("th:econtains(" + item + ")").index() + 1) + ")").addClass("columnSelected");
+        if (_this.options.firstColumnTooltip) {
+          $(_this.element).find("tr td:nth-child(" + ($(_this.element).find("th:econtains(" + item + ")").index() + 1) + ")").each(function () {
+            $(this).attr("rel", "tooltip").attr("title", "#" + $(this).parent().find("td:first-child").text()).tooltip({
+              placement:'left'
+            });
+          });
+        }
+        $(_this.element).parent().animate({
+          scrollLeft:$(_this.element).find("th:econtains(" + item + ")").position().left + $(_this.element).parent().scrollLeft() - $(_this.element).parent().offset().left - 30
+        }, 300);
+        $(_this.element).find("tr.rowSelected td:nth-child(" + ($(_this.element).find("th:econtains(" + item + ")").index() + 1) + ")").addClass("cellSelected");
+      }
+    });
+
+    $(_this.element).parent().bind("mouseleave", function () {
+      jHueTableExtenderNavigator.hide();
+    });
+
+    jHueTableExtenderNavigator.bind("mouseenter", function (e) {
+      jHueTableExtenderNavigator.show();
+    });
+
+    if (_this.options.hintElement != null) {
+      var showAlertTimeout = -1;
+      $(_this.element).find("tbody").mousemove(function () {
+        window.clearTimeout(showAlertTimeout);
+        if ($(_this.options.hintElement).data("show") == null || $(_this.options.hintElement).data("show")) {
+          showAlertTimeout = window.setTimeout(function () {
+            $(_this.options.hintElement).fadeIn();
+          }, 1300);
+        }
+      });
+
+      $(_this.options.hintElement).find(".close").click(function () {
+        $(_this.options.hintElement).data("show", false);
+      });
+    }
+
+    if (_this.options.fixedHeader) {
+      var clonedTable = $(_this.element).clone();
+      clonedTable.removeClass("resultTable").find("tbody").remove().css("margin-bottom", "0");
+      $(_this.element).find("thead>tr th").each(function (i) {
+        var originalTh = $(this);
+        clonedTable.find("thead>tr th:eq(" + i + ")").width(originalTh.width()).css("background-color", "#FFFFFF");
+        clonedTable.find("thead>tr th:eq(" + i + ")").click(function () {
+          originalTh.click();
+          clonedTable.find("thead>tr th").attr("class", "sorting");
+          $(this).attr("class", originalTh.attr("class"));
+        });
+      });
+      var clonedTableContainer = $("<div>").width($(_this.element).outerWidth());
+      clonedTable.appendTo(clonedTableContainer);
+
+      var clonedTableVisibleContainer = $("<div>").width($(_this.element).parent().width()).css("overflow-x", "hidden");
+      clonedTableVisibleContainer.css("position", "fixed");
+
+      clonedTableContainer.appendTo(clonedTableVisibleContainer);
+      clonedTableVisibleContainer.prependTo($(_this.element).parent());
+
+      $(_this.element).parent().scroll(function () {
+        clonedTableVisibleContainer.scrollLeft($(this).scrollLeft());
+      });
+
+      $(_this.element).parent().data("w", clonedTableVisibleContainer.width());
+
+      window.setInterval(function () {
+        if ($(_this.element).parent().width() != $(_this.element).parent().data("w")) {
+          clonedTableVisibleContainer.width($(_this.element).parent().width());
+          $(_this.element).parent().data("w", clonedTableVisibleContainer.width());
+          $(_this.element).find("thead>tr th").each(function (i) {
+            clonedTable.find("thead>tr th:eq(" + i + ")").width($(this).width()).css("background-color", "#FFFFFF");
+          });
+        }
+      }, 250);
+
+      $(_this.element).parent().resize(function () {
+        clonedTableVisibleContainer.width($(this).width());
+      });
+    }
+
+  };
+
+  $.fn[pluginName] = function (options) {
+    return this.each(function () {
+      if (!$.data(this, 'plugin_' + pluginName)) {
+        $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+      }
+      else {
+        $.data(this, 'plugin_' + pluginName).setOptions(options);
+      }
+    });
+  }
+
+})(jQuery, window, document);