1、校验用户是否存在, 是在 校验输入合法后 调用方法,发送Ajax请求。
    2、校验用户已经存在,则需要“保存”按钮不能保存数据,retuen false。
    3、因为 校验用户是否存在的 Ajax 请求只会发一次,如果再次点击“新增”后,输入框里的内容还存在,这时点击保存,则不会在此发送 Ajax 请求校验。所以需要再次点击“新增”按钮时,清空输入框里的内容。

    | <%@ page contentType=”text/html;charset=UTF-8language=”java“ %>
    <%@ taglib prefix=”curi=”http://java.sun.com/jsp/jstl/core“ %>
    <html>
    <head>
    <title>员工信息查询</title>
    <%
    pageContext.setAttribute(“path”,request.getContextPath());
    %>
    </
    head>
    <
    body>
    ${path}<%— /SSM —%>
    <
    a href=”${path}/distinctuser?empName=张三”>chaxun</a>
    <%—新增页—%>
    <
    div class=”modal fade” id=”addEmpMyModal” tabindex=”-1” role=”dialog” aria-labelledby=”myModalLabel”>
    <
    div class=”modal-dialog” role=”document”>
    <
    div class=”modal-content”>
    <
    div class=”modal-header”>
    <
    button type=”button” class=”close” data-dismiss=”modal” aria-label=”Close”><span aria-hidden=”true”>×</span></button>
    <
    h4 class=”modal-title” id=”myModalLabel”>新增</h4>
    </
    div>
    <%—姓名输入框—%>
    <
    div class=”modal-body”>
    <
    form class=”form-horizontal”>
    <
    div class=”form-group”>
    <
    label for=”inputEmpName” class=”col-sm-2 control-label”>姓名</label>
    <
    div class=”col-sm-10”>
    <
    input type=”text” onblur=”testEmpName ()“ name=”empName” class=”form-control” id=”inputEmpName” placeholder=”请输入2-5中文或6-16位英文大小写和数字组合”>
    <
    span class=”help-block”></span>
    </
    div>
    </
    div>
    <%—email输入框—%>
    <
    div class=”form-group”>
    <
    label for=”inputEmail” class=”col-sm-2 control-label”>Email</label>
    <
    div class=”col-sm-10”>
    <
    input type=”email” onblur=”testEmpEmail ()“ name=”email” class=”form-control” id=”inputEmail” placeholder=”Email”>
    <
    span class=”help-block”></span>
    </
    div>
    </
    div>
    <%—性别单选—%>
    <
    div class=”form-group”>
    <
    label class=”col-sm-2 control-label”>性别</label>
    <
    label for=”Emp_gender1” class=”radio-inline”>
    <
    input type=”radio” name=”gender” id=”Emp_gender1” value=”男” checked=”checked”>男
    </
    label>
    <
    label for=”Emp_gender0” class=”radio-inline”>
    <
    input type=”radio” name=”gender” id=”Emp_gender0” value=”男”>女
    </
    label>
    </
    div>
    <%—部门名,下拉列表—%>
    <
    div class=”form-group”>
    <
    label for=”select_Deparements” class=”col-sm-2 control-label”>部门</label>
    <
    div class=”col-sm-10”>
    <%—name=”dId” 获取提交的部门—%>
    <
    select name=”dId” class=”form-control” id=”select_Deparements”**>

    1. </**select**><br /> </**div**><br /> </**div**>
    2. </**form**><br /> </**div**><br /> <**div class="modal-footer"**><br /> <**button id="save_employee_button" type="button" class="btn btn-primary"**>保存</**button**><br /> <**button type="button" class="btn btn-default" data-dismiss="modal"**>取消</**button**><br /> </**div**><br /> </**div**><br /> </**div**><br /></**div**>

    <%—搭建页面—%>
    <div class=”container”>
    <%—标题—%>
    <div class=”row”>
    <div class=”.col-lg-12”>
    <h1>SSM-CRUD</h1>
    </div>
    </div>
    <%—按钮—%>
    <div class=”row”>
    <div class=”col-md-4 col-md-offset-8”><%—列偏移—%>
    <button type=”button” id=”addEmployeeBtn” class=”btn btn-success”>新增</button>
    <button type=”button” id=”deleteEmployee” class=”btn btn-danger”>删除</button>
    </div>
    </div>
    <%—显示表格数据—%>
    <div class=”row “>
    <div class=”col-md-12”>
    <table class=”table table-hover” id=”employees_table”>
    <thead>
    <tr>
    <th>ID</th>
    <th>姓名</th>
    <th>性别</th>
    <th>邮箱</th>
    <th>部门</th>
    <th>操作</th>
    </tr>
    </thead>
    <tbody>

    1. </**tbody**><br /> </**table**><br /> </**div**><br /> </**div**>
    2. <%--分选,点选条--%><br /> <**div id="navigation_pages" class="row" **>
    3. </**div**>
    4. <%--分页,信息条--%><br /> <**div id="page_info" class="col-md-6"**>
    5. </**div**>

    </div>

    <%—引入jQuery—%>
    <script type=”text/javascript” src=”${path}/static/script/jquery-3.6.0.js”></script>
    <%—引入样式—%>
    <link href=”${path}/static/bootstrap-3.4.1-dist/css/bootstrap.min.css” rel=”stylesheet”>
    <script src=”${path}/static/bootstrap-3.4.1-dist/js/bootstrap.min.js”></script>

    <script type=”text/javascript”>
    //全局变量,用于 “保存” 后,来到最后一页。
    var lastPages;

    //1、页面加载完成后,直接发送Ajax请求,获取分页数据。<br />    **$**(**function**(){<br />        //去首页<br />        to_page(1);<br />    });
    
    //Ajax请求、与函数回调<br />    **function **to_page(pageNumber) {<br />        **$**.**ajax**({<br />            **url**:**"${**path**}/list"**,//请求地址<br />            **data**:**"pageNumber="**+pageNumber,//携带参数<br />            **type**:**"GET"**,//请求方式<br />            success:**function **(result){//回调函数<br />                //console.log(result);//输出结果到浏览器 响应 Response<br />                //1、调用函数,信息显示<br />                build_employee_table(result);<br />                //2、显示分页信息<br />                build_page_info(result);<br />                //3、显示分页条<br />                build_page_nav(result);<br />            }<br />        });<br />    }<br />    /*员工信息表格*/<br />    **function **build_employee_table(result){<br />        //清空table,员工信息,跳转页面后刷新数据,而不是复制。<br />        **$**(**"#employees_table tbody"**).empty();<br />        **var **employees = result.extend.pageInfo.**list**;<br />        /**<br />         * employees:要遍历的数据<br />         * index:索引<br />         * item:遍历的,变量名<br />         * */<br />        **$**.each(employees,**function **(index,item){<br />            //alert(item.empName);<br />            **var **empIdTd = **$**(**"<td></td>"**).append(item.empId);/*创建 <td></td> 标签 并添加遍历的内容*/<br />            **var **empNameTd = **$**(**"<td></td>"**).append(item.**empName**);<br />            **var **denderTd = **$**(**"<td></td>"**).append(item.**gender**);<br />            **var **emailTd = **$**(**"<td></td>"**).append(item.**email**);<br />            **var **deptNameTd = **$**(**"<td></td>"**).append(item.department.deptName);
    
            //编辑按钮<br />            **var **editBtn = **$**(**"<button></button>"**).addClass(**"btn btn-primary"**).<br />            append(**$**(**"<span></span>"**).addClass(**"glyphicon glyphicon-pencil btn-xs"**)).<br />            append(**"编辑"**);<br />            //删除按钮<br />            **var **deleteBtn = **$**(**"<button></button>"**).addClass(**"btn btn-danger"**).<br />            append(**$**(**"<span></span>"**).addClass(**"glyphicon glyphicon-trash btn-xs"**)).<br />            append(**"删除"**);<br />            //把编辑、删除两个按钮添加到 同一个单元格里<br />            **var **button = **$**(**"<td></td>"**).append(editBtn).append(**" "**).append(deleteBtn);<br />            /*创建<tr></tr>标签 把遍历到的员工信息,追加到内容追加到里面*/<br />            **$**(**"<tr></tr>"**).append(empIdTd).<br />            append(empNameTd).<br />            append(denderTd).<br />            append(emailTd).<br />            append(deptNameTd).<br />            append(button).<br />            **appendTo**(**"#employees_table tbody"**);//使用选择器,把<tr>插入到 id="#employees_table" 下的 tbody标签中<br />        });<br />    }
    
    //分页信息<br />    **function **build_page_info(result){<br />        //点击跳转页面后,清空分页条信息,重新刷新。<br />        **$**(**"#page_info"**).empty();<br />        **$**(**"#page_info"**).append(**"当前第" **+ result.extend.pageInfo.pageNum +<br />            **"页,共" **+ result.extend.pageInfo.pages +<br />            **"页,共" **+ result.extend.pageInfo.**total **+ **"条记录"**);<br />        /**<br />         * result.extend.pageInfo.pages + 1:总页码 +1,大于总页码,来到最后一页<br />         * 赋值给上面的,全局变量,用于 “保存” 后,来到最后一页。<br />         * */<br />        **lastPages **= result.extend.pageInfo.pages+1;<br />    }
    
    //解析,分页条<br />    **function **build_page_nav(result){<br />        //点击跳转页面后,清空分页条,重新刷新。<br />        **$**(**"#navigation_pages"**).empty();
    
        //<ul></ul> 标签<br />        **var **divUl = **$**(**"<ul></ul>"**).addClass(**"pagination"**);
    
        //首页<br />        **var **firstPage = **$**(**"<li></li>"**).append(**$**(**"<a></a>"**).append(**"首页"**));
    
        //上一页,<br />        **var **prePage   = **$**(**"<li></li>"**).append(**$**(**"<a></a>"**).attr(**"href"**,**"#"**).attr(**"aria-label"**,**"Previous"**).<br />        append(**$**(**"<span></span>"**).attr(**"aria-hidden"**,**"true"**).append(**"&laquo;"**)));
    
        //判断没有"上一页"时,"首页"、上一页"禁用,有则不禁用。<br />        **if **(result.extend.pageInfo.hasPreviousPage == **false**){<br />            firstPage.addClass(**"disabled"**);<br />            prePage.addClass(**"disabled"**);//disabled 是 BootStrap 的选中禁用状态<br />        }**else **{<br />            //为 "首页" 添加单击事件,使它可以点击跳转<br />            firstPage.click(**function **() {<br />                to_page(1);<br />            });
    
            //为 "上一页" 添加单击事件,使他们可以点击跳转<br />            prePage.click(**function **() {<br />                to_page(result.extend.pageInfo.pageNum-1);<br />            });<br />        }
    
        //添加到 <ul></ul>中<br />        divUl.append(firstPage).append(prePage);
    
        //遍历显示分页条,页面的连续页码1、2、3、、5、...<br />        **$**.each(result.extend.pageInfo.navigatepageNums,**function **(index,item){<br />            //显示页面的连续页码1、2、3、、5、...<br />            **var **navpage   = **$**(**"<li></li>"**).append(**$**(**"<a></a>"**).attr(**"href"**,**"#"**).append(item));<br />            //判断是当前页,就添加高亮<br />            **if **(result.extend.pageInfo.pageNum == item) {<br />                navpage.addClass(**"active"**);//active 是 BootStrap 的选中高亮状态<br />            }<br />            //为显示页面的连续页码1、2、3、、5、...添加单击事件<br />            navpage.click(**function **() {<br />                //调用ajax请求,ajax请求会调用员工信息、分页信息、分页条<br />                //其中,员工信息、分页条,会添加.empty();清空数据后,再遍历,达到刷新信息的目的。<br />                to_page(item);<br />            });<br />            divUl.append(navpage);//添加到 <ul></ul>中<br />        });<br />        //下一页<br />        **var **nextPage  = **$**(**"<li></li>"**).append(**$**(**"<a></a>"**).attr(**"href"**,**"#"**).append(**"&raquo;"**));<br />        //末页<br />        **var **lastPage  = **$**(**"<li></li>"**).append(**$**(**"<a></a>"**).append(**"末页"**));<br />        //添加到 <ul></ul>中<br />        divUl.append(nextPage).append(lastPage);<br />        //判断没有"下一页"时,"末页"、下一页"禁用,有则不禁用。<br />        **if **(result.extend.pageInfo.hasNextPage == **false**){<br />            nextPage.addClass(**"disabled"**);<br />            lastPage.addClass(**"disabled"**);//disabled 是 BootStrap 的选中禁用状态<br />        } **else **{<br />            //为 "下一页" 添加单击事件,使他们可以点击跳转<br />            nextPage.click(**function **() {<br />                to_page(result.extend.pageInfo.pageNum+1);<br />            });<br />            //为 "末页" 添加单击事件,使它可以点击跳转<br />            lastPage.click(**function **() {<br />                to_page(result.extend.pageInfo.pages);<br />            });<br />        }
    
        //最后添加到,分页条的 div 中。<br />        **$**(**"<nav></nav>"**).attr(**"aria-label"**,**"Page navigation"**).append(divUl).**appendTo**(**$**(**"#navigation_pages"**));
    
    }
    
    //"新增按钮",绑定 “新增”窗口的点击事件<br />    **$**(**"#addEmployeeBtn"**).click(**function **() {<br />        //每次点击 “新增”后 按钮先清空“新增”窗口输入框里的内容<br />        //reset() 是 DOM 对象的方法。$("#addEmpMyModal form")[0] 获取 DOM对象<br />        **$**(**"#addEmpMyModal form"**)[0].reset();
    
        //发送Ajax请求,查出部门信息。显示在下拉列表中<br />        getDepartement();<br />        //弹出"新增 "窗口,backdrop:"static" 背景<br />        **$**(**"#addEmpMyModal"**).**modal**({<br />            **backdrop**:**"static"<br />        **});<br />    });
    
    **function **getDepartement(){<br />        **$**.**ajax**({<br />            **url**:**"${**path**}/departement"**,<br />            **type**:**"GET"**,<br />            success:**function **(result){<br />                //console.log(result)<br />                /**<br />                 * this 代表,正在遍历的对象,例如 list":[{"deptId":1,"deptName":"工程部"},{"deptId":2,"deptName":"生产部"},<br />                 * {"deptId":3,"deptName":"外交部"},{"deptId":4,"deptName":"财务部"}]<br />                 *<br />                 * attr("value",this.deptId) :为 <open> 添加value 属性,值为 this.deptId<br />                 * append(this.deptName) :为 <open> 中插入文本,this.deptName 当前对象的部门名<br />                 * appendTo($("#inputDeparements"):把<open></open> 插入到 id=“inputDeparements” 标签中<br />                 */<br />                **$**.each(result.extend.pageInfo.**list**,**function **(){<br />                    **$**(**"<option></option>"**).attr(**"value"**,**this**.deptId).append(**this**.deptName).**appendTo**(**$**(**"#select_Deparements"**));<br />                });
    
            }<br />        });<br />    }
    
    //=========================保存功能的单击事件==========================<br />    **$**(**"#save_employee_button"**).click(**function **() {<br />        //校验:validate_add_form() 不为true<br />        **if **(!(testEmpName())&#124;!(testEmpEmail())) {<br />            **return false**;<br />        }
    
        //判断 “保存” 按钮的 ajax_val 属性的值,值为 error 禁用保存跳转<br />        **if **(**$**(**"this"**).attr(**"ajax_val"**) == **"error"**) {<br />            **return false**;<br />        }
    
        //1、模态框中填写的表单数据集提交给服务器保存<br />        //alert($("#addEmpMyModal form").serialize());<br />        //2、发送 Ajax请求保存数据<br />        **$**.**ajax**({<br />            **url**:**"${**path**}/save"**,<br />            **type**:**"POST"**,<br />            //$("#addEmpMyModal form").serialize():获取模态框下 form 表单的数据,并序列化为字符串,以key=value形式<br />            **data**:**$**(**"#addEmpMyModal form"**).serialize(),//data:携带参数<br />            success:**function **(result) {<br />                alert(result.msg);<br />                //员工保存成功后<br />                //1、关闭模态框,BootStarp 模态框中的方法<br />                **$**(**"#addEmpMyModal"**).**modal**(**"hide"**);<br />                //2、来到最后一页,显示刚才保存的数据<br />                /**<br />                 * 发送 Ajax 请求显示最后一页<br />                 * 调用to_page(pageNumber)方法。传一个大于总页码的数,<br />                 * 利用 分页条插件的 设置,当大于总页码时候,来到最后一页。<br />                 */<br />                to_page(**lastPages**);<br />            }<br />        });
    
    });
    
    **function **testEmpName (){<br />        //获取,新增 模态框输入的 员工名<br />        **var **empName = **$**(**"#inputEmpName"**).val();
    
        /**<br />         * 小写a-z,大写A-Z,0-9、_、-<br />         * {6,16}:6-16位<br />         * 或<br />         * ^[\\u2E80-\\u9FFF]{2,5}):2-5个中文字符<br />         */<br />        **var **testName = /(^[a**-**zA**-**Z0**-**9_-]{6,16}$)&#124;(^[\\u2E80**-**\\u9FFF]{2,5})/;<br />        **if **(!testName.test(empName)) {<br />            //校验失败<br />            show_validate_msg(**"#inputEmpName"**,**"error"**,**"请输入2-5中文或6-16位英文大小写和数字组合"**);<br />            //alert("请输入2-5中文或6-16位英文大小写和数字组合")<br />            **return false**;//不跳转<br />        }**else **{<br />            //校验成功<br />            show_validate_msg(**"#inputEmpName"**,**"success"**,**""**);<br />            //校验成功后,调用方法校验用户名是否已经存在。return true;//继续执行,跳转<br />            test_empName_distinct ();<br />            **return true**;<br />        }<br />    }
    
    **function **testEmpEmail (){<br />        //===========校验邮箱==============<br />        //获取,新增 模态框输入的 Email<br />        **var **email = **$**(**"#inputEmail"**).val();<br />        **var **testEmail = /^([a**-**z0**-**9_\\.-]+)@([\\da**-**z\\.-]+)\\.([a**-**z\\.]{2,6})$/;<br />        **if **(!testEmail.test(email)) {<br />            //alert("请输入正确的email!")<br />            //校验失败<br />            show_validate_msg(**"#inputEmail"**,**"error"**,**"请输入正确的email!"**);<br />            **return false**;//不执行,表示不跳转<br />        }**else **{<br />            //校验成功<br />            show_validate_msg(**"#inputEmail"**,**"success"**,**""**)
    
            **return true**;//跳转<br />        }
    
    }
    
    //Ajax 校验用户是否重复,change 内容改变事件  $("#inputEmpName").change(function ()function test_empName_distinct()<br />    **function **test_empName_distinct (){//testEmpName ()  test_empName_distinct()<br />        //获取当前正在输入的,输入框中的内容<br />        **var **empName = **$**(**"#inputEmpName"**).val();<br />        //发送Ajax请求校验用户名是否可用<br />        **$**.**ajax**({<br />            **url**:**"${**path**}/distinctuser"**,//EmployeeController,中的校验方法<br />            **data**:**"empName="**+empName,//携带获取到的value<br />            **type**:**"POST"**,<br />            success:**function **(result) {<br />                //alert(result.code);<br />                **if **(result.**code**==100){//Msg类中的,成功码100<br />                    //校验用户名可用后,调用方法,为用户输入框下显示 "用户名可用"。<br />                    show_validate_msg(**"#inputEmpName"**,**"success"**,**"用户名可用"**);<br />                    //用户名可用后,为 “保存:按钮添加 一个 ajax_val 属性 值为 success。<br />                    //为点击保存时候获取 ajax_val 的值,为 success “保存”按钮可用<br />                    **$**(**"#save_employee_button"**).attr(**"ajax_val"**,**"success"**);<br />                } **else **{<br />                    //校验用户名不可用后,调用方法,为用户输入框下显示 "用户名已存在"。<br />                    show_validate_msg(**"#inputEmpName"**,**"error"**,**"用户名已存在"**);<br />                    //用户名不可用后,为 “保存:按钮添加 一个 ajax_val 属性 值为 success。<br />                    //为了点击保存时候获取 ajax_val 的值,为 "error" “保存”按钮不可用<br />                    **$**(**"#save_employee_button"**).attr(**"ajax_val"**,**"error"**);<br />                }<br />            }<br />        });<br />    }
    
    /**<br />     * **@param **element:接收选择的元素<br />     * **@param **status:状态<br />     * **@param **msg:提示信息<br />     */<br />   **function **show_validate_msg(element,status,msg){<br />        **if **(**"success" **== status){//校验成功<br />            //校验通过后,先删除 has-error 不成功的样式<br />            //防止 第一次输入校验失败,输入框是 红色,第二次校验成功后,还是红色。<br />            **$**(element).parent().removeClass(**"has-error"**);<br />            //获取标签元素,的父元素,并添加绿色样式。表示输入框校验成功,显示绿色。<br />            **$**(element).parent().addClass(**"has-success"**);<br />            //校验成功,清空输入框下的 提示信息<br />            **$**(element).next(**"span"**).text(msg);<br />        }**else if**(**"error" **== status){<br />            //校验失败后,先删除 has-success 成功的样式,下面在添加失败的样式<br />            //防止 第二次输入校验失败,输入框本该是 红色,结果还是显示,第一次校验瑟绿色框<br />            **$**(element).parent().removeClass(**"has-success"**);<br />            //获取标签元素,的父元素,并添加绿色样式。表示输入框校验失败,显示红色。<br />            **$**(element).parent().addClass(**"has-error"**);<br />            //校验失败,输入框下的 提示信息<br />            **$**(element).next(**"span"**).text(msg);<br />        }<br />    }
    

    </script>
    </body>
    </html>

    | | —- |