annotate life_calendar/happy.js @ 106:712cc41e0be2

merge heads
author paulo
date Sat, 28 Dec 2019 00:58:28 -0800
parents
children
rev   line source
paulo@81 1 /*global $*/
paulo@81 2 (function happyJS($) {
paulo@81 3 function trim(el) {
paulo@81 4 return (''.trim) ? el.val().trim() : $.trim(el.val());
paulo@81 5 }
paulo@81 6 $.fn.isHappy = function isHappy(config) {
paulo@81 7 var fields = [], item;
paulo@81 8 var pauseMessages = false;
paulo@81 9
paulo@81 10 function isFunction(obj) {
paulo@81 11 return !!(obj && obj.constructor && obj.call && obj.apply);
paulo@81 12 }
paulo@81 13 function defaultError(error) { //Default error template
paulo@81 14 var msgErrorClass = config.classes && config.classes.message || 'unhappyMessage';
paulo@81 15 return $('<span id="' + error.id + '" class="' + msgErrorClass + '" role="alert">' + error.message + '</span>');
paulo@81 16 }
paulo@81 17 function getError(error) { //Generate error html from either config or default
paulo@81 18 if (isFunction(config.errorTemplate)) {
paulo@81 19 return config.errorTemplate(error);
paulo@81 20 }
paulo@81 21 return defaultError(error);
paulo@81 22 }
paulo@81 23 function handleSubmit() {
paulo@81 24 var i, l;
paulo@81 25 var errors = false;
paulo@81 26 for (i = 0, l = fields.length; i < l; i += 1) {
paulo@81 27 if (!fields[i].testValid(true)) {
paulo@81 28 errors = true;
paulo@81 29 }
paulo@81 30 }
paulo@81 31 if (errors) {
paulo@81 32 if (isFunction(config.unHappy)) config.unHappy();
paulo@81 33 return false;
paulo@81 34 } else if (config.testMode) {
paulo@81 35 if (isFunction(config.happy)) return config.happy();
paulo@81 36 if (window.console) console.warn('would have submitted');
paulo@81 37 return false;
paulo@81 38 }
paulo@81 39 if (isFunction(config.happy)) return config.happy();
paulo@81 40 }
paulo@81 41 function handleMouseUp() {
paulo@81 42 pauseMessages = false;
paulo@81 43 }
paulo@81 44 function handleMouseDown() {
paulo@81 45 pauseMessages = true;
paulo@81 46 $(window).bind('mouseup', handleMouseUp);
paulo@81 47 }
paulo@81 48 function processField(opts, selector) {
paulo@81 49 var field = $(selector);
paulo@81 50 var error = {
paulo@81 51 message: opts.message || '',
paulo@81 52 id: selector.slice(1) + '_unhappy'
paulo@81 53 };
paulo@81 54 var errorEl = $(error.id).length > 0 ? $(error.id) : getError(error);
paulo@81 55 var handleBlur = function handleBlur() {
paulo@81 56 if (!pauseMessages) {
paulo@81 57 field.testValid();
paulo@81 58 } else {
paulo@81 59 $(window).bind('mouseup', field.testValid.bind(this));
paulo@81 60 }
paulo@81 61 };
paulo@81 62
paulo@81 63 fields.push(field);
paulo@81 64 field.testValid = function testValid(submit) {
paulo@81 65 var val, gotFunc, temp;
paulo@81 66 var el = $(this);
paulo@81 67 var errorTarget = (opts.errorTarget && $(opts.errorTarget)) || el;
paulo@81 68 var error = false;
paulo@81 69 var required = !!el.get(0).attributes.getNamedItem('required') || opts.required;
paulo@81 70 var password = (field.attr('type') === 'password');
paulo@81 71 var arg = isFunction(opts.arg) ? opts.arg() : opts.arg;
paulo@81 72 var fieldErrorClass = config.classes && config.classes.field || 'unhappy';
paulo@81 73
paulo@81 74 // handle control groups (checkboxes, radio)
paulo@81 75 if (el.length > 1) {
paulo@81 76 val = [];
paulo@81 77 el.each(function(i,obj) {
paulo@81 78 val.push($(obj).val());
paulo@81 79 });
paulo@81 80 val = val.join(',');
paulo@81 81 } else {
paulo@81 82 // clean it or trim it
paulo@81 83 if (isFunction(opts.clean)) {
paulo@81 84 val = opts.clean(el.val());
paulo@81 85 } else if (!password && typeof opts.trim === 'undefined' || opts.trim) {
paulo@81 86 val = trim(el);
paulo@81 87 } else {
paulo@81 88 val = el.val();
paulo@81 89 }
paulo@81 90
paulo@81 91 // write it back to the field
paulo@81 92 el.val(val);
paulo@81 93 }
paulo@81 94
paulo@81 95 // get the value
paulo@81 96 gotFunc = ((val.length > 0 || required === 'sometimes') && isFunction(opts.test));
paulo@81 97
paulo@81 98 // check if we've got an error on our hands
paulo@81 99 if (submit === true && required === true && val.length === 0) {
paulo@81 100 error = true;
paulo@81 101 } else if (gotFunc) {
paulo@81 102 error = !opts.test(val, arg);
paulo@81 103 }
paulo@81 104
paulo@81 105 if (error) {
paulo@81 106 errorTarget.addClass(fieldErrorClass).after(errorEl);
paulo@81 107 return false;
paulo@81 108 } else {
paulo@81 109 temp = errorEl.get(0);
paulo@81 110 // this is for zepto
paulo@81 111 if (temp.parentNode) {
paulo@81 112 temp.parentNode.removeChild(temp);
paulo@81 113 }
paulo@81 114 errorTarget.removeClass(fieldErrorClass);
paulo@81 115 return true;
paulo@81 116 }
paulo@81 117 };
paulo@81 118 field.bind(opts.when || config.when || 'blur', handleBlur);
paulo@81 119 }
paulo@81 120
paulo@81 121 for (item in config.fields) {
paulo@81 122 processField(config.fields[item], item);
paulo@81 123 }
paulo@81 124
paulo@81 125 $(config.submitButton || this).bind('mousedown', handleMouseDown);
paulo@81 126
paulo@81 127 if (config.submitButton) {
paulo@81 128 $(config.submitButton).click(handleSubmit);
paulo@81 129 } else {
paulo@81 130 this.bind('submit', handleSubmit);
paulo@81 131 }
paulo@81 132 return this;
paulo@81 133 };
paulo@81 134 })(this.jQuery || this.Zepto);