概要
v-modelを使ったテーブルで、ユーザが指定した値と一致するレコードのチェックボックスを外す方法をまとめました。
画面イメージは以下の通りです。
- 入力欄に名称を入力
- 「チェック解除」ボタンを押下すると、入力欄の名称と一致するレコードを検索
- 一致するレコードの「チェック」ボタンがON(赤色の状態)の場合、OFF(灰色の状態)にする
画面を構成しているのは以下の3つのファイルです。
チェックボタンコンポーネント:AppCheckButton.vue
テーブルコンポーネント:Table.vue
ページ:TestSetting.vue
今回はスタイルの説明は割愛させていただきます。
各ファイルのコード
チェックボックスを外す機能を実装する前に、各ファイルのコードを軽く説明します。
チェックボタンコンポーネント(AppCheckButton.vue)
<template>
<label>
<input type="checkbox" name="checkbox" class="checkbox-input" v-model="selected" :value="value">
<span class="rounded_btn">{{ label }}</span>
</label>
</template>
<script>
export default {
name: 'AppCheckButton',
data () {
return {
selected: [],
};
},
props: {
label: String,
value: [Number,String]
},
</script>
inputタグをtype="checkbox"
v-model="selected"
:value="value"
に設定します。チェックを付けるとselectedにvalueが格納される仕組みです。
selectedはリストで本コンポーネントに定義し、labelとvalueはpropsを使ってTable.vueからデータを取ってくるようにします。
テーブルコンポーネント(Table.vue)
<template>
<div class="vt">
<div class="master-table">
<table id="vt">
<thead>
<tr class="table-header-row">
<th v-for="(header, index) in headers"
v-bind:key="index"
:width="header.width"
class="table-header-col">
{{header.text}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in items"
v-bind:key="item.id"
class='table-col'
>
<td class="text-field">
{{ item.field1 }}
</td>
<td>
<span class="CheckButton">
<AppCheckButton
label="チェック"
class="notlink"
:value="item.field1"
ref="check"
/>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import AppCheckButton from "@/components/atoms/Input/AppCheckButton.vue";
export default {
name: "Table",
components: {
AppCheckButton
},
data() {
return {};
},
props: {
headers: {
type: Array,
required: true,
},
items: {
type: Array,
required: true,
}
},
</script>
TestSetting.vueからheadersとitemsを参照し、ヘッダとボディにそれぞれv-forで格納しています。
先程紹介したAppCheckButton.vueで定義していたlabelには"チェック"という文字列を、valueにはitem.field1のデータを渡しています。
item.field1の具体的なデータは次で紹介するTestSetting.vueに記述されています。
ページ(TestSetting.vue)
<template>
<div>
<ValidationObserver ref="validationObserver">
<label>
<input tipe="text" class="testInput" id="testInput">
<input type="button" value="チェック解除" class="testButton">
</label>
<Table
ref="table"
name="名称"
:headers="NameHeaders"
:items="NameItems"
/>
</ValidationObserver>
</div>
</template>
<script>
import Table from "../organisms/Table.vue";
export default {
name: "TestSetting",
components: {
Table
},
data() {
return {
NameHeaders: [
{ text: "名称",
align: "start",
value: "field1",
sortable: false,
width: "40%"
},
{ text: "操作",
value: "check",
sortable: false,
width: "20%"
},
],
NameItems: [
{field1:"test1", NameId:1, id:1},
{field1:"test2", NameId:2, id:2},
{field1:"test3", NameId:3, id:3}
],
};
},
</script>
Table.vueをインポートしており、Table.vueのheadersにNameHeaders、itemsにNameItemsを渡しています。
また、「チェック解除」ボタンを押下すると、buttonClick()が発火します。buttonClick()の内容は、入力欄の値を取得し、$refsを用いてTable.vueに登録されているchangeCheck()を発火させるというものです。
チェックボックスを外す機能の実装
上記で紹介したテーブル画面に、指定した値と一致するレコードのチェックボックスを外す機能を追加していきます。
動作の大まかな流れは以下の通りです。
① 入力欄の値を取得 (TestSetting.vue)
② テーブルの長さ分だけfor文を回す (Table.vue)
③ 入力欄の値とテーブルのレコードの値を比べ、値が一致した場合、チェックを外す (AppCheckButton.vue)
①入力欄の値を取得 (TestSetting.vue)
入力欄の値を取得するbuttonClick()関数を作成します。@clickで「チェック解除」ボタン押下時に発火するよう紐づけます。また、$refsを使って、②でTable.vue内に定義するchangeCheck()が実行されるよう設定します。
<!-- 省略 -->
<label>
<input tipe="text" class="testInput" id="testInput">
<input type="button" value="チェック解除" @click="buttonClick" class="testButton">
</label>
<!-- 省略 -->
<script>
// 省略
methods: {
buttonClick() {
let inputValue = document.getElementById("testInput").value;
this.$refs.table.changeCheck(inputValue);
},
}
</script>
② テーブルの長さ分だけfor文を回す (Table.vue)
v-forでテーブルにデータを渡しているため、<AppCheckButton/>
もデータの個数分生成されます。そのためテーブルの長さをthis.$refs.check.lengthで表すことが可能です。
this.$refs.check.length分for文を回し、AppCheckButton.vueで定義するunchecked()に、TestSetting.vueで渡した入力欄の値を渡します。
<!-- 省略 -->
<script>
// 省略
methods: {
changeCheck (Value){
for(var i = 0; i < this.$refs.check.length; i++){
this.$refs.check[i].unchecked(Value);
}
}
}
</script>
③ 入力欄の値とテーブルのレコードの値を比べ、値が一致した場合、チェックを外す (AppCheckButton.vue)
チェックが付いている状態ではselected[]にvalueが格納されており、チェックが外れている状態ではselected[]は空の状態になります。分かりやすい様に下記の<!-- 追加 -->
部分をAppCheckButton.vueに追加して画面を確認してみましょう。
<template>
<label>
<input type="checkbox" name="checkbox" class="checkbox-input" v-model="selected" :value="value"
>
<span class="rounded_btn">{{ label }}</span>
<span class="rounded_btn">{{ selected }}</span> <!-- 追加 -->
</label>
</template>
チェックが外れているときはselectedは空ですが、
チェックを付けると、、、
selectedにvalueが入っています。
つまり、入力欄の値とテーブルの値が一致した際にselectedを空にしてあげればよいという事なので、以下の様なunchecked()関数を作成すれば無事チェックボックスを外す機能が完成します。
<!-- 省略 -->
<script>
// 省略
methods: {
unchecked: function(Value){
if(this.selected[0] == Value){
this.selected = [];
}
}
}
}
</script>
確認
全レコードにチェックを入れ、入力欄に"test3"と入力し、「チェック解除」を押下します。
おまけ
この仕組みを応用すれば、下記の様な機能が作れます。
削除予定のレコードの「削除」ボタンにチェックを入れる
表示順を変更・変更内容を保存
削除不可の場合
「削除」ボタンのチェックが解除される
登録・編集・削除ができるマスタテーブルで、削除予定のレコードが削除不可の場合、「削除」チェックがオフになるよう制御しています。
テーブルの表示順が可変の場合でも、今回紹介した仕組みを使えば、レコードを特定することが可能です。
おわりに
今回は指定した値と一致するレコードのチェックボックスを外す方法を記事にまとめました。
今回の実装を経て、propsや$refsの仕組みなど、Vue.jsの理解をまた少し深められたと感じています。
Vue.jsを用いて似たような機能を実装したい方がいらっしゃれば、参考にしていただけますと幸いです。