From 34ccdd5e0e285dd8bb92ba6bb4fedbf372d58668 Mon Sep 17 00:00:00 2001 From: sxw Date: Wed, 5 Aug 2015 19:38:28 +0800 Subject: [PATCH 1/5] =?UTF-8?q?1.=E4=BB=BF=E7=85=A7=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8D=E5=86=99=E4=BA=86=E5=8E=9FusernameCheck=E7=9A=84valid?= =?UTF-8?q?ator=E3=80=82=E9=87=8D=E5=91=BD=E5=90=8D=E4=B8=BAremoteCSRF?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E4=BD=BF=E7=94=A8ajax=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E5=90=91=E6=9C=8D=E5=8A=A1=E5=99=A8=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=94=AF=E4=B8=80=E6=80=A7=E3=80=82=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E4=B8=BAurl=EF=BC=9A=E8=AF=B7=E6=B1=82=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=EF=BC=8Cfield=EF=BC=9A=E5=90=91=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E5=8F=91=E9=80=81=E7=9A=84=E8=A1=A8=E7=A4=BA=E7=AC=A6?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=EF=BC=9B=202.=E6=B7=BB=E5=8A=A0=E4=BA=86emai?= =?UTF-8?q?lAddress=E7=9A=84validator=E7=9A=84requires.js=E7=9A=84config.?= =?UTF-8?q?=20[ci=20skip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/config.js | 5 +- .../formValidation/validator/remoteCSRF.js | 46 +++++++++++++++++++ .../formValidation/validator/usernameCheck.js | 37 --------------- static/src/js/utils/validation.js | 3 +- 4 files changed, 51 insertions(+), 40 deletions(-) create mode 100644 static/src/js/lib/formValidation/validator/remoteCSRF.js delete mode 100644 static/src/js/lib/formValidation/validator/usernameCheck.js diff --git a/static/src/js/config.js b/static/src/js/config.js index 3907d1c9..30f49699 100644 --- a/static/src/js/config.js +++ b/static/src/js/config.js @@ -26,8 +26,9 @@ var require = { "validator/date": "lib/formValidation/validator/date", "validator/integer": "lib/formValidation/validator/integer", "validator/between": "lib/formValidation/validator/between", - 'validator/confirm':"lib/formValidation/validator/confirm", - "validator/usernameCheck":"lib/formValidation/validator/usernameCheck", + "validator/confirm":"lib/formValidation/validator/confirm", + "validator/remoteCSRF":"lib/formValidation/validator/remoteCSRF", + "validator/emailAddress":"lib/formValidation/validator/emailAddress", //富文本编辑器 不要直接使用,而是使用上面的editor simditor: "lib/simditor/simditor", "simple-module": "lib/simditor/module", diff --git a/static/src/js/lib/formValidation/validator/remoteCSRF.js b/static/src/js/lib/formValidation/validator/remoteCSRF.js new file mode 100644 index 00000000..9cab354f --- /dev/null +++ b/static/src/js/lib/formValidation/validator/remoteCSRF.js @@ -0,0 +1,46 @@ +/** + * remoteCSRF validator + */ +(function(root, factory) { + + "use strict"; + + // AMD module is defined + if (typeof define === "function" && define.amd) { + define("validator/remoteCSRF", ["jquery", "base", "csrf"], factory); + } else { + // planted over the root! + factory(root.jQuery, root.FormValidation); + } +}(this, function ($, FormValidation, csrfHeader) { + FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, { + 'en_US': { + remoteCSRF: { + 'default': '' + } + } + }); + FormValidation.Validator.remoteCSRF = { + validate: function(validator, $field, options) { + var dfd = new $.Deferred(), ajaxData = {}; + ajaxData[options.field] = $field.val(); + if ($field.val() === '') + return true; + var url = options.url; + var xhr = $.ajax({ + beforeSend: csrfHeader, + url: url, + dataType: 'json', + data: ajaxData, + method: "post" + }); + xhr.success(function(response) { + dfd.resolve($field, 'remoteCSRF',{valid:!response.data, message:options.msg}); + }) + .error(function(response) { + dfd.resolve($field, 'remoteCSRF', {valid: false}); + }); + return dfd; + } + }; +})); diff --git a/static/src/js/lib/formValidation/validator/usernameCheck.js b/static/src/js/lib/formValidation/validator/usernameCheck.js deleted file mode 100644 index 36a77626..00000000 --- a/static/src/js/lib/formValidation/validator/usernameCheck.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * usernameCheck validator - */ -(function(root, factory) { - - "use strict"; - - // AMD module is defined - if (typeof define === "function" && define.amd) { - define("validator/usernameCheck", ["jquery", "base", "csrf"], factory); - } else { - // planted over the root! - factory(root.jQuery, root.FormValidation); - } -}(this, function ($, FormValidation, csrfHeader) { - FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, { - 'en_US': { - usernameCheck: { - 'default': 'Please input the same value' - } - } - }); - FormValidation.Validator.usernameCheck = { - validate: function(validator, $field, options) { - if ($field.val() == '') - return true; - return !$.ajax({ - async: false, - beforeSend: csrfHeader, - url: "/api/username_check/", - data: {username: $field.val()}, - dataType: "json", - method: "post", - }).responseJSON.data; - } - }; -})); diff --git a/static/src/js/utils/validation.js b/static/src/js/utils/validation.js index 5fe792f0..45da8f56 100644 --- a/static/src/js/utils/validation.js +++ b/static/src/js/utils/validation.js @@ -9,6 +9,7 @@ define("validation", 'validator/integer', 'validator/between', 'validator/confirm', - 'validator/usernameCheck'], + 'validator/remoteCSRF', + 'validator/emailAddress'], function () { }); \ No newline at end of file From c868441d615e78402bd6b258941305ac52b78a23 Mon Sep 17 00:00:00 2001 From: sxw Date: Wed, 5 Aug 2015 19:40:02 +0800 Subject: [PATCH 2/5] =?UTF-8?q?1.=E5=9C=A8=E7=94=A8=E6=88=B7=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E9=A1=B5=E9=9D=A2=E6=B7=BB=E5=8A=A0=E4=BA=86email?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=B9=B6=E9=99=84=E5=B8=A6=E9=AA=8C?= =?UTF-8?q?=E8=AF=81;=202.=E7=BB=9F=E4=B8=80=E4=BA=86username=E5=92=8Cemai?= =?UTF-8?q?l=E5=AD=97=E6=AE=B5=E7=9A=84=E5=94=AF=E4=B8=80=E6=80=A7?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E6=96=B9=E6=B3=95=E3=80=82=20[ci=20skip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/app/oj/account/register.js | 22 ++++++++++++++++++++-- template/oj/account/register.html | 4 ++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/static/src/js/app/oj/account/register.js b/static/src/js/app/oj/account/register.js index e6b4deb5..b9d3468e 100644 --- a/static/src/js/app/oj/account/register.js +++ b/static/src/js/app/oj/account/register.js @@ -2,6 +2,11 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf $("#register-form") .formValidation({ framework: "bootstrap", + icon: { + valid: 'glyphicon glyphicon-ok', + invalid: 'glyphicon glyphicon-remove', + validating: 'glyphicon glyphicon-refresh' + }, fields: { username: { validators: { @@ -50,6 +55,21 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf message: "两次输入的密码必须一致" } } + }, + email: { + validators: { + notEmpty: { + message: "请填写电子邮箱邮箱地址" + }, + emailAddress: { + message: "请填写有效的邮箱地址" + }, + remoteCSRF: { + message: "您已经注册过了", + url: "/api/email_check/", + field: 'email' + } + } } } } @@ -72,8 +92,6 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf bs_alert(data.data); } } - }) }); - }); \ No newline at end of file diff --git a/template/oj/account/register.html b/template/oj/account/register.html index a93014cf..34dc9a4c 100644 --- a/template/oj/account/register.html +++ b/template/oj/account/register.html @@ -14,6 +14,10 @@ +
+ + +
From c5446361db23f10e62257d2128baec6ec0966494 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 5 Aug 2015 19:45:35 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=20admin=20spa?= =?UTF-8?q?=20=E7=9A=84=E9=80=9A=E7=94=A8=E4=BB=A3=E7=A0=81[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/urls.py | 4 +- static/src/js/app/admin/admin.js | 31 ++++++++ static/src/js/config.js | 1 + template/admin/admin.html | 122 +++++++++++++++++++++++++++++++ template/admin/index.html | 4 - template/admin/index/index.html | 1 + template/admin_base.html | 8 +- 7 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 static/src/js/app/admin/admin.js create mode 100644 template/admin/admin.html delete mode 100644 template/admin/index.html create mode 100644 template/admin/index/index.html diff --git a/oj/urls.py b/oj/urls.py index 0c8ea519..cc49f420 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -5,11 +5,12 @@ from django.views.generic import TemplateView from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView from announcement.views import AnnouncementAPIView +from admin.views import AdminTemplateView urlpatterns = [ url("^$", TemplateView.as_view(template_name="oj/index.html"), name="index_page"), url(r'^docs/', include('rest_framework_swagger.urls')), - url(r'^admin/$', TemplateView.as_view(template_name="admin/index.html"), name="admin_index_page"), + url(r'^admin/$', TemplateView.as_view(template_name="admin/admin.html"), name="admin_spa_page"), url(r'^login/$', TemplateView.as_view(template_name="oj/account/login.html"), name="user_login_page"), url(r'^register/$', TemplateView.as_view(template_name="oj/account/register.html"), name="user_register_page"), url(r'^change_password/$', TemplateView.as_view(template_name="oj/account/change_password.html"), name="user_change_password_page"), @@ -22,4 +23,5 @@ urlpatterns = [ url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"), url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"), + url(r'^admin/template/(?P\w+)/(?P\w+).html', AdminTemplateView.as_view(), name="admin_template") ] diff --git a/static/src/js/app/admin/admin.js b/static/src/js/app/admin/admin.js new file mode 100644 index 00000000..d3e30ac8 --- /dev/null +++ b/static/src/js/app/admin/admin.js @@ -0,0 +1,31 @@ +define("admin", ["jquery", "avalon"], function($, avalon){ + function li_active(selector){ + $(selector).attr("class", "list-group-item active"); + } + + function li_inactive(selector){ + $(".list-group-item").attr("class", "list-group-item"); + } + + var hash = window.location.hash.substring(1); + + if(hash){ + li_active("#li-" + hash); + }else { + li_active("#li-index"); + } + + window.onhashchange = function() { + var hash = window.location.hash.substring(1); + if(hash){ + li_inactive(".list-group-item"); + li_active("#li-" + hash); + vm.template_url = "template/index/" + hash + ".html"; + } + }; + + var vm = avalon.define({ + $id: "admin", + template_url: "template/index/index.html" + }); +}); \ No newline at end of file diff --git a/static/src/js/config.js b/static/src/js/config.js index 3907d1c9..079e45c5 100644 --- a/static/src/js/config.js +++ b/static/src/js/config.js @@ -15,6 +15,7 @@ var require = { submit_code: "app/oj/problem/submit_code", contest: "app/admin/contest/contest", csrf: "utils/csrf", + admin: "app/admin/admin", //formValidation 不要在代码中单独使用,而是使用和修改utils/validation base: "lib/formValidation/base", diff --git a/template/admin/admin.html b/template/admin/admin.html new file mode 100644 index 00000000..c7120847 --- /dev/null +++ b/template/admin/admin.html @@ -0,0 +1,122 @@ + + + + + + + + + + + 在线评测系统 - 后台管理 + + + {% block css_block %}{% endblock %} + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + + +
+ +
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/template/admin/index.html b/template/admin/index.html deleted file mode 100644 index df51a668..00000000 --- a/template/admin/index.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "admin_base.html" %} -{% block body %} -Hello world -{% endblock %} \ No newline at end of file diff --git a/template/admin/index/index.html b/template/admin/index/index.html new file mode 100644 index 00000000..61168280 --- /dev/null +++ b/template/admin/index/index.html @@ -0,0 +1 @@ +

Hello world

\ No newline at end of file diff --git a/template/admin_base.html b/template/admin_base.html index 8525b2ec..86cf7e28 100644 --- a/template/admin_base.html +++ b/template/admin_base.html @@ -65,14 +65,14 @@ -
+
  • List header
  • -
  • Home
  • -
  • Library
  • +
  • 主页
  • +
  • 公告
  • Applications
  • Another list header
  • Help
  • @@ -108,7 +108,7 @@ {% block js_block %}{% endblock %} From 5eacb9f3d74651cea6f8e6d57dcc246bd5478c11 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 5 Aug 2015 19:47:49 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20admin=20=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E8=BF=94=E5=9B=9E=E6=89=A7=E8=A1=8C=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=9A=84=20views=20=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/views.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/admin/views.py b/admin/views.py index 91ea44a2..78762c02 100644 --- a/admin/views.py +++ b/admin/views.py @@ -1,3 +1,14 @@ -from django.shortcuts import render +# coding=utf-8 +from django.conf import settings +from django.http import HttpResponse, Http404 -# Create your views here. +from rest_framework.views import APIView + + +class AdminTemplateView(APIView): + def get(self, request, template_dir, template_name): + path = settings.TEMPLATE_DIRS[0] + "/admin/" + template_dir + "/" + template_name + ".html" + try: + return HttpResponse(open(path).read(), content_type="text/html") + except IOError: + raise Http404 From cbb86d72f1c7a5ab4030a34a8e4c1b9e8688097b Mon Sep 17 00:00:00 2001 From: sxw Date: Wed, 5 Aug 2015 20:01:15 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E4=BA=86validator?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8CremoteCSR?= =?UTF-8?q?F->remote.=E6=8A=8A=E5=8E=9F=E7=94=9F=E7=9A=84remote=E6=94=B9?= =?UTF-8?q?=E6=88=90=E4=BA=86remotex=E3=80=82=E3=80=82=E3=80=82=20[ci=20sk?= =?UTF-8?q?ip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/app/oj/account/register.js | 8 +- static/src/js/config.js | 2 +- .../js/lib/formValidation/validator/remote.js | 144 +++-------------- .../formValidation/validator/remoteCSRF.js | 46 ------ .../lib/formValidation/validator/remotex.js | 146 ++++++++++++++++++ static/src/js/utils/validation.js | 2 +- 6 files changed, 175 insertions(+), 173 deletions(-) delete mode 100644 static/src/js/lib/formValidation/validator/remoteCSRF.js create mode 100644 static/src/js/lib/formValidation/validator/remotex.js diff --git a/static/src/js/app/oj/account/register.js b/static/src/js/app/oj/account/register.js index b9d3468e..a7a3ea12 100644 --- a/static/src/js/app/oj/account/register.js +++ b/static/src/js/app/oj/account/register.js @@ -18,8 +18,10 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf max: 30, message: '用户名长度必须在3到30位之间' }, - usernameCheck:{ - message: '用户名已存在' + remote: { + message: "用户名已存在", + url: "/api/username_check/", + field: 'username' } } }, @@ -64,7 +66,7 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf emailAddress: { message: "请填写有效的邮箱地址" }, - remoteCSRF: { + remote: { message: "您已经注册过了", url: "/api/email_check/", field: 'email' diff --git a/static/src/js/config.js b/static/src/js/config.js index dc8b37c2..67bb9b66 100644 --- a/static/src/js/config.js +++ b/static/src/js/config.js @@ -28,7 +28,7 @@ var require = { "validator/integer": "lib/formValidation/validator/integer", "validator/between": "lib/formValidation/validator/between", "validator/confirm":"lib/formValidation/validator/confirm", - "validator/remoteCSRF":"lib/formValidation/validator/remoteCSRF", + "validator/remote":"lib/formValidation/validator/remote", "validator/emailAddress":"lib/formValidation/validator/emailAddress", //富文本编辑器 不要直接使用,而是使用上面的editor simditor: "lib/simditor/simditor", diff --git a/static/src/js/lib/formValidation/validator/remote.js b/static/src/js/lib/formValidation/validator/remote.js index b0ba1af2..e7f8d024 100755 --- a/static/src/js/lib/formValidation/validator/remote.js +++ b/static/src/js/lib/formValidation/validator/remote.js @@ -1,146 +1,46 @@ /** * remote validator - * - * @link http://formvalidation.io/validators/remote/ - * @author https://twitter.com/nghuuphuoc - * @copyright (c) 2013 - 2015 Nguyen Huu Phuoc - * @license http://formvalidation.io/license/ */ - (function(root, factory) { "use strict"; // AMD module is defined if (typeof define === "function" && define.amd) { - define("validator/remote", ["jquery", "base"], factory); + define("validator/remote", ["jquery", "base", "csrf"], factory); } else { // planted over the root! factory(root.jQuery, root.FormValidation); } - -}(this, function ($, FormValidation) { +}(this, function ($, FormValidation, csrfHeader) { FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, { 'en_US': { remote: { - 'default': 'Please enter a valid value' + 'default': '' } } }); - FormValidation.Validator.remote = { - html5Attributes: { - message: 'message', - name: 'name', - type: 'type', - url: 'url', - data: 'data', - delay: 'delay' - }, - - /** - * Destroy the timer when destroying the bootstrapValidator (using validator.destroy() method) - */ - destroy: function(validator, $field, options) { - var ns = validator.getNamespace(), - timer = $field.data(ns + '.remote.timer'); - if (timer) { - clearTimeout(timer); - $field.removeData(ns + '.remote.timer'); - } - }, - - /** - * Request a remote server to check the input value - * - * @param {FormValidation.Base} validator Plugin instance - * @param {jQuery} $field Field element - * @param {Object} options Can consist of the following keys: - * - url {String|Function} - * - type {String} [optional] Can be GET or POST (default) - * - data {Object|Function} [optional]: By default, it will take the value - * { - * : - * } - * - delay - * - name {String} [optional]: Override the field name for the request. - * - message: The invalid message - * - headers: Additional headers - * @returns {Deferred} - */ validate: function(validator, $field, options) { - var ns = validator.getNamespace(), - value = validator.getFieldValue($field, 'remote'), - dfd = new $.Deferred(); - if (value === '') { - dfd.resolve($field, 'remote', { valid: true }); - return dfd; - } - - var name = $field.attr('data-' + ns + '-field'), - data = options.data || {}, - url = options.url, - type = options.type || 'GET', - headers = options.headers || {}; - - // Support dynamic data - if ('function' === typeof data) { - data = data.call(this, validator); - } - - // Parse string data from HTML5 attribute - if ('string' === typeof data) { - data = JSON.parse(data); - } - - // Support dynamic url - if ('function' === typeof url) { - url = url.call(this, validator); - } - - data[options.name || name] = value; - function runCallback() { - var xhr = $.ajax({ - type: type, - headers: headers, - url: url, - dataType: 'json', - data: data - }); - - xhr - .success(function(response) { - response.valid = response.valid === true || response.valid === 'true'; - dfd.resolve($field, 'remote', response); - }) - .error(function(response) { - dfd.resolve($field, 'remote', { - valid: false - }); - }); - - dfd.fail(function() { - xhr.abort(); - }); - - return dfd; - } - - if (options.delay) { - // Since the form might have multiple fields with the same name - // I have to attach the timer to the field element - if ($field.data(ns + '.remote.timer')) { - clearTimeout($field.data(ns + '.remote.timer')); - } - - $field.data(ns + '.remote.timer', setTimeout(runCallback, options.delay)); - return dfd; - } else { - return runCallback(); - } + var dfd = new $.Deferred(), ajaxData = {}; + ajaxData[options.field] = $field.val(); + if ($field.val() === '') + return true; + var url = options.url; + var xhr = $.ajax({ + beforeSend: csrfHeader, + url: url, + dataType: 'json', + data: ajaxData, + method: "post" + }); + xhr.success(function(response) { + dfd.resolve($field, 'remote',{valid:!response.data, message:options.msg}); + }) + .error(function(response) { + dfd.resolve($field, 'remote', {valid: false}); + }); + return dfd; } }; - - - return FormValidation.Validator.remote; })); diff --git a/static/src/js/lib/formValidation/validator/remoteCSRF.js b/static/src/js/lib/formValidation/validator/remoteCSRF.js deleted file mode 100644 index 9cab354f..00000000 --- a/static/src/js/lib/formValidation/validator/remoteCSRF.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * remoteCSRF validator - */ -(function(root, factory) { - - "use strict"; - - // AMD module is defined - if (typeof define === "function" && define.amd) { - define("validator/remoteCSRF", ["jquery", "base", "csrf"], factory); - } else { - // planted over the root! - factory(root.jQuery, root.FormValidation); - } -}(this, function ($, FormValidation, csrfHeader) { - FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, { - 'en_US': { - remoteCSRF: { - 'default': '' - } - } - }); - FormValidation.Validator.remoteCSRF = { - validate: function(validator, $field, options) { - var dfd = new $.Deferred(), ajaxData = {}; - ajaxData[options.field] = $field.val(); - if ($field.val() === '') - return true; - var url = options.url; - var xhr = $.ajax({ - beforeSend: csrfHeader, - url: url, - dataType: 'json', - data: ajaxData, - method: "post" - }); - xhr.success(function(response) { - dfd.resolve($field, 'remoteCSRF',{valid:!response.data, message:options.msg}); - }) - .error(function(response) { - dfd.resolve($field, 'remoteCSRF', {valid: false}); - }); - return dfd; - } - }; -})); diff --git a/static/src/js/lib/formValidation/validator/remotex.js b/static/src/js/lib/formValidation/validator/remotex.js new file mode 100644 index 00000000..b0ba1af2 --- /dev/null +++ b/static/src/js/lib/formValidation/validator/remotex.js @@ -0,0 +1,146 @@ +/** + * remote validator + * + * @link http://formvalidation.io/validators/remote/ + * @author https://twitter.com/nghuuphuoc + * @copyright (c) 2013 - 2015 Nguyen Huu Phuoc + * @license http://formvalidation.io/license/ + */ + +(function(root, factory) { + + "use strict"; + + // AMD module is defined + if (typeof define === "function" && define.amd) { + define("validator/remote", ["jquery", "base"], factory); + } else { + // planted over the root! + factory(root.jQuery, root.FormValidation); + } + +}(this, function ($, FormValidation) { + FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, { + 'en_US': { + remote: { + 'default': 'Please enter a valid value' + } + } + }); + + FormValidation.Validator.remote = { + html5Attributes: { + message: 'message', + name: 'name', + type: 'type', + url: 'url', + data: 'data', + delay: 'delay' + }, + + /** + * Destroy the timer when destroying the bootstrapValidator (using validator.destroy() method) + */ + destroy: function(validator, $field, options) { + var ns = validator.getNamespace(), + timer = $field.data(ns + '.remote.timer'); + if (timer) { + clearTimeout(timer); + $field.removeData(ns + '.remote.timer'); + } + }, + + /** + * Request a remote server to check the input value + * + * @param {FormValidation.Base} validator Plugin instance + * @param {jQuery} $field Field element + * @param {Object} options Can consist of the following keys: + * - url {String|Function} + * - type {String} [optional] Can be GET or POST (default) + * - data {Object|Function} [optional]: By default, it will take the value + * { + * : + * } + * - delay + * - name {String} [optional]: Override the field name for the request. + * - message: The invalid message + * - headers: Additional headers + * @returns {Deferred} + */ + validate: function(validator, $field, options) { + var ns = validator.getNamespace(), + value = validator.getFieldValue($field, 'remote'), + dfd = new $.Deferred(); + if (value === '') { + dfd.resolve($field, 'remote', { valid: true }); + return dfd; + } + + var name = $field.attr('data-' + ns + '-field'), + data = options.data || {}, + url = options.url, + type = options.type || 'GET', + headers = options.headers || {}; + + // Support dynamic data + if ('function' === typeof data) { + data = data.call(this, validator); + } + + // Parse string data from HTML5 attribute + if ('string' === typeof data) { + data = JSON.parse(data); + } + + // Support dynamic url + if ('function' === typeof url) { + url = url.call(this, validator); + } + + data[options.name || name] = value; + function runCallback() { + var xhr = $.ajax({ + type: type, + headers: headers, + url: url, + dataType: 'json', + data: data + }); + + xhr + .success(function(response) { + response.valid = response.valid === true || response.valid === 'true'; + dfd.resolve($field, 'remote', response); + }) + .error(function(response) { + dfd.resolve($field, 'remote', { + valid: false + }); + }); + + dfd.fail(function() { + xhr.abort(); + }); + + return dfd; + } + + if (options.delay) { + // Since the form might have multiple fields with the same name + // I have to attach the timer to the field element + if ($field.data(ns + '.remote.timer')) { + clearTimeout($field.data(ns + '.remote.timer')); + } + + $field.data(ns + '.remote.timer', setTimeout(runCallback, options.delay)); + return dfd; + } else { + return runCallback(); + } + } + }; + + + return FormValidation.Validator.remote; +})); diff --git a/static/src/js/utils/validation.js b/static/src/js/utils/validation.js index 45da8f56..191d5850 100644 --- a/static/src/js/utils/validation.js +++ b/static/src/js/utils/validation.js @@ -9,7 +9,7 @@ define("validation", 'validator/integer', 'validator/between', 'validator/confirm', - 'validator/remoteCSRF', + 'validator/remote', 'validator/emailAddress'], function () { }); \ No newline at end of file