• 动态表单(javascript实现)


         经常遇到一些项目,需要在数据库某些表中增加一些字段;但是这些字段既不用于查询,也不用于统计,仅仅用于显示。这样一来,每次更改就需要改动许多地方,显得非常繁琐。

         比较流行的动态表单/智能表单,都是很好的解决方案,但用在这里显得大材小用,有些浪费了。

         所以特地用javascript实现一种比较简便的方法,对于所有仅用于显示的表单元素,取得它们的值,以”key=value,key=value”形式存储到数据库中,数据库中仅需要一个text字段即可;在修改时,从数据库取得这些值,再根据key给相应的元素赋值。

         主要使用data-skey的自定义属性作为key,支持select、textarea及input type为text、radio、checkbox的表单元素。

         具体实现如下:

    function dynamicForm(container) {
            this.container = typeof (container) === 'string' ? document.getElementById(container) : container;
        }
        dynamicForm.prototype = {
            _keyValueSplitter: '=',
            _itemSplitter: ',',
            _attrKey: 'data-skey',
            _chkTypes: ['checkbox', 'radio'],
            _isInType: function (a, el) {
                var etype = el.type.toLowerCase();
                var i = a.length;
                while (i--) {
                    if (a[i] === etype) {
                        return true;
                    }
                }
                return false;
            },
            _addElement: function (array, tag, types) {
                var el, nodes = this.container.getElementsByTagName(tag);
                for (var i = 0, l = nodes.length; i < l; i++) {
                    el = nodes[i];
                    if (!types || (types && this._isInType(types, el))) {
                        array.push(el);
                    }
                }
            },
            _getElements: function () {
                var ret = [];
                this._addElement(ret, 'input', ['text'].concat(this._chkTypes));
                this._addElement(ret, 'textarea');
                this._addElement(ret, 'select');
                return ret;
            },
            /*获取所有元素的值*/
            getValues: function () {
                var elArray = this._getElements(), ret = [], el, key, isChk;
                for (var i = 0, l = elArray.length; i < l; i++) {
                    el = elArray[i];
                    key = el.getAttribute(this._attrKey);
                    if (key) {
                        isChk = this._isInType(this._chkTypes, el);
                        if ((!isChk && el.value) || (isChk && el.checked))
                            ret.push(key + this._keyValueSplitter + encodeURIComponent(el.value));
                    }
                }
                return ret.join(this._itemSplitter);
            },
            _setValues: function (val, elArray, callback) {
                if (!(val || val.length)) return;
                var elen = elArray.length, valArray = val.split(this._itemSplitter), keyValue;
                for (var i = 0, l = valArray.length; i < l; i++) {
                    keyValue = valArray[i].split(this._keyValueSplitter);
                    callback.call(this, elArray, elen, keyValue);
                }
            },
            /*为所有元素赋值(可用于修改页面)*/
            setValues: function (val) {
                if (!(val || val.length)) return;
                this._setValues(val, this._getElements(), this._setElementValue);
            },
            _setElementValue: function (elArray, elen, keyValue) {
                var el, key = keyValue[0], val = decodeURIComponent(keyValue[1]), hasSet;
                for (var i = 0; i < elen; i++) {
                    el = elArray[i];
                    if (el.getAttribute(this._attrKey) == key) {
                        if (this._isInType(this._chkTypes, el)) {
                            if (val == el.value)
                                hasSet = el.checked = true;
                        }
                        else if (val) {
                            el.value = val;
                            hasSet = true;
                        }
                        if (hasSet) {
                            elArray.splice(i, 1);
                            break;
                        }
                    }
                }
            },
            /*用于显示到页面(只读)*/
            showTo: function (val, tag) {
                if (!(val || val.length)) return;
                var ret = [];
                this._addElement(ret, tag);
                this._setValues(val, ret, this._showToElement);
            },
            _showToElement: function (elArray, elen, keyValue) {
                var el, key = keyValue[0], val = decodeURIComponent(keyValue[1]), hasSet;
                for (var i = 0; i < elen; i++) {
                    el = elArray[i];
                    if (el.getAttribute(this._attrKey) == key) {
                        el.innerHTML = val;
                        elArray.splice(i, 1);
                        break;
                    }
                }
            }
        };

    相关的测试代码:

    <!DOCTYPE HTML>
    <html>
    <head>
        <title></title>
        <script src="dynamicForm-compiled.js"></script>
        <script>
            function saveData() {
                var f = new dynamicForm('form-wrapper');
                document.getElementById('hf1').value = f.getValues();
            }
            function restoreData() {
                var f = new dynamicForm('form-wrapper');
                f.setValues(document.getElementById('hf1').value);
            }
            function showData() {
                var f = new dynamicForm('view-wrapper');
                f.showTo(document.getElementById('hf1').value, 'span');
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div id="form-wrapper">
            <asp:Literal runat="server" ID="view1" />        
        </div>
        <asp:HiddenField ID="hf1" runat="server" />
        <asp:Button ID="B1" runat="server" Text="提交" onclick="B1_Click" OnClientClick="saveData()" />
        <input type="button" value="还原表单" onclick="restoreData()" />
        <hr />
        <div id="view-wrapper">
            <asp:Literal runat="server" ID="view2" />
        </div>
        </form>
    </body>
    </html>

    后台代码:

    public partial class test_Default : Page
        {
            protected override void OnLoad(EventArgs e)
            {
                view1.Text = File.ReadAllText(Server.MapPath("template-form.html"));
                base.OnLoad(e);
            }
    
            protected void B1_Click(object sender, EventArgs e)
            {
                view2.Text = File.ReadAllText(Server.MapPath("template-view.html"));
                ClientScript.RegisterStartupScript(this.GetType(), Guid.NewGuid().ToString(), "showData();", true);
            }
        }

    用于添加修改数据的模板:

    姓名:<input type="text" data-skey="name" />
    <br />
    性别:
    <input type="radio" name="rdo_group1" value="男" data-skey="gender" />男
    <input type="radio" name="rdo_group1" value="女" data-skey="gender" />女
    <br />
    谁可以看到:
    <select data-skey="see">
        <option value="">请选择</option>
        <option value="任何人">任何人</option>
        <option value="仅好友">仅好友</option>
        <option value="保密">保密</option>
    </select>
    <br />
    自我介绍:
    <textarea data-skey="intro"></textarea>

    用于显示数据的模板:

    姓名:<span data-skey="name"></span>
    <br />
    性别:
    <span  data-skey="gender"></span>
    <br />
    谁可以看到:
    <span data-skey="see"></span>
    <br />
    自我介绍:
    <span data-skey="intro"></span>

    代码下载:点击下载

    作者:囧月
    出处:http://lwme.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    五种方法来遍历Map
    怎样去理解Java中的volatile
    大二层网络----Vxlan技术
    HTTP请求响应过程
    TCP数据传输
    TCP标志位
    TCP协议中的三次握手和四次挥手(图解)
    HTTP报文分析
    HTTP报文图示
    DNS数据包结构
  • 原文地址:https://www.cnblogs.com/lwme/p/2233663.html
Copyright © 2020-2023  润新知