この記事からの続きとなります。
まだご覧になっていない方はどうぞ。
タイトルの通り昇順のソートを行います。
目次
昇順
index.htmlを編集します。
まずは無駄なコードが多いためシンプルにします。
<div id="sample_app">
<table class="table table-striped">
<thead>
<tr>
<th v-for="(column, key) in columns">
[[ column ]]
</th>
</tr>
</thead>
<tbody>
<tr v-for="result in results">
<td v-for="(colum, key) in columns">
[[ result[key] ]]
</td>
</tr>
</tbody>
</table>
</div>
~~~~~~
~~~~~~
<script>
new Vue({
el: '#sample_app',
delimiters: ['[[', ']]'], // Flaskのdelimiterとの重複を回避
data: {
results: [],
columns: null,
},
created() {
axios.get('/json')
.then(response => {
this.results = response.data;
})
.catch(error => {
console.log(error);
});
this.columns = {
number : '#',
age : 'AGE',
b : 'B',
chas : 'CHAS',
crim : 'CRIM',
dis : 'DIS',
indus : 'INDUS',
lstat : 'LSTAT',
nox : 'NOX',
ptratio: 'PTRATIO',
rad : 'RAD',
rm : 'RM',
tax : 'TAX',
zn : 'ZN',
}
},
});
</script>
$ main.py
http://127.0.0.1:5000/index
にアクセスして前回同様に表示されていればOKです。
次にソートメソッドを実装します。
sort_key: ”の追加と
createdの下にメソッドを実装します。
<script>
data: {
sort_key: ''
},
created() {
},
methods: {
sort(key) {
this.sort_key = key
this.results.sort((a, b) => {
if (a[this.sort_key] < b[this.sort_key]) return -1;
if (a[this.sort_key] > b[this.sort_key]) return 1;
return 0;
});
return this.results;
}
}
</script>
実装が終わったらテーブルの項目をクリックするとソートできる仕様にしたいため、@clickというメソッドを仕掛けます。
jqueryが必要なため簡易的なjqueryをインポートします。
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
続いて@click=”sort(key)を追記します。
<tr>
<th v-for="(column, key) in columns" @click="sort(key)">
[[ column ]]
</th>
</tr>
サーバーを再起動して再度下記へアクセスしてthの部分をクリックしてみて下さい。
http://127.0.0.1:5000/index
ソート前
thをクリックどれでもいいです!
ソート(昇順)されればOK!
上の画像はサンプルです。LSTATが昇順でソートされているのが分かります。
ここまでの全体コードです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>BOSTON DF</h1>
<div id="sample_app">
<table class="table table-striped">
<thead>
<tr>
<th v-for="(column, key) in columns" @click="sort(key)">
[[ column ]]
</th>
</tr>
</thead>
<tbody>
<tr v-for="result in results">
<td v-for="(colum, key) in columns">
[[ result[key] ]]
</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
<script>
new Vue({
el: '#sample_app',
delimiters: ['[[', ']]'], // Flaskのdelimiterとの重複を回避
data: {
results: [],
columns: null,
sort_key: ''
},
created() {
axios.get('/json')
.then(response => {
this.results = response.data;
})
.catch(error => {
console.log(error);
});
this.columns = {
number : '#',
age : 'AGE',
b : 'B',
chas : 'CHAS',
crim : 'CRIM',
dis : 'DIS',
indus : 'INDUS',
lstat : 'LSTAT',
nox : 'NOX',
ptratio: 'PTRATIO',
rad : 'RAD',
rm : 'RM',
tax : 'TAX',
zn : 'ZN',
}
},
methods: {
sort(key) {
this.sort_key = key
this.results.sort((a, b) => {
if (a[this.sort_key] < b[this.sort_key]) return -1;
if (a[this.sort_key] > b[this.sort_key]) return 1;
return 0;
});
return this.results;
}
}
});
</script>
</body>
</html>
降順
続きまして降順の処理を追記していきたいと思います。
index.htmlを編集します。
body内の変更と
dataとmethodsに下記を追記します。sort()メソッドも若干編集します。
sortByにkeyを渡してsortByメソッド内でsort()メソッドを実行する使用に変更しました。
<body>
<thead>
<tr>
<th v-for="(column, key) in columns" @click="sortBy(key)">
</body>
<script>
data:{
sort_asc: true,
},
methods: {
sort() {
if (this.sort_key != '') {
let set = this.sort_asc ? 1 : -1;
this.results.sort((a, b) => {
if (a[this.sort_key] < b[this.sort_key]) return -1 * set;
if (a[this.sort_key] > b[this.sort_key]) return 1 * set;
return 0;
});
return this.results;
} else {
return this.results;
}
},
sortBy(key) {
this.sort_key === key ? (this.sort_asc = !this.sort_asc) : (this.sort_asc = true);
this.sort_key = key;
this.sort();
},
},
</script>
thをクリックして昇順・降順が切り替わればOKです!
これだと昇順なのか降順なのか分かりにくいのでstyleで表示させたいと思います。
引き続きindex.htmlを編集します。
<head>
<style>
.asc::after {
content: "▼";
}
.desc::after {
content: "▲";
}
</style>
</head>
<body>
<thead>
<tr>
<th v-for="(column, key) in columns" @click="sortBy(key)" :class="sortAddClass(key)">>
</body>
<script>
methods: {
sortAddClass(key) {
return {
asc: this.sort_key === key && this.sort_asc,
desc: this.sort_key === key && !this.sort_asc,
};
},
}
</script>
thをクリックして▼が出ればOKです。
ソートうまくできたでしょうか。
index.htmlの全体コードも載せておきます。
参考になれば幸いです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.asc::after {
content: "▼";
}
.desc::after {
content: "▲";
}
</style>
</head>
<body>
<h1>BOSTON DF</h1>
<div id="sample_app">
<table class="table table-striped">
<thead>
<tr>
<th v-for="(column, key) in columns" @click="sortBy(key)" :class="sortAddClass(key)">
[[ column ]]
</th>
</tr>
</thead>
<tbody>
<tr v-for="result in results">
<td v-for="(colum, key) in columns">
[[ result[key] ]]
</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
<script>
var vm = new Vue({
el: '#sample_app',
delimiters: ['[[', ']]'], // Flaskのdelimiterとの重複を回避
data: {
results: [],
columns: null,
sort_key: '',
sort_asc: true,
},
created() {
axios.get('/json')
.then(response => {
this.results = response.data;
})
.catch(error => {
console.log(error);
});
this.columns = {
number : '#',
age : 'AGE',
b : 'B',
chas : 'CHAS',
crim : 'CRIM',
dis : 'DIS',
indus : 'INDUS',
lstat : 'LSTAT',
nox : 'NOX',
ptratio: 'PTRATIO',
rad : 'RAD',
rm : 'RM',
tax : 'TAX',
zn : 'ZN',
}
},
methods: {
sort() {
if (this.sort_key != '') {
let set = this.sort_asc ? 1 : -1;
this.results.sort((a, b) => {
if (a[this.sort_key] < b[this.sort_key]) return -1 * set;
if (a[this.sort_key] > b[this.sort_key]) return 1 * set;
return 0;
});
return this.results;
} else {
return this.results;
}
},
sortBy(key) {
this.sort_key === key ? (this.sort_asc = !this.sort_asc) : (this.sort_asc = true);
this.sort_key = key;
this.sort();
},
sortAddClass(key) {
return {
asc: this.sort_key === key && this.sort_asc,
desc: this.sort_key === key && !this.sort_asc,
};
},
},
});
</script>
</body>
</html>
コメント