gembox 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,212 @@
1
+ (function(){
2
+ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
3
+
4
+ // The base Class implementation (does nothing)
5
+ this.Class = function(){};
6
+
7
+ // Create a new Class that inherits from this class
8
+ Class.extend = function(prop) {
9
+ var _super = this.prototype;
10
+
11
+ // Instantiate a base class (but only create the instance,
12
+ // don't run the init constructor)
13
+ initializing = true;
14
+ var prototype = new this();
15
+ initializing = false;
16
+
17
+ // Copy the properties over onto the new prototype
18
+ for (var name in prop) {
19
+ // Check if we're overwriting an existing function
20
+ prototype[name] = typeof prop[name] == "function" &&
21
+ typeof _super[name] == "function" && fnTest.test(prop[name]) ?
22
+ (function(name, fn){
23
+ return function() {
24
+ var tmp = this._super;
25
+
26
+ // Add a new ._super() method that is the same method
27
+ // but on the super-class
28
+ this._super = _super[name];
29
+
30
+ // The method only need to be bound temporarily, so we
31
+ // remove it when we're done executing
32
+ var ret = fn.apply(this, arguments);
33
+ this._super = tmp;
34
+
35
+ return ret;
36
+ };
37
+ })(name, prop[name]) :
38
+ prop[name];
39
+ }
40
+
41
+ // The dummy class constructor
42
+ function Class() {
43
+ // All construction is actually done in the init method
44
+ if ( !initializing && this.init )
45
+ this.init.apply(this, arguments);
46
+ }
47
+
48
+ // Populate our constructed prototype object
49
+ Class.prototype = prototype;
50
+
51
+ // Enforce the constructor to be what we expect
52
+ Class.constructor = Class;
53
+
54
+ // And make this class extendable
55
+ Class.extend = arguments.callee;
56
+
57
+ return Class;
58
+ };
59
+ })();
60
+
61
+
62
+ $.fn.extend({
63
+ getId: function() {
64
+ var match = $(this).attr("id").match(/\d+/)
65
+ return match ? parseInt(match[0]) : null;
66
+ },
67
+ setInputHint: function() {
68
+ el = $(this);
69
+ el.data('default', el.val());
70
+
71
+ el.focus(function() {
72
+ if(el.data('default') != el.val()) return;
73
+ el.removeClass('hint').val('');
74
+ })
75
+ .blur(function() {
76
+ if($.trim(el.val()) != '') return;
77
+ el.addClass('hint').val(el.data('default'));
78
+ })
79
+ .addClass('hint');
80
+ },
81
+ fadeUp: function(speed) {
82
+ $(this).css({'position':'relative'}).animate({top:"-150px", opacity: 0}, speed, function() { $(this).remove(); })
83
+ return $(this);
84
+ }
85
+ });
86
+
87
+ $.extend({
88
+ log: function() {
89
+ if (typeof console == 'undefined') {
90
+ // do nothing
91
+ } else {
92
+ console.log(arguments);
93
+ }
94
+ },
95
+ timestamp: function() {
96
+ return Math.floor(new Date().getTime()/1000);
97
+ }
98
+ });
99
+
100
+ // authenticity tokens
101
+ // http://www.viget.com/extend/ie-jquery-rails-and-http-oh-my
102
+ $(function() {
103
+ $(document).ajaxSend(function(event, request, settings) {
104
+ if (settings.type == 'GET' || settings.type == 'get' || typeof(AUTH_TOKEN) == "undefined") return;
105
+ // settings.data is a serialized string like "foo=bar&baz=boink" (or null)
106
+ settings.data = settings.data || "";
107
+ settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
108
+ });
109
+ });
110
+
111
+ var Base = {
112
+ popup: function (link,title,width,height) {
113
+ return window.open(link,title,"height="+height+",width="+width+",status=no,toolbar=no,menubar=no,location=no");
114
+ },
115
+ urlify: function(title) {
116
+ // self.downcase.gsub(/(_|-|\/|\\|\&|,| )/,'_')[0..40]
117
+ return title.toString().strip().toLowerCase().gsub(/ /, '_').gsub(/[^a-z0-9\-_]/,'').truncate(40,'');
118
+ },
119
+ copyTextToClipboard: function(text) {
120
+ // create form element
121
+ var form_element = $('clipboard_holder') ? $('clipboard_holder') : new Element('input',{'type':'hidden','id':'clipboard_holder','name':'clipboard_holder','value':text});
122
+ if (form_element.createTextRange) {
123
+ var range = form_element.createTextRange();
124
+ if (range && BodyLoaded==1)
125
+ range.execCommand('Copy');
126
+ } else {
127
+ var flashcopier = $('flashcopier') ? $('flashcopier') : new Element('div',{id: 'flashcopier'});
128
+ $(flashcopier).innerHTML = '<embed src="/swf/_clipboard.swf" FlashVars="clipboard='+escape(form_element.value)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
129
+ document.body.appendChild(flashcopier);
130
+ }
131
+ },
132
+ images: {
133
+ hover_suffix: '_on',
134
+ active_suffix: '_on',
135
+ deactive_suffix: '_off',
136
+ swap: function(for_el,to) {
137
+ $(for_el).attr('src', to);
138
+ },
139
+ activate: function (for_el) {
140
+ return this.swap(for_el,this.activateSrc(for_el));
141
+ },
142
+ deactivate: function (for_el) {
143
+ return this.swap(for_el,this.deactivateSrc(for_el));
144
+ },
145
+ hover: function (for_el) {
146
+ return this.swap(for_el,this.hoverSrc(for_el));
147
+ },
148
+ replaceSrc: function (for_el,search,replace_with) {
149
+ return $(for_el).attr('src').replace(search,replace_with);
150
+ },
151
+ activateSrc: function (for_el) {
152
+ return this.replaceSrc(for_el,this.deactive_suffix,this.active_suffix);
153
+ },
154
+ deactivateSrc: function (for_el) {
155
+ return this.replaceSrc(for_el,this.active_suffix,this.deactive_suffix);
156
+ },
157
+ hoverSrc: function (for_el) {
158
+ return this.replaceSrc(for_el,this.deactive_suffix,this.hover_suffix);
159
+ },
160
+ restore: function (for_el) {
161
+ MM_swapImgRestore();
162
+ }
163
+ }
164
+ };
165
+
166
+ $.extend({
167
+ param: function( a, nest_in ) {
168
+ var s = [ ];
169
+ // check for nest
170
+ if (typeof nest_in == 'undefined') nest_in = false;
171
+
172
+ function nested(key) {
173
+ if (nest_in)
174
+ return nest_in + '[' + key + ']';
175
+ else
176
+ return key;
177
+ }
178
+ function add( key, value ){
179
+ key = nested(key)
180
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
181
+ };
182
+ // If an array was passed in, assume that it is an array
183
+ // of form elements
184
+ if ( jQuery.isArray(a) || a.jquery )
185
+ // Serialize the form elements
186
+ jQuery.each( a, function(){
187
+ add( this.name, this.value );
188
+ });
189
+
190
+ // Otherwise, assume that it's an object of key/value pairs
191
+ else
192
+ // Serialize the key/values
193
+ for ( var j in a )
194
+ // If the value is an array then the key names need to be repeated
195
+ if ( jQuery.isArray(a[j]) )
196
+ jQuery.each( a[j], function(){
197
+ add( j, this );
198
+ });
199
+ else if (a[j].constructor == Object)
200
+ s.push($.param(a[j], nested(j)));
201
+ else
202
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
203
+
204
+ // Return the resulting serialization
205
+ return s.join("&").replace(/%20/g, "+");
206
+ },
207
+ shove: function(fn, object) {
208
+ return function() {
209
+ return fn.apply(object, arguments);
210
+ }
211
+ }
212
+ });
@@ -0,0 +1,75 @@
1
+ (function($) {
2
+ $.metadata.setType("attr", "data");
3
+
4
+ function clippy(path, bgcolor) {
5
+ return '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"' +
6
+ 'width="110"' +
7
+ 'height="14"' +
8
+ 'id="clippy" >' +
9
+ '<param name="movie" value="/swf/clippy.swf"/>' +
10
+ '<param name="allowScriptAccess" value="always" />' +
11
+ '<param name="quality" value="high" />' +
12
+ '<param name="scale" value="noscale" />' +
13
+ '<param NAME="FlashVars" value="text=#{text}">' +
14
+ '<param name="bgcolor" value="' + bgcolor +'">' +
15
+ '<embed src="/swf/clippy.swf"' +
16
+ ' width="110"' +
17
+ ' height="14"' +
18
+ ' name="clippy"' +
19
+ ' quality="high"' +
20
+ ' allowScriptAccess="always"' +
21
+ ' type="application/x-shockwave-flash"' +
22
+ ' pluginspage="http://www.macromedia.com/go/getflashplayer"' +
23
+ ' FlashVars="text='+ path + '"' +
24
+ ' bgcolor="'+ bgcolor +'"' +
25
+ '/>' +
26
+ '</object>';
27
+ }
28
+
29
+ Gembox = {
30
+ initialize: function() {
31
+ this.setFileHover();
32
+ },
33
+ setFileHover: function() {
34
+ $('li.dir').hover(
35
+ function() {
36
+ $(this).addClass('file_hover')
37
+ .children('ul').show();
38
+ var $file = $(this).children('.file')
39
+ var meta = $file.metadata();
40
+ if ($file.next('.controls').length > 0) {
41
+ $file.next('.controls').show();
42
+ } else {
43
+ // build controls
44
+ var $controls = $('<span class="controls"></span>');
45
+ $('<a><img src="/images/edit.png" alt="Edit"/></a>')
46
+ .attr('href', meta.url + '&action=edit')
47
+ .appendTo($controls);
48
+ if (!meta.subdirs) {
49
+ $('<a><img src="/images/page_white_text.png" alt="View Raw"/></a>')
50
+ .attr('href', meta.url + '&action=view')
51
+ .appendTo($controls);
52
+ }
53
+ if (meta.github) {
54
+ $('<a><img src="/images/git.gif" alt="On Github"/></a>')
55
+ .attr('href', meta.github)
56
+ .appendTo($controls);
57
+ }
58
+ $(clippy(meta.filename, '#F4F6E6')).appendTo($controls);
59
+ $file.after($controls);
60
+ }
61
+ },
62
+ function() {
63
+ $(this)
64
+ .children('ul').hide().end()
65
+ .removeClass('file_hover')
66
+ .children('.controls').hide();
67
+ }
68
+ );
69
+ }
70
+ };
71
+
72
+ $(function() {
73
+ Gembox.initialize();
74
+ });
75
+ })(jQuery);
@@ -0,0 +1,632 @@
1
+ /*
2
+ * jQuery Form Plugin
3
+ * version: 2.21 (08-FEB-2009)
4
+ * @requires jQuery v1.2.2 or later
5
+ *
6
+ * Examples and documentation at: http://malsup.com/jquery/form/
7
+ * Dual licensed under the MIT and GPL licenses:
8
+ * http://www.opensource.org/licenses/mit-license.php
9
+ * http://www.gnu.org/licenses/gpl.html
10
+ */
11
+ ;(function($) {
12
+
13
+ /*
14
+ Usage Note:
15
+ -----------
16
+ Do not use both ajaxSubmit and ajaxForm on the same form. These
17
+ functions are intended to be exclusive. Use ajaxSubmit if you want
18
+ to bind your own submit handler to the form. For example,
19
+
20
+ $(document).ready(function() {
21
+ $('#myForm').bind('submit', function() {
22
+ $(this).ajaxSubmit({
23
+ target: '#output'
24
+ });
25
+ return false; // <-- important!
26
+ });
27
+ });
28
+
29
+ Use ajaxForm when you want the plugin to manage all the event binding
30
+ for you. For example,
31
+
32
+ $(document).ready(function() {
33
+ $('#myForm').ajaxForm({
34
+ target: '#output'
35
+ });
36
+ });
37
+
38
+ When using ajaxForm, the ajaxSubmit function will be invoked for you
39
+ at the appropriate time.
40
+ */
41
+
42
+ /**
43
+ * ajaxSubmit() provides a mechanism for immediately submitting
44
+ * an HTML form using AJAX.
45
+ */
46
+ $.fn.ajaxSubmit = function(options) {
47
+ // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
48
+ if (!this.length) {
49
+ log('ajaxSubmit: skipping submit process - no element selected');
50
+ return this;
51
+ }
52
+
53
+ if (typeof options == 'function')
54
+ options = { success: options };
55
+
56
+ options = $.extend({
57
+ url: this.attr('action') || window.location.toString(),
58
+ type: this.attr('method') || 'GET'
59
+ }, options || {});
60
+
61
+ // hook for manipulating the form data before it is extracted;
62
+ // convenient for use with rich editors like tinyMCE or FCKEditor
63
+ var veto = {};
64
+ this.trigger('form-pre-serialize', [this, options, veto]);
65
+ if (veto.veto) {
66
+ log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
67
+ return this;
68
+ }
69
+
70
+ // provide opportunity to alter form data before it is serialized
71
+ if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
72
+ log('ajaxSubmit: submit aborted via beforeSerialize callback');
73
+ return this;
74
+ }
75
+
76
+ var a = this.formToArray(options.semantic);
77
+ if (options.data) {
78
+ options.extraData = options.data;
79
+ for (var n in options.data) {
80
+ if(options.data[n] instanceof Array) {
81
+ for (var k in options.data[n])
82
+ a.push( { name: n, value: options.data[n][k] } )
83
+ }
84
+ else
85
+ a.push( { name: n, value: options.data[n] } );
86
+ }
87
+ }
88
+
89
+ // give pre-submit callback an opportunity to abort the submit
90
+ if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
91
+ log('ajaxSubmit: submit aborted via beforeSubmit callback');
92
+ return this;
93
+ }
94
+
95
+ // fire vetoable 'validate' event
96
+ this.trigger('form-submit-validate', [a, this, options, veto]);
97
+ if (veto.veto) {
98
+ log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
99
+ return this;
100
+ }
101
+
102
+ var q = $.param(a);
103
+
104
+ if (options.type.toUpperCase() == 'GET') {
105
+ options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
106
+ options.data = null; // data is null for 'get'
107
+ }
108
+ else
109
+ options.data = q; // data is the query string for 'post'
110
+
111
+ var $form = this, callbacks = [];
112
+ if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
113
+ if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
114
+
115
+ // perform a load on the target only if dataType is not provided
116
+ if (!options.dataType && options.target) {
117
+ var oldSuccess = options.success || function(){};
118
+ callbacks.push(function(data) {
119
+ $(options.target).html(data).each(oldSuccess, arguments);
120
+ });
121
+ }
122
+ else if (options.success)
123
+ callbacks.push(options.success);
124
+
125
+ options.success = function(data, status) {
126
+ for (var i=0, max=callbacks.length; i < max; i++)
127
+ callbacks[i].apply(options, [data, status, $form]);
128
+ };
129
+
130
+ // are there files to upload?
131
+ var files = $('input:file', this).fieldValue();
132
+ var found = false;
133
+ for (var j=0; j < files.length; j++)
134
+ if (files[j])
135
+ found = true;
136
+
137
+ // options.iframe allows user to force iframe mode
138
+ if (options.iframe || found) {
139
+ // hack to fix Safari hang (thanks to Tim Molendijk for this)
140
+ // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
141
+ if (options.closeKeepAlive)
142
+ $.get(options.closeKeepAlive, fileUpload);
143
+ else
144
+ fileUpload();
145
+ }
146
+ else
147
+ $.ajax(options);
148
+
149
+ // fire 'notify' event
150
+ this.trigger('form-submit-notify', [this, options]);
151
+ return this;
152
+
153
+
154
+ // private function for handling file uploads (hat tip to YAHOO!)
155
+ function fileUpload() {
156
+ var form = $form[0];
157
+
158
+ if ($(':input[name=submit]', form).length) {
159
+ alert('Error: Form elements must not be named "submit".');
160
+ return;
161
+ }
162
+
163
+ var opts = $.extend({}, $.ajaxSettings, options);
164
+ var s = jQuery.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);
165
+
166
+ var id = 'jqFormIO' + (new Date().getTime());
167
+ var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />');
168
+ var io = $io[0];
169
+
170
+ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
171
+
172
+ var xhr = { // mock object
173
+ aborted: 0,
174
+ responseText: null,
175
+ responseXML: null,
176
+ status: 0,
177
+ statusText: 'n/a',
178
+ getAllResponseHeaders: function() {},
179
+ getResponseHeader: function() {},
180
+ setRequestHeader: function() {},
181
+ abort: function() {
182
+ this.aborted = 1;
183
+ $io.attr('src','about:blank'); // abort op in progress
184
+ }
185
+ };
186
+
187
+ var g = opts.global;
188
+ // trigger ajax global events so that activity/block indicators work like normal
189
+ if (g && ! $.active++) $.event.trigger("ajaxStart");
190
+ if (g) $.event.trigger("ajaxSend", [xhr, opts]);
191
+
192
+ if (s.beforeSend && s.beforeSend(xhr, s) === false) {
193
+ s.global && jQuery.active--;
194
+ return;
195
+ }
196
+ if (xhr.aborted)
197
+ return;
198
+
199
+ var cbInvoked = 0;
200
+ var timedOut = 0;
201
+
202
+ // add submitting element to data if we know it
203
+ var sub = form.clk;
204
+ if (sub) {
205
+ var n = sub.name;
206
+ if (n && !sub.disabled) {
207
+ options.extraData = options.extraData || {};
208
+ options.extraData[n] = sub.value;
209
+ if (sub.type == "image") {
210
+ options.extraData[name+'.x'] = form.clk_x;
211
+ options.extraData[name+'.y'] = form.clk_y;
212
+ }
213
+ }
214
+ }
215
+
216
+ // take a breath so that pending repaints get some cpu time before the upload starts
217
+ setTimeout(function() {
218
+ // make sure form attrs are set
219
+ var t = $form.attr('target'), a = $form.attr('action');
220
+
221
+ // update form attrs in IE friendly way
222
+ form.setAttribute('target',id);
223
+ if (form.getAttribute('method') != 'POST')
224
+ form.setAttribute('method', 'POST');
225
+ if (form.getAttribute('action') != opts.url)
226
+ form.setAttribute('action', opts.url);
227
+
228
+ // ie borks in some cases when setting encoding
229
+ if (! options.skipEncodingOverride) {
230
+ $form.attr({
231
+ encoding: 'multipart/form-data',
232
+ enctype: 'multipart/form-data'
233
+ });
234
+ }
235
+
236
+ // support timout
237
+ if (opts.timeout)
238
+ setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
239
+
240
+ // add "extra" data to form if provided in options
241
+ var extraInputs = [];
242
+ try {
243
+ if (options.extraData)
244
+ for (var n in options.extraData)
245
+ extraInputs.push(
246
+ $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
247
+ .appendTo(form)[0]);
248
+
249
+ // add iframe to doc and submit the form
250
+ $io.appendTo('body');
251
+ io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
252
+ form.submit();
253
+ }
254
+ finally {
255
+ // reset attrs and remove "extra" input elements
256
+ form.setAttribute('action',a);
257
+ t ? form.setAttribute('target', t) : $form.removeAttr('target');
258
+ $(extraInputs).remove();
259
+ }
260
+ }, 10);
261
+
262
+ var nullCheckFlag = 0;
263
+
264
+ function cb() {
265
+ if (cbInvoked++) return;
266
+
267
+ io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
268
+
269
+ var ok = true;
270
+ try {
271
+ if (timedOut) throw 'timeout';
272
+ // extract the server response from the iframe
273
+ var data, doc;
274
+
275
+ doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
276
+
277
+ if ((doc.body == null || doc.body.innerHTML == '') && !nullCheckFlag) {
278
+ // in some browsers (cough, Opera 9.2.x) the iframe DOM is not always traversable when
279
+ // the onload callback fires, so we give them a 2nd chance
280
+ nullCheckFlag = 1;
281
+ cbInvoked--;
282
+ setTimeout(cb, 100);
283
+ return;
284
+ }
285
+
286
+ xhr.responseText = doc.body ? doc.body.innerHTML : null;
287
+ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
288
+ xhr.getResponseHeader = function(header){
289
+ var headers = {'content-type': opts.dataType};
290
+ return headers[header];
291
+ };
292
+
293
+ if (opts.dataType == 'json' || opts.dataType == 'script') {
294
+ var ta = doc.getElementsByTagName('textarea')[0];
295
+ xhr.responseText = ta ? ta.value : xhr.responseText;
296
+ }
297
+ else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
298
+ xhr.responseXML = toXml(xhr.responseText);
299
+ }
300
+ data = $.httpData(xhr, opts.dataType);
301
+ }
302
+ catch(e){
303
+ ok = false;
304
+ $.handleError(opts, xhr, 'error', e);
305
+ }
306
+
307
+ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
308
+ if (ok) {
309
+ opts.success(data, 'success');
310
+ if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
311
+ }
312
+ if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
313
+ if (g && ! --$.active) $.event.trigger("ajaxStop");
314
+ if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
315
+
316
+ // clean up
317
+ setTimeout(function() {
318
+ $io.remove();
319
+ xhr.responseXML = null;
320
+ }, 100);
321
+ };
322
+
323
+ function toXml(s, doc) {
324
+ if (window.ActiveXObject) {
325
+ doc = new ActiveXObject('Microsoft.XMLDOM');
326
+ doc.async = 'false';
327
+ doc.loadXML(s);
328
+ }
329
+ else
330
+ doc = (new DOMParser()).parseFromString(s, 'text/xml');
331
+ return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
332
+ };
333
+ };
334
+ };
335
+
336
+ /**
337
+ * ajaxForm() provides a mechanism for fully automating form submission.
338
+ *
339
+ * The advantages of using this method instead of ajaxSubmit() are:
340
+ *
341
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
342
+ * is used to submit the form).
343
+ * 2. This method will include the submit element's name/value data (for the element that was
344
+ * used to submit the form).
345
+ * 3. This method binds the submit() method to the form for you.
346
+ *
347
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
348
+ * passes the options argument along after properly binding events for submit elements and
349
+ * the form itself.
350
+ */
351
+ $.fn.ajaxForm = function(options) {
352
+ return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
353
+ $(this).ajaxSubmit(options);
354
+ return false;
355
+ }).each(function() {
356
+ // store options in hash
357
+ $(":submit,input:image", this).bind('click.form-plugin',function(e) {
358
+ var form = this.form;
359
+ form.clk = this;
360
+ if (this.type == 'image') {
361
+ if (e.offsetX != undefined) {
362
+ form.clk_x = e.offsetX;
363
+ form.clk_y = e.offsetY;
364
+ } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
365
+ var offset = $(this).offset();
366
+ form.clk_x = e.pageX - offset.left;
367
+ form.clk_y = e.pageY - offset.top;
368
+ } else {
369
+ form.clk_x = e.pageX - this.offsetLeft;
370
+ form.clk_y = e.pageY - this.offsetTop;
371
+ }
372
+ }
373
+ // clear form vars
374
+ setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
375
+ });
376
+ });
377
+ };
378
+
379
+ // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
380
+ $.fn.ajaxFormUnbind = function() {
381
+ this.unbind('submit.form-plugin');
382
+ return this.each(function() {
383
+ $(":submit,input:image", this).unbind('click.form-plugin');
384
+ });
385
+
386
+ };
387
+
388
+ /**
389
+ * formToArray() gathers form element data into an array of objects that can
390
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
391
+ * Each object in the array has both a 'name' and 'value' property. An example of
392
+ * an array for a simple login form might be:
393
+ *
394
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
395
+ *
396
+ * It is this array that is passed to pre-submit callback functions provided to the
397
+ * ajaxSubmit() and ajaxForm() methods.
398
+ */
399
+ $.fn.formToArray = function(semantic) {
400
+ var a = [];
401
+ if (this.length == 0) return a;
402
+
403
+ var form = this[0];
404
+ var els = semantic ? form.getElementsByTagName('*') : form.elements;
405
+ if (!els) return a;
406
+ for(var i=0, max=els.length; i < max; i++) {
407
+ var el = els[i];
408
+ var n = el.name;
409
+ if (!n) continue;
410
+
411
+ if (semantic && form.clk && el.type == "image") {
412
+ // handle image inputs on the fly when semantic == true
413
+ if(!el.disabled && form.clk == el)
414
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
415
+ continue;
416
+ }
417
+
418
+ var v = $.fieldValue(el, true);
419
+ if (v && v.constructor == Array) {
420
+ for(var j=0, jmax=v.length; j < jmax; j++)
421
+ a.push({name: n, value: v[j]});
422
+ }
423
+ else if (v !== null && typeof v != 'undefined')
424
+ a.push({name: n, value: v});
425
+ }
426
+
427
+ if (!semantic && form.clk) {
428
+ // input type=='image' are not found in elements array! handle them here
429
+ var inputs = form.getElementsByTagName("input");
430
+ for(var i=0, max=inputs.length; i < max; i++) {
431
+ var input = inputs[i];
432
+ var n = input.name;
433
+ if(n && !input.disabled && input.type == "image" && form.clk == input)
434
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
435
+ }
436
+ }
437
+ return a;
438
+ };
439
+
440
+ /**
441
+ * Serializes form data into a 'submittable' string. This method will return a string
442
+ * in the format: name1=value1&amp;name2=value2
443
+ */
444
+ $.fn.formSerialize = function(semantic) {
445
+ //hand off to jQuery.param for proper encoding
446
+ return $.param(this.formToArray(semantic));
447
+ };
448
+
449
+ /**
450
+ * Serializes all field elements in the jQuery object into a query string.
451
+ * This method will return a string in the format: name1=value1&amp;name2=value2
452
+ */
453
+ $.fn.fieldSerialize = function(successful) {
454
+ var a = [];
455
+ this.each(function() {
456
+ var n = this.name;
457
+ if (!n) return;
458
+ var v = $.fieldValue(this, successful);
459
+ if (v && v.constructor == Array) {
460
+ for (var i=0,max=v.length; i < max; i++)
461
+ a.push({name: n, value: v[i]});
462
+ }
463
+ else if (v !== null && typeof v != 'undefined')
464
+ a.push({name: this.name, value: v});
465
+ });
466
+ //hand off to jQuery.param for proper encoding
467
+ return $.param(a);
468
+ };
469
+
470
+ /**
471
+ * Returns the value(s) of the element in the matched set. For example, consider the following form:
472
+ *
473
+ * <form><fieldset>
474
+ * <input name="A" type="text" />
475
+ * <input name="A" type="text" />
476
+ * <input name="B" type="checkbox" value="B1" />
477
+ * <input name="B" type="checkbox" value="B2"/>
478
+ * <input name="C" type="radio" value="C1" />
479
+ * <input name="C" type="radio" value="C2" />
480
+ * </fieldset></form>
481
+ *
482
+ * var v = $(':text').fieldValue();
483
+ * // if no values are entered into the text inputs
484
+ * v == ['','']
485
+ * // if values entered into the text inputs are 'foo' and 'bar'
486
+ * v == ['foo','bar']
487
+ *
488
+ * var v = $(':checkbox').fieldValue();
489
+ * // if neither checkbox is checked
490
+ * v === undefined
491
+ * // if both checkboxes are checked
492
+ * v == ['B1', 'B2']
493
+ *
494
+ * var v = $(':radio').fieldValue();
495
+ * // if neither radio is checked
496
+ * v === undefined
497
+ * // if first radio is checked
498
+ * v == ['C1']
499
+ *
500
+ * The successful argument controls whether or not the field element must be 'successful'
501
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
502
+ * The default value of the successful argument is true. If this value is false the value(s)
503
+ * for each element is returned.
504
+ *
505
+ * Note: This method *always* returns an array. If no valid value can be determined the
506
+ * array will be empty, otherwise it will contain one or more values.
507
+ */
508
+ $.fn.fieldValue = function(successful) {
509
+ for (var val=[], i=0, max=this.length; i < max; i++) {
510
+ var el = this[i];
511
+ var v = $.fieldValue(el, successful);
512
+ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
513
+ continue;
514
+ v.constructor == Array ? $.merge(val, v) : val.push(v);
515
+ }
516
+ return val;
517
+ };
518
+
519
+ /**
520
+ * Returns the value of the field element.
521
+ */
522
+ $.fieldValue = function(el, successful) {
523
+ var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
524
+ if (typeof successful == 'undefined') successful = true;
525
+
526
+ if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
527
+ (t == 'checkbox' || t == 'radio') && !el.checked ||
528
+ (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
529
+ tag == 'select' && el.selectedIndex == -1))
530
+ return null;
531
+
532
+ if (tag == 'select') {
533
+ var index = el.selectedIndex;
534
+ if (index < 0) return null;
535
+ var a = [], ops = el.options;
536
+ var one = (t == 'select-one');
537
+ var max = (one ? index+1 : ops.length);
538
+ for(var i=(one ? index : 0); i < max; i++) {
539
+ var op = ops[i];
540
+ if (op.selected) {
541
+ var v = op.value;
542
+ if (!v) // extra pain for IE...
543
+ v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
544
+ if (one) return v;
545
+ a.push(v);
546
+ }
547
+ }
548
+ return a;
549
+ }
550
+ return el.value;
551
+ };
552
+
553
+ /**
554
+ * Clears the form data. Takes the following actions on the form's input fields:
555
+ * - input text fields will have their 'value' property set to the empty string
556
+ * - select elements will have their 'selectedIndex' property set to -1
557
+ * - checkbox and radio inputs will have their 'checked' property set to false
558
+ * - inputs of type submit, button, reset, and hidden will *not* be effected
559
+ * - button elements will *not* be effected
560
+ */
561
+ $.fn.clearForm = function() {
562
+ return this.each(function() {
563
+ $('input,select,textarea', this).clearFields();
564
+ });
565
+ };
566
+
567
+ /**
568
+ * Clears the selected form elements.
569
+ */
570
+ $.fn.clearFields = $.fn.clearInputs = function() {
571
+ return this.each(function() {
572
+ var t = this.type, tag = this.tagName.toLowerCase();
573
+ if (t == 'text' || t == 'password' || tag == 'textarea')
574
+ this.value = '';
575
+ else if (t == 'checkbox' || t == 'radio')
576
+ this.checked = false;
577
+ else if (tag == 'select')
578
+ this.selectedIndex = -1;
579
+ });
580
+ };
581
+
582
+ /**
583
+ * Resets the form data. Causes all form elements to be reset to their original value.
584
+ */
585
+ $.fn.resetForm = function() {
586
+ return this.each(function() {
587
+ // guard against an input with the name of 'reset'
588
+ // note that IE reports the reset function as an 'object'
589
+ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
590
+ this.reset();
591
+ });
592
+ };
593
+
594
+ /**
595
+ * Enables or disables any matching elements.
596
+ */
597
+ $.fn.enable = function(b) {
598
+ if (b == undefined) b = true;
599
+ return this.each(function() {
600
+ this.disabled = !b
601
+ });
602
+ };
603
+
604
+ /**
605
+ * Checks/unchecks any matching checkboxes or radio buttons and
606
+ * selects/deselects and matching option elements.
607
+ */
608
+ $.fn.selected = function(select) {
609
+ if (select == undefined) select = true;
610
+ return this.each(function() {
611
+ var t = this.type;
612
+ if (t == 'checkbox' || t == 'radio')
613
+ this.checked = select;
614
+ else if (this.tagName.toLowerCase() == 'option') {
615
+ var $sel = $(this).parent('select');
616
+ if (select && $sel[0] && $sel[0].type == 'select-one') {
617
+ // deselect all other options
618
+ $sel.find('option').selected(false);
619
+ }
620
+ this.selected = select;
621
+ }
622
+ });
623
+ };
624
+
625
+ // helper fn for console logging
626
+ // set $.fn.ajaxSubmit.debug to true to enable debug logging
627
+ function log() {
628
+ if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
629
+ window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
630
+ };
631
+
632
+ })(jQuery);