Code Monkey home page Code Monkey logo

nice-validator's People

Contributors

bitdeli-chef avatar gitter-badger avatar larry4xie avatar niceue avatar peterdavehello avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nice-validator's Issues

当isValid方法传入回调时,就返回jQuery对象维持链式调用

在之前版本中,如果表单中没有远程验证,可以直接使用$(“#form”).isValid()来判断表单是否验证通过。但是,如果表单中有远程验证,就必须使用回调方式了。

如果是回调方式,就维持jQuery对象链

example:

$('#formId').isValid(function(v){
    console.log(v ? '表单验证通过' : '表单验证不通过');
}).find("#email").isValid(function(v){
    console.log(v ? '邮箱验证通过' : '邮箱验证不通过');
});

FAQ: 详解主题机制

所谓主题,是通过配置表单的class、消息模板以及其他一些参数实现的不同展现效果。
有了主题,可以帮助简化很多UI方面的配置,也可以作为一些特殊的配置存在。
关于参数的更多了解,参见参数配置

nice Validator 的主题具有以下特点:
  1. 简单,js配置,stylus生成样式,少量代码便可以配置出新的主题
  2. 独立,不同表单可以应用不同主题
  3. 自由,除了用于配置主题的msg开头的参数,其他大部分参数也都可以配置到主题中
  4. 灵活,主题配置本质上是在传参,优先级高于全局配置,但是又会被调用时的传参覆盖

准备工作

  1. 你需要安装Node.js环境,并且在validator目录执行npm install命令安装依赖
  2. 你需要知道Stylus的语法,很简单的,一旦你学会Stylus,你以后写样式的时候肯定会离不开它!

你说你不想花时间来学习Stylus?
那好吧,硬写css也是能搞定的,你可以省略这一步直接说:我已经准备好了!Ready? Go!

编写主题

所有主题配置文件放置在src/themes目录,然后通过src/jquery.validator.styl文件导入,编译该文件就得到根目录下的jquery.validator.css文件。
该文件默认代码如下:

@import "themes/base";

/*********************
 * Themes
 *********************/
@import "themes/default";
@import "themes/simple";
@import "themes/yellow";

themes/simple的styl文件代码如下:

/* theme: simple */
.n-simple {
    .msg-wrap {
        .n-icon {
            background-image: url(images/validator_simple.png);
        }
    }
    .n-left, .n-right {
        margin-top: 5px;
    }
    .n-bottom .msg-wrap {
        margin-top: 3px;
    }
    .n-tip {
        .n-icon {display:none;}
    }
}

别小看这一点css代码哦!它可是包含了上下左右四个方向的消息,原理就是.n-position中的position是哪个方向,消息就会自动显示在输入框的周围哪个位置。

`.n-right`会使消息显示在输入框右边;  
`.n-bottom`会使消息显示在输入框下边;  
`.n-top`会使消息显示在输入框上边;  
`.n-left`会使消息显示在输入框左边;  

怎么样是不是很简单?
再来看下js配置文件中的代码吧:

$.validator.setTheme({
    'simple_right': {
        formClass: 'n-simple',
        msgClass: 'n-right'
    },
    'simple_bottom': {
        formClass: 'n-simple',
        msgClass: 'n-bottom'
    }
});

其中的formClass是用于控制该主题css的命名空间,会自动添加到初始化后的表单上面。msgClass是控制每条消息方向的类。也就是说这个参数四选一,不用你起名字了。
当你写完上面那段样式后,就可以配置出同一款主题的4个方向的样式了。上面js配置中simple_right和simple_bottom是用于调用的时候传递的主题名字。

最后,附上自动生成的msg-box的DOM结构,你在写样式的时候也可以利用谷歌或者火狐的开发者工具查看,会更直观:

<span class="msg-box n-right" style="" data-for="user[name]">
    <span class="msg-wrap n-error" role="alert">
        <span class="n-icon"></span>
        <span class="n-msg">不能为空</span>
    </span>
</span>

checkbox以及radio的智能消息位置不准

修正后, 消息可以自动添加到最后面,但是任然不排除由于结构的影响,导致消息的位置计算错误。
例如:

<label class="form-label">兴趣:</label>
<label><input type="checkbox" name="interest" data-rule="checked[2~]">看书</label> &nbsp;
<label><input type="checkbox" name="interest">上网</label> &nbsp;
<label><input type="checkbox" name="interest">睡觉</label> &nbsp;
<label><input type="checkbox" name="interest">运动</label> &nbsp;
<label><input type="checkbox" name="interest">发呆</label>

以上结构,消息可以自动添加到最后面,如果智能消息位置不符合预期,也可以自己定义一个消息占位,例如:

<span class="msg-box n-right" data-for="interest"></span>

最后面的span.msg-box就是一个消息占位,.msg-box和data-for都是必须的

优化:支持完全自定义消息的DOM结构

消息的结构,消息的样式,消息的显示方式。

0.5.0版本作了以下优化:

  1. 去掉了msgTemplate这个用处不大的参数
  2. 增加参数msgWrapper,用于设置消息容器的标签
  3. 增加参数msgMaker,用于完全自定义消息的结构

看下面的例子:

$('#demo').validator({
    fields: {
        'user[name]': 'required;username'
        ,'user[pwd]': 'required;password'
    },
    msgWrapper: 'div',
    msgMaker: function(opt){
        return '<span class="'+ opt.type +'">' + opt.msg + '</span>';
    }
});

最后自动生成的消息为:

<div class="msg-box n-right" for="user[name]">
    <span class="n-error">不能为空</span>
</div>

msgMaker方法的参数opt包含以下选项:

  • type:消息类型(可能的值为:error / ok / tip / loading)
  • cls: 即msgClass参数的值
  • style: 即msgStyle参数的值
  • icon: 即msgIcon参数的值
  • arrow: 即msgArrow参数的值
  • show: 即msgShow参数的值
  • hide: 即msgHide参数的值

增加msgHandler、msgShow、msgHide参数,去掉showError参数

1、通过msgHandler回调,错误消息将完全交给你去自由控制,你可以决定消息的显示位置、样式以及显示方式(弹出还是固定位置)

2、去掉effect参数,取而代之的是msgShow和msgHide两个参数,用来控制消息的显示和隐藏之前干的事情,例如:搞点动画效果

注意
如果传了msgHandler,不论是一个function还是true,验证系统将停止自动显示消息。利用这个特性,可以实现两个目的:
1、msgHandler: true 可以实现不显示所有消息
2、msgHandler: function(){} 可以把消息控制权完全交给你

与Bootstrap 3集成时,验证消息显示位置不正确

在与Bootstrap 3.0.0 RC2集成时,验证信息显示位置如下图所示:

image

javascript:

$(function() {
    $('#registerForm').validator({
        theme : 'simple_right',
        fields : {
            'email' : 'required;email;remote[check/email]',
            'username' : 'required;username;remote[check/username]',
            'password' : 'required;password'
        }
    });
});

html:

<div class="container">
    <form id="registerForm" class="form-horizontal" action="" method="POST">
        <fieldset>
            <legend>注册</legend>
            <div class="form-group">
                <label for="inputEmail" class="col-lg-2 control-label">电子邮箱</label>
                <div class="col-lg-4">
                    <input name="email" type="text" class="form-control" id="inputEmail" placeholder="电子邮箱">
                </div>
            </div>
            <div class="form-group">
                <label for="inputUsername" class="col-lg-2 control-label">用户名</label>
                <div class="col-lg-4">
                    <input name="username" type="text" class="form-control" id="inputUsername" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label for="inputPassword" class="col-lg-2 control-label">密码</label>
                <div class="col-lg-4">
                    <input name="password" type="password" class="form-control" id="inputPassword" placeholder="密码">
                </div>
            </div>
            <div class="form-group">
                <div class="col-lg-offset-2 col-lg-10">
                    <button type="submit" class="btn btn-primary">注册</button>
                </div>
            </div>
        </fieldset>
    </form>
</div>

优化tip消息的体验

  1. 提交表单
  2. 第一个错误的输入框提示错误消息,并且获的焦点
  3. 如果表单验证不通过,触发invalid回调和invalid.form事件
  4. 这时候虽然出错的输入框已经获得焦点,但是当再次点击输入框时,如果有tip则优先提示tip

优化:使用ID标识字段的时候单独创建消息容器

HTML:

<form id="demo_142" action="results.php" method="post">
<fieldset>
    <p><input name="aaa[]" id="aaa1"></p>
    <p><input name="aaa[]" id="aaa2"></p>
</fieldset>
<button type="submit">提交</button>
</form>

以上两个字段虽然name相同,但是拥有不同id,所以分别创建消息容器

多次动态插入input 同一name input tips会出现问题

<input id="d_name_1" name="textfield" type="text" aria-required="true" class="" aria-invalid="false" data-inputstatus="ok" readonly="readonly">

<input id="d_name_2" name="textfield" type="text" aria-required="true" class="n-invalid" aria-invalid="true" data-inputstatus="error">

以上两个均为append插入至DOM的,不过后面的 _2 input可以进行校验,不过他在校验后,显示的结果显示在了 _1显示的位置

尝试解决时发现:

假如以 input的 id作为name 只有 id_1 的input ok,可以正常显示tips,id_2 处于没有反应的状态 ,将name_2 的那么 改为 name_1后 可以显示,但是显示在 id_1的input后面tips

原先出现问题是插入的代码为 
<input  data-rule="required;"  type="text" name="d_name" id="d_name_'+ d.sid+'" />
经修改:
<input  data-rule="required;"  type="text" name="d_name_'+ d.sid+'" id="d_name_'+ d.sid+'" />

优化默认样式

  1. 减少选择器层级,便于主题覆盖
  2. 默认只提供一种主题,其他主题额外提供
  3. 增强样式兼容性

规则match[name]实现双向验证

以下例子:

<fieldset>
    <label class="form-label">密码:</label>
    <input name="pwd" data-rule="密码:required;"><br>
    <label class="form-label">确认密码:</label>
    <input name="againPwd" data-rule="确认密码: required;match[pwd]">
</fieldset>

目的:验证“againPwd”字段是否与“pwd”字段相同
需求:pwd字段验证通过后,如果againPwd字段的值不为空,还要接着触发againPwd字段验证

添加.holdSubmit()方法,用来防止表单重复提交

$("#myForm").validator({
    valid: function(form){
        var me = this;
        // 提交表单之前,hold住表单,防止重复提交
        me.holdSubmit();

        $.ajax({
            url: "xxx.php",
            data: $(form).serialize(),
            type: "POST",
            success: function(){
                // 提交表单成功后,释放hold
                me.holdSubmit(false);
            }
        });
    }
});

消息占位的属性data-for改为for

<input name="fieldname" id="fieldid" data-rule="required">

以前版本中要实现消息占位需要这样:

<span class="msg-box n-right" data-for="fieldname"></span>

0.5.0后更加简单:

<span class="msg-box" for="fieldid"></span>

0.5.0后,for属性的表现更像是一个label,对应的是input的id

远程验证GET方式无效

从0.2.1升级到0.4.0后,之前正常的remote规则失效,使用默认的POST方式能正常验证,替换成GET方式不会触发任何验证。

js代码如下:

fields : {
    'email' : 'required;email;remote(GET:/api/accounts/checking/email)'
},

html代码如下:

<input id="email" name="email" type="text" class="form-control" autofocus="autofocus">

通过启用调试模式,在控制台输出:

0: api -> true

优化target参数的作用

  1. target为表单元素(input、select、textarea)时,消息显示位置以该元素为准
  2. target为其他元素时则消息显示到该元素内

bug:如果界面验证中,其中一项验证规则为remote:[]而对应项本次又未进行修改,并未出发验证,直接点击提交表单时,首次点击仅会触发验证,而不会发出事件valid.form

bug:如果界面验证中,其中一项验证规则为remote:[]而对应项本次又未进行修改,并未出发验证,直接点击提交表单时,首次点击仅会触发验证,而不会发出事件valid.form

界面js与元素大致如下:
$('#organizationForm').on('valid.form', function(){
alert('valid.form');
//ajax提交
$(this).ajaxSubmit({
url:"${contextPath}/organization/updateOrganization.action",
success: function(data) {
if(data){
DialogUtils.tip("更新组织成功");
parent.DialogUtils.closeDialogById("updateOrganization");
}
}
});
});

....

名称:

<form:input path="name" cssClass="text"
data-rule="名称:required;"
data-tip="必填"/>

别名:

<form:input path="alias" cssClass="text"/>



编号


<form:input path="code" cssClass="text"
data-rule="编号:required;digits;remote[get:${contextPath }/organization/organizationCodeIsExist.action, id, code]"
data-tip="不能重复的数字"/>

组织类型:

<form:select path="type" cssClass="select" >
--- 请选择 ---
<form:options items="${OrganizationTypes }"/>
/form:select


....

动态插入input会引起未知错误

以下为堆栈日志

<error>
d_identifyCardNumber_2 39:377
<input id="d_identifyCardNumber_2" class=​"checkidcard n-invalid" name=​"textfield2" data-rule=​"required;​idcard;​" type=​"text" aria-invalid=​"true" data-inputstatus=​"error">​
 39:365
d_identifyCardNumber_2 39:377
<input id="d_identifyCardNumber_2" class=​"checkidcard n-invalid" name=​"textfield2" data-rule=​"required;​idcard;​" type=​"text" aria-invalid=​"true" data-inputstatus=​"error">​
 39:365
<error>
<input id="d_identifyCardNumber_2" class=​"checkidcard" name=​"textfield2" data-rule=​"required;​idcard;​" type=​"text" aria-invalid=​"false" data-inputstatus=​"ok">​
 jquery.validator.js:5
0: required -> true jquery.validator.js:5
1: idcard -> true jquery.validator.js:5
<input id="d_phoneNumber_2" name=​"textfield14" data-rule=​"required;​mtelc1;​" type=​"text" class=​"n-invalid" aria-invalid=​"true" data-inputstatus=​"error">​
 jquery.validator.js:5
0: required -> 不能为空 jquery.validator.js:5
2
<error>
jQuery.event.dispatch
elemData.handle
jQuery.event.trigger
(anonymous function)
jQuery.extend.each
jQuery.fn.jQuery.each
jQuery.fn.extend.trigger
(anonymous function)
jQuery.event.dispatch
elemData.handle
jQuery.event.trigger
(anonymous function)
jQuery.extend.each
jQuery.fn.jQuery.each

报错的部分使用的是DOM插入的

 '<div class="bd_table"> '+
 '  <table cellspacing="1" cellpadding="0" border="0" width="100%" class="tableInputst"> '+
 '    <tr> '+
 '      <td class="bd_td_e" width="200">姓名</td> '+
 '      <td><input id="d_name_'+ d.sid+'" name="textfield" type="text" data-rule="required;"/></td> '+
 '      <td class="bd_td_e" width="200">身份证号</td> '+
 '      <td><input id="d_identifyCardNumber_'+ d.sid+'" class="checkidcard" name="textfield2" data-rule="required;idcard;" type="text"/><input id="d_id_'+ d.sid+'" name="textfield14" type="hidden"/></td> '+
 '    </tr> '+
 '    <tr> '+
 '      <td class="bd_td_e">性别</td> '+
 '      <td><label for="bdselect"/> '+
 '      <input id="d_genderType_'+ d.sid+'" type="text"/> '+
 ' </td> '+
 '      <td class="bd_td_e" width="200">出生日期</td> '+
 ' <td><input value="" type="hidden" id="d_birthd >'

代码片段,以上会append到某个地方并显示出来,造成页面卡顿,并提示堆栈溢出
以上 chrome 最新x64

jQuery1.8+兼容问题

jQuery1.8+移除了$.data(elem, 'events'),对本插件照成影响,导致js报错,无法验证。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.