我们专注攀枝花网站设计 攀枝花网站制作 攀枝花网站建设
成都网站建设公司服务热线:400-028-6601

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

jQueryUI模态表单疯狂踩坑

想套用一下前端的组件写一个表单验证的页面,于是试了一下jQuery UI

创新互联于2013年开始,先为苏尼特左等服务建站,苏尼特左等地企业,进行企业商务咨询服务。为苏尼特左企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

官网的例子

首先把官网的例子贴上:




    
    
    jQuery UI Dialog - Modal form
    
    
    
    
    
    


All form fields are required.

Existing Users:

Name Email Password
John Doe john.doe@example.com johndoe1

试了一下,一切都很美好。

From表单DIV的位置

首先看到CSS写的很粗,比如第一条:

label, input { display:block; }

直接就定义了所有label和input标签的样式。看着body里是2个DIV,于是想把2个div外面再包一层div,像下面这样:


然后所有的css样式前面都加上自己的这个div,就不会和别的样式冲突了,比如这样:

#myui label, #myui input { display:block; }

问题:修改后,模态框里的css样式都没有应用上。比如lable和input没有变成块级标签,导致没有换行
原因:这里 id="dialog-form" 这个div的位置变了,跑到了 id="myui" 这个div的外面了。造成这个情况的原因是,jQuery UI就是这么做的,把 id="dialog-form" 这个div挖出来,出来好之后append到一个位置,而默认位置是 body 标签。
解决方法:知道原因后,修改css的写法也是可以实现的。但是也是有方法按照原来想的那样,让 id="dialog-form" 这个div仍然放在 id="myui" 里面的。在dialog里加上一个 appendTo 参数,指定模态框要添加的位置,之前没有指定就是默认(body):

            dialog = $( "#dialog-form" ).dialog({
                appendTo: '#myui',
                autoOpen: false,
                height: 400,
                width: 350,
                modal: true,
                buttons: {
                    "Create an account": addUser,
                    Cancel: function() {
                        dialog.dialog( "close" );
                    }
                },
                close: function() {
                    form[ 0 ].reset();
                    allFields.removeClass( "ui-state-error" );
                }
            });

实际有2个提交的按钮

在提交表单之前,先要知道,实际这个例子中有2个按钮可以用来提交的。其中一个隐藏了。
写在form里的submit按钮:

            
            

实际位置应该是跑到屏幕外面去了。这里把style属性去掉就能看到了。这个按钮的作用是方便我们用键盘的回车键操作的。
另外jQuery UI帮我们生成的按钮是在 dialog = $( "#dialog-form" ).dialog() 里用buttons属性生成的,这里可以自定义以及添加更多的按钮:

                buttons: {
                    "Create an account": addUser,
                    Cancel: function() {
                        dialog.dialog( "close" );
                    }
                },

另外这里的确认按钮不是submit,而是触发一个addUser进行表单验证的方法。addUser里验证通过后会生成前端的标签,在前端添加一行数据,但是submit提交。

表单无法提交

演示的代码是一个纯前端的实现,如果要提交到后端,那么就是在form标签里加上action属性。然后先把submit按钮的style属性去掉,用submit先提交。
问题:后端收不到发来的请求
原因:前端阻止了submit事件的默认操作,具体就是下面这句

            form = dialog.find( "form" ).on( "submit", function( event ) {
                event.preventDefault();  // 这句的意思就是取消事件的默认操作
                addUser();
            });

解决方法:这里直接把阻止的代码注释掉就好了
现在可以使用回车键进行submit提交了,但是确认按钮并不能提交

问题2:确认按钮不是submit
原因:这个按钮绑定的是addUser,而addUser里也没有submit提交
解决方法:把确认按钮的click绑定为触发form的submit事件,这样这个确认按钮的效果就和submit一样了,而且submit里也是要先执行addUser()进行验证的。把 dialog = $( "#dialog-form" ).dialog() 里用buttons属性改成了下面这样,这个buttons的参数是可支持 Object 和 Array 两种形式,这里我改用了Array的形式:

            buttons: [
                {text: "确认", click: function () {
                        form.submit();
                    }},
                {text: "取消", click: function () {
                        dialog.dialog('close');
                    }
                }
            ],

请求的表单内容为空

现在后端可以收到请求了,但是收到的都是没有值的空的请求。
问题:后端内收到请求,但是请求的值都是空值
原因:前端在发送submit请求前,清空了表单的内容。在 dialog = $( "#dialog-form" ).dialog() 里最后有一个close属性,值是一个方法:

                close: function() {
                    form[ 0 ].reset();
                    allFields.removeClass( "ui-state-error" );
                }

close属性是在对话框关闭的时候要执行的内容,这里面清空了form表单的内容。
具体步骤是,submit事件会首先触发addUser()进行表单验证。addUser()里面会先用 checkLength() 验证长度,然后用 checkRegexp() 进行正则的验证。如果验证失败会返回false组织之后事件的发生。如果验证通过则会先执行关闭模态框的操作:

                    dialog.dialog( "close" );

这里就要关闭模态框了,然后返回true,之后才是执行submit提交的动作。但是关闭模态框的时候,数据就清空了。服务的收到的就是被清空后的空表单发来的请求,并且是在通过了前端的数据验证之后的。
解决方法:应该可以先不关闭模态框,等submit提交之后再关闭。不过实现起来也不方便。表单清空的功能还是有用的,但是只要在下次打开前清空就好了。这里可以用一个open方法替代原来的close方法。
另外一个坑:官网的页面里是有一个create方法的,本来想用这个的。但是发现没有用,然后去源码里找了一下(jquery-ui.js):

$.widget( "ui.dialog", {
    version: "1.12.1",
    options: {
        appendTo: "body",
        autoOpen: true,
        buttons: [],
        classes: {
            "ui-dialog": "ui-corner-all",
            "ui-dialog-titlebar": "ui-corner-all"
        },
        closeOnEscape: true,
        closeText: "Close",
        draggable: true,
        hide: null,
        height: "auto",
        maxHeight: null,
        maxWidth: null,
        minHeight: 150,
        minWidth: 150,
        modal: false,
        position: {
            my: "center",
            at: "center",
            of: window,
            collision: "fit",

            // Ensure the titlebar is always visible
            using: function( pos ) {
                var topOffset = $( this ).css( pos ).offset().top;
                if ( topOffset < 0 ) {
                    $( this ).css( "top", pos.top - topOffset );
                }
            }
        },
        resizable: true,
        show: null,
        title: null,
        width: 300,

        // Callbacks
        beforeClose: null,
        close: null,
        drag: null,
        dragStart: null,
        dragStop: null,
        focus: null,
        open: null,
        resize: null,
        resizeStart: null,
        resizeStop: null
    },

上面的Callbacks应该就是所有的方法了,并没有create。然后才试的open。

优化-调整模态框大小

还是这个生成模态框的函数 dialog = $( "#dialog-form" ).dialog() ,里面的 height 和 width 属性,可以设置模态框的默认大小
问题:这里模态框有可能会出现滚轮
原因:模态框 id="dialog-form" 这个div里有这个样式 overflow: auto ,所以溢出会出现滚动条。
解决方法:把overflow样式覆盖掉应该就可以了,不过根本问题是溢出。我这里造成溢出的标签是form里的input标签。样式是这样的:

input.text { margin-bottom:12px; width:95%; padding: .4em; }

这里我调整了 width 的宽度就好了。

优化-直接隐藏模态框

例子中没有这个情况,但是我用的时候页面加载的时候会首先显示出模态框,等加载完毕后模态框会隐藏掉。
问题:加载页面的时候会有一瞬出现模态框
原因:因为我把js代码的位置放到的最后,所以模态框的标签的代码读完的时候会显示出来,等js代码读取完的时候才会隐藏
解决方法:应该把生成模态框的js主要是 dialog = $( "#dialog-form" ).dialog() 方法提到前面就好了。不过我用了另外一个方法,给我的模态框的div标签加上了这个类:

jquery-ui.css 里,这个类是这样的:

.ui-helper-hidden {
    display: none;
}

就是简单的隐藏掉,试过之后依然可以显示出来。

修改后的版本

替换掉了模板语言的部分,我用的修改后的版本如下:




    
    Title
    
    


请填写要新建的组的名称

用户组列表:

id 群组名 备注
1 测试一 test1
2 测试2 test2
3 测试三 test3

当前标题:jQueryUI模态表单疯狂踩坑
文章转载:http://mswzjz.cn/article/pdipoh.html

其他资讯