2017年5月23日 星期二

Bootstrap Table 表格內容直接編輯 : X-editable

最近需要做一個表格內可直接編輯的網頁
使用Bootstrap Table 與 x-editable結合
實作了
1. 單純的文字編輯,且更新不能為空
2. 下拉選單,設定三個選項
效果圖:


index.html

<!DOCTYPE html>

<head>
    <!--基本設定-->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, shrink-to-fit=no, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- 頁籤標題 -->
    <title>X-editable</title>

    <!--引用jquery-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

    <!-- 引用bootstrap -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <!-- Bootstrap Table -->
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.css">
    <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/locale/bootstrap-table-zh-TW.min.js"></script>


    <!--X-editable (bootstrap version)-->
    <link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet" />
    <script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>

    <!-- Bootstrap Table X-editable 額外插件 -->
    <script src="../extensions/editable/bootstrap-table-editable.js"></script>

    <!-- 自定義表格 -->
    <script src="./index.js"></script>

    <!--自訂css樣式-->
    <style type="text/css">

    </style>

</head>

<body>
    <div class="container">
        <table id="mainTable">
        </table>
    </div>
</body>

</html>


index.js

$(document).ready(function() {

    $.fn.editable.defaults.mode = 'popup'; // 可選inline或是popup,分別代表不彈出編輯或是彈出編輯
    $.fn.editable.defaults.emptytext = '-'; // 修改空值時的顯示,預設為紅色Empty

    $('#mainTable').bootstrapTable({
        url: 'getData.php',
        method: 'get',
        queryParams: {
            action: "getData"
        },
        idField: "id",
        pagination: true,
        sidePagination: "client",
        pageNumber: 1,
        pageSize: 1,
        pageList: [1, 3, 5, 10, 'ALL'],
        paginationPreText: '上一頁',
        paginationNextText: '下一頁',
        toolbar: '#report_toolbar_search',
        striped: true,
        cache: false,
        sortStable: true,
        sortName: 'ordernumber',
        sortOrder: "ASC",
        search: true,
        showColumns: false,
        minimumCountColumns: 2,
        strictSearch: false,
        showRefresh: true,
        clickToSelect: true,
        uniqueId: "id",
        undefinedText: "-",
        columns: [{
            field: 'id',
            title: 'id',
        }, {
            field: 'itemName',
            title: '物品名稱',
            editable: {
                type: 'text',
                title: 'Item ID',
                validate: function(v) {
                    if (!v) return '物品名稱不能為空';
                }
            }
        }, {
            field: 'itemSelect',
            title: '選擇',
            editable: {
                type: 'select',
                title: 'Item Select',
                source: [{
                    text: "選擇1", // 顯示的
                    value: "選擇1" // 實際的值
                }, {
                    text: "選擇2",
                    value: "選擇2"
                }, {
                    text: "選擇3",
                    value: "選擇3"
                }, ],
            }
        }, ],
        onEditableSave: function(field, row, oldValue, $el) {
            // field:修改的欄位
            // row:修改後的資料(JSON Object)
            // oldValue:修改前的值
            // -------------------------------------------------
            // 可用ajax方法去更新資料
            // $.ajax({
            //     type: "post",
            //     url: "update.php",
            //     data: row,
            //     dataType: 'JSON',
            //     success: function(data, status) {
            //         if (status == "success") {
            //             alert('修改成功');
            //         }
            //     },
            //     error: function() {
            //         alert('修改失敗');
            //     },
            //     complete: function() {

            //     }

            // });
            // -------------------------------------------------
        }
    });


});

getData.php

<?php
$action = filter_input(INPUT_GET, "action");
switch ($action) {
    case "getData":
        getData();
        break;
    default:
        defaultFun();
}

function getData()
{
    $data = array(
        array(
            "id"=>"1" ,
            "itemName"=>"物品名稱1" ,
            "itemSelect"=>"選擇1" ,
        ),
        array(
            "id"=>"2" ,
            "itemName"=>"物品名稱2" ,
            "itemSelect"=>"選擇2" ,
        ),
        array(
            "id"=>"3" ,
            "itemName"=>"物品名稱3" ,
            "itemSelect"=>"選擇3" ,
        )
    );
    print_r(json_encode($data));
};

function defaultFun()
{
    $data[]=array(
            "id"=>"default" ,
            "itemName"=>"default" ,
            "itemSelect"=>"default"
        );
    print_r(json_encode($data));
}


bootstrap-table-editable.js
額外插件,要自己設定好index.html中的路徑,目前放在
../extensions/editable/bootstrap-table-editable.js


/**
 * @author zhixin wen <wenzhixin2010@gmail.com>
 * extensions: https://github.com/vitalets/x-editable
 */

(function($) {

    'use strict';

    $.extend($.fn.bootstrapTable.defaults, {
        editable: true,
        onEditableInit: function() {
            return false;
        },
        onEditableSave: function(field, row, oldValue, $el) {
            return false;
        },
        onEditableShown: function(field, row, $el, editable) {
            return false;
        },
        onEditableHidden: function(field, row, $el, reason) {
            return false;
        }
    });

    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
        'editable-init.bs.table': 'onEditableInit',
        'editable-save.bs.table': 'onEditableSave',
        'editable-shown.bs.table': 'onEditableShown',
        'editable-hidden.bs.table': 'onEditableHidden'
    });

    var BootstrapTable = $.fn.bootstrapTable.Constructor,
        _initTable = BootstrapTable.prototype.initTable,
        _initBody = BootstrapTable.prototype.initBody;

    BootstrapTable.prototype.initTable = function() {
        var that = this;
        _initTable.apply(this, Array.prototype.slice.apply(arguments));

        if (!this.options.editable) {
            return;
        }

        $.each(this.columns, function(i, column) {
            if (!column.editable) {
                return;
            }

            var editableOptions = {},
                editableDataMarkup = [],
                editableDataPrefix = 'editable-';

            var processDataOptions = function(key, value) {
                // Replace camel case with dashes.
                var dashKey = key.replace(/([A-Z])/g, function($1) {
                    return "-" + $1.toLowerCase();
                });
                if (dashKey.slice(0, editableDataPrefix.length) == editableDataPrefix) {
                    var dataKey = dashKey.replace(editableDataPrefix, 'data-');
                    editableOptions[dataKey] = value;
                }
            };

            $.each(that.options, processDataOptions);

            column.formatter = column.formatter || function(value, row, index) {
                return value;
            };
            column._formatter = column._formatter ? column._formatter : column.formatter;
            column.formatter = function(value, row, index) {
                var result = column._formatter ? column._formatter(value, row, index) : value;

                $.each(column, processDataOptions);

                $.each(editableOptions, function(key, value) {
                    editableDataMarkup.push(' ' + key + '="' + value + '"');
                });

                var _dont_edit_formatter = false;
                if (column.editable.hasOwnProperty('noeditFormatter')) {
                    _dont_edit_formatter = column.editable.noeditFormatter(value, row, index);
                }

                if (_dont_edit_formatter === false) {
                    return ['<a href="javascript:void(0)"',
                        ' data-name="' + column.field + '"',
                        ' data-pk="' + row[that.options.idField] + '"',
                        ' data-value="' + result + '"',
                        editableDataMarkup.join(''),
                        '>' + '</a>'
                    ].join('');
                } else {
                    return _dont_edit_formatter;
                }

            };
        });
    };

    BootstrapTable.prototype.initBody = function() {
        var that = this;
        _initBody.apply(this, Array.prototype.slice.apply(arguments));

        if (!this.options.editable) {
            return;
        }

        $.each(this.columns, function(i, column) {
            if (!column.editable) {
                return;
            }

            that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
                .off('save').on('save', function(e, params) {
                    var data = that.getData(),
                        index = $(this).parents('tr[data-index]').data('index'),
                        row = data[index],
                        oldValue = row[column.field];

                    $(this).data('value', params.submitValue);
                    row[column.field] = params.submitValue;
                    that.trigger('editable-save', column.field, row, oldValue, $(this));
                    that.resetFooter();
                });
            that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
                .off('shown').on('shown', function(e, editable) {
                    var data = that.getData(),
                        index = $(this).parents('tr[data-index]').data('index'),
                        row = data[index];

                    that.trigger('editable-shown', column.field, row, $(this), editable);
                });
            that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
                .off('hidden').on('hidden', function(e, reason) {
                    var data = that.getData(),
                        index = $(this).parents('tr[data-index]').data('index'),
                        row = data[index];

                    that.trigger('editable-hidden', column.field, row, $(this), reason);
                });
        });
        this.trigger('editable-init');
    };

})(jQuery);




參考資料:
1. X-editable
2. Bootstrap Table Getting Start
3. JS组件系列——BootstrapTable 行内编辑解决方案:x-editable


1 則留言:

  1. 特別感謝這篇文章,從這裡摳的 bootstrap-table-editable.js 可以正常運作(哭泣),CDN 最新版的不知道是我的問題還是超自然的問題,就是沒辦法正常運作🫠💦

    回覆刪除