0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Vue.js】指定した値と一致するレコードのチェックボックスを外す

Posted at

概要

v-modelを使ったテーブルで、ユーザが指定した値と一致するレコードのチェックボックスを外す方法をまとめました。
画面イメージは以下の通りです。

  • 入力欄に名称を入力
  • 「チェック解除」ボタンを押下すると、入力欄の名称と一致するレコードを検索
  • 一致するレコードの「チェック」ボタンがON(赤色の状態)の場合、OFF(灰色の状態)にする

1.png

1-2.png

画面を構成しているのは以下の3つのファイルです。
 チェックボタンコンポーネント:AppCheckButton.vue
 テーブルコンポーネント:Table.vue
 ページ:TestSetting.vue

今回はスタイルの説明は割愛させていただきます。

各ファイルのコード

チェックボックスを外す機能を実装する前に、各ファイルのコードを軽く説明します。

チェックボタンコンポーネント(AppCheckButton.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)

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)

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()が実行されるよう設定します。

TestSetting.vue
<!-- 省略 -->
        <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で渡した入力欄の値を渡します。

Table.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に追加して画面を確認してみましょう。

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は空ですが、
2.png
チェックを付けると、、、
3.png
selectedにvalueが入っています。

つまり、入力欄の値とテーブルの値が一致した際にselectedを空にしてあげればよいという事なので、以下の様なunchecked()関数を作成すれば無事チェックボックスを外す機能が完成します。

AppCheckButton.vue
<!-- 省略 -->
<script>
// 省略
    methods: {
      unchecked: function(Value){
        if(this.selected[0] == Value){
          this.selected = [];
        }
      }
    }
  }
</script>

確認

全レコードにチェックを入れ、入力欄に"test3"と入力し、「チェック解除」を押下します。
4.png

無事、test3だけチェックが外れました!
5.png

おまけ

この仕組みを応用すれば、下記の様な機能が作れます。

削除予定のレコードの「削除」ボタンにチェックを入れる
6.png
表示順を変更・変更内容を保存
7.png
削除不可の場合
8.png
「削除」ボタンのチェックが解除される
9.png

登録・編集・削除ができるマスタテーブルで、削除予定のレコードが削除不可の場合、「削除」チェックがオフになるよう制御しています。
テーブルの表示順が可変の場合でも、今回紹介した仕組みを使えば、レコードを特定することが可能です。

おわりに

今回は指定した値と一致するレコードのチェックボックスを外す方法を記事にまとめました。
今回の実装を経て、propsや$refsの仕組みなど、Vue.jsの理解をまた少し深められたと感じています。
Vue.jsを用いて似たような機能を実装したい方がいらっしゃれば、参考にしていただけますと幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?