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) {
25 if (typeof options.callback === "function") {
26 options.callback.call(elt);
33 var Toggler = Class.create({
34 initialize: function(target, options) {
35 options = Object.extend({}, options);
36 target = $(target).hide();
38 var openIcn = options.openIcn || 'icons/bullet_arrow_right.png',
39 closeIcn = options.closeIcn || 'icons/bullet_arrow_down.png';
41 this.element = new Element("img", { src: openIcn })
42 .setStyle({ border: 'none', // in firefox, in image inside an anchor has a border
43 verticalAlign: "middle"});
45 this.element.observe('click', function(evt) {
46 if (target.visible()) {
47 evt.target.src = openIcn;
50 evt.target.src = closeIcn;
56 if (options.initialShow) {
58 this.element.src = closeIcn;
63 var Deck = Class.create({
64 initialize: function(elt, options) {
65 this.element = $(elt);
67 this.setIndex(parseInt(this.element.readAttribute("selectedindex") || 0, 10));
69 setIndex: function(idx) {
70 if (idx === this.index) {
74 var childs = this.element.childElements();
75 if (childs.length === 0) {
79 idx = Math.max(0, idx);
80 idx = Math.min(childs.length - 1, idx);
82 childs.each(function(item, i) {
91 getIndex: function() {
97 highlight: function(element, color, timeout) {
99 if (typeof timeout === "undefined") {
102 current = element.getStyle('backgroundColor');
103 Element.setStyle(element, {'backgroundColor': color});
104 Element.setStyle.delay(timeout, element, {'backgroundColor': current});
109 Ajax.TimedRequest = Class.create(Ajax.Request, {
114 // see http://blog.pothoven.net/2007/12/aborting-ajax-requests-for-prototypejs.html
115 this.transport.onreadystatechange = Prototype.emptyFunction;
116 this.transport.abort();
117 Ajax.activeRequestCount--;
120 initialize: function($super, url, delay, options) {
126 options.onSuccess = options.onSuccess &&
127 options.onSuccess.wrap(function(proceed, transport, json) {
129 window.clearTimeout(this.timeout);
132 if (transport.getStatus() === 0) {
133 this.options.onFailure(transport, json);
135 proceed(transport, json);
139 options.onFailure = options.onFailure &&
140 options.onFailure.wrap(function(proceed, transport, json) {
142 window.clearTimeout(this.timeout);
145 proceed(transport, json);
148 $super(url, options);
151 request: function($super, url) {
152 this.timeout = function() {
153 if (this.options.onFailure) {
154 this.options.onFailure(null);
157 }.bind(this).delay(this.delay);
162 Ajax.Responders.register({
163 // needed for Ajax.TimedRequest.abort to work: see
164 // http://blog.pothoven.net/2007/12/aborting-ajax-requests-for-prototypejs.html
166 onComplete: function() {
167 Ajax.activeRequestCount--;
168 if (Ajax.activeRequestCount < 0) {
169 Ajax.activeRequestCount = 0;
174 // wrapper around Form.request that sets up the submit listener, stops the
175 // submit event, calls presubmit function, calls Form.request and calls a
176 // postsubmit function
177 Element.addMethods('form', {
178 ajaxize : function(form, options) {
181 options = Object.clone(options || {});
183 $(form).observe('submit', function(evt) {
184 evt.stop(); // cancel form submission
186 reqoptions = Object.clone(options);
187 delete(reqoptions.presubmit);
188 delete(reqoptions.postsubmit);
189 delete(reqoptions.delay);
191 if (Object.isFunction(options.presubmit)) {
192 if (options.presubmit(this) === false) {
197 var params = reqoptions.parameters, action = this.readAttribute('action') || '';
199 if (action.blank()) {
200 action = window.location.href;
202 reqoptions.parameters = this.serialize(true);
205 if (Object.isString(params)) {
206 params = params.toQueryParams();
208 Object.extend(reqoptions.parameters, params);
211 if (this.hasAttribute('method') && !reqoptions.method) {
212 reqoptions.method = this.method;
215 if (reqoptions.onFailure) {
216 reqoptions.onFailure = reqoptions.onFailure.wrap(function(proceed, transport, json) {
218 proceed(transport, json);
221 reqoptions.onFailure = function() {
226 if (reqoptions.onSuccess) {
227 reqoptions.onSuccess = reqoptions.onSuccess.wrap(function(proceed, transport, json) {
229 proceed(transport, json);
232 reqoptions.onSuccess = function() {
237 new Ajax.TimedRequest(action, options.delay || 20, reqoptions);
239 if (Object.isFunction(options.postsubmit)) {
240 options.postsubmit(this);
242 Form.getElements(form).each(function(elt) {
249 setfocus: function(form) {
253 error = form.down('.error');
255 tofocus = error.previous('input,textarea');
257 tofocus = form.down('input:not([readonly],[disabled]),textarea:not([readonly][disabled])');
260 if (error && (typeof tofocus.highlight === "function")) {
261 tofocus.highlight('#F08080');
267 checkEmptyElements: function(form, errorMessage) {
269 form.select('.required').each(function(elt) {
270 var id = elt.getAttribute('for'), control = $(id);
274 if (!control.check(function() {
275 return !this.value.strip().empty();
277 results.push(control);
284 Element.addMethods(['input', 'textarea'], {
285 check: function(control, callback, errorMessage) {
286 if (callback.call(control)) {
290 after: new Element("div", {className: 'error'}).update(errorMessage)
295 observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) {
296 if (eventName === "contentchange") {
297 proceed(element, 'keyup', function(evt) {
298 if (evt.keyCode === 13) {
301 handler.apply(null, arguments);
303 proceed(element, 'paste', handler);
304 return proceed(element, 'change', handler);
306 return proceed(element, eventName, handler);
309 timedobserve: function(element, callback, delay) {
310 var timeout = null, initialvalue = element.value;
312 if (typeof delay !== "number") {
315 delay = delay * 1000;
317 var canceltimer = function() {
319 clearTimeout(timeout);
323 var resettimer = function() {
325 timeout = setTimeout(triggercallback, delay);
327 var triggercallback = function() {
329 if (initialvalue !== element.value) {
330 initialvalue = element.value;
331 callback.call(element);
335 element.observe('blur', triggercallback).
336 observe('keyup', resettimer).
337 observe('paste', resettimer);
342 Element.addMethods('div', {
343 setMessage: function(div, message, status) {
346 div.setMessageStatus(status);
349 div.addMessage(message);
354 clearMessages: function(div) {
355 var node = div.firstChild, nextNode;
358 nextNode = node.nextSibling;
359 if (node.nodeType === 3 || node.tagName.toLowerCase() === 'br') {
360 div.removeChild(node);
368 addMessage: function(div, message) {
369 var node = (div.ownerDocument || document).createTextNode(message);
371 if ($A(div.childNodes).filter(function(node) {
372 return (node.nodeType === 3 || node.tagName.toLowerCase() === 'br');
374 div.insert(new Element('br'));
377 div.appendChild(node);
381 setMessageStatus: function(div, status) {
382 return div.removeClassName('error').
383 removeClassName('warn').
384 removeClassName('info').
385 removeClassName('success').
386 addClassName(status);