Browse Source

rename the table.js and add sort feature for table.

zhixin 12 years ago
parent
commit
307a171edc
2 changed files with 111 additions and 31 deletions
  1. 28 14
      index.html
  2. 83 17
      bootstrap-table.js

+ 28 - 14
index.html

@@ -22,25 +22,29 @@
     <a href="https://github.com/wenzhixin/bootstrap-table" class="fork_me"></a>
     <a href="https://github.com/wenzhixin/bootstrap-table" class="fork_me"></a>
     
     
     <script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
     <script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
-    <script type="text/javascript" src="bootstrap-table.js"></script>
+    <script type="text/javascript" src="jquery.bootstrap.table.js"></script>
     <script type="text/javascript">
     <script type="text/javascript">
       $(function() {
       $(function() {
         $('#table').bootstrapTable({
         $('#table').bootstrapTable({
           columns: [
           columns: [
-            {field: 'name', title: 'Name', align: 'center', width: 60},
+            {field: 'name', title: 'Name', align: 'center', width: 60, sortable: true},
             {field: 'type', title: 'Type', align: 'center', width: 60},
             {field: 'type', title: 'Type', align: 'center', width: 60},
             {field: 'description', title: 'Description', width: 400},
             {field: 'description', title: 'Description', width: 400},
             {field: 'default', title: 'Default', align: 'right', width: 180}
             {field: 'default', title: 'Default', align: 'right', width: 180}
           ],
           ],
           data: [
           data: [
+            {name: 'sortName', type: 'String', description: 'Defines which column can be sorted.', 'default': 'undefined'},
+            {name: 'sortOrder', type: 'String', description: 'Defines the column sort order, can only be "asc" or "desc".', 'default': 'asc'},
             {name: 'className', type: 'String', description: 'The table class name', 'default': 'table table-bordered table-hover'},
             {name: 'className', type: 'String', description: 'The table class name', 'default': 'table table-bordered table-hover'},
             {name: 'columns', type: 'Array', description: 'The table columns config object, see column properties for more details.', 'default': '[]'},
             {name: 'columns', type: 'Array', description: 'The table columns config object, see column properties for more details.', 'default': '[]'},
             {name: 'data', type: 'Array', description: 'The data to be loaded.', 'default': '[]'}
             {name: 'data', type: 'Array', description: 'The data to be loaded.', 'default': '[]'}
           ]
           ]
         });
         });
         $('#column').bootstrapTable({
         $('#column').bootstrapTable({
+          sortName: 'name',
+          sortOrder: 'asc',
           columns: [
           columns: [
-            {field: 'name', title: 'Name', align: 'center', width: 60},
+            {field: 'name', title: 'Name', align: 'center', width: 60, sortable: true},
             {field: 'type', title: 'Type', align: 'center', width: 60},
             {field: 'type', title: 'Type', align: 'center', width: 60},
             {field: 'description', title: 'Description', width: 400},
             {field: 'description', title: 'Description', width: 400},
             {field: 'default', title: 'Default', align: 'right', width: 180}
             {field: 'default', title: 'Default', align: 'right', width: 180}
@@ -50,30 +54,40 @@
             {name: 'title', type: 'String', description: 'The column title text.', 'default': 'undefined'},
             {name: 'title', type: 'String', description: 'The column title text.', 'default': 'undefined'},
             {name: 'align', type: 'String', description: 'Indicate how to align the column data. "left", "right", "center" can be used.', 'default': 'undefined'},
             {name: 'align', type: 'String', description: 'Indicate how to align the column data. "left", "right", "center" can be used.', 'default': 'undefined'},
             {name: 'width', type: 'Number', description: 'The width of column. If not defined, the width will auto expand to fit its contents.', 'default': 'undefined'},
             {name: 'width', type: 'Number', description: 'The width of column. If not defined, the width will auto expand to fit its contents.', 'default': 'undefined'},
-            {name: 'formatter', type: 'Function', description: 'The cell formatter function, take two parameters: <br />value: the field value. <br />row: the row record data.', 'default': 'undefined'}
+            {name: 'sortable', type: 'Boolean', description: 'True to allow the column can be sorted.', 'default': 'false'},
+            {name: 'order', type: 'String', description: 'The default sort order, can only be "asc" or "desc".', 'default': 'asc'},
+            {name: 'formatter', type: 'Function', description: 'The cell formatter function, take two parameters: <br />value: the field value. <br />row: the row record data.', 'default': 'undefined'},
+            {name: 'sorter', type: 'Function', description: 'The custom field sort function that used to do local sorting, take two parameters: <br />a: the first field value.<br /> b: the second field value.', 'default': 'undefined'}
           ]
           ]
         });
         });
         $('#event').bootstrapTable({
         $('#event').bootstrapTable({
           columns: [
           columns: [
-            {field: 'name', title: 'Name', align: 'center', width: 100},
-            {field: 'parameter', title: 'Parameter', align: 'center', width: 100},
-            {field: 'description', title: 'Description', width: 400}
+            {field: 'name', title: 'Name', align: 'center', width: 100, sortable: true},
+            {field: 'parameter', title: 'Parameter', align: 'center', width: 100, sortable: true},
+            {field: 'description', title: 'Description', width: 400, sortable: true}
           ],
           ],
           data: [
           data: [
-            {name: 'onClickRow', parameter: 'row', description: 'Fires when user click a row, the parameters contains: <br />row: the record corresponding to the clicked row'}
-          ]
+            {name: 'onClickRow', parameter: 'row', description: 'Fires when user click a row, the parameters contains: <br />row: the record corresponding to the clicked row'},
+            {name: 'onSort', parameter: 'name, order', description: 'Fires when user sort a column, the parameters contains: <br />name: the sort column field name<br />order: the sort column order'}
+          ],
+          onClickRow: function(row) {
+            console.log(row);
+          },
+          onSort: function(name, order) {
+            console.log(name, order);
+          }
         });
         });
         $('#method').bootstrapTable({
         $('#method').bootstrapTable({
           columns: [
           columns: [
             {field: 'name', title: 'Name', align: 'center', width: 100},
             {field: 'name', title: 'Name', align: 'center', width: 100},
             {field: 'parameter', title: 'Parameter', align: 'center', width: 100},
             {field: 'parameter', title: 'Parameter', align: 'center', width: 100},
             {field: 'description', title: 'Description', width: 400}
             {field: 'description', title: 'Description', width: 400}
-          ],
-          data: [
-            {name: 'load', parameter: 'data', description: 'Load the data to table.'},
-            {name: 'append', parameter: 'data', description: 'Append the data to table.'}
           ]
           ]
-        });
+        }).bootstrapTable('load', [
+          {name: 'load', parameter: 'data', description: 'Load the data to table.'}
+        ]).bootstrapTable('append', [
+          {name: 'append', parameter: 'data', description: 'Append the data to table.'}
+        ]);
       });
       });
     </script>
     </script>
     <script type="text/javascript" src="/js/analytics.js"></script>
     <script type="text/javascript" src="/js/analytics.js"></script>

+ 83 - 17
bootstrap-table.js

@@ -26,6 +26,7 @@
 			this.data = [];
 			this.data = [];
 			
 			
 			this.initHeader();
 			this.initHeader();
+			this.initData();
 			this.initBody();
 			this.initBody();
 		},
 		},
 		
 		
@@ -36,27 +37,76 @@
 			this.header = {
 			this.header = {
 				fields: [],
 				fields: [],
 				styles: [],
 				styles: [],
-				formatters: []
+				formatters: [],
+				sorters: []
 			};
 			};
 			$.each(this.options.columns, function(i, column) {
 			$.each(this.options.columns, function(i, column) {
-				var style = column.align ? 'text-align: ' + column.align + '; ': '';
-				style += column.width ? 'width: ' + column.width + 'px; ': '';
+				var style = column.align ? 'text-align: ' + column.align + '; ': '',
+					order = that.options.sortOrder || column.order || 'asc';
 				
 				
 				that.header.fields.push(column.field);
 				that.header.fields.push(column.field);
 				that.header.styles.push(style);
 				that.header.styles.push(style);
 				that.header.formatters.push(column.formatter);
 				that.header.formatters.push(column.formatter);
+				that.header.sorters.push(column.sorter);
+				
+				style += column.width ? 'width: ' + column.width + 'px; ': '';
+				style += column.sortable ? 'cursor: pointer;' : '';
 				
 				
-				html.push('<th style="' + style + '">' + column.title + '</th>');
+				html.push('<th' + 
+					(column.sortable ? ' data-sortable="' + column.field + '"' : '') + 
+					(order ? ' data-order="' + order + '"' : '') + 
+					' style="' + style + '">');
+				html.push(column.title);
+				if (that.options.sortName === column.field && column.sortable) {
+					html.push(that.getCaretHtml());
+				}
+				html.push('</th>');
 			});
 			});
 			html.push('</tr>');
 			html.push('</tr>');
 			this.$header.html(html.join(''));
 			this.$header.html(html.join(''));
+			
+			this.$header.find('th[data-sortable]').click(function() {
+				that.onSort($(this));
+			});
+		},
+		
+		initData: function(data, append) {
+			if (append) {
+				this.data = this.data.concat(data);
+			} else {
+				this.data = data || this.options.data;
+			}
+			
+			this.initSort();
+		},
+		
+		initSort: function() {
+			var name = this.options.sortName,
+				order = this.options.sortOrder === 'desc' ? -1 : 1,
+				index = $.inArray(this.options.sortName, this.header.fields);
+				
+			if (index !== -1) {
+				var sorter = this.header.sorters[index];
+				this.data.sort(function(a, b) {
+					if (typeof sorter === 'function') {
+						return order * sorter(a[name], b[name]);
+					}
+					if (a[name] === b[name]) {
+						return 0;
+					}
+					if (a[name] < b[name]) {
+						return order * -1;
+					}
+					return order;
+				});
+			}
 		},
 		},
 		
 		
-		initBody: function(data, append) {
+		initBody: function() {
 			var that = this,
 			var that = this,
 				html = [];
 				html = [];
-				
-			$.each(data || this.options.data, function(i, item) {
+			
+			$.each(this.data, function(i, item) {
 				html.push('<tr>');
 				html.push('<tr>');
 				$.each(that.header.fields, function(j, field) {
 				$.each(that.header.fields, function(j, field) {
 					var value = item[field];
 					var value = item[field];
@@ -67,24 +117,39 @@
 				});
 				});
 				html.push('</tr>');
 				html.push('</tr>');
 			});
 			});
-			this.$body[append ? 'append' : 'html'](html.join(''));
-			
-			if (append) {
-				this.data = this.data.concat(data);
-			} else {
-				this.data = data || this.options.data;
-			}
+			this.$body.html(html.join(''));
 			this.$body.find('tr').click(function() {
 			this.$body.find('tr').click(function() {
 				that.options.onClickRow(that.data[$(this).index()]);
 				that.options.onClickRow(that.data[$(this).index()]);
 			});
 			});
 		},
 		},
 		
 		
+		onSort: function($this) {
+			this.$header.find('span.order').remove();
+			this.options.sortName = $this.attr('data-sortable');
+			this.options.sortOrder = $this.attr('data-order') === 'asc' ? 'desc' : 'asc';
+			this.options.onSort(this.options.sortName, this.options.sortOrder);
+			$this.attr('data-order', this.options.sortOrder);
+			$this.append(this.getCaretHtml());
+			this.initSort();
+			this.initBody();
+		},
+		
+		getCaretHtml: function() {
+			return ['<span class="order' + (this.options.sortOrder === 'desc' ? '' : ' dropup') + '">',
+					'<span class="caret" style="margin: 8px;"></span>',
+				'</span>'].join('');
+		},
+		
+		/** public function **/
+		
 		load: function(data) {
 		load: function(data) {
-			this.initBody(data);
+			this.initData(data);
+			this.initBody();
 		},
 		},
 		
 		
 		append: function(data) {
 		append: function(data) {
-			this.initBody(data, true);
+			this.initData(data, true);
+			this.initBody();
 		}
 		}
 	};
 	};
 
 
@@ -122,6 +187,7 @@
 		className: 'table table-bordered table-hover',
 		className: 'table table-bordered table-hover',
 		columns: [],
 		columns: [],
 		data: [],
 		data: [],
-		onClickRow: function() {return false;}
+		onClickRow: function(value, row) {return false;},
+		onSort: function(name, order) {return false;}
 	};
 	};
 })(jQuery);
 })(jQuery);