Permalink
Browse files

Checkboxes/radios not updating validity when checked, fixes #30. Plus…

… formatting updates
  • Loading branch information...
1 parent 0f4e32c commit 6bf672cf670677b5c307740b6b418ede2ba65945 @ryanseddon committed Sep 30, 2012
Showing with 47 additions and 351 deletions.
  1. +0 −328 h5f.js
  2. +2 −2 h5f.min.js
  3. +21 −21 src/H5F.js
  4. +4 −0 test/H5F.html
  5. +20 −0 test/H5F_test.js
View
328 h5f.js
@@ -1,328 +0,0 @@
-/*! H5F - v1.0.0 - 2012-07-18
-* https://github.com/ryanseddon/H5F/
-* Copyright (c) 2012 Ryan Seddon; Licensed MIT */
-
-var H5F = H5F || {};
-
-(function(d){
-
- var field = d.createElement("input"),
- emailPatt = /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
- urlPatt = /[a-z][\-\.+a-z]*:\/\//i,
- nodes = /^(input|select|textarea)$/i,
- isSubmit, usrPatt, curEvt, args, custMsg = "",
- // Methods
- setup, validation, validity, checkField, checkValidity, setCustomValidity, support, pattern, placeholder, range, required, valueMissing, listen, unlisten, preventActions, getTarget, addClass, removeClass, isHostMethod;
-
- setup = function(form,settings) {
- var isCollection = !form.nodeType || false;
-
- var opts = {
- validClass : "valid",
- invalidClass : "error",
- requiredClass : "required",
- placeholderClass : "placeholder"
- };
-
- if(typeof settings === "object") {
- for (var i in opts) {
- if(typeof settings[i] === "undefined") { settings[i] = opts[i]; }
- }
- }
-
- args = settings || opts;
-
- if(isCollection) {
- for(var k=0,len=form.length;k<len;k++) {
- validation(form[k]);
- }
- } else {
- validation(form);
- }
- };
-
- validation = function(form) {
- var f = form.elements,
- flen = f.length,
- isRequired, noValidate = !!(form.attributes["novalidate"]);
-
- listen(form,"invalid",checkField,true);
- listen(form,"blur",checkField,true);
- listen(form,"input",checkField,true);
- listen(form,"keyup",checkField,true);
- listen(form,"focus",checkField,true);
-
- listen(form,"submit",function(e){
- isSubmit = true;
- if(!noValidate && !form.checkValidity()) {
- preventActions(e);
- }
- },false);
-
- if(!support()) {
- form.checkValidity = function() { return checkValidity(form); };
-
- while(flen--) {
- isRequired = !!(f[flen].attributes["required"]);
- // Firefox includes fieldsets inside elements nodelist so we filter it out.
- if(f[flen].nodeName.toLowerCase() !== "fieldset") {
- validity(f[flen]); // Add validity object to field
- }
- }
- }
- };
- validity = function(el) {
- var elem = el,
- missing = valueMissing(elem),
- attrs = {
- type: elem.getAttribute("type"),
- pattern: elem.getAttribute("pattern"),
- placeholder: elem.getAttribute("placeholder")
- },
- isType = /^(email|url)$/i,
- evt = /^(input|keyup)$/i,
- fType = ((isType.test(attrs.type)) ? attrs.type : ((attrs.pattern) ? attrs.pattern : false)),
- patt = pattern(elem,fType),
- step = range(elem,"step"),
- min = range(elem,"min"),
- max = range(elem,"max"),
- customError = (custMsg !== "");
-
- elem.checkValidity = function() { return checkValidity.call(this,elem); };
- elem.setCustomValidity = function(msg) { setCustomValidity.call(elem,msg); };
- elem.validationMessage = custMsg;
-
- elem.validity = {
- valueMissing: missing,
- patternMismatch: patt,
- rangeUnderflow: min,
- rangeOverflow: max,
- stepMismatch: step,
- customError: customError,
- valid: (!missing && !patt && !step && !min && !max && !customError)
- };
-
- if(attrs.placeholder && !evt.test(curEvt)) { placeholder(elem); }
- };
- checkField = function (e) {
- var el = getTarget(e) || e, // checkValidity method passes element not event
- events = /^(input|keyup|focusin|focus)$/i,
- ignoredTypes = /^(submit|image|button|reset)$/i,
- checkForm = true;
-
- if(nodes.test(el.nodeName) && !(ignoredTypes.test(el.type) || ignoredTypes.test(el.nodeName))) {
- curEvt = e.type;
- if(!support()) { validity(el); }
-
- if(el.validity.valid && el.value !== "" || el.value !== el.getAttribute("placeholder") && el.validity.valid) {
- removeClass(el,[args.invalidClass,args.requiredClass]);
- addClass(el,args.validClass);
- } else if(!events.test(curEvt)) {
- if(el.validity.valueMissing) {
- removeClass(el,[args.invalidClass,args.validClass]);
- addClass(el,args.requiredClass);
- } else if(!el.validity.valid) {
- removeClass(el,[args.validClass,args.requiredClass]);
- addClass(el,args.invalidClass);
- }
- } else if(el.validity.valueMissing) {
- removeClass(el,[args.requiredClass,args.invalidClass,args.validClass]);
- }
- if(curEvt === "input" && checkForm) {
- // If input is triggered remove the keyup event
- unlisten(el.form,"keyup",checkField,true);
- checkForm = false;
- }
- }
- };
- checkValidity = function (el) {
- var f, ff, isRequired, hasPattern, invalid = false;
-
- if(el.nodeName.toLowerCase() === "form") {
- f = el.elements;
-
- for(var i = 0,len = f.length;i < len;i++) {
- ff = f[i];
-
- isRequired = !!(ff.attributes["required"]);
- hasPattern = !!(ff.attributes["pattern"]);
-
- if(ff.nodeName.toLowerCase() !== "fieldset" && (isRequired || hasPattern && isRequired)) {
- checkField(ff);
- if(!ff.validity.valid && !invalid) {
- if(isSubmit) { // If it's not a submit event the field shouldn't be focused
- ff.focus();
- }
- invalid = true;
- }
- }
- }
- return !invalid;
- } else {
- checkField(el);
- return el.validity.valid;
- }
- };
- setCustomValidity = function (msg) {
- var el = this;
- custMsg = msg;
-
- el.validationMessage = custMsg;
- };
-
- support = function() {
- return (isHostMethod(field,"validity") && isHostMethod(field,"checkValidity"));
- };
-
- // Create helper methods to emulate attributes in older browsers
- pattern = function(el, type) {
- if(type === "email") {
- return !emailPatt.test(el.value);
- } else if(type === "url") {
- return !urlPatt.test(el.value);
- } else if(!type) {
- return false;
- } else {
- var placeholder = el.getAttribute("placeholder"),
- val = el.value;
-
- usrPatt = new RegExp('^(?:' + type + ')$');
-
- if(val === placeholder) {
- return true;
- } else if(val === "") {
- return false;
- } else {
- return !usrPatt.test(el.value);
- }
- }
- };
- placeholder = function(el) {
- var attrs = { placeholder: el.getAttribute("placeholder") },
- focus = /^(focus|focusin|submit)$/i,
- node = /^(input|textarea)$/i,
- ignoredType = /^password$/i,
- isNative = !!("placeholder" in field);
-
- if(!isNative && node.test(el.nodeName) && !ignoredType.test(el.type)) {
- if(el.value === "" && !focus.test(curEvt)) {
- el.value = attrs.placeholder;
- listen(el.form,'submit', function () {
- curEvt = 'submit';
- placeholder(el);
- }, true);
- addClass(el,args.placeholderClass);
- } else if(el.value === attrs.placeholder && focus.test(curEvt)) {
- el.value = "";
- removeClass(el,args.placeholderClass);
- }
- }
- };
- range = function(el,type) {
- // Emulate min, max and step
- var min = parseInt(el.getAttribute("min"),10) || 0,
- max = parseInt(el.getAttribute("max"),10) || false,
- step = parseInt(el.getAttribute("step"),10) || 1,
- val = parseInt(el.value,10),
- mismatch = (val-min)%step;
-
- if(!valueMissing(el) && !isNaN(val)) {
- if(type === "step") {
- return (el.getAttribute("step")) ? (mismatch !== 0) : false;
- } else if(type === "min") {
- return (el.getAttribute("min")) ? (val < min) : false;
- } else if(type === "max") {
- return (el.getAttribute("max")) ? (val > max) : false;
- }
- } else if(el.getAttribute("type") === "number") {
- return true;
- } else {
- return false;
- }
- };
- required = function(el) {
- var required = !!(el.attributes["required"]);
-
- return (required) ? valueMissing(el) : false;
- };
- valueMissing = function(el) {
- var placeholder = el.getAttribute("placeholder"),
- isRequired = !!(el.attributes["required"]);
- return !!(isRequired && (el.value === "" || el.value === placeholder));
- };
-
- /* Util methods */
- listen = function (node,type,fn,capture) {
- if(isHostMethod(window,"addEventListener")) {
- /* FF & Other Browsers */
- node.addEventListener( type, fn, capture );
- } else if(isHostMethod(window,"attachEvent") && typeof window.event !== "undefined") {
- /* Internet Explorer way */
- if(type === "blur") {
- type = "focusout";
- } else if(type === "focus") {
- type = "focusin";
- }
- node.attachEvent( "on" + type, fn );
- }
- };
- unlisten = function (node,type,fn,capture) {
- if(isHostMethod(window,"removeEventListener")) {
- /* FF & Other Browsers */
- node.removeEventListener( type, fn, capture );
- } else if(isHostMethod(window,"detachEvent") && typeof window.event !== "undefined") {
- /* Internet Explorer way */
- node.detachEvent( "on" + type, fn );
- }
- };
- preventActions = function (evt) {
- evt = evt || window.event;
-
- if(evt.stopPropagation && evt.preventDefault) {
- evt.stopPropagation();
- evt.preventDefault();
- } else {
- evt.cancelBubble = true;
- evt.returnValue = false;
- }
- };
- getTarget = function (evt) {
- evt = evt || window.event;
- return evt.target || evt.srcElement;
- };
- addClass = function (e,c) {
- var re;
- if (!e.className) {
- e.className = c;
- }
- else {
- re = new RegExp('(^|\\s)' + c + '(\\s|$)');
- if (!re.test(e.className)) { e.className += ' ' + c; }
- }
- };
- removeClass = function (e,c) {
- var re, m, arr = (typeof c === "object") ? c.length : 1, len = arr;
- if (e.className) {
- if (e.className === c) {
- e.className = '';
- }
- else {
- while(arr--) {
- re = new RegExp('(^|\\s)' + ((len > 1) ? c[arr] : c) + '(\\s|$)');
- m = e.className.match(re);
- if (m && m.length === 3) { e.className = e.className.replace(re, (m[1] && m[2])?' ':''); }
- }
- }
- }
- };
- isHostMethod = function(o, m) {
- var t = typeof o[m], reFeaturedMethod = new RegExp('^function|object$', 'i');
- return !!((reFeaturedMethod.test(t) && o[m]) || t === 'unknown');
- };
-
- // Since all methods are only used internally no need to expose globally
- window["H5F"] = {
- setup: setup
- };
-
-}(document));
Oops, something went wrong.

0 comments on commit 6bf672c

Please sign in to comment.