此插件使用angular.js、JQuery实现。(jQuery的引入需在angular 之前)
用户可以 在输入框输入数据后验证 必填项、整数型、浮点型验证。
如果在form 里面的输入框验证,可以点击 提交按钮后,实现 必填项验证。
效果图如下:
(1)验证未通过时,背景标红等样式为
input.ng-invalid, select.ng-invalid {
background-color: #ee82ee !important;
border: 1px solid #CCC;
}
.qtip {
position: absolute;
max-width: 260px;
display: none;
min-width: 50px;
font-size: 10.5px;
line-height: 12px;
direction: ltr;
}
.qtip-content {
position: relative;
padding: 5px 9px;
overflow: hidden;
text-align: left;
word-wrap: break-word;
}
.qtip-rounded, .qtip-tipsy {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.qtipmodal-ie6fix {
position: absolute !important;
}
.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 样式,因为这里重写此样式
input.ng-invalid, select.ng-invalid {
background-color: #ee82ee !important;
border: 1px solid #CCC;
}
(2)HTML 代码如下
<body ng-app="myApp"> <form name="baseInfoForm"> <div ng-controller="testCtrl"> <input type="text" ng-model="age" my-valid="r"><br> <input type="text" ng-model="name" my-valid="int fn:certCheck"><br> <input type="button" value="提交" ng-click="submit()"> </div> </form> </body>
(3)此插件使用 directive myValid 实现
app.directive('myValid', ['$parse', 'uiTipsFactory', 'uiValidFactory', function ($parse, tips, valid) {
var uiValidAttrIdName = 'ui-valid-id';
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, el, attrs, ctrl) {
var validId = el.attr(uiValidAttrIdName);
if (!validId) {
validId = Math.guid();
el.attr(uiValidAttrIdName, validId);
}
var getRules = function () {
return attrs.myValid;
};
var lastOldRules;
var validFn = function (value, oldRules) {
var sp = '_';
var rules = getRules();
var r = valid.check(value, rules, scope, attrs.uiValidTips);
if (lastOldRules && !oldRules) {
oldRules = lastOldRules;
}
if (r.flag && oldRules) {
rules = rules "htmlcode">
app.factory('uiValidFactory', ['$parse', 'uiTipsFactory', function ($parse, tips) {
return {
check: function (val, rules, $scope, defaultTips, extendParam) {
if (!rules) {
return {
flag: true
};
}
var rulesArr = rules.split(' '),
isBlank = val === null || val === undefined || val === '' || ('' + val === '');
//如果不是必填项 且没有输入值 则清除提示框
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(/:/), $scope, 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, $scope, 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(':') "htmlcode">
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 + '</div>';
$(html).css({
'display': 'none',
'position': 'absolute',
'top': top + 'px',
'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处理如下
ele.removeClass('ng-valid').removeClass('ng-pristine').addClass('ng-invalid').addClass('ng-dirty');
验证通过,CSS处理如下
ele.removeClass('ng-invalid').addClass('ng-valid');
2、背景提示语,则是在body上增加一个div层。
(6)其他相关代码
var app = angular.module('myApp', []);
app.controller('testCtrl', ['$scope', 'uiValidFactory', function ($scope, uiValidFactory) {
$scope.certCheck = function (val) {
if (val > 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];
})
};
整个代码如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="/UploadFiles/2021-04-02/jquery-1.11.1.js">
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
