app:datatable
| Widget Name | appcelerator datatable |
| Element | <app:datatable> |
| Author | Amro Mousa |
| Homepage | http://www.appcelerator.org |
| Description | datatable widget |
- Required Attributes (0)
- Optional Attributes (11)
- Examples (1)
- Source code
| Name | Type | Description | Default value |
|---|---|---|---|
| There are no required attributes | |||
| Name | Type | Description | Default value |
|---|---|---|---|
| on | On Expression | Used to populate the data table. | Not specified |
| sort | Enumeration of: client, server, off | Where the responsibility for sorting items in the table restsValid values are 'client', 'server', and 'off.' | client |
| sortRequest | Appcelerator Message Send | Message to be sent when the sort mode is 'server' and a column header is clicked. | |
| rowEvenClass | CSS Class name | Not specified | |
| rowOddClass | CSS Class name | Not specified | |
| width | CSS Dimension | Width of entire table. | 100% |
| property | Identifier | Not specified | |
| pagination | Boolean | Not specified | false |
| maxRows | Natural Number | Not specified | 0 |
| sortIndex | Natural Number | Not specified | -1 |
| stickySort | Boolean | Not specified | true |
Back to menuExample: Simple Example
Name
Age
Height
Epidermis Showing?
$MQ('l:load.datatable',{'rows':[{'col1':'Sam','col2':'18','col3':'5.5 feet','col4':'Yes'},
{'col1':'Vanessa','col2':'22','col3':'6.5 feet','col4':'No'},
{'col1':'Joe','col2':'18','col3':'5.0 feet','col4':'Yes'},
{'col1':'Bill','col2':'40','col3':'5.2 feet','col4':'Yes'},
{'col1':'James','col2':'33','col3':'6.1 feet','col4':'No'},
{'col1':'Mary','col2':'25','col3':'5.7 feet','col4':'Yes'}]});
This is a simple example that uses the <app:datatable>.
<style> <!-- .table_cell { padding: 3px; border-right: 1px solid #999; border-left: 1px solid #999; } .table_cell_header { padding-top: 3px; padding-bottom: 3px; padding-left: 5px; padding-right: 5px; background-color: #999; color:white; border: 1px solid #555; cursor: pointer; } .table_row_even { padding: 3px; border-right: 1px solid #999; border-left: 1px solid #999; border-bottom:1px solid #999; background-color: #fff; } .table_row_odd { padding: 3px; border-right: 1px solid #999; border-left: 1px solid #999; border-bottom:1px solid #999; background-color: #ddd; } --> </style> <app:datatable on="l:load.datatable then execute" width="50%" property="rows" sort="client" rowEvenClass="table_row_even" rowOddClass="table_row_odd"> <header property="col1" align="left" width="40%">Name</header> <header property="col2" align="center" width="30%">Age</header> <header property="col3" align="center" width="30%">Height</header> <header property="col4" align="center" width="30%">Epidermis Showing?</header> </app:datatable> <app:script style="display:none;"> $MQ('l:load.datatable',{'rows':[{'col1':'Sam','col2':'18','col3':'5.5 feet','col4':'Yes'}, {'col1':'Vanessa','col2':'22','col3':'6.5 feet','col4':'No'}, {'col1':'Joe','col2':'18','col3':'5.0 feet','col4':'Yes'}, {'col1':'Bill','col2':'40','col3':'5.2 feet','col4':'Yes'}, {'col1':'James','col2':'33','col3':'6.1 feet','col4':'No'}, {'col1':'Mary','col2':'25','col3':'5.7 feet','col4':'Yes'}]}); </app:script>
1 /* 2 * This file is part of Appcelerator. 3 * 4 * Copyright (C) 2006-2008 by Appcelerator, Inc. All Rights Reserved. 5 * For more information, please visit http://www.appcelerator.org 6 * 7 * Appcelerator is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 23 Appcelerator.Widget.Datatable = 24 { 25 modulePath:null, 26 setPath: function(path) 27 { 28 this.modulePath = path; 29 }, 30 getName: function() 31 { 32 return 'appcelerator datatable'; 33 }, 34 getDescription: function() 35 { 36 return 'datatable widget'; 37 }, 38 getVersion: function() 39 { 40 return 1.0; 41 }, 42 getSpecVersion: function() 43 { 44 return 1.0; 45 }, 46 getAuthor: function() 47 { 48 return 'Amro Mousa'; 49 }, 50 getModuleURL: function () 51 { 52 return 'http://www.appcelerator.org'; 53 }, 54 isWidget: function () 55 { 56 return true; 57 }, 58 getWidgetName: function() 59 { 60 return 'app:datatable'; 61 }, 62 getActions: function() 63 { 64 return ['execute', 'stop', 'start']; 65 }, 66 getAttributes: function() 67 { 68 var T = Appcelerator.Types; 69 return [{name: 'on', optional: true, 70 description: "Used to populate the data table.", 71 type: T.onExpr}, 72 {name: 'sort', optional: true, defaultValue: 'client', 73 description: "Where the responsibility for sorting items in the table rests"+ 74 "Valid values are 'client', 'server', and 'off.'", 75 type: T.enumeration('client','server','off')}, 76 {name: 'sortRequest', optional: true, defaultValue: '', 77 description: "Message to be sent when the sort mode is 'server' and a column header is clicked.", 78 type: T.messageSend}, 79 {name: 'rowEvenClass', optional: true, defaultValue: '', type: T.cssClass}, 80 {name: 'rowOddClass', optional: true, defaultValue: '', type: T.cssClass}, 81 {name: 'width', optional: true, defaultValue: '100%', 82 description: "Width of entire table.", 83 type: T.cssDimension}, 84 {name: 'property', optional: true, defaultValue: '', type: T.identifier}, 85 {name: 'pagination', optional: true, defaultValue: 'false', type: T.bool}, 86 {name: 'maxRows', optional: true, defaultValue: 0, type: T.naturalNumber}, 87 {name: 'sortIndex', optional: true, defaultValue: -1, type: T.naturalNumber}, 88 {name: 'stickySort', optional: true, defaultValue: true, type: T.bool}]; 89 }, 90 formatShift1k: function(cell_value,column_property_name, row) 91 { 92 if (!isNaN(cell_value)) 93 return parseInt(parseInt(cell_value)/1000); 94 else 95 return cell_value; 96 }, 97 formatShift1000k: function(cell_value,column_property_name, row) 98 { 99 if (!isNaN(cell_value)) 100 return parseInt(parseInt(cell_value)/1000000); 101 else 102 return cell_value; 103 }, 104 createDataTable: function (id, pagination_direction) 105 { 106 //list of on attributes to be parsed and evaluated at the end of create 107 var on_array = []; 108 109 var parameterMap = $(id).parameterMap; 110 var needRecompile=false; 111 var scope = parameterMap['scope']; 112 113 //Valid values are 'client', 'server', and 'off' 114 var sort = parameterMap['sort']; 115 116 //Really applies styles to the CELLS on the even and odd rows 117 var rowEvenClass = parameterMap['rowEvenClass']; 118 var rowOddClass = parameterMap['rowOddClass']; 119 120 //Width % of entire table 121 var width = parameterMap['width']; 122 123 //Controls whether or not to add spacers to the header (true on initial render) 124 var add_spacers_to_header = parameterMap['add_spacers_to_header']; 125 126 var header_array = parameterMap['header_array']; 127 var array = parameterMap['array']; 128 129 var pagination = parameterMap['pagination']; 130 var maxRows = parseInt(parameterMap['maxRows']); 131 132 if (pagination == 'true' && !pagination_direction) 133 { 134 pagination_direction = 'forward'; 135 maxRows = maxRows == 0 ? 10 : maxRows; 136 } 137 138 if (pagination == 'false') 139 { 140 maxRows = array.length; 141 } 142 parameterMap['maxRows'] = maxRows; 143 144 var html = ''; 145 146 //Default class names -- the only class names accepted directly by the table are rowEvenClass and rowOddClass 147 //.table_row 148 //.table_cell -- default IFF rowOddClass or rowEvenClass are not provided 149 //.table_row_header 150 //.table_cell_header 151 152 var table_open = '<table cellspacing="0" border="0" width="'+width+'">'; 153 var table_close = '</table>'; 154 var table_header_content = ''; 155 var table_data_content = ''; 156 var arrow_up_img = '<img src="'+ Appcelerator.Widget.Datatable.modulePath + 'images/arrow_up.png" title="sort ascending" style="position:relative;top:-1px; left: 2px;" />'; 157 var arrow_down_img = '<img src="'+ Appcelerator.Widget.Datatable.modulePath + 'images/arrow_down.png" title="sort ascending" style="position:relative;top:-1px; left: 2px;" />'; 158 var spacer_img = '<img src="'+ Appcelerator.Widget.Datatable.modulePath + 'images/arrow_spacer.png" title="sort ascending" style="position:relative;top:-1px; left: 2px;" />'; 159 160 //Add spacers to the header (initially) and clear up any extra icons 161 if (add_spacers_to_header) 162 { 163 for(var i = 0, len = header_array.length; i < len; i++) 164 { 165 header_array[i]['cell'] = header_array[i]['cell'].replace(arrow_up_img,''); 166 header_array[i]['cell'] = header_array[i]['cell'].replace(arrow_down_img,''); 167 header_array[i]['cell'] = header_array[i]['cell'].replace(spacer_img,''); 168 header_array[i]['cell'] += spacer_img; 169 } 170 } 171 172 //Create the header 173 for (var x = 0, len = header_array.length; x < len; x++) 174 { 175 var header_info = header_array[x]; 176 var formatterFunction = eval(header_array[x]['formatter']); 177 var onheader = header_array[x]['cellon']; 178 var onTemplate = null; 179 if (onheader) 180 { 181 needRecompile=true; 182 header_info.onTemplate = new Template('on="'+onheader+'"'); 183 } 184 if (formatterFunction) { 185 header_info.formatterFunction = formatterFunction; 186 } 187 188 var hclass = header_info['class']; 189 if (hclass == '' || hclass == null) 190 { 191 hclass='table_cell_header'; 192 } 193 194 var or = ''; 195 if (header_info['on'] != '') 196 { 197 or = ' or '; 198 } 199 200 var sort_string = ''; 201 if (sort == 'client') 202 { 203 sort_string = 'click then script[Appcelerator.Widget.Datatable.sortDataTableClient(' + x + ',' + '\'' + id + '\'' + ')]'; 204 } else if (sort == 'server') 205 { 206 sort_string = 'click then script[Appcelerator.Widget.Datatable.sortDataTableServer(' + x + ',' + '\'' + id + '\'' + ')]'; 207 208 if (parameterMap['current_server_sort_column'] == header_info['property']) 209 { 210 if (!parameterMap['sortBy'][parameterMap['current_server_sort_column']]) 211 { 212 header_array[x]['cell'] = header_array[x]['cell'].replace(spacer_img,''); 213 header_array[x]['cell'] += arrow_up_img; 214 } else 215 { 216 header_array[x]['cell'] = header_array[x]['cell'].replace(spacer_img,''); 217 header_array[x]['cell'] += arrow_down_img; 218 } 219 } 220 } else 221 { 222 sort_string = ''; 223 } 224 225 // Pass the index of the cell in header array 226 var hw = header_info['width']; 227 var td = '<td id="' + id + '_header_' + x + '" align="' + header_info['align'] + '" ' +(hw?'width="'+hw+'"':'')+' class="' + hclass + '"><span>' + header_info['cell'] + '</span></td>'; 228 229 if (sort_string != '') 230 { 231 var header_on_expression = header_info['on'] + or + sort_string; 232 on_array.push({'id': id + '_header_' + x, 'on': header_on_expression}); 233 } 234 235 236 table_header_content += td; 237 } 238 table_header_content = '<tr class="table_row_header">' + table_header_content + '</tr>'; 239 240 //Create the table body 241 var x = 0; 242 var length = maxRows; 243 244 if (pagination == 'true') 245 { 246 if (pagination_direction == 'forward') 247 { 248 if ($(id).initialLoad) 249 { 250 x = $(id).position; 251 $(id).initialLoad = false; 252 } else 253 { 254 x = $(id).position+maxRows >= array.length ? $(id).position : $(id).position+maxRows; 255 } 256 length = x+maxRows > array.length ? array.length : x+maxRows; 257 } else 258 { 259 if($(id).position-maxRows < 0) 260 { 261 x = 0; 262 length = maxRows > array.length ? array.length : maxRows; 263 } else 264 { 265 x = $(id).position-maxRows; 266 length = x+maxRows > array.length ? array.length : x+maxRows; 267 } 268 } 269 $(id).position = x; 270 } 271 272 var xrun = x; 273 274 for (; xrun < length; xrun++) 275 { 276 table_data_content += '<tr class="table_row">'; 277 for (var h = 0, lenH = header_array.length; h < lenH; h++) 278 { 279 var cell_class = (xrun % 2 == 0) ? rowEvenClass : rowOddClass; 280 if (cell_class == '') 281 { 282 cell_class = 'table_cell'; 283 } 284 285 //Get the column property needed to figure out what column from the current array item we need 286 var column_property_name = header_array[h]['property']; 287 var formatterFunction = header_array[h]['formatterFunction']; 288 var onTemplate = header_array[h]['onTemplate']; 289 cell_on=""; 290 if (onTemplate) 291 { 292 cell_on = onTemplate.evaluate(array[xrun]); 293 } 294 var cell_value = (Object.getNestedProperty(array[xrun],column_property_name)||''); 295 if (formatterFunction) { 296 cell_value = formatterFunction(cell_value,column_property_name, array[xrun]); 297 } else { 298 cell_value.toString().escapeHTML(); 299 } 300 var td ='<td align="' + header_array[h]['align'] +'" '+ cell_on+ ' class="' + cell_class + '"><span>' + cell_value +'</span></td>'; 301 table_data_content += td; 302 } 303 table_data_content += '</tr>'; 304 } 305 html = table_open + table_header_content + table_data_content + table_close; 306 307 var myidback = id + "_pagination_back"; 308 var myidforward = id + "_pagination_forward"; 309 310 if (pagination == 'true') 311 { 312 var pag_html = ''; 313 var myid = "'" + id + "'"; 314 var forward = '"forward"'; 315 var backward = "'backward'"; 316 317 pag_html = '<div style="padding-bottom: 5px;">'+ 318 '<a class="pagination_links" id="'+myidback+'"><img style="border: 0;" src="'+Appcelerator.Widget.Datatable.modulePath+'images/resultset_previous.png"/></a> ' + 319 '<a class="pagination_links" id="'+myidforward+'"><img style="border: 0;" src="'+Appcelerator.Widget.Datatable.modulePath + 'images/resultset_next.png"/></a> Showing '+(x+1)+'-'+(length)+' of '+array.length+'</div>'; 320 321 html = pag_html + html; 322 } 323 324 Appcelerator.Compiler.setHTML(id,html); 325 if (needRecompile) 326 Appcelerator.Compiler.dynamicCompile($(id)); 327 328 if (pagination == 'true') 329 { 330 $(myidback).onclick = function(){Appcelerator.Widget.Datatable.createDataTable(id, 'backward');}.bind(this); 331 $(myidforward).onclick = function(){Appcelerator.Widget.Datatable.createDataTable(id, 'forward');}.bind(this); 332 $(myidback).onmousedown = function(){Appcelerator.Widget.Datatable.paginateContinuously(id, 'backward');}.bind(this); 333 $(myidforward).onmousedown = function(){Appcelerator.Widget.Datatable.paginateContinuously(id, 'forward');}.bind(this); 334 $(myidback).onmouseup = function(){Appcelerator.Widget.Datatable.stopContinuousPagination(id)}.bind(this); 335 $(myidforward).onmouseup = function(){Appcelerator.Widget.Datatable.stopContinuousPagination(id)}.bind(this); 336 $(myidback).onmouseout = function(){Appcelerator.Widget.Datatable.stopContinuousPagination(id)}.bind(this); 337 $(myidforward).onmouseout = function(){Appcelerator.Widget.Datatable.stopContinuousPagination(id)}.bind(this); 338 } 339 var on_run_array = []; 340 341 for (var i = 0, len = on_array.length; i < len; i++) 342 { 343 on_run_array.push(Appcelerator.Compiler.compileExpression($(on_array[i]['id']),on_array[i]['on'],false)); 344 } 345 346 eval(on_run_array.join(';')); 347 }, 348 compileWidget: function (parameters, element) 349 { 350 }, 351 paginateContinuously: function (id, direction) 352 { 353 var paginator = function() 354 { 355 if (direction == 'forward') Appcelerator.Widget.Datatable.createDataTable(id,'forward'); 356 else Appcelerator.Widget.Datatable.createDataTable(id,'backward'); 357 }; 358 $(id).paginationInterval = setInterval(paginator,250); 359 }, 360 stopContinuousPagination: function (id) 361 { 362 clearInterval($(id).paginationInterval); 363 }, 364 sortDataTableClient: function (index, id, maintainSortOrder) 365 { 366 var parameterMap = $(id).parameterMap; 367 var header_array = parameterMap['header_array']; 368 var array = parameterMap['array']; 369 var column_property_name = header_array[index]['property']; 370 parameterMap['lastSortIndex'] = index; 371 372 $(id).position = 0; 373 $(id).initialLoad = true; 374 375 var sortFunction = eval(header_array[index]['sorter']); 376 377 //Are we sorting numbers or strings? Check only the column we're sorting by.. 378 var num_sort = false; 379 380 if (!sortFunction) { 381 num_sort = true; 382 for (var x = 0, len = array.length; x < len; x++) { 383 var cell_value = (Object.getNestedProperty(array[x],column_property_name) || ''); 384 385 if (isNaN(parseFloat(cell_value))) { 386 num_sort = false; 387 break; 388 } 389 } 390 } 391 392 //Initialize the object holding our previous per-column sort state 393 if (parameterMap['sortBy'] == null) 394 { 395 parameterMap['sortBy'] = {}; 396 parameterMap['sortBy'][column_property_name] = false; 397 } 398 399 //Flip the per column sort state for this column 400 parameterMap['sortBy'][column_property_name] = !maintainSortOrder ? !parameterMap['sortBy'][column_property_name] :