Skip to content

Commit 9b01315

Browse files
author
syshex
committed
* Fix to Sorting
* Added Multicolumn Sorting * Fix dynamic adding rows with update to interface * Ajax with multicolumn sorting
1 parent e83daa0 commit 9b01315

11 files changed

+17396
-111
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 1.1.2 (June 2, 2017)
4+
5+
* Fix to Sorting
6+
* Added Multicolumn Sorting
7+
* Fix dynamic adding rows with update to interface
8+
* Ajax with multicolumn sorting
9+
310
## 1.1.1 (June 1, 2017)
411

512
* Added more Events

README.md

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
vue-bootstrap-table is a sortable and searchable table, with Bootstrap styling, for Vue.js.
44

5-
### VUE 1 : 1.1.1
5+
### VUE 1 : 1.1.2
66

77
### Vue 2 : [jbaysolutions/vue2-bootstrap-table](https://github.com/jbaysolutions/vue2-bootstrap-table)
88

@@ -34,6 +34,7 @@ TODO UPDATE CHANGELOG
3434
## Features
3535

3636
* Sortable
37+
* Multicolumn Sorting
3738
* Searchable
3839
* Select display columns
3940
* Pagination
@@ -123,6 +124,7 @@ Or add the js script to your html (download from [releases](https://github.com/j
123124
:show-filter="true"
124125
:show-column-picker="true"
125126
:sortable="true"
127+
:multi-column-sortable=true
126128
:paginated="true"
127129
>
128130
</vue-bootstrap-table>
@@ -155,6 +157,15 @@ Or add the js script to your html (download from [releases](https://github.com/j
155157
required: false,
156158
default: true,
157159
},
160+
/**
161+
* Enable/disable table multicolumn sorting, optional, default false.
162+
* Also sortable must be enabled for this function to work.
163+
*/
164+
multiColumnSortable: {
165+
type: Boolean,
166+
required: false,
167+
default: false,
168+
},
158169
/**
159170
* Enable/disable input filter, optional, default false
160171
*/
@@ -279,13 +290,27 @@ ajax: {
279290

280291
When Ajax is enabled, the following parameters are sent with each request for the URL specified:
281292

282-
- `sortcol` : The name of the column to sort by (only sent when `delegate` is true, otherwise will be null)
283-
- `sortdir` : The sorting direction "ASC" or "DESC" (only sent when `delegate` is true, otherwise will be null)
293+
- `sortcol` : Array of String columns to sort (only sent when `delegate` is true, otherwise will be null)
294+
- `sortdir` : Array of sorting directions for each column on sortcol, "ASC" or "DESC" (only sent when `delegate` is true, otherwise will be null)
284295
- `filter` : The filter to be used (only sent when `delegate` is true, otherwise will be null)
285296
- `page` : The number of the page being requested ( when delegate is false, it will always be 1 )
286297
- `pagesize` : The number of records being requested.
287298
- `echo` : A unique number for the request.
288299

300+
##### When using GET
301+
302+
- `sortcol` : is sent in the following format `sortcol[]=COLNAME&sortcol[]=COLNAME`
303+
- `sortdir` : is sent in the following format `sortdir[]=ASC&sortdir[]=DESC`
304+
305+
This is performed automatically by AXIOS
306+
307+
##### When using POST
308+
309+
- `sortcol` : is sent in the following format `sortcol[0]=COLNAME ; sortcol[1]=COLNAME; `
310+
- `sortdir` : is sent in the following format `sortdir[0]=ASC ; sortdir[1]=DESC`
311+
312+
This is performed automatically by AXIOS
313+
289314
#### Ajax Expected Response
290315

291316
For all requests, vue-bootstrap-table expects an object of the following type:
@@ -360,6 +385,7 @@ If you have a feature request, please add it as an issue or make a pull request.
360385

361386
- [x] Basic table
362387
- [x] Sorting
388+
- [x] Multicolumn Sorting
363389
- [x] Filter
364390
- [x] Column picker
365391
- [x] Pagination
@@ -372,6 +398,13 @@ If you have a feature request, please add it as an issue or make a pull request.
372398

373399
## Changelog
374400

401+
### 1.1.2
402+
403+
* Fix to Sorting
404+
* Added Multicolumn Sorting
405+
* Fix dynamic adding rows with update to interface
406+
* Ajax with multicolumn sorting
407+
375408
### 1.1.1
376409

377410
* Added more Events

dist/vue-bootstrap-table.js

Lines changed: 17233 additions & 60 deletions
Large diffs are not rendered by default.

dist/vue-bootstrap-table.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/vue-bootstrap-table.min.js

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/01-basic.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ <h1>Vue Bootstrap Table Demo</h1>
2525
:show-filter="showFilter"
2626
:show-column-picker="showPicker"
2727
:paginated="paginated"
28+
:multi-column-sortable="multiColumnSortable"
2829
>
2930
</vue-bootstrap-table>
3031
</div>

examples/01-basic.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,34 @@ new Vue({
1111
showFilter: true,
1212
showPicker: true,
1313
paginated: true,
14+
multiColumnSortable: true,
15+
ajax: {
16+
enabled: false,
17+
url: "http://localhost:9430/data/test",
18+
method: "POST",
19+
delegate: true,
20+
},
1421
columns: [
1522
{
1623
title:"id",
1724
visible: true,
1825
editable: false,
1926
},
2027
{
21-
title:"name",
28+
title:"Name",
29+
name: "name",
2230
visible: true,
2331
editable: true,
2432
},
2533
{
26-
title:"age",
34+
title:"Age",
35+
name:"age",
2736
visible: true,
2837
editable: true,
2938
},
3039
{
31-
title:"country",
40+
title:"Country",
41+
name:"country",
3242
visible: true,
3343
editable: true,
3444
}

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ <h1>Vue Bootstrap Table</h1>
2525
:show-filter="showFilter"
2626
:show-column-picker="showPicker"
2727
:paginated="paginated"
28+
:multi-column-sortable="multiColumnSortable"
2829
:ajax="ajax"
2930
>
3031
</vue-bootstrap-table>

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"dependencies": {
2828
"babel-runtime": "^6.0.0",
2929
"axios": "^0.16.1",
30-
"qs": "^6.0.0"
30+
"qs": "^6.0.0",
31+
"lodash": "^4.17.4"
3132
},
3233
"devDependencies": {
3334
"babel-cli": "^6.5.1",

src/VueBootstrapTable.vue

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,18 @@
3737
<table class="table table-bordered table-hover table-condensed table-striped vue-table">
3838
<thead>
3939
<tr>
40-
<th v-for="column in displayCols | filterBy true in 'visible'" @click="sortBy(column.name)"
40+
<th v-for="column in displayColsVisible" @click="sortBy($event, column.name)"
4141
track-by="$index"
4242
:class="getClasses(column.name)">
4343
{{ column.title }}
4444
</th>
4545
</tr>
4646
</thead>
4747
<tbody>
48-
<tr v-for="entry in filteredValues | orderBy sortKey sortOrders[sortKey]" track-by="$index">
49-
<td v-for="column in displayCols | filterBy true in 'visible'" track-by="$index"
48+
<tr v-for="entry in filteredValuesSorted " track-by="$index">
49+
<td v-for="column in displayColsVisible" track-by="$index"
5050
v-show="column.visible">
51+
5152
<span v-if="!column.editable"> {{ entry[column.name] }} </span>
5253
<value-field-section v-else
5354
:entry="entry"
@@ -65,7 +66,7 @@
6566
<div class="btn-group" role="group" aria-label="pages">
6667
<button v-for="index in validPageNumbers"
6768
type="button" class="btn btn-default"
68-
v-bind:class="{ active: this.page===index }"
69+
:class="{ active: this.page===index }"
6970
@click="this.page=index">
7071
{{index}}
7172
</button>
@@ -182,6 +183,8 @@
182183
183184
import axios from 'axios';
184185
import qs from 'qs';
186+
import lodash from 'lodash';
187+
185188
186189
/* Field Section used for displaying and editing value of cell */
187190
var valueFieldSection = {
@@ -246,6 +249,15 @@
246249
required: false,
247250
default: true,
248251
},
252+
/**
253+
* Enable/disable table multicolumn sorting, optional, default false.
254+
* Also sortable must be enabled for this function to work.
255+
*/
256+
multiColumnSortable: {
257+
type: Boolean,
258+
required: false,
259+
default: false,
260+
},
249261
/**
250262
* Enable/disable input filter, optional, default false
251263
*/
@@ -298,9 +310,9 @@
298310
return {
299311
filteredSize: 0,
300312
filterKey: "",
301-
sortKey: "",
302-
sortDir: "",
313+
sortKey: [],
303314
sortOrders: {},
315+
sortChanged: 1,
304316
columnMenuOpen: false,
305317
displayCols: [],
306318
filteredValues: [],
@@ -360,7 +372,7 @@
360372
sortKey: function () {
361373
this.processFilter();
362374
},
363-
sortDir: function () {
375+
sortChanged: function () {
364376
this.processFilter();
365377
},
366378
page: function () {
@@ -375,6 +387,21 @@
375387
}
376388
},
377389
computed: {
390+
displayColsVisible: function () {
391+
var displayColsVisible = [];
392+
for (var a in this.displayCols) {
393+
if (this.displayCols[a].visible)
394+
displayColsVisible.push(this.displayCols[a]);
395+
}
396+
return displayColsVisible;
397+
},
398+
filteredValuesSorted: function () {
399+
var tColsDir = [];
400+
for(var i=0, len=this.sortKey.length; i < len; i++){
401+
tColsDir.push(this.sortOrders[this.sortKey[i]].toLowerCase());
402+
}
403+
return _.orderBy(this.filteredValues, this.sortKey , tColsDir);
404+
},
378405
validPageNumbers: function () {
379406
// 5 page max
380407
var result = [];
@@ -408,8 +435,23 @@
408435
self.loading = false;
409436
});
410437
} else {
411-
var result = this.$options.filters.filterBy(this.values, this.filterKey);
412-
result = this.$options.filters.orderBy(result, this.sortKey, this.sortOrders[this.sortKey]);
438+
var result = this.values.filter(item => {
439+
var good = false;
440+
for (var col in self.displayColsVisible) {
441+
if ( _.includes(item[self.displayColsVisible[col].name]+"" , self.filterKey+"")){
442+
good = true;
443+
}
444+
}
445+
return good;
446+
});
447+
448+
var tColsDir = [];
449+
for(var i=0, len=this.sortKey.length; i < len; i++){
450+
tColsDir.push(this.sortOrders[this.sortKey[i]].toLowerCase());
451+
}
452+
453+
result = _.orderBy(result, this.sortKey, tColsDir);
454+
413455
this.filteredSize = result.length;
414456
if (this.paginated) {
415457
var startIndex = (this.page - 1) * this.pageSize;
@@ -429,13 +471,17 @@
429471
fetchData: function ( dataCallBackFunction ) {
430472
var self = this;
431473
var ajaxParameters = {
432-
474+
params: {}
433475
};
434476
this.echo++;
435477
if (this.ajax.enabled && this.ajax.delegate) {
478+
var tColsDir = [];
479+
for(var i=0, len=this.sortKey.length; i < len; i++){
480+
tColsDir.push(this.sortOrders[this.sortKey[i]].toLowerCase());
481+
}
436482
if ( this.ajax.method=== "GET" ) {
437483
ajaxParameters.params.sortcol = this.sortKey;
438-
ajaxParameters.params.sortdir = this.sortDir;
484+
ajaxParameters.params.sortdir = tColsDir;
439485
ajaxParameters.params.filter = this.filterKey;
440486
if (self.paginated ) {
441487
ajaxParameters.params.page = this.page;
@@ -448,7 +494,7 @@
448494
}
449495
if ( this.ajax.method=== "POST" ) {
450496
ajaxParameters.sortcol = this.sortKey;
451-
ajaxParameters.sortdir = this.sortDir;
497+
ajaxParameters.sortdir = tColsDir;
452498
ajaxParameters.filter = this.filterKey;
453499
if (self.paginated ) {
454500
ajaxParameters.page = this.page;
@@ -504,45 +550,55 @@
504550
return obj;
505551
},
506552
setSortOrders: function () {
507-
this.sortKey = "";
553+
this.sortKey = [];
508554
var sortOrders = {};
509555
this.columns.forEach(function (column) {
510-
sortOrders[column.name] = 0;
556+
sortOrders[column.name] = "";
511557
});
512558
this.sortOrders = sortOrders;
513559
514560
},
515-
sortBy: function (key) {
561+
sortBy: function (event, key) {
516562
if (this.sortable) {
517563
var self = this;
518-
this.sortKey = key;
519-
this.columns.forEach(function (column) {
520-
if (column.name !== key) {
521-
self.sortOrders[column.name] = 0;
564+
565+
if (!this.multiColumnSortable || ( this.multiColumnSortable && !event.shiftKey)) {
566+
this.sortKey = [key];
567+
this.columns.forEach(function (column) {
568+
if (column.name !== key) {
569+
self.sortOrders[column.name] = "";
570+
}
571+
});
572+
} else {
573+
if (_.findIndex(this.sortKey, function(o) { return o === key; }) === -1) {
574+
this.sortKey.push(key);
522575
}
523-
});
524-
if (this.sortOrders[key] === 0) {
525-
this.sortOrders[key] = 1;
576+
}
577+
if (this.sortOrders[key] === "") {
578+
this.sortOrders[key] = "ASC";
579+
} else if (this.sortOrders[key] === "ASC") {
580+
this.sortOrders[key] = "DESC";
526581
} else {
527-
this.sortOrders[key] = this.sortOrders[key] * -1;
582+
this.sortOrders[key] = "ASC";
528583
}
529584
530-
if (this.sortOrders[key] === 1)
531-
this.sortDir = "ASC";
532-
if (this.sortOrders[key] === -1)
533-
this.sortDir = "DESC";
585+
this.sortChanged = this.sortChanged * -1;
534586
}
535587
},
536588
getClasses: function (key) {
537589
var classes = [];
538590
if (this.sortable) {
539591
classes.push("arrow");
540-
if (this.sortKey === key) {
592+
/*if (this.sortKey === key) {
593+
classes.push("active");
594+
}*/
595+
if (_.findIndex(this.sortKey, function(o) { return o === key; }) !== -1) {
541596
classes.push("active");
542597
}
543-
if (this.sortOrders[key] === 1) {
598+
599+
if (this.sortOrders[key] === "ASC") {
544600
classes.push("asc");
545-
} else if (this.sortOrders[key] === -1) {
601+
} else if (this.sortOrders[key] === "DESC") {
546602
classes.push("dsc");
547603
}
548604
}

0 commit comments

Comments
 (0)