[Vue.js] Table表格的checkbox的全選打勾範例程式碼

Table checkbox check all sample code

開發環境為ASP.net Core 2.1

這是我的ViewModel ↓

public class MyItem
{
        public string name { get; set; }
        public string sex { get; set; }
        public string job { get; set; }
}

View的畫面 ↓

@using SaleMenWeb.ViewModels
@using System.Data
@using Newtonsoft.Json
@{ 
    //模擬後端的假資料
    DataTable dt = new DataTable();
    dt.Columns.Add("name");
    dt.Columns.Add("sex");
    dt.Columns.Add("job");
    dt.Rows.Add("Jack","男","打字員");
    dt.Rows.Add("mandy", "女", "企劃");
    dt.Rows.Add("Allen", "男", "MIS");


    //準備要序列化給Vue的物件,通常不會和上面後端的資料一模一樣
    Dictionary<string, MyItem> vueItems = new Dictionary<string, MyItem>();
    //List<MyItem> vueItems = new List<MyItem>(); //List集合會序列化為Json Array,在 Vue.js的method中要用索引找資料不方便,所以使用Dictionary

}

<!DOCTYPE html>
<html lang="utf-8">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>測試頁</title> 
    <link href="~/css/bootstrap.css" rel="stylesheet" type="text/css" />
     <style type="text/css">
         body {
            padding-top:30px;

         }
     </style>
</head>
<body>
    <div class="container" id="myApp">
        <div class="row">

            <form method="post" action="@Url.Action("Test","Common")">
                <div class="form-group col-xs-12">
                    <table class="table table-bordered table-striped table-hover">
                        <thead>
                            <tr>
                                <th>
                                    全選
                                    <input type="checkbox" name="chk_all" v-model="chk_all" v-on:change="Chk_AllEvent" />
                                </th>
                                <th>
                                    假資料
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                            <!--模擬資料後端動態產出,不使用v-for是因為通常迴圈中有複雜的邏輯需要靠後端處理,v-for不足以應付-->
                            @foreach (DataRow dr in dt.Rows)
                            {
                                string vguid = Guid.NewGuid().ToString();
                                <tr>
                                    <td>
                                        <input type="checkbox" name="chklist" 
                                               value="@dr["name"]" v-model="checkedValues"   />
                                    </td>
                                    <td>
                                        @dr["name"]  @dr["sex"] @dr["job"]
                                    </td>
                                </tr>

                                vueItems.Add(vguid, new MyItem() {   name = dr["name"].ToString(), sex = dr["sex"].ToString(), job = dr["job"].ToString() });
                            }
                        </tbody>
                    </table>
                </div>
                <div class="form-group col-xs-12">
                    打勾的資料↓
                    <ul v-if="checkedValues.length>0">
                        <li v-for="(value ,index ) in checkedValues" v-text="value"></li>
                    </ul>
                </div>
                <div class="form-group col-xs-12">
                    <input type="submit" value="提交" class="btn btn-primary"/>
                </div>


            </form>
        </div>
    </div>

    <script src="~/Scripts/jquery-3.2.1.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
    <!--Vue.js-->
    <script src="~/Scripts/vue.js"></script>
    <script type="text/javascript">

        let vueItem = @Html.Raw(JsonConvert.SerializeObject(vueItems));
         
        let myApp = new Vue({
            el: "#myApp",
            data: {
                vueItem: vueItem,
                chk_all: false,
                checkedValues:[]
            },
            methods: {
                Chk_AllEvent: function ($event) {
                    let vm = this;
                    if (vm.chk_all === true)
                    {//全打勾
                        for (let key in vm.vueItem) //走訪每筆物件
                        {
                            let name = vm.vueItem[key]["name"];//因為 checkbox的value給的值是 資料name欄位
                            if (vm.checkedValues.indexOf(name) < 0)
                            {
                                //沒有 才加入集合(重複防呆)
                                vm.checkedValues.push(name);
                            }
                            
                        } 
                    } else {
                        //全不打勾
                        vm.checkedValues = new Array();
                    }
                },
                
            }
    }); 
    </script>
</body>
</html>

靜態網頁版的線上Demo:https://jsfiddle.net/ShadowKao/74xtg1ro/

※ 2019.1.20 追記

上面解法,把資料送到後端時,後端只能知道哪些資料打勾,並不能知道哪些資料沒勾,如果要連同沒打勾的資料都送給後端的話,↓

再補上範例程式碼

<!DOCTYPE html>
<html lang="utf-8">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>全選勾範例</title> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <style type="text/css">
        body {
            padding-top: 30px;
        }
    </style>
</head>
<body>
    <div class="container" id="myApp">
        <div class="row">

             
                <div class="form-group col-xs-12">
                    <table class="table table-bordered table-striped table-hover">
                        <thead>
                            <tr>
                                <th>
                                    全選
																		<input type="checkbox" v-model="chk_all" v-on:change="Chk_AllEvent" />
                                </th>
                                <th>
                                    假資料
                                </th>
                            </tr>
                        </thead>
                        <tbody>
                        <tr v-for="(user,index) in vueItems">
                         <td>
                             <input type="checkbox"  v-model="user.isChecked" />
                         </td>
                      <td>
                        {{user.name}}  {{user.sex}} {{user.job}}
                      </td>
                         </tr> 
                        </tbody>
                    </table>
                </div>
                
                <div class="form-group col-xs-12">
                    <input type="button" value="Ajax提交" class="btn btn-primary" v-on:click="AjaxSubmit"/>
                </div>
								<div class="form-group col-xs-12">
								 {{result}}
								</div>


             
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <!--Vue.js-->
    <script src="https://vuejs.org/js/vue.js"></script>
    <script type="text/javascript"> 
        let vueItems = [  { id:1,"name":"Jack","sex":"男","job":"打字員",isChecked:false}, {id:2,"name":"mandy","sex":"女","job":"企劃",isChecked:false}, 
				{id:3,"name":"Allen","sex":"男","job":"MIS",isChecked:false}];
				
         
        let myApp = new Vue({
            el: "#myApp",
            data: {
                vueItems: vueItems,
                chk_all: false , //預設「全選」不打勾
			    result:""
            },
            methods: {
                Chk_AllEvent: function () {
                    let vm = this;
					let isChecked = vm.chk_all;//有可能true or false
                    
					for (let index in vm.vueItems) //走訪每筆元素
					{
					vm.vueItems[index].isChecked = isChecked; 
					}//end for 
                    
                },
				AjaxSubmit:function(){
				let vm = this;
				vm.result=JSON.stringify(vm.vueItems);
								
				}
                
            }
    }); 
    </script>
</body>
</html>

線上Demo:https://jsfiddle.net/ShadowKao/wkeyfd39/