惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

博客园 - Do you know, jack?

js继承摘要 Css中position、float和clear整理 基于组织角色的权限设计 oracle最精简客户端(3个文件+1个path变量就搞定oracle客户端) oracle客户端免安装配置、64位机器PL/SQL和VS自带的IIS连接问题 Throw与Throw ex区别,记录日志的方法 oracle数据库连接方式 允许修改Svn注释 ctrl+Enter 自动加上 .com 而不是 .com.cn google chrome服务器hosts设置 Entity Framework关系映射容易出错的地方 CSS文件和JS文件组织 添加NotePad++到右键菜单 960 grid system的一点研究 如何查看NHibernate中生成的SQL The RPC server is unavailable的解决方法 编写一份代码,支持多种布署方式 为什么要使用AOP? Enterprise Library 和 Spring.Net的比较
web页面数据验证提醒方式
Do you know, jack? · 2011-07-01 · via 博客园 - Do you know, jack?

虽然现在MVC比较热, 但是使用Web Form方式进行开发的项目应该还有很多,这就少不了使用验证控件,但是验证控件在验证不通过时,提醒的方式很简单,不够友好。如果页面布局是流布局方式,很容易因为显示出来的错误信息造成布局混乱。AjaxControlToolkit的ValidatorCallout虽然可以很好,但是需要为每一个验证控件要再加多一个控件, 在实际使用中太麻烦了,于是分析了ValidatorCallout的原理后,自己来实现一个更好用的ValidatorCallout

原理: 每一个验证控件最后都会在页面中生成相应的元素,并有一个

evaluationfunction属性,这个方法会在验证的时候被调用, AjaxControlToolkit中就是通过重写这个方法来达到提示的目的。

         //               
        // Override the evaluation method of the current validator
        //
        if(elt.evaluationfunction) {
            
this._originalValidationMethod = Function.createDelegate(elt, elt.evaluationfunction);
            
this._validationMethodOverride = Function.createDelegate(thisthis._onvalidate);
            elt.evaluationfunction 
= this._validationMethodOverride;            
        }

 新的

ValidatorCallout实现方式与这个类似,由于所有的验证控件都在

Page_Validators这个数组中,这个是由验证控件自动生成的,所以应该不用再给每一个验证控件都再加一个控件,只引用相应的脚本就可以了,不用添加修改任何代码。

 实现方式:

var ValidatorCallout = function(validator) {    

    if (typeof (validator) =='string')

        this._validator = document.getElementById(validator);
    
else
        
this._validator = validator;this._validator.display = 'None'//the error message will not show when validate

    
if (typeof (validator.controltovalidate) == 'string') {
        
this._validatorControl = document.getElementById(validator.controltovalidate);
    }
    
else {
        
this._validatorControl = null;
    }
}

ValidatorCallout.zIndex 

= 999;

ValidatorCallout.prototype 

= {

    initiate: 

function() {
        
var divContainer = $('<div id="' + 'Validator_divContainer' + ValidatorCallout.zIndex + '"></div>')
        .addClass(
'tip_Container').css('zIndex', ValidatorCallout.zIndex++)
         .click(
function() {
             $(
this).css('zIndex', ValidatorCallout.zIndex++);
         });
this._divContainer = divContainer[0];var divCorner = $('<div></div>').addClass('tip_Corner').appendTo(divContainer);var count = 10;
        
if ($.browser.msie == true && $.browser.version == '6.0') {
            count 
= 5/* special for ie 6.0 */
        }
        
for (var i = 0; i < count; i++) {
            $(
'<div></div>').css('width', i + 'px')
            .addClass(
'tip_Corner_Line').appendTo(divCorner);
        }
var divPanel = $('<div></div>').addClass('tip_Panel').appendTo(divContainer);

        $(

'<span></span>').addClass('tip-message')
        .text(
this._validator.errormessage == null ? '' : this._validator.errormessage)
        .appendTo(divPanel);

        $(

'<div></div>').addClass('tip_close').appendTo(divPanel)
        .click(
function() {
            divContainer.css(
'display''none');
        });

        $(

'body').append(divContainer);this._validator.callout = this;//over write the validator.evaluationfunction to new funtion
        if (typeof (this._validator.evaluationfunction) == 'String') {
            
this._validator.evaluationfunction = eval(this._validator.evaluationfunction);
        }
var evaluationfunction = this._validator.evaluationfunction;
        
this._validator.evaluationfunction = function(val) {
            
if (!evaluationfunction(val)) {
                ValidatorCallout.show(val);
                
return false;
            }
            
else {
                ValidatorCallout.hide(val);
                
return true;
            }
        };

        $(

this._validatorControl).unbind('focus', ShowErrorMessageWhenFocus)
        .bind(
'focus', ShowErrorMessageWhenFocus);
    }

};

ValidatorCallout.show 

= function(validator) {
    
if (validator.callout._validatorControl != null) {var ctlValidator = $(validator.callout._validatorControl);
        ctlValidator.addClass(
"error");var errorPopupId = validator.callout._divContainer.id;
        
if (ctlValidator.attr('validator'== null || ctlValidator.attr('validator'== '') {
            ctlValidator.attr(
'validator', errorPopupId);
        }
//only show the first error when multiple validator validate one control
        if (ctlValidator.attr('validator'== errorPopupId) {
            ShowErrorMessage(ctlValidator, validator.callout._divContainer);
        }
    }
}

ValidatorCallout.hide 

= function(validator) {
    $(validator.callout._divContainer).css(
'display''none');if (validator.callout._validatorControl != null) {
        
var ctlValidator = $(validator.callout._validatorControl);
        
if (ctlValidator.attr('validator'== validator.callout._divContainer.id) {
            ctlValidator.removeClass(
'error');
            ctlValidator.removeAttr(
'validator');
        }
    }
}
function ShowErrorMessageWhenFocus(e) {
    
var ctlToValidate = $(this);
    
var messageDivId = ctlToValidate.attr('validator');
    
var messageDiv = $('#' + messageDivId);
    ShowErrorMessage(ctlToValidate, messageDiv);
}
function ShowErrorMessage(validatorControl, messageContainer) {
    
var ctlValidator = $(validatorControl);
    
var position = ctlValidator.position();
    position.top 
+= ctlValidator.outerHeight(true- 10;
    $(messageContainer)
         .css({
             
'width': ctlValidator.width()
             , 
'left': position.left
             , 
'top': position.top
             , 
'display''block'
         });
//setTimeout("HideObject('" +$(messageContainer).attr("id") + "');", 2500); 
}function HideObject(elemId) {
    $(
'#' + elemId).css('display''none');
}

jQuery(

function($) {
    
if (typeof (Page_Validators) != 'undefined') {
        
for (var i = 0; i < Page_Validators.length; i++) {
            
var validatorCall = new ValidatorCallout(Page_Validators[i]);
            validatorCall.initiate();
        }
    }

});

要点:

jQuery(function($) {
    
if (typeof (Page_Validators) != 'undefined') {
        
for (var i = 0; i < Page_Validators.length; i++) {
            
var validatorCall = new ValidatorCallout(Page_Validators[i]);
            validatorCall.initiate();
        }
    }

});

 在页面加载的时候,将 Page_Validators中的验证控件取出来创建validatorCallout,然后调用

initiate方法创建提示控件,将它的evaluationfunction修改成新的包装后的方法,实现方式:

        var evaluationfunction = this._validator.evaluationfunction;
        
this._validator.evaluationfunction = function(val) {
            
if (!evaluationfunction(val)) {
                ValidatorCallout.show(val);
                
return false;
            }
            
else {
                ValidatorCallout.hide(val);
                
return true;
            }

         }; 

关键方法:  

initiate: 初始化控件,并创建相应的提示信息元素

show: 显示错误提示信息

hide: 隐藏错误信息 

使用方法:在页面中加入JS脚本和CSS文件就可以了。(另外需要引用jQuery脚本文件)

下载:  ValidatorCallout.rar 

 效果大家试一下就知道了。