Commit 244d0d2b authored by root's avatar root

Merge branch 'wangyong' of gitcafe.com:ibuler/jumpserver into guanghongwei

Conflicts:
	jumpserver/templatetags/mytags.py
	juser/views.py
parents d878bb19 9b194946
...@@ -4,8 +4,16 @@ from jasset.views import * ...@@ -4,8 +4,16 @@ from jasset.views import *
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', index), url(r'^$', index),
url(r'jadd', jadd), url(r'^host_add/$', jadd_host),
url(r'jlist', jlist), url(r'^host_list/$', jlist_host),
url(r'jadd_idc', jadd_idc), url(r"^(\d+.\d+.\d+.\d+)/$",jlist_ip),
url(r'jlist_idc', jlist_idc), url(r'^idc_add/$', jadd_idc),
url(r'^idc_list/$', jlist_idc),
url(r'^idc_del/(\d+)/$', idc_del),
url(r'^group_add/$', jadd_group),
url(r'^group_list/$', jlist_group),
url(r'^group_del/(\d+)/$', group_del),
url(r'^host_del/(\d+.\d+.\d+.\d+)/$', host_del),
url(r'^host_edit/(\d+.\d+.\d+.\d+)/$', host_edit),
url(r'^test/$', test),
) )
\ No newline at end of file
# coding:utf-8 # coding:utf-8
import datetime from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext from django.template import RequestContext
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect from django.core.paginator import Paginator, EmptyPage
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from models import IDC, Asset, UserGroup from models import IDC, Asset, BisGroup
from connect import PyCrypt, KEY from connect import PyCrypt, KEY
cryptor = PyCrypt(KEY)
def index(request): def index(request):
return render_to_response('jasset/jasset.html', ) return render_to_response('jasset/jasset.html', )
def jadd(request): def jadd_host(request):
global j_passwd login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
header_title, path1, path2 = u'添加主机 | Add Host', u'资产管理', u'添加主机'
groups = [] groups = []
cryptor = PyCrypt(KEY)
eidc = IDC.objects.all() eidc = IDC.objects.all()
egroup = UserGroup.objects.all() egroup = BisGroup.objects.all()
is_actived = {'active': 1, 'no_active': 0}
login_typed = {'LDAP': 'L', 'SSH_KEY': 'S', 'PASSWORD': 'P', 'MAP': 'M'}
if request.method == 'POST': if request.method == 'POST':
j_ip = request.POST.get('j_ip') j_ip = request.POST.get('j_ip')
...@@ -32,56 +29,48 @@ def jadd(request): ...@@ -32,56 +29,48 @@ def jadd(request):
j_group = request.POST.getlist('j_group') j_group = request.POST.getlist('j_group')
j_active = request.POST.get('j_active') j_active = request.POST.get('j_active')
j_comment = request.POST.get('j_comment') j_comment = request.POST.get('j_comment')
if j_type == 'MAP':
j_user = request.POST.get('j_user')
j_password = cryptor.encrypt(request.POST.get('j_password'))
j_root = request.POST.get('j_root')
j_passwd = cryptor.encrypt(request.POST.get('j_passwd'))
j_idc = IDC.objects.get(name=j_idc) j_idc = IDC.objects.get(name=j_idc)
for group in j_group: for group in j_group:
c = UserGroup.objects.get(name=group) c = BisGroup.objects.get(name=group)
groups.append(c) groups.append(c)
if Asset.objects.filter(ip=str(j_ip)): if Asset.objects.filter(ip=str(j_ip)):
emg = u'该IP已存在!' emg = u'该IP已存在!'
return render_to_response('jasset/jadd.html', {'emg': emg, 'j_ip': j_ip}) return render_to_response('jasset/host_add.html', locals(), context_instance=RequestContext(request))
elif j_type == 'MAP': if j_type == 'M':
a = Asset(ip=j_ip, j_user = request.POST.get('j_user')
port=j_port, j_password = cryptor.encrypt(request.POST.get('j_password'))
login_type=login_typed[j_type], j_root = request.POST.get('j_root')
idc=j_idc, j_passwd = cryptor.encrypt(request.POST.get('j_passwd'))
is_active=int(is_actived[j_active]), a = Asset(ip=j_ip, port=j_port,
login_type=j_type, idc=j_idc,
is_active=int(j_active),
comment=j_comment, comment=j_comment,
username_common=j_user, username_common=j_user,
password_common=j_password, password_common=j_password,
username_super=j_root, username_super=j_root,
password_super=j_passwd,) password_super=j_passwd,)
else: else:
a = Asset(ip=j_ip, a = Asset(ip=j_ip, port=j_port,
port=j_port, login_type=j_type, idc=j_idc,
login_type=login_typed[j_type], is_active=int(j_active),
idc=j_idc,
is_active=int(is_actived[j_active]),
comment=j_comment) comment=j_comment)
a.save() a.save()
a.group = groups print 'ok'
a.bis_group = groups
a.save() a.save()
smg = u'主机 %s 添加成功' %j_ip
return render_to_response('jasset/jadd.html', return render_to_response('jasset/host_add.html', locals(), context_instance=RequestContext(request))
{'header_title': u'添加主机 | Add Host',
'path1': '资产管理',
'path2': '添加主机',
'eidc': eidc,
'egroup': egroup, }
)
def jlist(request): def jlist_host(request):
header_title, path1, path2 = u'查看主机 | List Host', u'资产管理', u'查看主机'
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
posts = contact_list = Asset.objects.all().order_by('ip') posts = contact_list = Asset.objects.all().order_by('ip')
print posts print posts
paginator = Paginator(contact_list, 5) p = paginator = Paginator(contact_list, 5)
try: try:
page = int(request.GET.get('page', '1')) page = int(request.GET.get('page', '1'))
except ValueError: except ValueError:
...@@ -92,19 +81,125 @@ def jlist(request): ...@@ -92,19 +81,125 @@ def jlist(request):
except (EmptyPage, InvalidPage): except (EmptyPage, InvalidPage):
contacts = paginator.page(paginator.num_pages) contacts = paginator.page(paginator.num_pages)
return render_to_response('jasset/jlist.html', return render_to_response('jasset/host_list.html', locals(), context_instance=RequestContext(request))
{"contacts": contacts,
'p': paginator, def host_del(request, offset):
'posts': posts, Asset.objects.filter(ip=str(offset)).delete()
'header_title': u'查看主机 | List Host', return HttpResponseRedirect('/jasset/host_list/')
'path1': '资产管理',
'path2': '查看主机', }, def host_edit(request, offset):
context_instance=RequestContext(request)) actives = {1: u'激活', 0: u'禁用'}
login_types = {'L': 'LDAP', 'S': 'SSH_KEY', 'P': 'PASSWORD', 'M': 'MAP'}
header_title, path1, path2 = u'修改主机 | Edit Host', u'资产管理', u'修改主机'
groups, e_group = [], []
eidc = IDC.objects.all()
egroup = BisGroup.objects.all()
for g in Asset.objects.get(ip=offset).bis_group.all():
e_group.append(g)
post = Asset.objects.get(ip = str(offset))
if request.method == 'POST':
j_ip = request.POST.get('j_ip')
j_idc = request.POST.get('j_idc')
j_port = request.POST.get('j_port')
j_type = request.POST.get('j_type')
j_group = request.POST.getlist('j_group')
j_active = request.POST.get('j_active')
j_comment = request.POST.get('j_comment')
j_idc = IDC.objects.get(name=j_idc)
for group in j_group:
c = BisGroup.objects.get(name=group)
groups.append(c)
a = Asset.objects.get(ip=str(offset))
if j_type == 'M':
j_user = request.POST.get('j_user')
j_password = cryptor.encrypt(request.POST.get('j_password'))
j_root = request.POST.get('j_root')
j_passwd = cryptor.encrypt(request.POST.get('j_passwd'))
a.ip = j_ip
a.port = j_port
a.login_type = j_type
a.idc = j_idc
a.is_active = j_active
a.comment = j_comment
a.username_common = j_user
a.password_common = j_password
a.username_super = j_root
a.password_super = j_passwd
else:
a.ip = j_ip
a.port = j_port
a.idc = j_idc
a.login_type = j_type
a.is_active = j_active
a.comment = j_comment
a.save()
a.bis_group = groups
a.save()
smg = u'主机 %s 修改成功' %j_ip
return HttpResponseRedirect('/jasset/host_list')
return render_to_response('jasset/host_edit.html', locals(), context_instance=RequestContext(request))
def jlist_ip(request, offset):
header_title, path1, path2 = u'主机详细信息 | Host Detail.', u'资产管理', u'主机详情'
print offset
post = contact_list = Asset.objects.get(ip = str(offset))
return render_to_response('jasset/jlist_ip.html', locals(), context_instance=RequestContext(request))
def jadd_idc(request): def jadd_idc(request):
pass header_title, path1, path2 = u'添加IDC | Add IDC', u'资产管理', u'添加IDC'
if request.method == 'POST':
j_idc = request.POST.get('j_idc')
j_comment = request.POST.get('j_comment')
print j_idc,j_comment
if IDC.objects.filter(name=j_idc):
emg = u'该IDC已存在!'
return render_to_response('jasset/idc_add.html', locals(), context_instance=RequestContext(request))
else:
smg = u'IDC:%s添加成功' %j_idc
IDC.objects.create(name=j_idc, comment=j_comment)
return render_to_response('jasset/idc_add.html', locals(), context_instance=RequestContext(request))
def jlist_idc(request): def jlist_idc(request):
pass header_title, path1, path2 = u'查看IDC | List Host', u'资产管理', u'查看IDC'
\ No newline at end of file posts = IDC.objects.all().order_by('id')
return render_to_response('jasset/idc_list.html', locals(), context_instance=RequestContext(request))
def idc_del(request, offset):
IDC.objects.filter(id=offset).delete()
return HttpResponseRedirect('/jasset/idc_list/')
def jadd_group(request):
header_title, path1, path2 = u'添加业务组 | Add Group', u'资产管理', u'添加业务组'
if request.method == 'POST':
j_group = request.POST.get('j_group')
j_comment = request.POST.get('j_comment')
if BisGroup.objects.filter(name=j_group):
emg = u'该业务组已存在!'
return render_to_response('jasset/group_add.html', locals(), context_instance=RequestContext(request))
else:
smg = u'业务组%s添加成功' %j_group
BisGroup.objects.create(name=j_group, comment=j_comment)
return render_to_response('jasset/group_add.html', locals(), context_instance=RequestContext(request))
def jlist_group(request):
header_title, path1, path2 = u'查看业务组 | Add Group', u'资产管理', u'查看业务组'
posts = BisGroup.objects.all().order_by('id')
return render_to_response('jasset/group_list.html', locals(), context_instance=RequestContext(request))
def group_del(request, offset):
BisGroup.objects.filter(id=offset).delete()
return HttpResponseRedirect('/jasset/group_list/')
def test(request):
return render_to_response('jasset/test.html', locals())
\ No newline at end of file
...@@ -8,7 +8,11 @@ password = mysql234 ...@@ -8,7 +8,11 @@ password = mysql234
database = jumpserver database = jumpserver
[ldap] [ldap]
ldap_enable = 1 host_url = ldap://192.168.8.60:389
base_dn = dc=fengxing,dc=org
root_dn = cn=admin,dc=fengxing,dc=org
root_pw = 123456
ldap_enable = 0
host_url = ldap://127.0.0.1:389 host_url = ldap://127.0.0.1:389
base_dn = dc=jumpserver,dc=org base_dn = dc=jumpserver,dc=org
root_dn = cn=admin,dc=jumpserver,dc=org root_dn = cn=admin,dc=jumpserver,dc=org
......
...@@ -34,3 +34,7 @@ def groups_str(username): ...@@ -34,3 +34,7 @@ def groups_str(username):
for group in user.user_group.all(): for group in user.user_group.all():
groups.append(group.name) groups.append(group.name)
return ','.join(groups) return ','.join(groups)
@register.filter(name='get_item')
def get_item(dictionary, key):
return dictionary.get(key)
...@@ -107,7 +107,6 @@ class LDAPMgmt(): ...@@ -107,7 +107,6 @@ class LDAPMgmt():
except ldap.LDAPError, e: except ldap.LDAPError, e:
print e print e
def gen_sha512(salt, password): def gen_sha512(salt, password):
return crypt.crypt(password, '$6$%s$' % salt) return crypt.crypt(password, '$6$%s$' % salt)
...@@ -161,7 +160,6 @@ def user_list(request): ...@@ -161,7 +160,6 @@ def user_list(request):
def db_add_user(**kwargs): def db_add_user(**kwargs):
groups_post = kwargs.pop('groups') groups_post = kwargs.pop('groups')
user = User(**kwargs) user = User(**kwargs)
group_select = []
for group_id in groups_post: for group_id in groups_post:
group = UserGroup.objects.filter(id=group_id) group = UserGroup.objects.filter(id=group_id)
group_select.extend(group) group_select.extend(group)
......
/*
Colorbox Core Style:
The following CSS is consistent between example themes and should not be altered.
*/
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
#cboxWrapper {max-width:none;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
.cboxIframe{width:100%; height:100%; display:block; border:0; padding:0; margin:0;}
#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
/*
User Style:
Change the following styles to modify the appearance of Colorbox. They are
ordered & tabbed in a way that represents the nesting of the generated HTML.
*/
#cboxOverlay{background:#fff; opacity: 0.9; filter: alpha(opacity = 90);}
#colorbox{outline:0;}
#cboxContent{margin-top:32px; overflow:visible; background:#000;}
.cboxIframe{background:#fff;}
#cboxError{padding:50px; border:1px solid #ccc;}
#cboxLoadedContent{background:#000; padding:1px;}
#cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
#cboxLoadingOverlay{background:#000;}
#cboxTitle{position:absolute; top:-22px; left:0; color:#000;}
#cboxCurrent{position:absolute; top:-22px; right:205px; text-indent:-9999px;}
/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
#cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; text-indent:-9999px; width:20px; height:20px; position:absolute; top:-20px; background:url(images/controls.png) no-repeat 0 0;}
/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
#cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
#cboxPrevious{background-position:0px 0px; right:44px;}
#cboxPrevious:hover{background-position:0px -25px;}
#cboxNext{background-position:-25px 0px; right:22px;}
#cboxNext:hover{background-position:-25px -25px;}
#cboxClose{background-position:-50px 0px; right:0;}
#cboxClose:hover{background-position:-50px -25px;}
.cboxSlideshow_on #cboxPrevious, .cboxSlideshow_off #cboxPrevious{right:66px;}
.cboxSlideshow_on #cboxSlideshow{background-position:-75px -25px; right:44px;}
.cboxSlideshow_on #cboxSlideshow:hover{background-position:-100px -25px;}
.cboxSlideshow_off #cboxSlideshow{background-position:-100px 0px; right:44px;}
.cboxSlideshow_off #cboxSlideshow:hover{background-position:-75px -25px;}
/*! nice Validator 0.7.3
* (c) 2012-2014 Jony Zhang <zj86@live.cn>, MIT Licensed
* http://niceue.com/validator/
*/
.n-inline-block,.nice-validator input,.nice-validator select,.nice-validator textarea,.msg-wrap,.n-icon,.n-msg{display:inline-block;*display:inline;*zoom:1}
.msg-box{position:relative;*zoom:1}
.msg-wrap{position:relative;white-space:nowrap}
.msg-wrap,.n-icon,.n-msg{vertical-align:top}
.n-arrow{position:absolute;overflow:hidden;}
.n-arrow b,.n-arrow i{position:absolute;left:0;top:0;border:0;margin:0;padding:0;overflow:hidden;font-weight:400;font-style:normal;font-size:12px;font-family:serif;line-height:14px;_line-height:15px}
.n-arrow i{text-shadow:none}
.n-icon{width:16px;height:16px;overflow:hidden;background-repeat:no-repeat}
.n-msg{display:inline-block;line-height:15px;margin-left:2px;*margin-top:-1px;_margin-top:0;font-size:12px;font-family:simsun}
.n-error{color:#c33}
.n-ok{color:#390}
.n-tip,.n-loading{color:#808080}
.n-error .n-icon{background-position:0 0}
.n-ok .n-icon{background-position:-16px 0}
.n-tip .n-icon{background-position:-32px 0}
.n-loading .n-icon{background:url("images/loading.gif") 0 center no-repeat !important}
.n-top,.n-right,.n-bottom,.n-left{display:inline-block;line-height:0;vertical-align:top;outline:0}
.n-top .n-arrow,.n-bottom .n-arrow{height:6px;width:12px;left:8px}
.n-left .n-arrow,.n-right .n-arrow{width:6px;height:12px;top:6px}
.n-top{vertical-align:top;}
.n-top .msg-wrap{margin-bottom:6px}
.n-top .n-arrow{bottom:-6px;}
.n-top .n-arrow b{top:-6px}
.n-top .n-arrow i{top:-7px}
.n-bottom{vertical-align:bottom;}
.n-bottom .msg-wrap{margin-top:6px}
.n-bottom .n-arrow{top:-6px;}
.n-bottom .n-arrow b{top:-1px}
.n-bottom .n-arrow i{top:0}
.n-left .msg-wrap{right:100%;margin-right:6px}
.n-left .n-arrow{right:-6px;}
.n-left .n-arrow b{left:-6px}
.n-left .n-arrow i{left:-7px}
.n-right .msg-wrap{margin-left:6px}
.n-right .n-arrow{left:-6px;}
.n-right .n-arrow b{left:1px}
.n-right .n-arrow i{left:2px}
.n-default .n-left,.n-default .n-right{margin-top:5px}
.n-default .n-top .msg-wrap{bottom:100%}
.n-default .n-bottom .msg-wrap{top:100%}
.n-default .msg-wrap{position:absolute;z-index:1;}
.n-default .msg-wrap .n-icon{background-image:url("images/validator_default.png")}
.n-default .n-tip .n-icon{display:none}
.n-simple .msg-wrap{position:absolute;z-index:1;}
.n-simple .msg-wrap .n-icon{background-image:url("images/validator_simple.png")}
.n-simple .n-top .msg-wrap{bottom:100%}
.n-simple .n-bottom .msg-wrap{top:100%}
.n-simple .n-left,.n-simple .n-right{margin-top:5px}
.n-simple .n-bottom .msg-wrap{margin-top:3px}
.n-simple .n-tip .n-icon{display:none}
.n-yellow .msg-wrap{position:absolute;z-index:1;padding:4px 6px;font-size:12px;border:1px solid transparent;background-color:#fffcef;border-color:#ffbb76;color:#db7c22;box-shadow:0 1px 3px #ccc;border-radius:2px;}
.n-yellow .msg-wrap .n-arrow b{color:#ffbb76;text-shadow:0 0 2px #ccc}
.n-yellow .msg-wrap .n-arrow i{color:#fffcef}
.n-yellow .msg-wrap .n-icon{background-image:url("images/validator_simple.png")}
.n-yellow .n-top .msg-wrap{bottom:100%}
.n-yellow .n-bottom .msg-wrap{top:100%}
.n-yellow .n-tip,.n-yellow .n-ok,.n-yellow .n-loading{background-color:#f8fdff;border-color:#ddd;color:#333;box-shadow:0 1px 3px #ccc;}
.n-yellow .n-tip .n-arrow b,.n-yellow .n-ok .n-arrow b,.n-yellow .n-loading .n-arrow b{color:#ddd;text-shadow:0 0 2px #ccc}
.n-yellow .n-tip .n-arrow i,.n-yellow .n-ok .n-arrow i,.n-yellow .n-loading .n-arrow i{color:#f8fdff}
.n-yellow .n-tip .n-icon{display:none}
/*!
Colorbox 1.5.14
license: MIT
http://www.jacklmoore.com/colorbox
*/
(function ($, document, window) {
var
// Default settings object.
// See http://jacklmoore.com/colorbox for details.
defaults = {
// data sources
html: false,
photo: false,
iframe: false,
inline: false,
// behavior and appearance
transition: "elastic",
speed: 300,
fadeOut: 300,
width: false,
initialWidth: "600",
innerWidth: false,
maxWidth: false,
height: false,
initialHeight: "450",
innerHeight: false,
maxHeight: false,
scalePhotos: true,
scrolling: true,
opacity: 0.9,
preloading: true,
className: false,
overlayClose: true,
escKey: true,
arrowKey: true,
top: false,
bottom: false,
left: false,
right: false,
fixed: false,
data: undefined,
closeButton: true,
fastIframe: true,
open: false,
reposition: true,
loop: true,
slideshow: false,
slideshowAuto: true,
slideshowSpeed: 2500,
slideshowStart: "start slideshow",
slideshowStop: "stop slideshow",
photoRegex: /\.(gif|png|jp(e|g|eg)|bmp|ico|webp|jxr|svg)((#|\?).*)?$/i,
// alternate image paths for high-res displays
retinaImage: false,
retinaUrl: false,
retinaSuffix: '@2x.$1',
// internationalization
current: "image {current} of {total}",
previous: "previous",
next: "next",
close: "close",
xhrError: "This content failed to load.",
imgError: "This image failed to load.",
// accessbility
returnFocus: true,
trapFocus: true,
// callbacks
onOpen: false,
onLoad: false,
onComplete: false,
onCleanup: false,
onClosed: false,
rel: function() {
return this.rel;
},
href: function() {
// using this.href would give the absolute url, when the href may have been inteded as a selector (e.g. '#container')
return $(this).attr('href');
},
title: function() {
return this.title;
}
},
// Abstracting the HTML and event identifiers for easy rebranding
colorbox = 'colorbox',
prefix = 'cbox',
boxElement = prefix + 'Element',
// Events
event_open = prefix + '_open',
event_load = prefix + '_load',
event_complete = prefix + '_complete',
event_cleanup = prefix + '_cleanup',
event_closed = prefix + '_closed',
event_purge = prefix + '_purge',
// Cached jQuery Object Variables
$overlay,
$box,
$wrap,
$content,
$topBorder,
$leftBorder,
$rightBorder,
$bottomBorder,
$related,
$window,
$loaded,
$loadingBay,
$loadingOverlay,
$title,
$current,
$slideshow,
$next,
$prev,
$close,
$groupControls,
$events = $('<a/>'), // $({}) would be prefered, but there is an issue with jQuery 1.4.2
// Variables for cached values or use across multiple functions
settings,
interfaceHeight,
interfaceWidth,
loadedHeight,
loadedWidth,
index,
photo,
open,
active,
closing,
loadingTimer,
publicMethod,
div = "div",
requests = 0,
previousCSS = {},
init;
// ****************
// HELPER FUNCTIONS
// ****************
// Convenience function for creating new jQuery objects
function $tag(tag, id, css) {
var element = document.createElement(tag);
if (id) {
element.id = prefix + id;
}
if (css) {
element.style.cssText = css;
}
return $(element);
}
// Get the window height using innerHeight when available to avoid an issue with iOS
// http://bugs.jquery.com/ticket/6724
function winheight() {
return window.innerHeight ? window.innerHeight : $(window).height();
}
function Settings(element, options) {
if (options !== Object(options)) {
options = {};
}
this.cache = {};
this.el = element;
this.value = function(key) {
var dataAttr;
if (this.cache[key] === undefined) {
dataAttr = $(this.el).attr('data-cbox-'+key);
if (dataAttr !== undefined) {
this.cache[key] = dataAttr;
} else if (options[key] !== undefined) {
this.cache[key] = options[key];
} else if (defaults[key] !== undefined) {
this.cache[key] = defaults[key];
}
}
return this.cache[key];
};
this.get = function(key) {
var value = this.value(key);
return $.isFunction(value) ? value.call(this.el, this) : value;
};
}
// Determine the next and previous members in a group.
function getIndex(increment) {
var
max = $related.length,
newIndex = (index + increment) % max;
return (newIndex < 0) ? max + newIndex : newIndex;
}
// Convert '%' and 'px' values to integers
function setSize(size, dimension) {
return Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : winheight()) / 100) : 1) * parseInt(size, 10));
}
// Checks an href to see if it is a photo.
// There is a force photo option (photo: true) for hrefs that cannot be matched by the regex.
function isImage(settings, url) {
return settings.get('photo') || settings.get('photoRegex').test(url);
}
function retinaUrl(settings, url) {
return settings.get('retinaUrl') && window.devicePixelRatio > 1 ? url.replace(settings.get('photoRegex'), settings.get('retinaSuffix')) : url;
}
function trapFocus(e) {
if ('contains' in $box[0] && !$box[0].contains(e.target) && e.target !== $overlay[0]) {
e.stopPropagation();
$box.focus();
}
}
function setClass(str) {
if (setClass.str !== str) {
$box.add($overlay).removeClass(setClass.str).addClass(str);
setClass.str = str;
}
}
function getRelated(rel) {
index = 0;
if (rel && rel !== false && rel !== 'nofollow') {
$related = $('.' + boxElement).filter(function () {
var options = $.data(this, colorbox);
var settings = new Settings(this, options);
return (settings.get('rel') === rel);
});
index = $related.index(settings.el);
// Check direct calls to Colorbox.
if (index === -1) {
$related = $related.add(settings.el);
index = $related.length - 1;
}
} else {
$related = $(settings.el);
}
}
function trigger(event) {
// for external use
$(document).trigger(event);
// for internal use
$events.triggerHandler(event);
}
var slideshow = (function(){
var active,
className = prefix + "Slideshow_",
click = "click." + prefix,
timeOut;
function clear () {
clearTimeout(timeOut);
}
function set() {
if (settings.get('loop') || $related[index + 1]) {
clear();
timeOut = setTimeout(publicMethod.next, settings.get('slideshowSpeed'));
}
}
function start() {
$slideshow
.html(settings.get('slideshowStop'))
.unbind(click)
.one(click, stop);
$events
.bind(event_complete, set)
.bind(event_load, clear);
$box.removeClass(className + "off").addClass(className + "on");
}
function stop() {
clear();
$events
.unbind(event_complete, set)
.unbind(event_load, clear);
$slideshow
.html(settings.get('slideshowStart'))
.unbind(click)
.one(click, function () {
publicMethod.next();
start();
});
$box.removeClass(className + "on").addClass(className + "off");
}
function reset() {
active = false;
$slideshow.hide();
clear();
$events
.unbind(event_complete, set)
.unbind(event_load, clear);
$box.removeClass(className + "off " + className + "on");
}
return function(){
if (active) {
if (!settings.get('slideshow')) {
$events.unbind(event_cleanup, reset);
reset();
}
} else {
if (settings.get('slideshow') && $related[1]) {
active = true;
$events.one(event_cleanup, reset);
if (settings.get('slideshowAuto')) {
start();
} else {
stop();
}
$slideshow.show();
}
}
};
}());
function launch(element) {
var options;
if (!closing) {
options = $(element).data(colorbox);
settings = new Settings(element, options);
getRelated(settings.get('rel'));
if (!open) {
open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys.
setClass(settings.get('className'));
// Show colorbox so the sizes can be calculated in older versions of jQuery
$box.css({visibility:'hidden', display:'block', opacity:''});
$loaded = $tag(div, 'LoadedContent', 'width:0; height:0; overflow:hidden; visibility:hidden');
$content.css({width:'', height:''}).append($loaded);
// Cache values needed for size calculations
interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();
interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width();
loadedHeight = $loaded.outerHeight(true);
loadedWidth = $loaded.outerWidth(true);
// Opens inital empty Colorbox prior to content being loaded.
var initialWidth = setSize(settings.get('initialWidth'), 'x');
var initialHeight = setSize(settings.get('initialHeight'), 'y');
var maxWidth = settings.get('maxWidth');
var maxHeight = settings.get('maxHeight');
settings.w = (maxWidth !== false ? Math.min(initialWidth, setSize(maxWidth, 'x')) : initialWidth) - loadedWidth - interfaceWidth;
settings.h = (maxHeight !== false ? Math.min(initialHeight, setSize(maxHeight, 'y')) : initialHeight) - loadedHeight - interfaceHeight;
$loaded.css({width:'', height:settings.h});
publicMethod.position();
trigger(event_open);
settings.get('onOpen');
$groupControls.add($title).hide();
$box.focus();
if (settings.get('trapFocus')) {
// Confine focus to the modal
// Uses event capturing that is not supported in IE8-
if (document.addEventListener) {
document.addEventListener('focus', trapFocus, true);
$events.one(event_closed, function () {
document.removeEventListener('focus', trapFocus, true);
});
}
}
// Return focus on closing
if (settings.get('returnFocus')) {
$events.one(event_closed, function () {
$(settings.el).focus();
});
}
}
var opacity = parseFloat(settings.get('opacity'));
$overlay.css({
opacity: opacity === opacity ? opacity : '',
cursor: settings.get('overlayClose') ? 'pointer' : '',
visibility: 'visible'
}).show();
if (settings.get('closeButton')) {
$close.html(settings.get('close')).appendTo($content);
} else {
$close.appendTo('<div/>'); // replace with .detach() when dropping jQuery < 1.4
}
load();
}
}
// Colorbox's markup needs to be added to the DOM prior to being called
// so that the browser will go ahead and load the CSS background images.
function appendHTML() {
if (!$box) {
init = false;
$window = $(window);
$box = $tag(div).attr({
id: colorbox,
'class': $.support.opacity === false ? prefix + 'IE' : '', // class for optional IE8 & lower targeted CSS.
role: 'dialog',
tabindex: '-1'
}).hide();
$overlay = $tag(div, "Overlay").hide();
$loadingOverlay = $([$tag(div, "LoadingOverlay")[0],$tag(div, "LoadingGraphic")[0]]);
$wrap = $tag(div, "Wrapper");
$content = $tag(div, "Content").append(
$title = $tag(div, "Title"),
$current = $tag(div, "Current"),
$prev = $('<button type="button"/>').attr({id:prefix+'Previous'}),
$next = $('<button type="button"/>').attr({id:prefix+'Next'}),
$slideshow = $tag('button', "Slideshow"),
$loadingOverlay
);
$close = $('<button type="button"/>').attr({id:prefix+'Close'});
$wrap.append( // The 3x3 Grid that makes up Colorbox
$tag(div).append(
$tag(div, "TopLeft"),
$topBorder = $tag(div, "TopCenter"),
$tag(div, "TopRight")
),
$tag(div, false, 'clear:left').append(
$leftBorder = $tag(div, "MiddleLeft"),
$content,
$rightBorder = $tag(div, "MiddleRight")
),
$tag(div, false, 'clear:left').append(
$tag(div, "BottomLeft"),
$bottomBorder = $tag(div, "BottomCenter"),
$tag(div, "BottomRight")
)
).find('div div').css({'float': 'left'});
$loadingBay = $tag(div, false, 'position:absolute; width:9999px; visibility:hidden; display:none; max-width:none;');
$groupControls = $next.add($prev).add($current).add($slideshow);
}
if (document.body && !$box.parent().length) {
$(document.body).append($overlay, $box.append($wrap, $loadingBay));
}
}
// Add Colorbox's event bindings
function addBindings() {
function clickHandler(e) {
// ignore non-left-mouse-clicks and clicks modified with ctrl / command, shift, or alt.
// See: http://jacklmoore.com/notes/click-events/
if (!(e.which > 1 || e.shiftKey || e.altKey || e.metaKey || e.ctrlKey)) {
e.preventDefault();
launch(this);
}
}
if ($box) {
if (!init) {
init = true;
// Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly.
$next.click(function () {
publicMethod.next();
});
$prev.click(function () {
publicMethod.prev();
});
$close.click(function () {
publicMethod.close();
});
$overlay.click(function () {
if (settings.get('overlayClose')) {
publicMethod.close();
}
});
// Key Bindings
$(document).bind('keydown.' + prefix, function (e) {
var key = e.keyCode;
if (open && settings.get('escKey') && key === 27) {
e.preventDefault();
publicMethod.close();
}
if (open && settings.get('arrowKey') && $related[1] && !e.altKey) {
if (key === 37) {
e.preventDefault();
$prev.click();
} else if (key === 39) {
e.preventDefault();
$next.click();
}
}
});
if ($.isFunction($.fn.on)) {
// For jQuery 1.7+
$(document).on('click.'+prefix, '.'+boxElement, clickHandler);
} else {
// For jQuery 1.3.x -> 1.6.x
// This code is never reached in jQuery 1.9, so do not contact me about 'live' being removed.
// This is not here for jQuery 1.9, it's here for legacy users.
$('.'+boxElement).live('click.'+prefix, clickHandler);
}
}
return true;
}
return false;
}
// Don't do anything if Colorbox already exists.
if ($[colorbox]) {
return;
}
// Append the HTML when the DOM loads
$(appendHTML);
// ****************
// PUBLIC FUNCTIONS
// Usage format: $.colorbox.close();
// Usage from within an iframe: parent.jQuery.colorbox.close();
// ****************
publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
var settings;
var $obj = this;
options = options || {};
if ($.isFunction($obj)) { // assume a call to $.colorbox
$obj = $('<a/>');
options.open = true;
} else if (!$obj[0]) { // colorbox being applied to empty collection
return $obj;
}
if (!$obj[0]) { // colorbox being applied to empty collection
return $obj;
}
appendHTML();
if (addBindings()) {
if (callback) {
options.onComplete = callback;
}
$obj.each(function () {
var old = $.data(this, colorbox) || {};
$.data(this, colorbox, $.extend(old, options));
}).addClass(boxElement);
settings = new Settings($obj[0], options);
if (settings.get('open')) {
launch($obj[0]);
}
}
return $obj;
};
publicMethod.position = function (speed, loadedCallback) {
var
css,
top = 0,
left = 0,
offset = $box.offset(),
scrollTop,
scrollLeft;
$window.unbind('resize.' + prefix);
// remove the modal so that it doesn't influence the document width/height
$box.css({top: -9e4, left: -9e4});
scrollTop = $window.scrollTop();
scrollLeft = $window.scrollLeft();
if (settings.get('fixed')) {
offset.top -= scrollTop;
offset.left -= scrollLeft;
$box.css({position: 'fixed'});
} else {
top = scrollTop;
left = scrollLeft;
$box.css({position: 'absolute'});
}
// keeps the top and left positions within the browser's viewport.
if (settings.get('right') !== false) {
left += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.get('right'), 'x'), 0);
} else if (settings.get('left') !== false) {
left += setSize(settings.get('left'), 'x');
} else {
left += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2);
}
if (settings.get('bottom') !== false) {
top += Math.max(winheight() - settings.h - loadedHeight - interfaceHeight - setSize(settings.get('bottom'), 'y'), 0);
} else if (settings.get('top') !== false) {
top += setSize(settings.get('top'), 'y');
} else {
top += Math.round(Math.max(winheight() - settings.h - loadedHeight - interfaceHeight, 0) / 2);
}
$box.css({top: offset.top, left: offset.left, visibility:'visible'});
// this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
// but it has to be shrank down around the size of div#colorbox when it's done. If not,
// it can invoke an obscure IE bug when using iframes.
$wrap[0].style.width = $wrap[0].style.height = "9999px";
function modalDimensions() {
$topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = (parseInt($box[0].style.width,10) - interfaceWidth)+'px';
$content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = (parseInt($box[0].style.height,10) - interfaceHeight)+'px';
}
css = {width: settings.w + loadedWidth + interfaceWidth, height: settings.h + loadedHeight + interfaceHeight, top: top, left: left};
// setting the speed to 0 if the content hasn't changed size or position
if (speed) {
var tempSpeed = 0;
$.each(css, function(i){
if (css[i] !== previousCSS[i]) {
tempSpeed = speed;
return;
}
});
speed = tempSpeed;
}
previousCSS = css;
if (!speed) {
$box.css(css);
}
$box.dequeue().animate(css, {
duration: speed || 0,
complete: function () {
modalDimensions();
active = false;
// shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation.
$wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px";
$wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px";
if (settings.get('reposition')) {
setTimeout(function () { // small delay before binding onresize due to an IE8 bug.
$window.bind('resize.' + prefix, publicMethod.position);
}, 1);
}
if ($.isFunction(loadedCallback)) {
loadedCallback();
}
},
step: modalDimensions
});
};
publicMethod.resize = function (options) {
var scrolltop;
if (open) {
options = options || {};
if (options.width) {
settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth;
}
if (options.innerWidth) {
settings.w = setSize(options.innerWidth, 'x');
}
$loaded.css({width: settings.w});
if (options.height) {
settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight;
}
if (options.innerHeight) {
settings.h = setSize(options.innerHeight, 'y');
}
if (!options.innerHeight && !options.height) {
scrolltop = $loaded.scrollTop();
$loaded.css({height: "auto"});
settings.h = $loaded.height();
}
$loaded.css({height: settings.h});
if(scrolltop) {
$loaded.scrollTop(scrolltop);
}
publicMethod.position(settings.get('transition') === "none" ? 0 : settings.get('speed'));
}
};
publicMethod.prep = function (object) {
if (!open) {
return;
}
var callback, speed = settings.get('transition') === "none" ? 0 : settings.get('speed');
$loaded.remove();
$loaded = $tag(div, 'LoadedContent').append(object);
function getWidth() {
settings.w = settings.w || $loaded.width();
settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w;
return settings.w;
}
function getHeight() {
settings.h = settings.h || $loaded.height();
settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h;
return settings.h;
}
$loaded.hide()
.appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations.
.css({width: getWidth(), overflow: settings.get('scrolling') ? 'auto' : 'hidden'})
.css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height.
.prependTo($content);
$loadingBay.hide();
// floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width.
$(photo).css({'float': 'none'});
setClass(settings.get('className'));
callback = function () {
var total = $related.length,
iframe,
complete;
if (!open) {
return;
}
function removeFilter() { // Needed for IE8 in versions of jQuery prior to 1.7.2
if ($.support.opacity === false) {
$box[0].style.removeAttribute('filter');
}
}
complete = function () {
clearTimeout(loadingTimer);
$loadingOverlay.hide();
trigger(event_complete);
settings.get('onComplete');
};
$title.html(settings.get('title')).show();
$loaded.show();
if (total > 1) { // handle grouping
if (typeof settings.get('current') === "string") {
$current.html(settings.get('current').replace('{current}', index + 1).replace('{total}', total)).show();
}
$next[(settings.get('loop') || index < total - 1) ? "show" : "hide"]().html(settings.get('next'));
$prev[(settings.get('loop') || index) ? "show" : "hide"]().html(settings.get('previous'));
slideshow();
// Preloads images within a rel group
if (settings.get('preloading')) {
$.each([getIndex(-1), getIndex(1)], function(){
var img,
i = $related[this],
settings = new Settings(i, $.data(i, colorbox)),
src = settings.get('href');
if (src && isImage(settings, src)) {
src = retinaUrl(settings, src);
img = document.createElement('img');
img.src = src;
}
});
}
} else {
$groupControls.hide();
}
if (settings.get('iframe')) {
iframe = document.createElement('iframe');
if ('frameBorder' in iframe) {
iframe.frameBorder = 0;
}
if ('allowTransparency' in iframe) {
iframe.allowTransparency = "true";
}
if (!settings.get('scrolling')) {
iframe.scrolling = "no";
}
$(iframe)
.attr({
src: settings.get('href'),
name: (new Date()).getTime(), // give the iframe a unique name to prevent caching
'class': prefix + 'Iframe',
allowFullScreen : true // allow HTML5 video to go fullscreen
})
.one('load', complete)
.appendTo($loaded);
$events.one(event_purge, function () {
iframe.src = "//about:blank";
});
if (settings.get('fastIframe')) {
$(iframe).trigger('load');
}
} else {
complete();
}
if (settings.get('transition') === 'fade') {
$box.fadeTo(speed, 1, removeFilter);
} else {
removeFilter();
}
};
if (settings.get('transition') === 'fade') {
$box.fadeTo(speed, 0, function () {
publicMethod.position(0, callback);
});
} else {
publicMethod.position(speed, callback);
}
};
function load () {
var href, setResize, prep = publicMethod.prep, $inline, request = ++requests;
active = true;
photo = false;
trigger(event_purge);
trigger(event_load);
settings.get('onLoad');
settings.h = settings.get('height') ?
setSize(settings.get('height'), 'y') - loadedHeight - interfaceHeight :
settings.get('innerHeight') && setSize(settings.get('innerHeight'), 'y');
settings.w = settings.get('width') ?
setSize(settings.get('width'), 'x') - loadedWidth - interfaceWidth :
settings.get('innerWidth') && setSize(settings.get('innerWidth'), 'x');
// Sets the minimum dimensions for use in image scaling
settings.mw = settings.w;
settings.mh = settings.h;
// Re-evaluate the minimum width and height based on maxWidth and maxHeight values.
// If the width or height exceed the maxWidth or maxHeight, use the maximum values instead.
if (settings.get('maxWidth')) {
settings.mw = setSize(settings.get('maxWidth'), 'x') - loadedWidth - interfaceWidth;
settings.mw = settings.w && settings.w < settings.mw ? settings.w : settings.mw;
}
if (settings.get('maxHeight')) {
settings.mh = setSize(settings.get('maxHeight'), 'y') - loadedHeight - interfaceHeight;
settings.mh = settings.h && settings.h < settings.mh ? settings.h : settings.mh;
}
href = settings.get('href');
loadingTimer = setTimeout(function () {
$loadingOverlay.show();
}, 100);
if (settings.get('inline')) {
var $target = $(href);
// Inserts an empty placeholder where inline content is being pulled from.
// An event is bound to put inline content back when Colorbox closes or loads new content.
$inline = $('<div>').hide().insertBefore($target);
$events.one(event_purge, function () {
$inline.replaceWith($target);
});
prep($target);
} else if (settings.get('iframe')) {
// IFrame element won't be added to the DOM until it is ready to be displayed,
// to avoid problems with DOM-ready JS that might be trying to run in that iframe.
prep(" ");
} else if (settings.get('html')) {
prep(settings.get('html'));
} else if (isImage(settings, href)) {
href = retinaUrl(settings, href);
photo = new Image();
$(photo)
.addClass(prefix + 'Photo')
.bind('error',function () {
prep($tag(div, 'Error').html(settings.get('imgError')));
})
.one('load', function () {
if (request !== requests) {
return;
}
// A small pause because some browsers will occassionaly report a
// img.width and img.height of zero immediately after the img.onload fires
setTimeout(function(){
var percent;
$.each(['alt', 'longdesc', 'aria-describedby'], function(i,val){
var attr = $(settings.el).attr(val) || $(settings.el).attr('data-'+val);
if (attr) {
photo.setAttribute(val, attr);
}
});
if (settings.get('retinaImage') && window.devicePixelRatio > 1) {
photo.height = photo.height / window.devicePixelRatio;
photo.width = photo.width / window.devicePixelRatio;
}
if (settings.get('scalePhotos')) {
setResize = function () {
photo.height -= photo.height * percent;
photo.width -= photo.width * percent;
};
if (settings.mw && photo.width > settings.mw) {
percent = (photo.width - settings.mw) / photo.width;
setResize();
}
if (settings.mh && photo.height > settings.mh) {
percent = (photo.height - settings.mh) / photo.height;
setResize();
}
}
if (settings.h) {
photo.style.marginTop = Math.max(settings.mh - photo.height, 0) / 2 + 'px';
}
if ($related[1] && (settings.get('loop') || $related[index + 1])) {
photo.style.cursor = 'pointer';
photo.onclick = function () {
publicMethod.next();
};
}
photo.style.width = photo.width + 'px';
photo.style.height = photo.height + 'px';
prep(photo);
}, 1);
});
photo.src = href;
} else if (href) {
$loadingBay.load(href, settings.get('data'), function (data, status) {
if (request === requests) {
prep(status === 'error' ? $tag(div, 'Error').html(settings.get('xhrError')) : $(this).contents());
}
});
}
}
// Navigates to the next page/image in a set.
publicMethod.next = function () {
if (!active && $related[1] && (settings.get('loop') || $related[index + 1])) {
index = getIndex(1);
launch($related[index]);
}
};
publicMethod.prev = function () {
if (!active && $related[1] && (settings.get('loop') || index)) {
index = getIndex(-1);
launch($related[index]);
}
};
// Note: to use this within an iframe use the following format: parent.jQuery.colorbox.close();
publicMethod.close = function () {
if (open && !closing) {
closing = true;
open = false;
trigger(event_cleanup);
settings.get('onCleanup');
$window.unbind('.' + prefix);
$overlay.fadeTo(settings.get('fadeOut') || 0, 0);
$box.stop().fadeTo(settings.get('fadeOut') || 0, 0, function () {
$box.hide();
$overlay.hide();
trigger(event_purge);
$loaded.remove();
setTimeout(function () {
closing = false;
trigger(event_closed);
settings.get('onClosed');
}, 1);
});
}
};
// Removes changes Colorbox made to the document, but does not remove the plugin.
publicMethod.remove = function () {
if (!$box) { return; }
$box.stop();
$[colorbox].close();
$box.stop(false, true).remove();
$overlay.remove();
closing = false;
$box = null;
$('.' + boxElement)
.removeData(colorbox)
.removeClass(boxElement);
$(document).unbind('click.'+prefix).unbind('keydown.'+prefix);
};
// A method for fetching the current element Colorbox is referencing.
// returns a jQuery object.
publicMethod.element = function () {
return $(settings.el);
};
publicMethod.settings = defaults;
}(jQuery, document, window));
/*! nice Validator 0.7.3
* (c) 2012-2014 Jony Zhang <zj86@live.cn>, MIT Licensed
* http://niceue.com/validator/
*/
!function(e,t){"use strict";function i(n,s){var r=this;return!r instanceof i?new i(n,s):(r.$el=e(n),r._init(n,s),t)}function n(e,t){var i=t?t===!0?this:t:n.prototype;if(z(e))for(var s in e)i[s]=r(e[s])}function s(e,t){var i=t?t===!0?this:t:s.prototype;if(z(e))for(var n in e){if(!e[n])return;i[n]=e[n]}}function r(t){switch(e.type(t)){case"function":return t;case"array":return function(e){return t[0].test(e.value)||t[1]||!1};case"regexp":return function(e){return t.test(e.value)}}}function a(t){var i="";return e.map(t.split(" "),function(e){i+=","+("#"===e.charAt(0)?e:'[name="'+e+'"]')}),i.substring(1)}function l(t){var i;if(t&&t.tagName){switch(t.tagName){case"INPUT":case"SELECT":case"TEXTAREA":case"BUTTON":case"FIELDSET":i=t.form||e(t).closest("."+k);break;case"FORM":i=t;break;default:i=e(t).closest("."+k)}return e(i).data(h)||e(i)[h]().data(h)}}function u(e){var t,i=e.currentTarget;i.form&&null===K(i.form,q)&&(t=l(i),t?(t._parse(i),t["_"+e.type](e)):K(i,V,null))}function o(i,n){var s=e.trim(K(i,V+"-"+n));if(s)return s=Function("return "+s)(),s?r(s):t}function d(e,t,i,n){var s=t.msg,r=t._r;return z(s)&&(s=s[r]),Q(s)||(s=K(e,A+"-"+r)||K(e,A)||i||(n?Q(n)?n:n[r]:"")),s}function c(e){var t;return e&&(t=H.exec(e)),t?t[1]:""}function f(e){return"INPUT"===e.tagName&&"checkbox"===e.type||"radio"===e.type}function g(e){return Date.parse(e.replace(/\.|\-/g,"/"))}var p,m,h="validator",v="."+h,y=".rule",_=".field",b=".form",k="nice-"+h,w="n-ok",M="n-error",O="n-tip",$="n-loading",x="msg-box",C="aria-required",F="aria-invalid",V="data-rule",A="data-msg",R="data-tip",T="data-ok",S="data-target",E="data-inputstatus",q="novalidate",N=":verifiable",j=/(!?)\s?(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?\s*(;|\||&)?/g,D=/(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?/,I=/(?:([^:;\(\[]*):)?(.*)/,U=/[^\x00-\xff]/g,H=/^.*(top|right|bottom|left).*$/,L=/(?:(post|get):)?(.+)/i,P=/<|>/g,W=e.noop,B=e.proxy,X=e.isFunction,J=e.isArray,Q=function(e){return"string"==typeof e},z=function(e){return e&&"[object Object]"===Object.prototype.toString.call(e)},G=!window.XMLHttpRequest,K=function(e,i,n){return n===t?e.getAttribute(i):(null===n?e.removeAttribute(i):e.setAttribute(i,""+n),t)},Y=window.console||{log:W,info:W},Z={debug:0,timely:1,theme:"default",ignore:"",focusInvalid:!0,beforeSubmit:W,validClass:"n-valid",invalidClass:"n-invalid",msgWrapper:"span",msgMaker:function(e){var t,i={error:M,ok:w,tip:O,loading:$}[e.type];return t='<span class="msg-wrap '+i+'" role="alert">',t+=e.arrow+e.icon+'<span class="n-msg">'+e.msg+"</span>",t+="</span>"},msgIcon:'<span class="n-icon"></span>',msgArrow:"",msgClass:"",defaultMsg:"{0} is not valid.",loadingMsg:"Validating..."},et={"default":{formClass:"n-default",msgClass:"n-right",showOk:""}};e.fn[h]=function(t){var n=this,s=arguments;return n.is(":input")?n:(!n.is("form")&&(n=this.find("form")),!n.length&&(n=this),n.each(function(){var n=e(this).data(h);if(n)if(Q(t)){if("_"===t.charAt(0))return;n[t].apply(n,Array.prototype.slice.call(s,1))}else t&&(n._reset(!0),n._init(this,t));else new i(this,t)}),this)},e.fn.isValid=function(e,t){var i,n,s=l(this[0]),r=X(e);return s?(s.checkOnly=!!t,n=s.options,i=s._multiValidate(this.is(":input")?this:this.find(N),function(t){t||!n.focusInvalid||s.checkOnly||s.$el.find(":input["+F+"]:first").focus(),r&&e.call(null,t),s.checkOnly=!1}),r?this:i):!0},e.expr[":"].verifiable=function(e){var t=e.nodeName.toLowerCase();return("input"===t&&!{submit:1,button:1,reset:1,image:1}[e.type]||"select"===t||"textarea"===t)&&e.disabled===!1},i.prototype={_init:function(i,r){var l,u,o,d=this;if(X(r)&&(r={valid:r}),r=r||{},o=K(i,"data-"+h+"-option"),o=o&&"{"===o.charAt(0)?Function("return "+o)():{},u=et[r.theme||o.theme||Z.theme],l=d.options=e.extend({},Z,u,o,d.options,r),d.rules=new n(l.rules,!0),d.messages=new s(l.messages,!0),d.elements=d.elements||{},d.deferred={},d.errors={},d.fields={},d._initFields(l.fields),J(l.groups)&&e.map(l.groups,function(i){return Q(i.fields)&&X(i.callback)?(i.$elems=d.$el.find(a(i.fields)),e.map(i.fields.split(" "),function(e){d.fields[e]=d.fields[e]||{},d.fields[e].group=i}),t):null}),d.msgOpt={type:"error",pos:c(l.msgClass),wrapper:l.msgWrapper,cls:l.msgClass,style:l.msgStyle,icon:l.msgIcon,arrow:l.msgArrow,show:l.msgShow,hide:l.msgHide},d.isAjaxSubmit=!1,l.valid||!e.trim(K(i,"action")))d.isAjaxSubmit=!0;else{var f=e[e._data?"_data":"data"](i,"events");f&&f.valid&&e.map(f.valid,function(e){return-1!==e.namespace.indexOf("form")?1:null}).length&&(d.isAjaxSubmit=!0)}d.$el.data(h)||(d.$el.data(h,d).addClass(k+" "+l.formClass).on("submit"+v+" validate"+v,B(d,"_submit")).on("reset"+v,B(d,"_reset")).on("showtip"+v,B(d,"_showTip")).on("focusin"+v+" click"+v+" showtip"+v,N,B(d,"_focusin")).on("focusout"+v+" validate"+v,N,B(d,"_focusout")),l.timely>=2&&d.$el.on("keyup"+v+" paste"+v,N,B(d,"_focusout")).on("click"+v,":radio,:checkbox",B(d,"_focusout")).on("change"+v,'select,input[type="file"]',B(d,"_focusout")),d._novalidate=K(i,q),K(i,q,q))},_initFields:function(t){var i=this;z(t)&&e.each(t,function(e,t){if(null===t){var n=i.elements[e];n&&i._resetElement(n,!0),delete i.fields[e]}else i.fields[e]=Q(t)?{rule:t}:t}),i.$el.find(N).each(function(){i._parse(this)})},_parse:function(e){var t,i=this,n=e.name,s=K(e,V);s&&K(e,V,null),(e.id&&"#"+e.id in i.fields||!e.name)&&(n="#"+e.id),n&&(t=i.fields[n]||{},t.key=n,t.old={},t.rule=t.rule||s||"",t.rule&&(t.rule.match(/match|checked/)&&(t.must=!0),-1!==t.rule.indexOf("required")&&(t.required=!0,K(e,C,!0)),("timely"in t&&!t.timely||!i.options.timely)&&K(e,"notimely",!0),Q(t.target)&&K(e,S,t.target),Q(t.tip)&&K(e,R,t.tip),i.fields[n]=i._parseRule(t)))},_parseRule:function(e){var i=I.exec(e.rule),n=this.options;if(i)return e._i=0,i[1]&&(e.display=i[1]),!e.display&&n.display&&(e.display=n.display),i[2]&&(e.rules=[],i[2].replace(j,function(){var i=arguments;i[3]=i[3]||i[4],e.rules.push({not:"!"===i[1],method:i[2],params:i[3]?i[3].split(", "):t,or:"|"===i[5]})})),e},_multiValidate:function(i,n){var s=this,r=s.options;return s.verifying=!0,s.isValid=!0,r.ignore&&(i=i.not(r.ignore)),i.each(function(e,i){var n=s.getField(i);return n&&(s._validate(i,n),!s.isValid&&r.stopOnError)?!1:t}),e.when.apply(null,e.map(s.deferred,function(e){return e})).done(function(){n.call(s,s.isValid),s.verifying=!1}),e.isEmptyObject(s.deferred)?s.isValid:t},_submit:function(t){var i=this,n=i.options,s=t.target,r="submit"===t.type;t.preventDefault(),m&&~(m=!1)||i.submiting||"validate"===t.type&&i.$el[0]!==s||n.beforeSubmit.call(i,s)===!1||(n.debug&&Y.log("\n"+t.type),i._reset(),i.submiting=!0,i._multiValidate(i.$el.find(N),function(t){var a,l=t||2===n.debug?"valid":"invalid";t||(n.focusInvalid&&i.$el.find(":input["+F+'="true"]:first').focus(),a=e.map(i.errors,function(e){return e})),i.submiting=!1,X(n[l])&&n[l].call(i,s,a),i.$el.trigger(l+b,[s,a]),t&&!i.isAjaxSubmit&&r&&(m=!0,p&&p.name&&i.$el.append('<input type="hidden" name="'+p.name+'" value="'+e(p).val()+'">'),s.submit())}))},_reset:function(e){var t=this;t.errors={},e&&t.$el.find(N).each(function(e,i){t._resetElement(i)})},_resetElement:function(t,i){var n=this.options;e(t).removeClass(n.validClass+" "+n.invalidClass),this.hideMsg(t),i&&K(t,C,null)},_focusin:function(t){var i,n=this,s=n.options,r=t.target;n.verifying||("showtip"!==t.type&&"error"===K(r,E)&&s.focusCleanup&&(e(r).removeClass(s.invalidClass),n.hideMsg(r)),i=K(r,R),i&&n.showMsg(r,{type:"tip",msg:i}))},_focusout:function(t){var i,n,s=this,r=s.options,a=t.target,l=t.type,u={click:1,change:1,paste:1},o=0;if(!u[l]){if("validate"===l)n=!0;else{if(K(a,"notimely"))return;if(r.timely>=2&&"keyup"!==l)return}if(r.ignore&&e(a).is(r.ignore))return;if("keyup"===l){var d=t.keyCode,c={8:1,9:1,16:1,32:1,46:1};if(9===d&&!a.value)return;if(48>d&&!c[d])return;o=r.timely>=100?r.timely:500}}i=s.getField(a),i&&(o?(i._t&&clearTimeout(i._t),i._t=setTimeout(function(){s._validate(a,i,n)},o)):s._validate(a,i,n))},_showTip:function(e){var t=this;t.$el[0]===e.target&&t.$el.find(N+"["+R+"]").each(function(){t.showMsg(this,{msg:K(this,R),type:"tip"})})},_validatedField:function(t,i,n){var s=this,r=s.options,a=n.isValid=i.isValid=!!n.isValid,l=a?"valid":"invalid";n.key=i.key,n.rule=i._r,a?n.type="ok":(s.submiting&&(s.errors[i.key]=n.msg),s.isValid=!1),i.old.value=t.value,i.old.id=t.id,s.elements[i.key]=n.element=t,s.$el[0].isValid=a?s.isFormValid():a,X(i[l])&&i[l].call(s,t,n),e(t).attr(F,a?null:!0).removeClass(a?r.invalidClass:r.validClass).addClass(n.skip?"":a?r.validClass:r.invalidClass).trigger(l+_,[n,s]),s.$el.triggerHandler("validation",[n,s]),s.checkOnly||(i.msgMaker||r.msgMaker)&&s[n.showOk||n.msg?"showMsg":"hideMsg"](t,n,i)},_validatedRule:function(i,n,s,r){n=n||o.getField(i),r=r||{};var a,l,u,o=this,c=o.options,f=n._r,g=!1;if(null===s)return o._validatedField(i,n,{isValid:!0,skip:!0}),t;if(s===!0||s===t||""===s?g=!0:Q(s)?a=s:z(s)&&(s.error?a=s.error:(a=s.ok,g=!0)),n.rules&&(l=n.rules[n._i],l.not&&(a=t,g="required"===f||!g),l.or))if(g)for(;n._i<n.rules.length&&n.rules[n._i].or;)n._i++;else u=!0;u||(g?(r.isValid=g,c.showOk!==!1&&(Q(a)||(Q(n.ok)?a=n.ok:Q(K(i,T))?a=K(i,T):Q(c.showOk)&&(a=c.showOk)),Q(a)&&(r.showOk=g,r.msg=a)),e(i).trigger("valid"+y,[f,r.msg])):(r.msg=(d(i,n,a,o.messages[f])||Z.defaultMsg).replace("{0}",o._getDisplay(i,n.display||"")),e(i).trigger("invalid"+y,[f,r.msg]))),c.debug&&Y.log(" "+n._i+": "+f+" => "+(g||r.msg||g)),u||g&&n._i<n.rules.length-1?(n._i++,o._checkRule(i,n)):(n._i=0,o._validatedField(i,n,r))},_checkRule:function(i,n){var s,r,a=this,l=n.key,u=n.rules[n._i],d=u.method,c=u.params;a.submiting&&a.deferred[l]||(r=n.old,n._r=d,s=!n.must&&r.ret!==t&&r.rule===u&&r.id===i.id&&i.value&&r.value===i.value?r.ret:(o(i,d)||a.rules[d]||W).call(a,i,c,n),z(s)&&X(s.then)?(a.deferred[l]=s,!a.checkOnly&&a.showMsg(i,{type:"loading",msg:a.options.loadingMsg},n),s.then(function(s,l,o){var d,c=o.responseText,f=n.dataFilter||a.options.dataFilter;"json"===this.dataType?c=s:"{"===c.charAt(0)&&(c=e.parseJSON(c)||{}),X(f)||(f=function(e){return Q(e)||z(e)&&("error"in e||"ok"in e)?e:t}),d=f(c),d===t&&(d=f(c.data)),r.rule=u,r.ret=d,a._validatedRule(i,n,d)},function(e,t){a._validatedRule(i,n,t)}).always(function(){delete a.deferred[l]}),n.isValid=t):a._validatedRule(i,n,s))},_validate:function(i,n){if(!i.disabled&&null===K(i,q)){var s,r=this,a={},l=n.group,u=n.isValid=!0;if(n.rules||r._parse(i),r.options.debug&&Y.info(n.key),l&&(s=l.callback.call(r,l.$elems),s!==t&&(r.hideMsg(l.target,{},n),s===!0?s=t:(n._i=0,n._r="group",u=!1,r.hideMsg(i,{},n),e.extend(a,l)))),u&&!n.required&&!n.must&&!i.value){if("tip"===K(i,E))return;if(!f(i))return r._validatedField(i,n,{isValid:!0}),t}s!==t?r._validatedRule(i,n,s,a):n.rule&&r._checkRule(i,n)}},test:function(e,i){var n,s,r,a=this,l=D.exec(i);return l&&(s=l[1],s in a.rules&&(r=l[2]||l[3],r=r?r.split(", "):t,n=a.rules[s].call(a,e,r))),n===!0||n===t||null===n},getRangeMsg:function(e,t,i,n){if(t){var s=this,r=s.messages[i]||"",a=t[0].split("~"),l=a[0],u=a[1],o="rg",d=[""],c=+e===+e;if(2===a.length){if(l&&u){if(c&&e>=+l&&+u>=e)return!0;d=d.concat(a)}else if(l&&!u){if(c&&e>=+l)return!0;d.push(l),o="gte"}else if(!l&&u){if(c&&+u>=e)return!0;d.push(u),o="lte"}}else{if(e===+l)return!0;d.push(l),o="eq"}return r&&(n&&r[o+n]&&(o+=n),d[0]=r[o]),s.renderMsg.apply(null,d)}},renderMsg:function(){var e=arguments,t=e[0],i=e.length;if(t){for(;--i;)t=t.replace("{"+i+"}",e[i]);return t}},_getDisplay:function(e,t){return Q(t)?t:X(t)?t.call(this,e):""},_getMsgOpt:function(t){return e.extend({},this.msgOpt,Q(t)?{msg:t}:t)},_getMsgDOM:function(t,i){var n,s,r,a=e(t);if(a.is(":input")?(r=i.target||K(t,S),r&&(r=X(r)?r.call(this,t):this.$el.find(r),r.length&&(r.is(":input")?t=r.get(0):n=r)),n||(s=!f(t)&&t.id?t.id:t.name,n=this.$el.find(i.wrapper+"."+x+'[for="'+s+'"]'))):n=a,!n.length)if(a=this.$el.find(r||t),n=e("<"+i.wrapper+">").attr({"class":x+(i.cls?" "+i.cls:""),style:i.style||"","for":s}),f(t)){var l=a.parent();n.appendTo(l.is("label")?l.parent():l)}else n[i.pos&&"right"!==i.pos?"insertBefore":"insertAfter"](a);return n},showMsg:function(t,i,n){var s,r=this,a=r.options;if(i=r._getMsgOpt(i),(i.msg||i.showOk)&&(t=e(t).get(0),e(t).is(N)&&(K(t,E,i.type),n=n||r.getField(t),n&&(i.style=n.msgStyle||i.style,i.cls=n.msgClass||i.cls,i.wrapper=n.msgWrapper||i.wrapper,i.target=n.target||a.target)),s=(n||{}).msgMaker||a.msgMaker)){var l=r._getMsgDOM(t,i),u=l[0].className;!H.test(u)&&l.addClass(i.cls),G&&"bottom"===i.pos&&(l[0].style.marginTop=e(t).outerHeight()+"px"),l.html(s.call(r,i))[0].style.display="",X(i.show)&&i.show.call(r,l,i.type)}},hideMsg:function(t,i,n){var s=this,r=s.options;t=e(t).get(0),i=s._getMsgOpt(i),e(t).is(N)&&(K(t,E,null),K(t,F,null),n=n||s.getField(t),n&&(i.wrapper=n.msgWrapper||i.wrapper,i.target=n.target||r.target));var a=s._getMsgDOM(t,i);a.length&&(X(i.hide)?i.hide.call(s,a,i.type):a[0].style.display="none")},mapMsg:function(t){var i=this;e.each(t,function(e,t){var n=i.elements[e]||i.$el.find(':input[name="'+e+'"]')[0];i.showMsg(n,t)})},setMsg:function(e){new s(e,this.messages)},setRule:function(t){new n(t,this.rules),e.map(this.fields,function(e){e.old={}})},getField:function(e){var t,i=this;return t=e.id&&"#"+e.id in i.fields||!e.name?"#"+e.id:e.name,K(e,V)&&i._parse(e),i.fields[t]},setField:function(e,t){var i={};Q(e)?i[e]=t:z(e)&&(i=e),this._initFields(i)},isFormValid:function(){var e=this.fields;for(var t in e)if(!e[t].isValid)return e[t].isValid;return!0},holdSubmit:function(e){this.submiting=e===t||e},cleanUp:function(){this._reset(1)},destroy:function(){this._reset(1),this.$el.off(v).removeData(h),K(this.$el[0],q,this._novalidate)}},e(document).on("focusin",":input["+V+"]",function(e){u(e)}).on("click","input,button",function(e){var t=this,i=t.name;if(t.form)if("submit"===t.type)p=t,null!==K(t,q)&&(m=!0);else if(i&&f(t)){var n=t.form.elements[i];n.length&&(n=n[0]),K(n,V)&&u(e)}}).on("submit validate","form",function(t){if(null===K(this,q)){var i,n=e(this);n.data(h)||(i=n[h]().data(h),e.isEmptyObject(i.fields)?(K(this,q,q),n.off(v).removeData(h)):i._submit(t))}}),new n({required:function(t,i){var n=e.trim(t.value),s=!0;if(i)if(1===i.length){if(!n&&!this.test(t,i[0]))return K(t,C,null),null;K(t,C,!0)}else"not"===i[0]&&e.map(i.slice(1),function(t){n===e.trim(t)&&(s=!1)});return s&&!!n},integer:function(e,t){var i,n="0|",s="[1-9]\\d*",r=t?t[0]:"*";switch(r){case"+":i=s;break;case"-":i="-"+s;break;case"+0":i=n+s;break;case"-0":i=n+"-"+s;break;default:i=n+"-?"+s}return i="^(?:"+i+")$",RegExp(i).test(e.value)||this.messages.integer[r]},match:function(t,i,n){if(i){var s,r,a,l,u,o,d,c=this,f="eq";if(1===i.length?a=i[0]:(f=i[0],a=i[1]),u="#"===a.charAt(0)?a:':input[name="'+a+'"]',o=c.$el.find(u)[0]){if(d=c.getField(o),s=t.value,r=o.value,n._match||(c.$el.on("valid"+_+v,u,function(){e(t).trigger("validate")}),n._match=d._match=1),!n.required&&""===s&&""===r)return null;if(i[2]&&("date"===i[2]?(s=g(s),r=g(r)):"time"===i[2]&&(s=+s.replace(":",""),r=+r.replace(":",""))),"eq"!==f&&!isNaN(+s)&&isNaN(+r))return!0;switch(l=c.messages.match[f].replace("{1}",c._getDisplay(t,d.display||a)),f){case"lt":return+r>+s||l;case"lte":return+r>=+s||l;case"gte":return+s>=+r||l;case"gt":return+s>+r||l;case"neq":return s!==r||l;default:return s===r||l}}}},range:function(e,t){return this.getRangeMsg(+e.value,t,"range")},checked:function(t,i,n){if(f(t)){var s,r,a=this;return r=a.$el.find('input[name="'+t.name+'"]').filter(function(){var t=this;return!s&&f(t)&&(s=t),!t.disabled&&t.checked&&e(t).is(":visible")}).length,i?a.getRangeMsg(r,i,"checked"):!!r||d(s,n,"")||a.messages.required}},length:function(e,t){var i=e.value,n=(t[1]?i.replace(U,"xx"):i).length;return this.getRangeMsg(n,t,"length",t[1]?"_2":"")},remote:function(t,i){if(i){var n,s=this,r=L.exec(i[0]),a=r[2],l=(r[1]||"POST").toUpperCase(),u={};return u[t.name]=t.value,i[1]&&e.map(i.slice(1),function(t){var i,n=t.split(":");t=e.trim(n[0]),i=e.trim(n[1]||"")||t,u[t]=s.$el.find("#"===i.charAt(0)?i:':input[name="'+i+'"]').val()}),u=e.param(u),"POST"===l&&(n=a.indexOf("?"),-1!==n&&(u+="&"+a.substring(n+1,a.length),a=a.substring(0,n))),e.ajax({url:a,type:l,data:u,cache:!1})}},filter:function(e,t){e.value=e.value.replace(t?RegExp("["+t[0]+"]","gm"):P,"")}}),i.config=function(t){e.each(t,function(e,t){"rules"===e?new n(t):"messages"===e?new s(t):Z[e]=t})},i.setTheme=function(t,i){z(t)?e.each(t,function(e,t){et[e]=t}):Q(t)&&z(i)&&(et[t]=i)},e[h]=i}(jQuery);
/*********************************
* Themes, rules, and i18n support
* Locale: Chinese; 中文
*********************************/
(function(factory) {
if (typeof define === 'function') {
define(function(require, exports, module){
var $ = require('jquery');
$._VALIDATOR_URI = module.uri;
require('../src/jquery.validator')($);
factory($);
});
} else {
factory(jQuery);
}
}(function($) {
/* Global configuration
*/
$.validator.config({
//stopOnError: false,
//theme: 'yellow_right',
defaultMsg: "{0}格式不正确",
loadingMsg: "正在验证...",
// Custom rules
rules: {
digits: [/^\d+$/, "请输入数字"]
,letters: [/^[a-z]+$/i, "{0}只能输入字母"]
,tel: [/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/, "电话格式不正确"]
,mobile: [/^1[3-9]\d{9}$/, "手机号格式不正确"]
,email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "邮箱格式不正确"]
,qq: [/^[1-9]\d{4,}$/, "QQ号格式不正确"]
,date: [/^\d{4}-\d{1,2}-\d{1,2}$/, "请输入正确的日期,例:yyyy-mm-dd"]
,time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, "请输入正确的时间,例:14:30或14:30:00"]
,ID_card: [/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[A-Z])$/, "请输入正确的身份证号码"]
,url: [/^(https?|ftp):\/\/[^\s]+$/i, "网址格式不正确"]
,postcode: [/^[1-9]\d{5}$/, "邮政编码格式不正确"]
,chinese: [/^[\u0391-\uFFE5]+$/, "请输入中文"]
,username: [/^\w{3,12}$/, "请输入3-12位数字、字母、下划线"]
,password: [/^[0-9a-zA-Z]{6,16}$/, "密码由6-16位数字、字母组成"]
,accept: function (element, params){
if (!params) return true;
var ext = params[0];
return (ext === '*') ||
(new RegExp(".(?:" + (ext || "png|jpg|jpeg|gif") + ")$", "i")).test(element.value) ||
this.renderMsg("只接受{1}后缀", ext.replace('|', ','));
}
}
});
/* Default error messages
*/
$.validator.config({
messages: {
required: "{0}不能为空",
remote: "{0}已被使用",
integer: {
'*': "请输入整数",
'+': "请输入正整数",
'+0': "请输入正整数或0",
'-': "请输入负整数",
'-0': "请输入负整数或0"
},
match: {
eq: "{0}与{1}不一致",
neq: "{0}与{1}不能相同",
lt: "{0}必须小于{1}",
gt: "{0}必须大于{1}",
lte: "{0}必须小于或等于{1}",
gte: "{0}必须大于或等于{1}"
},
range: {
rg: "请输入{1}到{2}的数",
gte: "请输入大于或等于{1}的数",
lte: "请输入小于或等于{1}的数"
},
checked: {
eq: "请选择{1}项",
rg: "请选择{1}到{2}项",
gte: "请至少选择{1}项",
lte: "请最多选择{1}项"
},
length: {
eq: "请输入{1}个字符",
rg: "请输入{1}到{2}个字符",
gte: "请至少输入{1}个字符",
lte: "请最多输入{1}个字符",
eq_2: "",
rg_2: "",
gte_2: "",
lte_2: ""
}
}
});
/* Themes
*/
var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>';
$.validator.setTheme({
'simple_right': {
formClass: 'n-simple',
msgClass: 'n-right'
},
'simple_bottom': {
formClass: 'n-simple',
msgClass: 'n-bottom'
},
'yellow_top': {
formClass: 'n-yellow',
msgClass: 'n-top',
msgArrow: TPL_ARROW
},
'yellow_right': {
formClass: 'n-yellow',
msgClass: 'n-right',
msgArrow: TPL_ARROW
},
'yellow_right_effect': {
formClass: 'n-yellow',
msgClass: 'n-right',
msgArrow: TPL_ARROW,
msgShow: function($msgbox, type){
var $el = $msgbox.children();
if ($el.is(':animated')) return;
if (type === 'error') {
$el.css({
left: '20px',
opacity: 0
}).delay(100).show().stop().animate({
left: '-4px',
opacity: 1
}, 150).animate({
left: '3px'
}, 80).animate({
left: 0
}, 80);
} else {
$el.css({
left: 0,
opacity: 1
}).fadeIn(200);
}
},
msgHide: function($msgbox, type){
var $el = $msgbox.children();
$el.stop().delay(100).show().animate({
left: '20px',
opacity: 0
}, 300, function(){
$msgbox.hide();
});
}
}
});
}));
\ No newline at end of file
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon"> <link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
{% include 'link_css.html' %} {% include 'link_css.html' %}
{% include 'script.html' %}
</head> </head>
...@@ -26,7 +27,7 @@ ...@@ -26,7 +27,7 @@
</div> </div>
</div> </div>
{% include 'script.html' %} <!--{% include 'script.html' %}-->
</body> </body>
</html> </html>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
<link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet">
<link href="/static/css/animate.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/colorbox.css" rel="stylesheet">
<!-- Mainly scripts -->
<script src="/static/js/jquery-2.1.1.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
<!-- Peity -->
<script src="/static/js/plugins/peity/jquery.peity.min.js"></script>
<!-- Custom and plugin javascript -->
<script src="/static/js/inspinia.js"></script>
<script src="/static/js/plugins/pace/pace.min.js"></script>
<!-- iCheck -->
<script src="/static/js/plugins/iCheck/icheck.min.js"></script>
<!-- Peity -->
<script src="/static/js/demo/peity-demo.js"></script>
<!-- pop windows -->
<script src="/static/js/jquery.colorbox.js"></script>
<script>
$(document).ready(function(){
$(".iframe").colorbox({iframe:true, width:"90%", height:"90%"});
});
</script>
\ No newline at end of file
{% extends 'base.html' %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 填写业务组基本信息 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
{% if emg %}
<div class="alert alert-warning text-center">{{ emg }}</div>
{% endif %}
{% if smg %}
<div class="alert alert-success text-center">{{ smg }}</div>
{% endif %}
<form id="assetForm" method="post" class="form-horizontal">
<div class="form-group"><label class="col-sm-2 control-label"> 业务组名 </label>
<div class="col-sm-8"><input type="text" value="{{ j_group }}" placeholder="网站" name="j_group" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
<div class="col-sm-8"><input type="text" value="{{ j_comment }}" placeholder=包括web组所有主机 name="j_comment" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-5">
<button class="btn btn-white" type="submit"> 重置 </button>
<button class="btn btn-primary" type="submit"> 提交 </button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$('#assetForm').validator({
timely: 2,
theme: "yellow_right_effect",
fields: {
"j_group": {
rule: "required",
tip: "输入业务组名",
ok: "",
msg: {required: "业务组名必须填写!"},
data: {'data-ok':"业务组名可以使用"}
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5> IDC详细信息列表 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="">
<a target="_blank" href="/jasset/group_add" class="btn btn-sm btn-primary "> 添加 </a>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center"> ID </th>
<th class="text-center"> 机房名 </th>
<th class="text-center"> 备注 </th>
<th class="text-center"> 操作 </th>
</tr>
</thead>
<tbody>
{% for post in posts %}
<tr class="gradeX">
<td class="text-center"> {{ post.id }} </td>
<td class="text-center"> {{ post.name }} </td>
<td class="text-center"> {{ post.comment }} </td>
<td class="text-center">
<a href="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
<a href="/jasset/host_edit/{{ post.ip }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jasset/group_del/{{ post.id }}" class="btn btn-xs btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
\ No newline at end of file
...@@ -5,7 +5,13 @@ ...@@ -5,7 +5,13 @@
<div class="row"> <div class="row">
<div class="col-lg-10"> <div class="col-lg-10">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="text-center">
<span>请选择添加内容: </span>
<a href="#" class="btn btn-xs btn-primary" id="addhost">添加主机</a>
<a href="#" class="btn btn-xs btn-primary" id="addidc">添加IDC</a>
<a href="#" class="btn btn-xs btn-primary" id="addbis">添加业务组</a>
</div>
<div id="ibox-content" class="ibox-title">
<h5> 填写主机基本信息 </h5> <h5> 填写主机基本信息 </h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
...@@ -30,49 +36,51 @@ ...@@ -30,49 +36,51 @@
{% if emg %} {% if emg %}
<div class="alert alert-warning text-center">{{ emg }}</div> <div class="alert alert-warning text-center">{{ emg }}</div>
{% endif %} {% endif %}
<form method="post" class="form-horizontal"> {% if smg %}
<div class="alert alert-success text-center">{{ smg }}</div>
{% endif %}
<form id="assetForm" method="post" class="form-horizontal">
<div class="form-group"><label class="col-sm-2 control-label"> IP地址 </label> <div class="form-group"><label class="col-sm-2 control-label"> IP地址 </label>
<div class="col-sm-8"><input type="text" value="{{ j_ip }}" placeholder="192.168.1.1" name="j_ip" class="form-control"></div> <div class="col-sm-8"><input type="text" name="j_ip" placeholder="192.168.1.1" class="form-control"></div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 端口号 </label> <div class="form-group"><label class="col-sm-2 control-label"> 端口号 </label>
<div class="col-sm-8"><input type="text" value="{{ s_port }}" placeholder="22" name="j_port" class="form-control"></div> <div class="col-sm-8"><input type="text" placeholder="22" name="j_port" class="form-control"></div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 登录方式 </label> <div class="form-group"><label class="col-sm-2 control-label"> 登录方式 </label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="radio i-checks"><label> <input type="radio" checked="" value="LDAP" name="j_type" onclick="show(this)"> <i> LDAP </i></label></div> <div class="radio i-checks"><label> <input type="radio" id="L" checked="" value="L" name="j_type" onclick="show(this)"> <i> LDAP </i></label></div>
<div class="radio i-checks"><label> <input type="radio" value="SSH_KEY" name="j_type" onclick="show(this)"> <i> SSH_KEY </i></label></div> <div class="radio i-checks"><label> <input type="radio" id="S" value="S" name="j_type" onclick="show(this)"> <i> SSH_KEY </i></label></div>
<div class="radio i-checks"><label> <input type="radio" value="PASSWORD" name="j_type" onclick="show(this)"> <i> PASSWORD </i></label></div> <div class="radio i-checks"><label> <input type="radio" id="P" value="P" name="j_type" onclick="show(this)"> <i> PASSWORD </i></label></div>
<div class="radio i-checks"><label> <input type="radio" value="MAP" name="j_type" onclick="show(this)"> <i> MAP </i></label></div> <div class="radio i-checks"><label> <input type="radio" id="M" value="M" name="j_type" onclick="show(this)"> <i> MAP </i></label></div>
</div> </div>
<div name="a1" id=a1 style="display:none;"> <div name="a1" id=a1 style="display:none;">
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 普通用户名 </label> <div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 普通用户名 </label>
<div class="col-sm-6"><input type="text" value="{{ j_user }}" name="j_user" placeholder="lilei" class="form-control"></div> <div class="col-sm-6"><input type="text" name="j_user" placeholder="lilei" class="form-control"></div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 普通用户密码 </label> <div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 普通用户密码 </label>
<div class="col-sm-6"><input type="password" value="{{ j_password }}" name="j_password" placeholder="Password" class="form-control"></div> <div class="col-sm-6"><input type="password" name="j_password" placeholder="Password" class="form-control"></div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 超管用户名 </label> <div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 超管用户名 </label>
<div class="col-sm-6"><input type="text" value="{{ j_root }}" name="j_root" placeholder="root" class="form-control"></div> <div class="col-sm-6"><input type="text" name="j_root" placeholder="root" class="form-control"></div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 超管用户密码 </label> <div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 超管用户密码 </label>
<div class="col-sm-6"><input type="password" value="{{ j_passwd }}" name="j_passwd" placeholder="Password" class="form-control"></div> <div class="col-sm-6"><input type="password" name="j_passwd" placeholder="Password" class="form-control"></div>
</div> </div>
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<label for="j_idc" class="col-lg-2 control-label"> 所属IDC </label> <label for="j_idc" class="col-lg-2 control-label"> 所属IDC </label>
...@@ -98,8 +106,8 @@ ...@@ -98,8 +106,8 @@
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 是否激活 </label> <div class="form-group"><label class="col-sm-2 control-label"> 是否激活 </label>
<div class="col-sm-8"> <div class="col-sm-8">
<div class="radio i-checks"><label> <input type="radio" checked="" value="active" name="j_active"> <i> 激活 </i></label></div> <div class="radio i-checks"><label> <input type="radio" checked="" value="1" name="j_active"> <i> 激活 </i></label></div>
<div class="radio i-checks"><label> <input type="radio" value="no_active" name="j_active"> <i> 禁用 </i></label></div> <div class="radio i-checks"><label> <input type="radio" value="0" name="j_active"> <i> 禁用 </i></label></div>
</div> </div>
</div> </div>
...@@ -111,7 +119,7 @@ ...@@ -111,7 +119,7 @@
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-5"> <div class="col-sm-4 col-sm-offset-5">
<button class="btn btn-white" type="submit"> 重置 </button> <!--<button class="btn btn-white" type="submit"> 重置 </button>-->
<button class="btn btn-primary" type="submit"> 提交 </button> <button class="btn btn-primary" type="submit"> 提交 </button>
</div> </div>
</div> </div>
...@@ -122,19 +130,74 @@ ...@@ -122,19 +130,74 @@
</div> </div>
</div> </div>
<script> <script>
var showFlag={}; var showFlag={};
function show(o){ function show(o){
showFlag[o.name]=o.value; showFlag[o.name]=o.value;
if(showFlag.j_type=="MAP"){ if(showFlag.j_type=="M"){
document.getElementById("a1").style.display=""; document.getElementById("a1").style.display="";
} }
else{ else{
document.getElementById("a1").style.display="none"; document.getElementById("a1").style.display="none";
}}; }};
$('#assetForm').validator({
timely: 2,
theme: "yellow_right_effect",
rules: {
check_ip: [/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/, 'ip地址不正确'],
check_port: [/^\d{1,5}$/, '端口号不正确'],
type_m: function(element){
return $("#M").is(":checked");
}
},
fields: {
"j_ip": {
rule: "required;check_ip",
tip: "输入IP",
ok: "",
msg: {required: "必须填写!"}
},
"j_port": {
rule: "required;check_port",
tip: "输入端口号",
ok: "",
msg: {required: "必须填写!"}
},
"j_group": {
rule: "checked",
tip: "选择业务组",
ok: "",
msg: {checked: "至少选择一个组"}
},
"j_user": {
rule: "required(type_m)",
tip: "普通用户名",
ok: "",
msg: {required: "请填写用户名"}
},
"j_password": {
rule: "required(type_m);length[6~16]",
tip: "密码6-16位",
ok: "",
msg: {required: "6-16位"}
},
"j_root": {
rule: "required(type_m)",
tip: "超管用户名",
ok: "",
msg: {required: "请填写用户名"}
},
"j_passwd": {
rule: "required(type_m);length[6~16]",
tip: "密码6-16位",
ok: "",
msg: {required: "6-16位"}
}
},
valid: function(form) {
form.submit();
}
});
</script> </script>
......
{% extends 'base.html' %}
{% load mytags %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 填写主机基本信息 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
{% if emg %}
<div class="alert alert-warning text-center">{{ emg }}</div>
{% endif %}
{% if smg %}
<div class="alert alert-success text-center">{{ smg }}</div>
{% endif %}
<form id="assetForm" method="post" class="form-horizontal" autocomplete="off">
<div class="form-group"><label class="col-sm-2 control-label"> IP地址 </label>
<div class="col-sm-8"><input type="text" name="j_ip" value="{{ post.ip }}" placeholder="192.168.1.1" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 端口号 </label>
<div class="col-sm-8"><input type="text" placeholder="22" name="j_port" value="{{ post.port }}" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 登录方式 </label>
<div class="col-sm-8">
{% for t, type in login_types.items %}
{% ifequal t post.login_type %}
<div class="radio i-checks"><label> <input type="radio" id="{{ t }}" checked value="{{ t }}" name="j_type" onclick="show(this)"> <i> {{ type }} </i></label></div>
{% else %}
<div class="radio i-checks"><label> <input type="radio" id="{{ t }}" value="{{ t }}" name="j_type" onclick="show(this)"> <i> {{ type }} </i></label></div>
{% endifequal %}
{% endfor %}
</div>
<div name="a1" id=a1 style="display:none;">
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 普通用户名 </label>
<div class="col-sm-6"><input type="text" value="{{ post.username_common }}" name="j_user" placeholder="lilei" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 普通用户密码 </label>
<div class="col-sm-6"><input type="password" value="{{ post.password_common }}" name="j_password" placeholder="Password" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 超管用户名 </label>
<div class="col-sm-6"><input type="text" value="{{ post.username_super }}" name="j_root" placeholder="root" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 col-sm-offset-1 control-label"> 超管用户密码 </label>
<div class="col-sm-6"><input type="password" value="{{ post.password_super }}" name="j_passwd" placeholder="Password" class="form-control"></div>
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="j_idc" class="col-lg-2 control-label"> 所属IDC </label>
<div class="col-sm-8">
<select id="j_idc" name="j_idc" class="form-control m-b">
{% for i in eidc %}
{% ifequal i.id post.idc_id %}
<option selected> {{ i }} </option>
{% else %}
<option> {{ i }} </option>
{% endifequal %}
{% endfor %}
</select>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<label for="j_group" class="col-sm-2 control-label"> 所属业务组 </label>
<div class="col-sm-8">
{% for g in egroup %}
{% if g in e_group %}
<label class="checkbox-inline"><input type="checkbox" id="j_group" checked value="{{ g }}" name="j_group"> {{ g }} </label>
{% else %}
<label class="checkbox-inline"><input type="checkbox" id="j_group" value="{{ g }}" name="j_group"> {{ g }} </label>
{% endif %}
{% endfor %}
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 是否激活 </label>
<div class="col-sm-8">
{% for a,active in actives.items %}
{% ifequal a post.is_active %}
<div class="radio i-checks"><label> <input type="radio" checked value="{{ a }}" name="j_active"> <i> {{ active }} </i></label></div>
{% else %}
<div class="radio i-checks"><label> <input type="radio" value="{{ a }}" name="j_active"> <i> {{ active }} </i></label></div>
{% endifequal %}
{% endfor %}
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
<div class="col-sm-8"><input type="text" placeholder="hadoop01" value="{{ post.comment }}" name="j_comment" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-5">
<button class="btn btn-white" type="submit"> 重置 </button>
<button class="btn btn-primary" type="submit"> 提交 </button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
var showFlag={};
function show(o){
showFlag[o.name]=o.value;
if(showFlag.j_type=="M"){
document.getElementById("a1").style.display="";
}
else{
document.getElementById("a1").style.display="none";
}};
$('#assetForm').validator({
timely: 2,
theme: "yellow_right_effect",
rules: {
check_ip: [/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/, 'ip地址不正确'],
check_port: [/^\d{1,5}$/, '端口号不正确'],
type_m: function(element){
return $("#M").is(":checked");
}
},
fields: {
"j_ip": {
rule: "required;check_ip",
tip: "输入IP",
ok: "",
msg: {required: "必须填写!"}
},
"j_port": {
rule: "required;check_port",
tip: "输入端口号",
ok: "",
msg: {required: "必须填写!"}
},
"j_group": {
rule: "checked",
tip: "选择业务组",
ok: "",
msg: {checked: "至少选择一个组"}
},
"j_user": {
rule: "required(type_m)",
tip: "普通用户名",
ok: "",
msg: {required: "请填写用户名"}
},
"j_password": {
rule: "required(type_m);length[6~16]",
tip: "密码6-16位",
ok: "",
msg: {required: "6-16位"}
},
"j_root": {
rule: "required(type_m)",
tip: "超管用户名",
ok: "",
msg: {required: "请填写用户名"}
},
"j_passwd": {
rule: "required(type_m);length[6~16]",
tip: "密码6-16位",
ok: "",
msg: {required: "6-16位"}
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %} {% extends 'base.html' %}
{% load mytags %}
{% block content %} {% block content %}
{% include 'nav_cat_bar.html' %} {% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
<div class="row"> <div class="row">
<div class="col-lg-10"> <div class="col-lg-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5> 主机详细信息列表 </h5> <h5> 主机详细信息列表 </h5>
...@@ -29,35 +30,43 @@ ...@@ -29,35 +30,43 @@
<div class="ibox-content"> <div class="ibox-content">
<div class=""> <div class="">
<a onclick="fnClickAddRow();" href="javascript:void(0);" class="btn btn-primary "> 添加 </a> <a target="_blank" href="/jasset/host_add" class="btn btn-sm btn-primary "> 添加 </a>
</div> </div>
<table class="table table-striped table-bordered table-hover " id="editable" > <table class="table table-striped table-bordered table-hover " id="editable" >
<thead> <thead>
<tr> <tr>
<th> IP地址 </th> <th class="text-center"><input type="checkbox" class="i-checks" name=""></th>
<th> 端口号 </th> <th class="text-center"> IP地址 </th>
<th> 登录方式 </th> <th class="text-center"> 端口号 </th>
<th> 所属IDC </th> <th class="text-center"> 登录方式 </th>
<th> 所属业务组 </th> <th class="text-center"> 所属IDC </th>
<th> 添加时间 </th> <th class="text-center"> 所属业务组 </th>
<th> 备注 </th> <th class="text-center"> 添加时间 </th>
<th class="text-center"> 备注 </th>
<th class="text-center"> 操作 </th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for post in contacts.object_list %} {% for post in contacts.object_list %}
<tr class="gradeX"> <tr class="gradeX">
<td> {{ post.ip }} </td> <td class="text-center"><input type="checkbox" class="i-checks" name=""></td>
<td> {{ post.port }} </td> <td class="text-center"> {{ post.ip }} </td>
<td> {{ post.login_type}} </td> <td class="text-center"> {{ post.port }} </td>
<td class="center"> {{ post.idc.name }} </td> <td class="text-center"> {{ login_types|get_item:post.login_type }} </td>
<td class="center"> <td class="text-center"> {{ post.idc.name }} </td>
{% for group in post.group.all %} <td class="text-center">
{% for group in post.bis_group.all %}
{{ group }} {{ group }}
{% endfor %} {% endfor %}
</td> </td>
<td class="center"> {{ post.date_added }} </td> <td class="text-center"> {{ post.date_added }} </td>
<td class="center"> {{ post.comment }} </td> <td class="text-center"> {{ post.comment }} </td>
<td class="text-center">
<a href="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
<a href="/jasset/host_edit/{{ post.ip }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jasset/host_del/{{ post.ip }}" class="btn btn-xs btn-danger">删除</a>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
...@@ -85,4 +94,10 @@ ...@@ -85,4 +94,10 @@
</div> </div>
</div> </div>
<script>
$(document).ready(function(){
$(".iframe").colorbox({iframe:true, width:"70%", height:"70%"});
});
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div id="ibox-content" class="ibox-title">
<h5> 填写IDC基本信息 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
{% if emg %}
<div class="alert alert-warning text-center">{{ emg }}</div>
{% endif %}
{% if smg %}
<div class="alert alert-success text-center">{{ smg }}</div>
{% endif %}
<form id="assetForm" method="post" class="form-horizontal">
<div class="form-group"><label class="col-sm-2 control-label"> IDC名 </label>
<div class="col-sm-8"><input type="text" value="{{ j_ip }}" placeholder="北京联通" name="j_idc" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label"> 备注 </label>
<div class="col-sm-8"><input type="text" value="{{ s_port }}" placeholder="核心联通机房" name="j_comment" class="form-control"></div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-5">
<button class="btn btn-white" type="submit"> 重置 </button>
<button class="btn btn-primary" type="sumbit"> 提交 </button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$('#assetForm').validator({
timely: 2,
theme: "yellow_right_effect",
fields: {
"j_idc": {
rule: "required",
tip: "输入IDC名",
ok: "",
msg: {required: "IDC名必须填写!"},
data: {'data-ok':"主机名可以使用", 'data-msg-required': '主机名已正确'}
}
},
valid: function(form) {
form.submit();
}
});
</script>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% block content %}
{% include 'nav_cat_bar.html' %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-lg-10">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5> IDC详细信息列表 </h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="#">未启用 1</a>
</li>
<li><a href="#">未启用 2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="">
<a target="_blank" href="/jasset/idc_add" class="btn btn-sm btn-primary "> 添加 </a>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center"> ID </th>
<th class="text-center"> 机房名 </th>
<th class="text-center"> 备注 </th>
<th class="text-center"> 操作 </th>
</tr>
</thead>
<tbody>
{% for post in posts %}
<tr class="gradeX">
<td class="text-center"> {{ post.id }} </td>
<td class="text-center"> {{ post.name }} </td>
<td class="text-center"> {{ post.comment }} </td>
<td class="text-center">
<a href="/jasset/{{ post.ip }}/" class="iframe btn btn-xs btn-primary">详情</a>
<a href="/jasset/host_edit/{{ post.ip }}" class="btn btn-xs btn-info">编辑</a>
<a href="/jasset/idc_del/{{ post.id }}" class="btn btn-xs btn-danger">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
\ No newline at end of file
<html>
<head>
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
<link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet">
<link href="/static/css/animate.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/colorbox.css" rel="stylesheet">
<!-- Mainly scripts -->
<script src="/static/js/jquery-2.1.1.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
<style type="text/css">
body
{
background: #FFFFFF;
}
</style>
</head>
<body>
<div class="row">
<div class="contact-box">
<h2 class="text-center">{{ offset }}主机详情</h2>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th> IP地址 </th>
<th> 端口号 </th>
<th> 登录方式 </th>
<th> 所属IDC </th>
<th> 所属业务组 </th>
<th> 添加时间 </th>
<th> 备注 </th>
</tr>
</thead>
<tbody>
<tr class="gradeX">
<td> <a class="iframe" href="/jasset/{{ post.ip }}/">{{ post.ip }}</a></td>
<td> {{ post.port }} </td>
<td> {{ post.get_login_type}} </td>
<td class="center"> {{ post.idc.name }} </td>
<td class="center">
{% for group in post.bis_group.all %}
{{ group }}
{% endfor %}
</td>
<td class="center"> {{ post.date_added }} </td>
<td class="center"> {{ post.comment }} </td>
</tr>
</tbody>
</table>
<a> 是否激活: {{ post.is_active }}</a>
</div>
</div>
</body>
</html>
\ No newline at end of file
<div id="result" class="tip-ok" style="display:none">提交成功</div>
<form id="signup_form" class="signup" autocomplete="off">
<fieldset>
<div class="form-item">
<div class="field-name">全名</div>
<div class="field-input">
<input type="text" name="user[name]" maxlength="20" autocomplete="off">
</div>
</div>
<div class="form-item">
<div class="field-name">电子邮件地址</div>
<div class="field-input">
<input type="text" name="user[email]" autocomplete="off">
</div>
</div>
<div class="form-item">
<div class="field-name">创建密码</div>
<div class="field-input">
<input type="password" name="user[user_password]">
</div>
</div>
<div class="form-item">
<div class="field-name">选择你的用户名</div>
<div class="field-input">
<input type="text" name="user[screen_name]" maxlength="15" autocomplete="off">
</div>
</div>
</fieldset>
<button id="btn-submit" class="btn-submit" type="submit">创建我的账号</button>
</form>
\ No newline at end of file
...@@ -3,3 +3,5 @@ ...@@ -3,3 +3,5 @@
<link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet"> <link href="/static/css/plugins/iCheck/custom.css" rel="stylesheet">
<link href="/static/css/animate.css" rel="stylesheet"> <link href="/static/css/animate.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet"> <link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/colorbox.css" rel="stylesheet">
<link href="/static/css/vaildator/jquery.validator.css" rel="stylesheet">
\ No newline at end of file
...@@ -23,10 +23,12 @@ ...@@ -23,10 +23,12 @@
<li> <li>
<a href="mailbox.html"><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a> <a href="mailbox.html"><i class="fa fa-cube"></i> <span class="nav-label">资产管理</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li><a href="/jasset/jlist/">查看资产</a></li> <li><a href="/jasset/host_list/">查看资产</a></li>
<li><a href="/jasset/jadd/">添加资产</a></li> <li><a href="/jasset/host_add/">添加资产</a></li>
<li><a href="/idc/showlist/">查看机房</a></li> <li><a href="/jasset/idc_list/">查看机房</a></li>
<li><a href="/idc/add/">添加机房</a></li> <li><a href="/jasset/idc_add/">添加机房</a></li>
<li><a href="/jasset/group_list/">查看业务组</a></li>
<li><a href="/jasset/group_add/">添加业务组</a></li>
</ul> </ul>
</li> </li>
<li> <li>
......
...@@ -17,12 +17,19 @@ ...@@ -17,12 +17,19 @@
<!-- Peity --> <!-- Peity -->
<script src="/static/js/demo/peity-demo.js"></script> <script src="/static/js/demo/peity-demo.js"></script>
<script> <!--<script>-->
$(document).ready(function(){ <!--$(document).ready(function(){-->
$('.i-checks').iCheck({ <!--$('.i-checks').iCheck({-->
checkboxClass: 'icheckbox_square-green', <!--checkboxClass: 'icheckbox_square-green',-->
radioClass: 'iradio_square-green', <!--radioClass: 'iradio_square-green',-->
}); <!--});-->
}); <!--});-->
</script> <!--</script>-->
<!-- pop windows -->
<script src="/static/js/jquery.colorbox.js"></script>
<!-- validator js -->
<script src="/static/js/validator/jquery.validator.js"></script>
<script src="/static/js/validator/zh_CN.js"></script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment