1. 程式人生 > >基於Bootstrap使用jQuery實現簡單可編輯表格

基於Bootstrap使用jQuery實現簡單可編輯表格

        editTable.js 提供編輯表格當前行、新增一行、刪除當前行的操作,其中可以設定引數,如:

operatePos 用於設定放置操作的列,從0開始,-1表示以最後一列作為放置操作的列;(這裡的操作包括 編輯當前行、在當前行下新增一行、刪除當前行)

handleFirst 設定表格的第一行是否作為操作的物件,true為真,false為假;

edit、save、cancel、add、confirm、del 分別設定顯示操作的操作名,預設顯示“編輯”、“儲存”、“取消”、“新增”、“確認”、“刪除”字樣;

       editableCols 設定可被編輯的列,從0開始,以陣列形式進行設定,如 [ 1, 2] ,表示第2、3列進行編輯操作時,可以被編輯;可以傳入 "all" ,表示選中所有列可被編輯;當然程式中會自動排除 已經設定要放置操作的列;

order 設定表格需要的操作,同時可以設定操作排放的順序;引數為陣列形式,陣列中的值可以為edit、add、del;傳入空陣列的話,預設提供edit編輯操作,相當於設定 [ "edit" ] 引數;此外預設提供所有功能,即編輯、新增、刪除,相當於設定 [ "edit", "add", "del"] 引數,且順序為編輯-》新增-》刪除;可以修改三者的順序,如 [ "add", "edit", "del" ];

       saveCallback 當提供編輯功能後,在編輯當前行的過程中,點選儲存後的回撥函式;需要使用者在使用編輯功能的同時,設定該引數,當進行儲存過中,該函式可以使用ajax傳遞編輯後的資料data(儲存在data陣列中),當ajax儲存資料成功後應該還需要呼叫函式 引數中的 isSuccess 方法,以修改介面中的可編輯狀態為不可編輯狀態;

addCallback和delCallback與saveCallback同理,只是分別應用在不同的操作上——新增和刪除。

editTable.js

/**
 * Created by DreamBoy on 2016/4/19.
 */
$(function() {
    $.fn.handleTable = function (options) {
        //1.Settings 初始化設定
        var c = $.extend({
            "operatePos" : -1, //-1表示預設操作列為最後一列
            "handleFirst" : false, //第一行是否作為操作的物件
            "edit" : "編輯",
            "save" : "儲存",
            "cancel" : "取消",
            "add" : "新增",
            "confirm" : "確認",
            "del" : "刪除",
            "editableCols" : "all", //可編輯的列,從0開始
            //"pos" : 0, //位置位於該列開頭,還是結尾(左側或右側)
            "order" : ["edit", "add", "del"], //指定三個功能的順序
            "saveCallback" : function(data, isSuccess) { //這裡可以寫ajax內容,用於儲存編輯後的內容
                //data: 返回的資料
                //isSuccess: 方法,用於儲存資料成功後,將可編輯狀態變為不可編輯狀態
                //ajax請求成功(儲存資料成功),才回調isSuccess函式(修改儲存狀態為編輯狀態)
            },
            "addCallback" : function(data, isSuccess) {
                //isSuccess: 方法,用於新增資料成功後,將可編輯狀態變為不可編輯狀態
            },
            "delCallback" : function(isSuccess) {
                //isSuccess: 方法,用於刪除資料成功後,將對應行刪除
            }
        }, options);

        //表格的列數
        var colsNum = $(this).find('tr').last().children().size();

        //2.初始化操作列,預設為最後一列,從1算起
        if(c.operatePos == -1) {
            c.operatePos = colsNum - 1;
        }

        //3.獲取所有需要被操作的行
        var rows = $(this).find('tr');
        if(!c.handleFirst) {
            rows = rows.not(":eq(0)");
        }

        //4.獲取放置“操作”的列,通過operatePos獲取
        var rowsTd = [];
        var allTd = rows.children();
        for(var i = c.operatePos; i <= allTd.size(); i += colsNum) {
            if(c.handleFirst) { //如果操作第一行,就把放置操作的列內容置為空
                allTd.eq(i).html("");
            }
            rowsTd.push(allTd.eq(i)[0]);
        }

        //6.修改設定 order 為空時的預設值
        if(c.order.length == 0) {
            c.order = ["edit"];
        }

        //7.儲存可編輯的列
        var cols = getEditableCols();

        //8.初始化連結的構建
        var saveLink = "", cancelLink = "", editLink = "", addLink = "", confirmLink = "", delLink = "";
        initLink();

        //9.初始化操作
        initFunc(c.order, rowsTd);

        /**
         * 建立操作連結
         */
        function createLink(str) {
            return "<a href=\"javascript:void(0)\" style=\"margin:0 3px\">" + str + "</a>";
        }
        /**
         * 初始各種操作的連結
         */
        function initLink() {
            for(var i = 0; i < c.order.length; i++) {
                switch (c.order[i]) {
                    case "edit":
                        //“編輯”連結
                        editLink = createLink(c.edit);
                        saveLink = createLink(c.save);
                        cancelLink = createLink(c.cancel);
                        break;
                    case "add":
                        //“新增”連結
                        addLink = createLink(c.add);
                        //“確認”連結
                        confirmLink = createLink(c.confirm);
                        //“取消”連結
                        cancelLink = createLink(c.cancel);
                        break;
                    case "del":
                        //“刪除”連結
                        delLink = createLink(c.del);
                        break;
                }
            }
        }

        /**
         * 獲取可進行編輯操作的列
         */
        function getEditableCols() {
            var cols = c.editableCols;
            if($.type(c.editableCols) != "array" && cols == "all") { //如果是所有列都可以編輯的話
                cols = [];
                for(var i = 0; i < colsNum; i++) {
                    if(i != c.operatePos) { //排除放置操作的列
                        cols.push(i);
                    }
                }
            } else if($.type(c.editableCols) == "array") { //有指定選擇編輯的列的話需要排序放置“編輯”功能的列
                var copyCols = [];
                for(var i = 0; i < cols.length; i++) {
                    if(cols[i] != c.operatePos) {
                        copyCols.push(cols[i]);
                    }
                }
                cols = copyCols;
            }
            return cols;
        }

        /**
         * 根據c.order引數設定提供的操作
         * @param func 需要設定的操作
         * @param cols 放置操作的列
         */
        function initFunc(func, cols) {
            for(var i = 0; i < func.length; i++) {
                var o = func[i];
                switch(o) {
                    case "edit":
                        createEdit(cols);
                        break;
                    case "add":
                        createAdd(cols);
                        break;
                    case "del":
                        createDel(cols);
                        break;
                }
            }
        }

        /**
         * 建立“編輯一行”的功能
         * @param operateCol 放置編輯操作的列
         */
        function createEdit(operateCol) {
            $(editLink).appendTo(operateCol).on("click", function() {
                if(replaceQuote($(this).html()) == replaceQuote(c.edit)) { //如果此時是編輯狀態
                    toSave(this); //將編輯狀態變為儲存狀態
                } else if(replaceQuote($(this).html()) == replaceQuote(c.save)) { //如果此時是儲存狀態
                    var p = $(this).parents('tr'); //獲取被點選的當前行
                    var data  = []; //儲存修改後的資料到資料內
                    for(var i = 0; i < cols.length; i++) {
                        var tr = p.children().eq(cols[i]);
                        var inputValue = tr.children('input').val();
                        data.push(inputValue);
                    }

                    $this = this; //此時的this表示的是 被點選的 編輯連結
                    c.saveCallback(data, function() {
                        toEdit($this, true);
                    });
                }
            });
            var afterSave = []; //儲存修改前的資訊,用於使用者點選取消後的數值返回操作
            //修改為“儲存”狀態
            function toSave(ele) {
                $(ele).html(c.save); //修改為“儲存”
                $(ele).after(cancelLink); //新增相應的取消儲存的“取消連結”
                $(ele).next().on('click', function() {
                    //if($(this).html() == c.cancel.replace(eval("/\'/gi"),"\"")) {
                    toEdit(ele, false);
                    //}
                });

                //獲取被點選編輯的當前行 tr jQuery物件
                var p = $(ele).parents('tr');

                afterSave = []; //清空原來儲存的資料
                for(var i = 0; i < cols.length; i++) {
                    var tr = p.children().eq(cols[i]);
                    var editTr = "<input type=\"text\" class=\"form-control\" value=\"" + tr.html() + "\"/>";
                    afterSave.push(tr.html()); //儲存未修改前的資料
                    tr.html(editTr);
                }
            }
            //修改為“編輯”狀態(此時,需要通過isSave標誌判斷是
            // 因為點選了“儲存”(儲存成功)變為“編輯”狀態的,還是因為點選了“取消”變為“編輯”狀態的)
            function toEdit(ele, isSave) {
                $(ele).html(c.edit);
                if(replaceQuote($(ele).next().html()) == replaceQuote(c.cancel)) {
                    $(ele).next().remove();
                }

                var p = $(ele).parents('tr');

                for(var i = 0; i < cols.length; i++) {
                    var tr = p.children().eq(cols[i]);
                    var value;
                    if(isSave) {
                        value = tr.children('input').val();
                    } else {
                        value = afterSave[i];
                    }

                    tr.html(value);
                }
            }
        }

        /**
         * 建立“新增一行”的功能
         * @param operateCol
         */
        function createAdd(operateCol) {
            $(addLink).appendTo(operateCol).on("click", function() {
                //獲取被點選“新增”的當前行 tr jQuery物件
                var p = $(this).parents('tr');
                var copyRow = p.clone(); //構建新的一行
                var input = "<input type=\"text\"/>";
                var childLen = p.children().length;
                for(var i = 0; i < childLen; i++) {
                    copyRow.children().eq(i).html("<input type=\"text\" class=\"form-control\"/>");
                }

                //最後一行是操作行
                var last = copyRow.children().eq(c.operatePos);
                last.html("");
                p.after(copyRow);

                var confirm = $(confirmLink).appendTo(last).on("click", function() {
                    var data = [];
                    for(var i = 0; i < childLen; i++) {
                        if(i != c.operatePos) {
                            var v = copyRow.children().eq(i).children("input").val();
                            data.push(v);
                            copyRow.children().eq(i).html(v);
                        }
                    }
                    c.addCallback(data, function() {
                        last.html("");
                        //------------這裡可以進行修改
                        initFunc(c.order, last);
                    });
                });

                $(confirm).after(cancelLink); //新增相應的取消儲存的“取消連結”
                $(confirm).next().on('click', function() {
                    copyRow.remove();
                });
            });
        }

        /**
         * 建立“刪除一行”的功能
         * @param operateCol
         */
        function createDel(operateCol) {
            $(delLink).appendTo(operateCol).on("click", function() {
                var _this = this;
                c.delCallback(function() {
                    $(_this).parents('tr').remove();
                });
            });
        }

        /**
         * 將str中的單引號轉為雙引號
         * @param str
         */
        function replaceQuote(str) {
            return str.replace(/\'/g, "\"");
        }
    };
});
使用過程中需要注意:需要在對應的table中加入可選擇到的選擇器,還有需要在放置”操作“的列放置空標籤<td></td>用於存放”操作“。

使用案例如下:

目錄結構:


index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>表格</title>
    <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css">
    <!--<link href="assets/font-awesome/css/font-awesome.css" rel="stylesheet" />-->
    <!--[if lt IE 9]>
    <script src="js/html5shiv.js"></script>
    <script src="js/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <div class="container">
        <div class="bs-example" data-example-id="hoverable-table">
            <table class="table table-hover editable">
                <thead>
                <tr>
                    <th>#</th>
                    <th>Test</th>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Username</th>
                    <th>Operations</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <th scope="row">1</th>
                    <td></td>
                    <td>Mark</td>
                    <td>Otto</td>
                    <td>@mdo</td>
                    <td><!--<a href="javascript:void(0)" class="edit"></a>--></td>
                </tr>
                <tr>
                    <th scope="row">2</th>
                    <td></td>
                    <td>Jacob</td>
                    <td>Thornton</td>
                    <td>@fat</td>
                    <td><!--<a href="javascript:void(0)" class="edit"></a>--></td>
                </tr>
                <tr>
                    <th scope="row">3</th>
                    <td></td>
                    <td>Larry</td>
                    <td>the Bird</td>
                    <td>@twitter</td>
                    <td><!--<a href="javascript:void(0)" class="edit"></a>--></td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>

    <script src="js/jquery-1.11.1.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="editTable.js"></script>
    <script>
        $(function() {
            //$('.edit').handleTable({"cancel" : "<span class='glyphicon glyphicon-remove'></span>"});
            $('.editable').handleTable({
                "handleFirst" : true,
                "cancel" : " <span class='glyphicon glyphicon-remove'></span> ",
                "edit" : " <span class='glyphicon glyphicon-edit'></span> ",
                "add" : " <span class='glyphicon glyphicon-plus'></span> ",
                "save" : " <span class='glyphicon glyphicon-saved'></span> ",
                "confirm" : " <span class='glyphicon glyphicon-ok'></span> ",
                "operatePos" : -1,
                "editableCols" : [2,3,4],
                "order": ["add","edit"],
                "saveCallback" : function(data, isSuccess) { //這裡可以寫ajax內容,用於儲存編輯後的內容
                    //data: 返回的資料
                    //isSucess: 方法,用於儲存資料成功後,將可編輯狀態變為不可編輯狀態
                    var flag = true; //ajax請求成功(儲存資料成功),才回調isSuccess函式(修改儲存狀態為編輯狀態)
                    if(flag) {
                        isSuccess();
                        alert(data + " 儲存成功");
                    } else {
                        alert(data + " 儲存失敗");
                    }

                    return true;
                },
                "addCallback" : function(data,isSuccess) {
                    var flag = true;
                    if(flag) {
                        isSuccess();
                        alert(data + " 增加成功");
                    } else {
                        alert(data + " 增加失敗");
                    }
                },
                "delCallback" : function(isSuccess) {
                    var flag = true;
                    if(flag) {
                        isSuccess();
                        alert("刪除成功");
                    } else {
                        alert("刪除失敗");
                    }
                }
            });
        });
    </script>
</body>
</html>

執行結果如下:


使用編輯操作:


進行修改:


點選儲存:


新增多行:


在其中新增一些資料:


點選“確定”:



可以取消其他多餘要新增的行: