view life_calendar/happy.js @ 142:2ed8cf5f36bf

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