annotate bns_website/static/js/tinymce/jscripts/tiny_mce/utils/validate.js @ 60:a0d3bc630ebd

For issue #8, create a videos application to randomize videos in the playlist. This commit now adds a dependency to the Google Python GData library. The admin enters a playlist URL in the admin. Then the admin uses an admin action to synchronize the playlist with YouTube. This reads the playlist title and retrieves the video list from YouTube. The view function reads all the playlist objects to get the complete list of videos, then shuffles them up. The template generates Javascript to create a YouTube player with the shuffled list. A fixture is included for convenience and for the tests. I also committed a test tool I wrote to prove out this idea in case it is useful for future enhancements or experimentation.
author Brian Neal <bgneal@gmail.com>
date Sat, 19 Nov 2011 14:19:00 -0600
parents ced908af601a
children
rev   line source
bgneal@29 1 /**
bgneal@29 2 * validate.js
bgneal@29 3 *
bgneal@29 4 * Copyright 2009, Moxiecode Systems AB
bgneal@29 5 * Released under LGPL License.
bgneal@29 6 *
bgneal@29 7 * License: http://tinymce.moxiecode.com/license
bgneal@29 8 * Contributing: http://tinymce.moxiecode.com/contributing
bgneal@29 9 */
bgneal@29 10
bgneal@29 11 /**
bgneal@29 12 // String validation:
bgneal@29 13
bgneal@29 14 if (!Validator.isEmail('myemail'))
bgneal@29 15 alert('Invalid email.');
bgneal@29 16
bgneal@29 17 // Form validation:
bgneal@29 18
bgneal@29 19 var f = document.forms['myform'];
bgneal@29 20
bgneal@29 21 if (!Validator.isEmail(f.myemail))
bgneal@29 22 alert('Invalid email.');
bgneal@29 23 */
bgneal@29 24
bgneal@29 25 var Validator = {
bgneal@29 26 isEmail : function(s) {
bgneal@29 27 return this.test(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
bgneal@29 28 },
bgneal@29 29
bgneal@29 30 isAbsUrl : function(s) {
bgneal@29 31 return this.test(s, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\.]+\\/?.*$');
bgneal@29 32 },
bgneal@29 33
bgneal@29 34 isSize : function(s) {
bgneal@29 35 return this.test(s, '^[0-9.]+(%|in|cm|mm|em|ex|pt|pc|px)?$');
bgneal@29 36 },
bgneal@29 37
bgneal@29 38 isId : function(s) {
bgneal@29 39 return this.test(s, '^[A-Za-z_]([A-Za-z0-9_])*$');
bgneal@29 40 },
bgneal@29 41
bgneal@29 42 isEmpty : function(s) {
bgneal@29 43 var nl, i;
bgneal@29 44
bgneal@29 45 if (s.nodeName == 'SELECT' && s.selectedIndex < 1)
bgneal@29 46 return true;
bgneal@29 47
bgneal@29 48 if (s.type == 'checkbox' && !s.checked)
bgneal@29 49 return true;
bgneal@29 50
bgneal@29 51 if (s.type == 'radio') {
bgneal@29 52 for (i=0, nl = s.form.elements; i<nl.length; i++) {
bgneal@29 53 if (nl[i].type == "radio" && nl[i].name == s.name && nl[i].checked)
bgneal@29 54 return false;
bgneal@29 55 }
bgneal@29 56
bgneal@29 57 return true;
bgneal@29 58 }
bgneal@29 59
bgneal@29 60 return new RegExp('^\\s*$').test(s.nodeType == 1 ? s.value : s);
bgneal@29 61 },
bgneal@29 62
bgneal@29 63 isNumber : function(s, d) {
bgneal@29 64 return !isNaN(s.nodeType == 1 ? s.value : s) && (!d || !this.test(s, '^-?[0-9]*\\.[0-9]*$'));
bgneal@29 65 },
bgneal@29 66
bgneal@29 67 test : function(s, p) {
bgneal@29 68 s = s.nodeType == 1 ? s.value : s;
bgneal@29 69
bgneal@29 70 return s == '' || new RegExp(p).test(s);
bgneal@29 71 }
bgneal@29 72 };
bgneal@29 73
bgneal@29 74 var AutoValidator = {
bgneal@29 75 settings : {
bgneal@29 76 id_cls : 'id',
bgneal@29 77 int_cls : 'int',
bgneal@29 78 url_cls : 'url',
bgneal@29 79 number_cls : 'number',
bgneal@29 80 email_cls : 'email',
bgneal@29 81 size_cls : 'size',
bgneal@29 82 required_cls : 'required',
bgneal@29 83 invalid_cls : 'invalid',
bgneal@29 84 min_cls : 'min',
bgneal@29 85 max_cls : 'max'
bgneal@29 86 },
bgneal@29 87
bgneal@29 88 init : function(s) {
bgneal@29 89 var n;
bgneal@29 90
bgneal@29 91 for (n in s)
bgneal@29 92 this.settings[n] = s[n];
bgneal@29 93 },
bgneal@29 94
bgneal@29 95 validate : function(f) {
bgneal@29 96 var i, nl, s = this.settings, c = 0;
bgneal@29 97
bgneal@29 98 nl = this.tags(f, 'label');
bgneal@29 99 for (i=0; i<nl.length; i++) {
bgneal@29 100 this.removeClass(nl[i], s.invalid_cls);
bgneal@29 101 nl[i].setAttribute('aria-invalid', false);
bgneal@29 102 }
bgneal@29 103
bgneal@29 104 c += this.validateElms(f, 'input');
bgneal@29 105 c += this.validateElms(f, 'select');
bgneal@29 106 c += this.validateElms(f, 'textarea');
bgneal@29 107
bgneal@29 108 return c == 3;
bgneal@29 109 },
bgneal@29 110
bgneal@29 111 invalidate : function(n) {
bgneal@29 112 this.mark(n.form, n);
bgneal@29 113 },
bgneal@29 114
bgneal@29 115 getErrorMessages : function(f) {
bgneal@29 116 var nl, i, s = this.settings, field, msg, values, messages = [], ed = tinyMCEPopup.editor;
bgneal@29 117 nl = this.tags(f, "label");
bgneal@29 118 for (i=0; i<nl.length; i++) {
bgneal@29 119 if (this.hasClass(nl[i], s.invalid_cls)) {
bgneal@29 120 field = document.getElementById(nl[i].getAttribute("for"));
bgneal@29 121 values = { field: nl[i].textContent };
bgneal@29 122 if (this.hasClass(field, s.min_cls, true)) {
bgneal@29 123 message = ed.getLang('invalid_data_min');
bgneal@29 124 values.min = this.getNum(field, s.min_cls);
bgneal@29 125 } else if (this.hasClass(field, s.number_cls)) {
bgneal@29 126 message = ed.getLang('invalid_data_number');
bgneal@29 127 } else if (this.hasClass(field, s.size_cls)) {
bgneal@29 128 message = ed.getLang('invalid_data_size');
bgneal@29 129 } else {
bgneal@29 130 message = ed.getLang('invalid_data');
bgneal@29 131 }
bgneal@29 132
bgneal@29 133 message = message.replace(/{\#([^}]+)\}/g, function(a, b) {
bgneal@29 134 return values[b] || '{#' + b + '}';
bgneal@29 135 });
bgneal@29 136 messages.push(message);
bgneal@29 137 }
bgneal@29 138 }
bgneal@29 139 return messages;
bgneal@29 140 },
bgneal@29 141
bgneal@29 142 reset : function(e) {
bgneal@29 143 var t = ['label', 'input', 'select', 'textarea'];
bgneal@29 144 var i, j, nl, s = this.settings;
bgneal@29 145
bgneal@29 146 if (e == null)
bgneal@29 147 return;
bgneal@29 148
bgneal@29 149 for (i=0; i<t.length; i++) {
bgneal@29 150 nl = this.tags(e.form ? e.form : e, t[i]);
bgneal@29 151 for (j=0; j<nl.length; j++) {
bgneal@29 152 this.removeClass(nl[j], s.invalid_cls);
bgneal@29 153 nl[j].setAttribute('aria-invalid', false);
bgneal@29 154 }
bgneal@29 155 }
bgneal@29 156 },
bgneal@29 157
bgneal@29 158 validateElms : function(f, e) {
bgneal@29 159 var nl, i, n, s = this.settings, st = true, va = Validator, v;
bgneal@29 160
bgneal@29 161 nl = this.tags(f, e);
bgneal@29 162 for (i=0; i<nl.length; i++) {
bgneal@29 163 n = nl[i];
bgneal@29 164
bgneal@29 165 this.removeClass(n, s.invalid_cls);
bgneal@29 166
bgneal@29 167 if (this.hasClass(n, s.required_cls) && va.isEmpty(n))
bgneal@29 168 st = this.mark(f, n);
bgneal@29 169
bgneal@29 170 if (this.hasClass(n, s.number_cls) && !va.isNumber(n))
bgneal@29 171 st = this.mark(f, n);
bgneal@29 172
bgneal@29 173 if (this.hasClass(n, s.int_cls) && !va.isNumber(n, true))
bgneal@29 174 st = this.mark(f, n);
bgneal@29 175
bgneal@29 176 if (this.hasClass(n, s.url_cls) && !va.isAbsUrl(n))
bgneal@29 177 st = this.mark(f, n);
bgneal@29 178
bgneal@29 179 if (this.hasClass(n, s.email_cls) && !va.isEmail(n))
bgneal@29 180 st = this.mark(f, n);
bgneal@29 181
bgneal@29 182 if (this.hasClass(n, s.size_cls) && !va.isSize(n))
bgneal@29 183 st = this.mark(f, n);
bgneal@29 184
bgneal@29 185 if (this.hasClass(n, s.id_cls) && !va.isId(n))
bgneal@29 186 st = this.mark(f, n);
bgneal@29 187
bgneal@29 188 if (this.hasClass(n, s.min_cls, true)) {
bgneal@29 189 v = this.getNum(n, s.min_cls);
bgneal@29 190
bgneal@29 191 if (isNaN(v) || parseInt(n.value) < parseInt(v))
bgneal@29 192 st = this.mark(f, n);
bgneal@29 193 }
bgneal@29 194
bgneal@29 195 if (this.hasClass(n, s.max_cls, true)) {
bgneal@29 196 v = this.getNum(n, s.max_cls);
bgneal@29 197
bgneal@29 198 if (isNaN(v) || parseInt(n.value) > parseInt(v))
bgneal@29 199 st = this.mark(f, n);
bgneal@29 200 }
bgneal@29 201 }
bgneal@29 202
bgneal@29 203 return st;
bgneal@29 204 },
bgneal@29 205
bgneal@29 206 hasClass : function(n, c, d) {
bgneal@29 207 return new RegExp('\\b' + c + (d ? '[0-9]+' : '') + '\\b', 'g').test(n.className);
bgneal@29 208 },
bgneal@29 209
bgneal@29 210 getNum : function(n, c) {
bgneal@29 211 c = n.className.match(new RegExp('\\b' + c + '([0-9]+)\\b', 'g'))[0];
bgneal@29 212 c = c.replace(/[^0-9]/g, '');
bgneal@29 213
bgneal@29 214 return c;
bgneal@29 215 },
bgneal@29 216
bgneal@29 217 addClass : function(n, c, b) {
bgneal@29 218 var o = this.removeClass(n, c);
bgneal@29 219 n.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
bgneal@29 220 },
bgneal@29 221
bgneal@29 222 removeClass : function(n, c) {
bgneal@29 223 c = n.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
bgneal@29 224 return n.className = c != ' ' ? c : '';
bgneal@29 225 },
bgneal@29 226
bgneal@29 227 tags : function(f, s) {
bgneal@29 228 return f.getElementsByTagName(s);
bgneal@29 229 },
bgneal@29 230
bgneal@29 231 mark : function(f, n) {
bgneal@29 232 var s = this.settings;
bgneal@29 233
bgneal@29 234 this.addClass(n, s.invalid_cls);
bgneal@29 235 n.setAttribute('aria-invalid', 'true');
bgneal@29 236 this.markLabels(f, n, s.invalid_cls);
bgneal@29 237
bgneal@29 238 return false;
bgneal@29 239 },
bgneal@29 240
bgneal@29 241 markLabels : function(f, n, ic) {
bgneal@29 242 var nl, i;
bgneal@29 243
bgneal@29 244 nl = this.tags(f, "label");
bgneal@29 245 for (i=0; i<nl.length; i++) {
bgneal@29 246 if (nl[i].getAttribute("for") == n.id || nl[i].htmlFor == n.id)
bgneal@29 247 this.addClass(nl[i], ic);
bgneal@29 248 }
bgneal@29 249
bgneal@29 250 return null;
bgneal@29 251 }
bgneal@29 252 };