Angular 输入框实现自定义验证功能 - 前端之家
Angular 输入框实现自定义验证功能
前端之家收集整理的这篇文章主要介绍了
Angular 输入框实现自定义验证功能,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
<p style="text-align: left">此插件使用angular.js、JQuery实现。(jQuery的引入需在angular 之前)
用户可以 在输入框输入数据后验证 必填项、整数型、浮点型验证。
如果在form 里面的输入框验证,可以点击 提交按钮后,实现 必填项验证。
效果图如下:
(1)验证未通过时,背景标红等样式为
Box-shadow-tips {
background-color: #F63;
border-color: #F5A88F;
color: white;
-moz-
Box-shadow: 2px 2px 2px #969696;
-webkit-
Box-shaow: 2px 2px 2px #969696;
Box-shadow: 2px 2px 2px #969696;
}
因为angular.js 内置验证未通过时,会自动为 标签 增加 .ng-invalid 样式,因为这里重写此样式
(2)HTML 代码如下
(3)此插件使用 directive myValid 实现
0) {
parsers.clean();
}
parsers.unshift(function (value) {
return validFn(value) ? value : undefined;
});
};
scope.$watch(attrs.ngModel,function (newVal,oldVal) {
if (newVal === oldVal) {
return;
}
if (ctrl.$modelValue != undefined && (ctrl.$invalid || el.hasClass('ng-invalid'))) {
validFn(ctrl.$modelValue);
}
});
scope.$watch(getRules,function (newRules,oldRules) {
init();
lastOldRules = oldRules;
if (ctrl.$modelValue === undefined || ctrl.$modelValue === null) {
var needValid = false;
el.hasClass('ng-invalid');
var isValNaN = ctrl.$viewValue !== ctrl.$viewValue;
if (ctrl.$invalid || (ctrl.$viewValue !== undefined && !isValNaN)) {
needValid = true;
}
if (needValid) {
ctrl.$setViewValue(ctrl.$viewValue);
}
} else {
if (!ctrl.$dirty && attrs.dirtyCheck) {
console.log('----');
} else {
validFn(ctrl.$modelValue,oldRules);
}
}
});
}
}
}]);
通过 监听 attrs.ngModel,验证规则 rules ,ctrl.$parser 来实现 输入框内容改变的响应。
一旦使用此directive,则动态为当前输入框添加ID,以便在 验证通过后,改变输入框的验证背景信息。
(4)验证逻辑处理 uiValidFactory
提示框
if ($.inArray('r',rulesArr) === -1 && isBlank) {
return {
flag: true
}
}
var i = 0,len = rulesArr.length;
for (; i < len; i++) {
var rule = rulesArr[i];
if (!rule) {
continue;
}
var flag = true;
if ('r' === rule) {
//如果是必填项,有值 返回true
flag = !isBlank;
} else if (rule.contains(':')) {
//如果校验规则是 fn:ctrl.certCheck
flag = this.checkRule(val,rule.split(/:/),extendParam);
} else {
//校验 规则是 int 用正则匹配 数字 邮箱 长度
var pat = this.pats[rule];
if (pat instanceof RegExp) {
if (angular.isString(val)) {
flag = this.mat(val,pat);
}
} else if (angular.isFunction(pat)) {
flag = pat(val);
} else {
flag = false;
}
}
//这是干什么的呢
if (angular.isString(flag)) {
return {
flag: false,msg: flag,rule: rule
}
}
if (flag === false) {
var msg = this.getMsg(rule,defaultTips) || this.getMsg('tips.valid');
console.log(msg);
return {
flag: false,msg: msg,rule: rule
}
}
}
return {
flag: true
}
},checkRule: function (val,ruleArr,extendParam) {
//ruleArr fn:certCheck
var rule = ruleArr[0];
if (rule === 'fn') {
fnName = ruleArr[1];//指定被调
函数的名字 certCheck
var fn = $parse(fnName)($scope);
if (!fn) {
return true;
}
return fn.call($scope,val,extendParam);
} else {
return true;
}
},checkValidForm: function (formName) {
//只检查必填项
//使用
属性筛选器 获得里面所有的元素
var formContext = $('form[name="{0}"],[ng-form="{0}"],[data-ng-form="{0}"]'.format(formName)),validList = formContext.find('[my-valid]');//validList 不是数组,是伪数组
if (!validList.length) {
return;
}
var that = this,validFlags = [];
validList.each(function () {
var ele = $(this),val = ele.val(),ruleStr = ele.attr('my-valid');
if (!ruleStr) {
return true;
}
if (angular.isString(val)) {
val = val.trim();
}
var validRules = ruleStr.split(' ');
if ($.inArray('r',validRules) != -1 && !val) {
var modelValue = ele.attr('ng-model') || ele.attr('data-ng-model');
validFlags.push(modelValue);
tips.on(ele,that.getMsg('r'));
}
}
);
return validFlags;
},mat: function (val,pat) {
if (!pat) {
return;
}
return pat.test(val);
},getMsg: function (rule,tips) {
tips = tips || '';
//可以在界面上直接写 tips
if (tips && tips.contains(':')) {
return tips;
}
var msg = this.msgs[rule];
if (msg) {
var params0 = tips.contains(':') ? tips.split(/:/)[0] : '';
var params1 = '';
if (rule.startsWith('min') || rule.startsWith('max')) {
var ruleArr = rule.split(/:/);
params1 = ruleArr[ruleArr.length - 1];
}
return msg.format(params0,params1);
} else {
}
},regPat: function (code,pat,msg) {
if (this.pat[code]) {
return;
}
this.pats[code] = pat;
this.msgs[code] = msg;
},msgs: {
'r': '必填','int': '{0}必须为整数'
},pats: {
'int': /^[\-\+]?([0-9]+)$/
}
}
}
])
;
通过获取输入框 ele.myValid 验证规则,
1、如果是必填,则返回 标红此输入框,鼠标移上,则显示 验证信息 “必填””。
2、如果是整数、浮点型等验证,则通过 正则表达式进行验证。
3、如果是最大(max)、最小(min),则自定义逻辑。
4、如果是 fn 验证,则根据 对应controller中函数进行验证。
5、用户点击提交按钮,则 判断是否必填项,验证不通过,对应元素背景标红。
(5) 验证不通过,提示Factory---uiTipsFactory
<div class="jb51code">
<pre class="brush:js;">
app.factory('uiTipsFactory',function () {
return {
filterClass: function (ele,invalid) {
if (invalid) {
//如果验证不通过
ele.removeClass('ng-valid').removeClass('ng-pristine').addClass('ng-invalid').addClass('ng-dirty');
} else {
ele.removeClass('ng-invalid').addClass('ng-valid');
}
},on: function (ele,msg) {
var lastTip = ele.data('last-tip');
if (lastTip && lastTip === msg) {
return;
}
ele.data('last-tip',msg);
this.filterClass(ele,true);
var offset = ele.offset();
if (!offset.top && !offset.left && ele.is('hidden')) {
offset = ele.show().offset();
}
var id = ele.attr('ui-valid-id');
if (!id) {
id = Math.guid();
ele.attr('ui-valid-id',id);
}
if (id.contains('.')) {
id = id.replace(/./g,'_');
}
var top = offset.top,left = offset.left;
var getTips = function () {
var tip = $('#vtip' + id);
if (_tip.length) {
tip.html(msg).css({
'display': 'none','top': top + 'px','left': left + ele.width() + 10 + 'px'
});
} else {
var html = '<div id="vtip' + id + '" class="vtip qtip qtip-rounded Box-shadow-tips">' +
'<div class="qtip-content">' + msg + '';
$(html).css({
'display': 'none','position': 'absolute','left': left + ele.width() + 10 + 'px'
}).appendTo($('body'));
}
};
var bindTipsShow = function () {
getTips();
ele.unbind('mouseenter mouseleave').bind('mouseenter',function () {
var tip = $('#vtip' + id);
if (_tip.is(':hidden')) {
tip.show();
}
}).bind('mouseleave',function () {
$('#vtip' + id).hide();
});
};
bindTipsShow();
},off: function (ele) {
ele.data('last-tip','');
this.filterClass(ele);
var id = ele.attr('ui-valid-id');
if (!id) {
return;
}
if (id.contains('.')) {
id = id.replace(/./g,'');
}
$('#vtip' + id).remove();
ele.unbind('mouseenter mouseleave');
}
}
});
1、验证不通过,增加背景色,元素css处理如下
验证通过,CSS处理如下
2、背景提示语,则是在body上增加一个div层。
(6)其他相关代码
32) {
return "数字太大了";
}
return true;
};
$scope.submit = function () {
if (!uiValidFactory.checkValidForm($scope.baseInfoForm.$name)) {
}
};
}]
);
Math.guid = function () {
var a = "",b = 1;
for (; b <= 32; b++) {
var c = Math.floor(Math.random() * 16).toString(16);
a += c;
if (b === 8 || b === 12 || b === 16 || b === 20) {
a += '-';
}
}
return a;
};
String.prototype.contains = String.prototype.contains || function (a) {
return this.indexOf(a) != -1;
};
String.prototype.format = String.prototype.format || function () {
var a = Array.prototype.slice.call(arguments);
return this.replace(/\{(\d+)}/g,function (c,b) {
return a[b];
})
};
整个代码如下: