1 /* This file is part of Syj, Copyright (c) 2010 Arnaud Renevier,
2 and is published under the AGPL license. */
4 var CloseBtn = Class.create({
5 initialize: function(elt, options) {
6 var btn, imgsrc, style;
13 style = Object.extend({
18 }, typeof options === "object" ? options.style: {});
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) {
29 var Deck = Class.create({
30 initialize: function(elt, options) {
31 this.element = $(elt);
33 this.setIndex(parseInt(this.element.readAttribute("selectedindex") || 0, 10));
35 setIndex: function(idx) {
36 if (idx === this.index) {
40 var childs = this.element.childElements();
41 if (childs.length === 0) {
45 idx = Math.max(0, idx);
46 idx = Math.min(childs.length - 1, idx);
48 childs.each(function(item, i) {
57 getIndex: function() {
63 highlight: function(element, color, timeout) {
65 if (typeof timeout === "undefined") {
68 current = element.getStyle('backgroundColor');
69 Element.setStyle(element, {'backgroundColor': color});
70 Element.setStyle.delay(timeout, element, {'backgroundColor': current});
75 Ajax.TimedRequest = Class.create(Ajax.Request, {
80 // see http://blog.pothoven.net/2007/12/aborting-ajax-requests-for-prototypejs.html
81 this.transport.onreadystatechange = Prototype.emptyFunction;
82 this.transport.abort();
83 Ajax.activeRequestCount--;
86 initialize: function($super, url, delay, options) {
92 options.onSuccess = options.onSuccess &&
93 options.onSuccess.wrap(function(proceed, transport, json) {
95 window.clearTimeout(this.timeout);
98 if (transport.getStatus() === 0) {
99 this.options.onFailure(transport, json);
101 proceed(transport, json);
105 options.onFailure = options.onFailure &&
106 options.onFailure.wrap(function(proceed, transport, json) {
108 window.clearTimeout(this.timeout);
111 proceed(transport, json);
114 $super(url, options);
117 request: function($super, url) {
118 this.timeout = (function() {
119 if (this.options.onFailure) {
120 this.options.onFailure(null);
123 }).bind(this).delay(this.delay);
128 Ajax.Responders.register({
129 // needed for Ajax.TimedRequest.abort to work: see
130 // http://blog.pothoven.net/2007/12/aborting-ajax-requests-for-prototypejs.html
132 onComplete: function() {
133 Ajax.activeRequestCount--;
134 if (Ajax.activeRequestCount < 0) {
135 Ajax.activeRequestCount = 0;
140 // wrapper around Form.request that sets up the submit listener, stops the
141 // submit event, calls presubmit function, calls Form.request and calls a
142 // postsubmit function
143 Element.addMethods('form', {
144 ajaxize : function(form, options) {
147 options = Object.clone(options || {});
149 $(form).observe('submit', function(evt) {
150 evt.stop(); // cancel form submission
152 reqoptions = Object.clone(options);
153 delete(reqoptions.presubmit);
154 delete(reqoptions.postsubmit);
155 delete(reqoptions.delay);
157 if (Object.isFunction(options.presubmit)) {
158 if (options.presubmit(this) === false) {
163 var params = reqoptions.parameters, action = this.readAttribute('action') || '';
165 if (action.blank()) {
166 action = window.location.href;
168 reqoptions.parameters = this.serialize(true);
171 if (Object.isString(params)) {
172 params = params.toQueryParams();
174 Object.extend(reqoptions.parameters, params);
177 if (this.hasAttribute('method') && !reqoptions.method) {
178 reqoptions.method = this.method;
181 new Ajax.TimedRequest(action, options.delay || 20, reqoptions);
183 if (Object.isFunction(options.postsubmit)) {
184 options.postsubmit(this);
189 focus: function(form) {
193 error = form.down('.error');
195 tofocus = error.previous('input,textarea');
197 tofocus = form.down('input:not([readonly],[disabled]),textarea:not([readonly][disabled])');
200 if (error && (typeof tofocus.highlight === "function")) {
201 tofocus.highlight('#F08080');
207 checkEmptyElements: function(form, errorMessage) {
209 form.select('.required').each(function(elt) {
210 var id = elt.getAttribute('for'), control = $(id);
214 if (!control.check(function() {
215 return !this.value.strip().empty();
217 results.push(control);
224 Element.addMethods(['input', 'textarea'], {
225 check: function(control, callback, errorMessage) {
226 if (callback.call(control)) {
230 after: new Element("div", {className: 'error'}).update(errorMessage)
235 observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) {
236 if (eventName === "contentchange") {
237 proceed(element, 'keyup', function(evt) {
238 if (evt.keyCode === 13) {
241 handler.apply(null, arguments);
243 proceed(element, 'paste', handler);
244 return proceed(element, 'change', handler);
246 return proceed(element, eventName, handler);
249 timedobserve: function(element, callback, delay) {
250 var timeout = null, initialvalue = element.value;
252 if (typeof delay !== "number") {
255 delay = delay * 1000;
257 var canceltimer = function() {
259 clearTimeout(timeout);
263 var resettimer = function() {
265 timeout = setTimeout(triggercallback, delay);
267 var triggercallback = function() {
269 if (initialvalue !== element.value) {
270 initialvalue = element.value;
271 callback.call(element);
275 element.observe('blur', triggercallback).
276 observe('keyup', resettimer).
277 observe('paste', resettimer);
282 Element.addMethods('div', {
283 setMessage: function(div, message, status) {
286 div.setMessageStatus(status);
289 div.addMessage(message);
294 clearMessages: function(div) {
295 var node = div.firstChild, nextNode;
298 nextNode = node.nextSibling;
299 if (node.nodeType === 3 || node.tagName.toLowerCase() === 'br') {
300 div.removeChild(node);
308 addMessage: function(div, message) {
309 var node = (div.ownerDocument || document).createTextNode(message);
311 div.insert(new Element('br'));
313 div.appendChild(node);
317 setMessageStatus: function(div, status) {
318 return div.removeClassName('error').
319 removeClassName('warn').
320 removeClassName('info').
321 removeClassName('success').
322 addClassName(status);