想套用一下前端的組件寫一個表單驗證的頁面,因而試了一下jQuery UIcss
首先把官網的例子貼上:html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>jQuery UI Dialog - Modal form</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <link rel="stylesheet" href="/resources/demos/style.css"> <style> label, input { display:block; } input.text { margin-bottom:12px; width:95%; padding: .4em; } fieldset { padding:0; border:0; margin-top:25px; } h1 { font-size: 1.2em; margin: .6em 0; } div#users-contain { width: 350px; margin: 20px 0; } div#users-contain table { margin: 1em 0; border-collapse: collapse; width: 100%; } div#users-contain table td, div#users-contain table th { border: 1px solid #eee; padding: .6em 10px; text-align: left; } .ui-dialog .ui-state-error { padding: .3em; } .validateTips { border: 1px solid transparent; padding: 0.3em; } </style> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $( function() { var dialog, form, // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29 emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/, name = $( "#name" ), email = $( "#email" ), password = $( "#password" ), allFields = $( [] ).add( name ).add( email ).add( password ), tips = $( ".validateTips" ); function updateTips( t ) { tips .text( t ) .addClass( "ui-state-highlight" ); setTimeout(function() { tips.removeClass( "ui-state-highlight", 1500 ); }, 500 ); } function checkLength( o, n, min, max ) { if ( o.val().length > max || o.val().length < min ) { o.addClass( "ui-state-error" ); updateTips( "Length of " + n + " must be between " + min + " and " + max + "." ); return false; } else { return true; } } function checkRegexp( o, regexp, n ) { if ( !( regexp.test( o.val() ) ) ) { o.addClass( "ui-state-error" ); updateTips( n ); return false; } else { return true; } } function addUser() { var valid = true; allFields.removeClass( "ui-state-error" ); valid = valid && checkLength( name, "username", 3, 16 ); valid = valid && checkLength( email, "email", 6, 80 ); valid = valid && checkLength( password, "password", 5, 16 ); valid = valid && checkRegexp( name, /^[a-z]([0-9a-z_\s])+$/i, "Username may consist of a-z, 0-9, underscores, spaces and must begin with a letter." ); valid = valid && checkRegexp( email, emailRegex, "eg. ui@jquery.com" ); valid = valid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" ); if ( valid ) { $( "#users tbody" ).append( "<tr>" + "<td>" + name.val() + "</td>" + "<td>" + email.val() + "</td>" + "<td>" + password.val() + "</td>" + "</tr>" ); dialog.dialog( "close" ); } return valid; } dialog = $( "#dialog-form" ).dialog({ 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" ); } }); form = dialog.find( "form" ).on( "submit", function( event ) { event.preventDefault(); addUser(); }); $( "#create-user" ).button().on( "click", function() { dialog.dialog( "open" ); }); }); </script> </head> <body> <div id="dialog-form" title="Create new user"> <p class="validateTips">All form fields are required.</p> <form> <fieldset> <label for="name">Name</label> <input type="text" name="name" id="name" value="Jane Smith" class="text ui-widget-content ui-corner-all"> <label for="email">Email</label> <input type="text" name="email" id="email" value="jane@smith.com" class="text ui-widget-content ui-corner-all"> <label for="password">Password</label> <input type="password" name="password" id="password" value="xxxxxxx" class="text ui-widget-content ui-corner-all"> <!-- Allow form submission with keyboard without duplicating the dialog button --> <input type="submit" tabindex="-1" style="position:absolute; top:-1000px"> </fieldset> </form> </div> <div id="users-contain" class="ui-widget"> <h1>Existing Users:</h1> <table id="users" class="ui-widget ui-widget-content"> <thead> <tr class="ui-widget-header "> <th>Name</th> <th>Email</th> <th>Password</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>john.doe@example.com</td> <td>johndoe1</td> </tr> </tbody> </table> </div> <button id="create-user">Create new user</button> </body> </html>
試了一下,一切都很美好。前端
首先看到CSS寫的很粗,好比第一條:jquery
label, input { display:block; }
直接就定義了全部label和input標籤的樣式。看着body裏是2個DIV,因而想把2個div外面再包一層div,像下面這樣:web
<body> <div id="myui"> <div id="dialog-form" title="Create new user"></div> <div id="users-contain" class="ui-widget"></div> </div> </body>
而後全部的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):app
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個按鈕能夠用來提交的。其中一個隱藏了。
寫在form裏的submit按鈕:ide
<!-- Allow form submission with keyboard without duplicating the dialog button --> <input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
實際位置應該是跑到屏幕外面去了。這裏把style屬性去掉就能看到了。這個按鈕的做用是方便咱們用鍵盤的回車鍵操做的。
另外jQuery UI幫咱們生成的按鈕是在 dialog = $( "#dialog-form" ).dialog()
裏用buttons屬性生成的,這裏能夠自定義以及添加更多的按鈕:函數
buttons: { "Create an account": addUser, Cancel: function() { dialog.dialog( "close" ); } },
另外這裏的確認按鈕不是submit,而是觸發一個addUser進行表單驗證的方法。addUser裏驗證經過後會生成前端的標籤,在前端添加一行數據,可是submit提交。post
演示的代碼是一個純前端的實現,若是要提交到後端,那麼就是在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標籤加上了這個類:
<div class="ui-helper-hidden" id="dialog-form" title="Create new user">
jquery-ui.css 裏,這個類是這樣的:
.ui-helper-hidden { display: none; }
就是簡單的隱藏掉,試過以後依然能夠顯示出來。
替換掉了模板語言的部分,我用的修改後的版本以下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <style> #jqui-dialog label, #jqui-dialog input { display:block; } #jqui-dialog form input { margin-bottom:12px; width: 92%; padding: .4em; } #jqui-dialog fieldset { padding:0; border:0; margin-top:25px; } #jqui-dialog h1 { font-size: 1.2em; margin: .6em 0; } #jqui-dialog div#users-contain { width: 350px; margin: 20px 0; } #jqui-dialog div#users-contain table { margin: 1em 0; border-collapse: collapse; width: 100%; } #jqui-dialog div#users-contain table td, #jqui-dialog div#users-contain table th { border: 1px solid #eee; padding: .6em 10px; text-align: left; } #jqui-dialog .ui-dialog .ui-state-error { padding: .3em; } #jqui-dialog .validateTips { border: 1px solid transparent; padding: 0.3em; } </style> </head> <body> <div id="jqui-dialog"> <div class="ui-helper-hidden" id="dialog-form" title="添加新用戶組"> <p class="validateTips">請填寫要新建的組的名稱</p> <form action="." method="post"> <fieldset> <label for="group_name">組名稱</label> <input type="text" name="group_name" id="group_name" class="text ui-widget-content ui-corner-all"> <label for="comments">備註</label> <input type="text" name="comments" id="comments" class="text ui-widget-content ui-corner-all"> <!-- Allow form submission with keyboard without duplicating the dialog button --> <input type="submit" tabindex="-1" style="position:absolute; top:-1000px"> </fieldset> </form> </div> <div id="users-contain" class="ui-widget"> <h1>用戶組列表:</h1> <button id="create-user">添加新用戶組</button> <table id="users" class="ui-widget ui-widget-content"> <thead> <tr class="ui-widget-header "> <th>id</th> <th>羣組名</th> <th>備註</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>測試一</td> <td>test1</td> </tr> <tr> <td>2</td> <td>測試2</td> <td>test2</td> </tr> <tr> <td>3</td> <td>測試三</td> <td>test3</td> </tr> </tbody> </table> </div> </div> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $(function () { var dialog, form, group_name = $('#group_name'), comments = $('#comments'), allFields = $([]).add(group_name).add(comments), tips_msg = null, tips = $('.validateTips'); // 長度驗證 function checkLength(o, n, min, max) { if (o.val().length > max || o.val().length < min) { o.addClass("ui-state-error"); updateTips(n + "的長度必須在" + min + "與" + max + "之間。"); return false } else { return true } } // 正則驗證 function checkRegexp(o, regexp, n) { if (!(regexp.test(o.val()))) { o.addClass("ui-state-error"); updateTips(n); return false } else { return true } } // 顯示錯誤信息 function updateTips(t) { tips_msg = tips_msg || tips.text(); tips.text(t).addClass("ui-state-highlight"); setTimeout(function () { tips.removeClass("ui-state-highlight", 1500); }, 500); } function addUser() { var valid = true; allFields.removeClass("ui-state-error"); valid = valid && checkLength(group_name, "組名稱", 3, 32); valid = valid && checkLength(comments, "備註", 0, 64); valid = valid && checkRegexp(group_name, /^[^0-9]/, "組名稱不能以數字開頭"); if (valid) { $( "#users tbody" ).append( "<tr>" + "<td>" + 'x' + "</td>" + "<td>" + group_name.val() + "</td>" + "<td>" + comments.val() + "</td>" + "</tr>" ); dialog.dialog('close'); } return valid } dialog = $("#dialog-form").dialog({ appendTo: '#jqui-dialog', autoOpen: false, height: 400, width: 350, modal: true, buttons: [ {text: "提交", click: function () { form.submit(); }}, {text: "取消", click: function () { dialog.dialog('close'); } } ], open: function() { form[ 0 ].reset(); allFields.removeClass( "ui-state-error" ); tips_msg && tips.text(tips_msg); } }); form = dialog.find("form").on("submit", function(event) { event.preventDefault(); // 阻止默認操做,須要提交到後端的時候註釋掉這句 return addUser(); // 返回驗證的結果,若是爲false,會阻止submit提交 }); $("#create-user").button().on("click", function() { dialog.dialog( "open" ); }); }) </script> </body> </html>