Skip to content

Commit efa0b8f

Browse files
author
Jiren Patel
committed
Streaming example and Readme
1 parent ffd64ab commit efa0b8f

File tree

9 files changed

+322
-610
lines changed

9 files changed

+322
-610
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
# git config --global core.excludesfile ~/.gitignore_global
66

77
/_tmp
8+
/_gh_pages
89
*.DS_Store

README.md

Lines changed: 218 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,227 @@
1-
FilterTable.js
2-
=============
1+
StreamTable.js
2+
==============
33

4-
FilterTable.js
4+
StreamTable.js streams data for tables in the background, updates and renders them using templating frameworks like Mustache.js, HandleBars.js
5+
6+
Why StreamTable.js?
7+
-------------------
8+
9+
Sometimes we want to show thousands of records in a table. This can take too long for the page to render and make the page unusable till the entire table is populated. To counter this we could populate the table using an Ajax call. In both cases, the users have to wait until all the table rows are populated. Additionally, user cannot do any operations on the table like search, pagination etc.
10+
11+
The idea behind StreamTable.js is to initially populate minimum rows (maybe 10 or 20) and after that in stream data silently in the background and update the table. This ensures that the page loads immediately and is also usable immediately for all operations. It maybe safe to assume that if the user remains on the same page for a little while longer, then the user is most probably going to perform some operation on table like search, page navigation, etc. So we can delay the process of streaming data to say 2 seconds after the page has loaded. Its also important to ensure that all the data streamed must be usable immediately. For example, after 2 seconds, if we have streamed 1000 rows, they should all be searchable and paginated.
512

613
Usage
714
-----
15+
16+
StreamTable has 3 arguments: the container (table) css selector, options and JSON data. This will render the table, set the pagination, search box and per page selection. The view function is mandatory in the options.
17+
18+
```javascript
19+
var options = {
20+
view: view, //View function to render table rows.
21+
data_url: 'data/data.json', //Data fetching url
22+
stream_after: 2, //Start streaming after 2 secs
23+
fetch_data_limit: 500, //Streaming data in batch of 500
24+
}
25+
26+
var st = StreamTable('#stream_table', options, data);
27+
28+
OR
829

9-
Json data
30+
$('#stream_table').stream_table(options, data); //Use as a jQuery plugin.
31+
```
32+
33+
"#stream_table" is the table selector which has initial structure with 'thead' and 'tbody'.
34+
35+
Here is a view function that has two arguments: JSON 'record' and the index. I have used Mustache.js as the html templating framework but you are free to choose your rendering mechanism.
36+
37+
38+
```javascript
39+
var template = Mustache.compile($.trim($("#template").html()));
40+
41+
var view = function(record, index){
42+
return template({record: record, index: index});
43+
};
44+
```
45+
46+
47+
Template Html:
48+
49+
```html
50+
<script id="template" type="text/html">
51+
<tr>
52+
<td>{{index}}</td>
53+
<td>{{record.name}}</td>
54+
<td>{{record.director}}</td>
55+
<td>{{record.actor}}</td>
56+
<td>{{record.rating}}</td>
57+
<td>{{record.year}}</td>
58+
</tr>
59+
</script>
60+
```
61+
62+
The initial display is also JSON data. The data format must be an array of arrays or an array of objects. If the JSON data is not in these formats, you can change the data format to allowed formats using the 'before_add' callback.
1063

11-
var movies = [
12-
{ name: 'Once Upon a Time in the West',
13-
rating: '8.7',
14-
director: 'Sergio Leone',
15-
year: '1968',
16-
actor: 'Henry Fonda' },
17-
{ name: 'Terminator 2: Judgment Day',
18-
rating: '8.6',
19-
director: 'James Cameron',
20-
year: '1991',
21-
actor: 'Arnold Schwarzenegger' },
22-
{ name: 'Braveheart',
23-
rating: '8.4',
24-
director: 'Mel Gibson',
25-
year: '1995',
26-
actor: 'Mel Gibson' }
27-
];
28-
29-
var template = Mustache.compile($.trim($("#template").html()));
30-
31-
var view = function(record){
32-
return template(record);
33-
};
34-
35-
var filter_table = FilterTable('#filter_table', {view: view, per_page: 10}, movies);
36-
37-
Add More Data
38-
-------------
39-
40-
filter_table.addData(data);
64+
```javascript
65+
var data = [
66+
{ name: 'Once Upon a Time in the West',
67+
rating: '8.7',
68+
director: 'Sergio Leone',
69+
year: '1968',
70+
actor: 'Henry Fonda' },
71+
{ name: 'Terminator 2: Judgment Day',
72+
rating: '8.6',
73+
director: 'James Cameron',
74+
year: '1991',
75+
actor: 'Arnold Schwarzenegger' },
76+
{ name: 'Braveheart',
77+
rating: '8.4',
78+
director: 'Mel Gibson',
79+
year: '1995',
80+
actor: 'Mel Gibson' }
81+
...
82+
...
83+
...
84+
];
85+
```
86+
87+
88+
Options
89+
=======
90+
91+
- view function
92+
- stream
93+
- callbacks
94+
- pagination options, per page selection options.
95+
- search box
96+
97+
**Note:** Only view function is mandatory.
98+
99+
Stream:
100+
-------
101+
102+
```javascript
103+
data_url: 'data/data.json', //Data fetching url
104+
stream_after: 1, //Start streaming after 1 sec
105+
fetch_data_limit: 500, //Streaming data in batch of 500.
106+
```
107+
108+
When you stream data in batches it will send ajax requests in following format. The offset will increase after each request by fetch_data_limit.
109+
110+
data/data.json?q="search text"&limit=500&offset=1000
111+
112+
if 'fetch_data_limit' option is not define then stream table will send only one ajax request to fetch all remaining data.
113+
114+
**Note:** Since the first page is being loaded with initial data, remember that the stream data request should send the **remaining** data and not all the data. Otherwise, you would have duplidate data that was loaded initially.
115+
116+
Serchbox:
117+
---------
118+
If searchbox option is not defined, then by default search box going to be added at the top of the table with class '.st_search' and id '#st_search'.
119+
If you have already searcbox then you can set the selector.
120+
121+
search_box: '#my-searchb0x'
122+
123+
You can enable search on specific fields
124+
125+
fields: ['id', 'name'] //if each record is an object, then mention the field names. i.e {user: {id: 1, name: 'user', amount: 2}}
126+
fields: [0, 2] //if each record is an array, then mention the index of fields. i.e [1, 'User', '2']
127+
128+
Pagination Options:
129+
-------------------
130+
131+
```javascript
132+
pagination: {
133+
span: 5, //Max Pagination span window.
134+
next_text: 'Next &rarr;',
135+
prev_text: '&larr; Previous',
136+
container_class: '.users-pagination', //Add pagination div class. Default is .st_pagination.
137+
ul_class: '.larger-pagination', //Add pagination ul class. Default is .pagination.
138+
per_page_select: true, //Show per page select box. Default us true.
139+
per_page_opts: [10, 25, 50], //Per Page select box options. Default is [10, 25, 50].
140+
per_page_class: '.select-box' //Per page select box class. Default is .st_per_page.
141+
per_page: 20 //Show number of record per page. Defalut 10.
142+
}
143+
```
144+
145+
If per_page_select is set to false, it will not show per page select box. If you have already select box for this then you can set selector of it i.e per_page_select: '#my-per-page'. If you are not using per page select box then you can set number of records you want to show on a page using 'per_page'.
146+
147+
Callbacks:
148+
----------
149+
150+
stream table has pagination, before_add and after_add data callbacks.
151+
152+
```javascript
153+
var callbacks = {
154+
pagination: function(summary){
155+
$('#summary).text( summary.from + ' to '+ summary.to +' of '+ summary.total +' entries');
156+
},
157+
after_add: function(){
158+
$('#records_count').text(this.data.length);
159+
},
160+
before_add: function(data){
161+
var new_data = [], d;
162+
163+
for(id in data){
164+
d = data[id].push(id);
165+
new_data.push(d);
166+
}
167+
168+
return new_data;
169+
}
170+
}
171+
```
172+
173+
174+
1. pagination: This callback executes after search, on page navigation, after data is added and when the per_page select box is changed. Using this callback user can update the summary of how many rows were found in search and also show current offset eg. '1 to 10 of 2000 entries'. It has one argument 'summary' that has 3 values: 'from' record, 'to' record and 'total' entries.
175+
176+
2. after_add: This callbacks execute after data is added. This is used when you stream data in batches and want to show the udpated records count.
177+
178+
3. before_add: This will execute before adding data. One use is to change data format to one that is compatible with streamTable. Remember to return the changed data. i.e if the data format is like {1: ['user-1', 10], 2: ['user-2', 100]}, we can convert it to an array of objects or an array of arrays, according to your view template.
179+
180+
After the conversion, the data MUST look like this:
181+
[[1,'user-1', 10], [2,'user-2', 100]]
182+
183+
OR
184+
185+
[{user: {id: 1, name: 'user-1', amount: 10}}, {user: {id: 2, name: 'user-2', amount: 100}}]
186+
187+
188+
Complete Options for reference:
189+
-------------------------------
190+
191+
```javascript
192+
var options = {
193+
view: view,
194+
data_url: 'data/data.json',
195+
stream_after: 1,
196+
fetch_data_limit: 500,
197+
pagination:{
198+
span: 5,
199+
next_text: 'Next &rarr;',
200+
prev_text: '&larr; Previous',
201+
container_class: '.users-pagination',
202+
ul_class: '.larger-pagination',
203+
per_page_select: true,
204+
per_page_opts: [10,25,50],
205+
per_page_class: '.select-box',
206+
per_page: 20
207+
},
208+
search_box: '#my-searchbox',
209+
fields: ['id', 'name'] //Or [1,2] index of array.
210+
}
211+
```
212+
213+
214+
Extra
215+
-----
216+
217+
If you are using StreamTable as a jQuery plugin and you want the stream table object, you can do this
218+
219+
var st = $('#stream_table').data('st')
220+
221+
Now, you can add more data manually.
222+
223+
st.addData(data);
224+
41225
42226
Contributing
43227
------------

examples/assets/css/style.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ body{
3030
margin: auto;
3131
}
3232

33-
.ftl_search{
33+
.st_search{
3434
max-width: 200px;
3535
float: right;
3636
margin-bottom: 10px;
@@ -45,7 +45,7 @@ body{
4545
background-color: #DCDCDC;
4646
}
4747

48-
.ftl_per_page{
48+
.st_per_page{
4949
width: 50px;
5050
height: 34px !important;
5151
float: right;
@@ -69,11 +69,12 @@ body{
6969
}
7070

7171
.example .progress{
72-
width: 300px;
72+
width: 400px;
7373
display: inline-block;
7474
height: 32px;
7575
line-height: 34px;
7676
float: left;
77+
background-color: #90EFC4;
7778
}
7879

7980
.example .progress .progress-bar{

examples/index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
<link href="assets/css/style.css" media="screen" rel="stylesheet" type="text/css">
66
<script src="assets/js/jquery.min.js" type="text/javascript"></script>
77
<script src="../vendors/mustache.js" type="text/javascript"></script>
8-
<script src="../filter_table.js" type="text/javascript"></script>
8+
<script src="../stream_table.js" type="text/javascript"></script>
99
<script src="movie_data.js" type="text/javascript"></script>
1010
<script src="index.js" type="text/javascript"></script>
1111
</head>
1212
<body>
1313
<div class="container">
1414
<div class='example'>
1515
<div class="title">
16-
<h1><span class="glyphicon glyphicon-filter"></span>FilterTable.js</h1>
16+
<h1>StreamTable.js</span></h1>
1717
</div>
1818
<a href='#' id="add_more" class="btn btn-primary"><span class="glyphicon glyphicon-plus"> Add More Records</span></a>
1919
<span id="spinner" class="glyphicon glyphicon-refresh"></span>
2020
<a href="#" class='record_count'>Records <span class="badge"></span></a>
2121
<span id="found" class="label label-info"></span>
22-
<table id="filter_table" class='table table-striped table-bordered'>
22+
<table id="stream_table" class='table table-striped table-bordered'>
2323
<thead>
2424
<tr>
2525
<th>#</th>
@@ -33,7 +33,7 @@ <h1><span class="glyphicon glyphicon-filter"></span>FilterTable.js</h1>
3333
<tbody>
3434
</tbody>
3535
</table>
36-
<div id="summery"><div>
36+
<div id="summary"><div>
3737
</div>
3838
</div>
3939

0 commit comments

Comments
 (0)