去年这个时候写过一篇全自动数据表格的文章http://www.cnblogs.com/liuyh/p/5747331.html。文章对自己写的一个js组件做了个概述,很多人把它当作了一款功能相似的纯前端表格组件,然而这并不是我的初衷,我的本意是让后台系统的开发从重复的增删查改中脱离出来,我想即使不使用代码生成器也能做到极快速的开发。它不是优秀的表格组件,而是一个极简的增删查改解决方案。
 
为什么不使用现有的表格组件
成熟的表格组件有很多,功能强大的也有不少。它们都大大减少了我们的工作量,那么为什么我还要自己再折腾一个呢?因为还能减少更多...比如:
1、现有的绝大部分表格组件依然避免不了我们需要手写新增、编辑页面相关的代码。
2、即使有表格内部支持编辑模式,但是几乎都不支持图片和富文本格式。
3、对于查询和分页等功能很多都需要自己去实现,至少服务端如此。
 
其实不是表格的设计者们没有想到这些问题,而是要实现这些功能对于一个表格组件来说显得过重了,我想很多表格的使用者们也不能接受使用表格前先引入一个ueditor吧。但是对于我们来说,在轻量级表格与轻量级的工作面前,我想结果是显而易见的,这才是我写表格组件bode.grid.js的初衷。
 
如何省去新增和编辑页面
很多人有一个惯性的思维,认为每个表格的新增、编辑页面都不同,字段不同,字段的类型也不同,有些是数字,有些是下拉选择,有些又要上传图片,有些还是富文本,都不能提取共性,更何谈省去。万事万物都是有共性的,就像人与老虎同属哺乳动物,鸟和鸡都是鸟类,难道说人和鸟就没有共性么?不是的,他们都是生物。好吧,扯远了...看看这个数据结构,它能满足我们的要求:
[
    {
        title:"名称",
        data:"字段名",
        type:"字段类型",
        value:""
    }
]

 对于一个简单的form表单,这个结构足以描述。太复杂的页面?自己写...。而就我的实践经验告诉我,这个结构足以满足90%后台系统中的新增与修改。

 
共性提取出来了,现在所需要做的就是按字段类型渲染不同的组件,比如图片类型的上传插件、富文本类型的编辑器等,只是dom结构的拼接以及组件的初始化,示例代码如下:
this.initForm = function () {
            var form = $('<form >);
            form.appendTo($("body"));

            for (var i = 0, iLen = this.columns.length; i < iLen; i++) {
                var colType = this.columns[i]["type"];
                if (!colType) continue;
                var row;
                if (["text", "number", "datepicker", "timepicker", "hide"].indexOf(colType) >= 0) {
                    row = $('<div class="form-group"><label for="' +
                        this.columns[i]["data"] +
                        '" class="col-sm-3 control-label">' +
                        this.columns[i]["title"] +
                        ':</label><div class="col-sm-9"><input type="text" class="form-control" id="' +
                        this.columns[i]["data"] +
                        '"></div></div>');
                    if (colType === "number") {
                        $.bode.tools.input.formatDiscount(row.find("#" + this.columns[i]["data"]));
                    } else if (colType === "datepicker" || colType === "timepicker") {
                        var showTime = colType === "timepicker";
                        $.bode.tools.input.formatTime(row.find("#" + this.columns[i]["data"]), showTime);
                    } else if (colType === "hide") {
                        row.hide();
                    }
                    row.appendTo(form);
                } else if (["switch", "dropdown"].indexOf(colType) >= 0) {
                    var source = this.columns[i]["source"];
                    var valueFiled = source.valueField || "value";
                    var textField = source.textField || "text";
                    row = $('<div class="form-group"><label for="' +
                        this.columns[i]["data"] +
                        '"  class="col-sm-3 control-label">' +
                        this.columns[i]["title"] +
                        ':</label><div class="col-sm-9"><select class="form-control" id="' +
                        this.columns[i]["data"] +
                        '"></select></div></div>');
                    var select = row.find("#" + this.columns[i]["data"]);
                    for (var j = 0, jLen = source["data"].length; j < jLen; j++) {
                        var option = source["data"][j];
                        $('<option value="' +
                                option[valueFiled] +
                                '">' +
                                option[textField
                        ] +
                                '</option>')
                            .appendTo(select);
                    }
                    row.appendTo(form);
                } else if (colType === "img") {
                    row = $('<div class="form-group"><label for="' +
                        this.columns[i]["data"] +
                        '"  class="col-sm-3 control-label">' +
                        this.columns[i]["title"] +
                        ':</label><div class="col-sm-9"><div class="uploader-list"><div class="file-item thumbnail"><img style="width:160px;height:90px;" id="img_' +
                        this.columns[i]["data"] +
                        '" src="" /></div></div><div id="' +
                        this.columns[i]["data"] +
                        '">选择图片</div></div></div>');
                    row.appendTo(form);
                    // 初始化Web Uploader
                    var uploader = WebUploader.create({
                        auto: true, // 选完文件后,是否自动上传。
                        swf: '/Content/js/plugs/webuploader/Uploader.swf', // swf文件路径
                        server: this.imgSaveUrl, // 文件接收服务端。
                        // 选择文件的按钮。可选。
                        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
                        pick: '#' + this.columns[i]["data"],

                        // 只允许选择图片文件。
                        accept: {
                            title: 'Images',
                            extensions: 'gif,jpg,jpeg,bmp,png',
                            mimeTypes: 'image/*'
                        }
                    });
                    uploader.on("uploadSuccess",
                        function (file, resp) {
                            $("#img_" + this.options.pick.substring(1)).attr("src", resp);
                        });
                } else if (colType === "textarea") {
                    row = $('<div class="form-group"><label for="' +
                        this.columns[i]["data"] +
                        '"  class="col-sm-3 control-label">' +
                        this.columns[i]["title"] +
                        ':</label><div class="col-sm-9"><textarea class="form-control" id="' +
                        this.columns[i]["data"] +
                        '" style="overflow: hidden; word-wrap: break-word; resize: horizontal; height: 48px;"></textarea></div></div>');
                    row.appendTo(form);
                    row.find('textarea').autosize({ append: "\n" });
                } else if (colType === "richtext") {
                    row = $('<div class="form-group"><label for="' +
                        this.columns[i]["data"] +
                        '"  class="col-sm-3 control-label">' +
                        this.columns[i]["title"] +
                        ':</label><div class="col-sm-9"><textarea class="form-control" id="' +
                        this.columns[i]["data"] +
                        '" style="heght:150px;"></textarea></div></div>');
                    row.appendTo(form);

                    var editor = new wangEditor(this.columns[i]["data"]);
                    editor.config.uploadImgUrl = this.imgSaveUrl;
                    editor.config.withCredentials = false;

                    editor.create();
                    editorHash[this.columns[i]["data"]] = editor;
                }
            }
            $('<hr class="wide" />').appendTo(form);
            this.isFormInited = true;
        }
View Code

 最后在公共的js里将整个表单加入页面上,这样就完成了省去新增和编辑页面的工作。页面是省去了,但是数据如何保存,试想我们一般的新增和编辑接口,其提交的数据结构大概是这样:

相关文章: