Selaa lähdekoodia

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 vuotta sitten
vanhempi
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);