]> dev.renevier.net Git - syj.git/blob - public/js/utils.js
allow anonymous routes creation
[syj.git] / public / js / utils.js
1 /*  This file is part of Syj, Copyright (c) 2010 Arnaud Renevier,
2     and is published under the AGPL license. */
3
4 var CloseBtn = Class.create({
5     initialize: function(elt, options) {
6         var btn, imgsrc, style;
7
8         elt = $(elt);
9         if (!elt) {
10             return;
11         }
12
13         style = Object.extend({
14             float: "right",
15             margin: "2px",
16             fontWeight: "bold",
17             padding: "0px"
18         }, typeof options === "object" ? options.style: {});
19
20         imgsrc = (options && options.closeBtnSrc) || "icons/close.png";
21         btn = new Element("input", { type: "image", src: imgsrc, alt: "X"}).setStyle(style);
22         elt.insert({top: btn});
23         btn.observe("click", function(evt) {
24             elt.hide();
25         });
26     }
27 });
28
29 var Deck = Class.create({
30     initialize: function(elt, options) {
31         this.element = $(elt);
32         this.index = null;
33         this.setIndex(parseInt(this.element.readAttribute("selectedindex") || 0, 10));
34     },
35     setIndex: function(idx) {
36         if (idx === this.index) {
37             return;
38         }
39
40         var childs = this.element.childElements();
41         if (childs.length === 0) {
42             this.index = -1;
43             return;
44         }
45         idx = Math.max(0, idx);
46         idx = Math.min(childs.length - 1, idx);
47
48         childs.each(function(item, i) {
49             if (idx === i) {
50                 item.show();
51             } else {
52                 item.hide();
53             }
54         });
55         this.index = idx;
56     },
57     getIndex: function() {
58         return this.index;
59     }
60 });
61
62 Element.addMethods({
63     highlight: function(element, color, timeout) {
64         var current;
65         if (typeof timeout === "undefined") {
66             timeout = 0.3;
67         }
68         current = element.getStyle('backgroundColor');
69         Element.setStyle(element, {'backgroundColor': color});
70         Element.setStyle.delay(timeout, element, {'backgroundColor': current});
71         return element;
72     }
73 });
74
75 // wrapper around Form.request that sets up the submit listener, stops the
76 // submit event, calls presubmit function, calls Form.request and calls a
77 // postsubmit function
78 Element.addMethods('form', {
79     ajaxize : function(form, options) {
80         var reqoptions, timeout;
81
82         options = Object.clone(options);
83         reqoptions = Object.clone(options);
84         timeout = null;
85
86         function onSuccess(transport, json) {
87             if (timeout) {
88                 window.clearTimeout(timeout);
89                 timeout = null;
90             }
91             if (transport.getStatus() === 0) {
92                 options.onFailure(transport, json);
93             } else {
94                 options.onSuccess(transport, json);
95             }
96         }
97
98         function onFailure(transport, json) {
99             if (timeout) {
100                 window.clearTimeout(timeout);
101                 timeout = null;
102             }
103             options.onFailure(transport, json);
104         }
105
106         delete(reqoptions.presubmit);
107         delete(reqoptions.postsubmit);
108
109         $(form).observe('submit', function(evt) {
110             var req;
111
112             evt.stop(); // cancel form submission
113             if (Object.isFunction(options.presubmit)) {
114                 if (options.presubmit(this) === false) {
115                     return;
116                 }
117             }
118             req = this.request(Object.extend(reqoptions, {
119                 onSuccess: onSuccess,
120                 onFailure: onFailure
121             }));
122             timeout = (function() {
123                 options.onFailure(null);
124                 req.abort();
125             }).delay(options.timeout || 20);
126             if (Object.isFunction(options.postsubmit)) {
127                 options.postsubmit(this);
128             }
129         });
130     },
131
132     focus: function(form) {
133         var tofocus, error;
134
135         tofocus = null;
136         error = form.down('.error');
137         if (error) {
138             tofocus = error.previous('input,textarea');
139         } else {
140             tofocus = form.down('input:not([readonly],[disabled]),textarea:not([readonly][disabled])');
141         }
142         if (tofocus) {
143             if (error && (typeof tofocus.highlight === "function")) {
144                 tofocus.highlight('#F08080');
145             }
146             tofocus.activate();
147         }
148     },
149
150     checkEmptyElements: function(form, errorMessage) {
151         var results = [];
152         form.select('.required').each(function(elt) {
153             var id = elt.getAttribute('for'), control = $(id);
154             if (!control) {
155                 return;
156             }
157             if (!control.check(function() {
158                     return !this.value.strip().empty();
159                 }, errorMessage)) {
160                 results.push(control);
161             }
162         });
163         return results;
164     }
165 });
166
167 Element.addMethods(['input', 'textarea'], {
168     check: function(control, callback, errorMessage) {
169         if (callback.call(control)) {
170             return true;
171         }
172         control.insert({
173             after: new Element("div", {className: 'error'}).update(errorMessage)
174         });
175         return false;
176     }
177 });
178
179 Element.addMethods('div', {
180     setMessage: function(div, message, status) {
181         div.clearMessages();
182         if (status) {
183             div.setMessageStatus(status);
184         }
185         if (message) {
186             div.addMessage(message);
187         }
188         return div;
189     },
190
191     clearMessages: function(div) {
192         var node = div.firstChild, nextNode;
193
194         while (node) {
195             nextNode = node.nextSibling;
196             if (node.nodeType === 3 || node.tagName.toLowerCase() === 'br') {
197                 div.removeChild(node);
198             }
199                 node = nextNode;
200         }
201
202         return div;
203     },
204
205     addMessage: function(div, message) {
206         var node = (div.ownerDocument || document).createTextNode(message);
207         if (!div.empty()) {
208             div.insert(new Element('br'));
209         }
210         div.appendChild(node);
211         return div.show();
212     },
213
214     setMessageStatus: function(div, status) {
215         return div.removeClassName('error').
216                 removeClassName('warn').
217                 removeClassName('info').
218                 removeClassName('success').
219                 addClassName(status);
220     }
221 });