hobo_jquery 1.4.0.pre6 → 1.4.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0.pre6
1
+ 1.4.0.pre7
@@ -8,11 +8,10 @@ hobo_jquery
8
8
  %>
9
9
  <def tag="page-scripts">
10
10
  <do param="default">
11
- <% attributes.reverse_merge!(:data_rapid_page_data => {
12
- 'form_auth_token' => { 'name' => request_forgery_protection_token, 'value' => form_authenticity_token},
13
- 'hobo_parts' => part_contexts_storage_uncoded}.to_json,
14
- :style => "display: none;") %>
15
- <%= tag("span", deunderscore_attributes(attributes)) %>
11
+ <% attrs = deunderscore_attributes(attributes).reverse_merge( 'form_auth_token' => { 'name' => request_forgery_protection_token, 'value' => form_authenticity_token},
12
+ 'hobo_parts' => part_contexts_storage_uncoded
13
+ ) %>
14
+ <%= tag("span", "data-rapid-page-data" => attrs.to_json, :style => "display: none;") %>
16
15
  </do>
17
16
  </def>
18
17
 
@@ -9,14 +9,9 @@
9
9
  var that = $(this);
10
10
  var options = that.data('rapid').a.ajax_attrs;
11
11
  if(!options.message) options.message="Loading...";
12
- var roptions = that.hjq('buildRequest', {
13
- type: 'GET',
14
- attrs: options
15
- });
16
- if(options.push_state) {
17
- window.History.pushState(null, options.new_title || null, that.attr('href'));
18
- };
19
- $.ajax(that.attr('href'), roptions);
12
+ var hobo_options = {type: 'GET', attrs: options};
13
+ var roptions = that.hjq('buildRequestData', hobo_options);
14
+ that.hjq("changeLocationAjax", that.attr('href'), roptions, hobo_options);
20
15
  return false;
21
16
  }
22
17
  };
@@ -19,17 +19,24 @@
19
19
 
20
20
  if(form.attr('enctype') == 'multipart/form-data') {
21
21
  if(form.ajaxSubmit) {
22
- var roptions= form.hjq('buildRequest', $.extend(options, {preamble: '<textarea>', postamble: '</textarea>', content_type: 'text/html'}));
22
+ options = $.extend(options, {preamble: '<textarea>', postamble: '</textarea>', content_type: 'text/html'});
23
+ var roptions = form.hjq('buildRequestData', options);
23
24
 
24
25
  if(!roptions) return false;
25
26
  roptions.iframe = true;
27
+
28
+ roptions = form.hjq('buildRequestCallbacks', roptions, options)
29
+
30
+ if(options.attrs.push_state) {
31
+ alert("push_state not supported on multipart forms");
32
+ }
26
33
  form.ajaxSubmit(roptions);
27
34
  } else {
28
35
  alert("malsup's jquery form plugin required to do ajax submissions of multipart forms");
29
36
  }
30
37
 
31
38
  } else {
32
- var roptions= form.hjq('buildRequest', options);
39
+ var roptions= form.hjq('buildRequestData', options);
33
40
  if(!roptions) return false;
34
41
 
35
42
  // make sure we don't serialize any nested formlets
@@ -39,10 +46,7 @@
39
46
 
40
47
  roptions.data = $.param(roptions.data) + "&" + data;
41
48
 
42
- if (options.attrs.push_state) {
43
- window.History.pushState(null, options.attrs.new_title || null, form[0].action+"?"+data);
44
- }
45
- $.ajax(form[0].action, roptions);
49
+ form.hjq("changeLocationAjax", form[0].action+"?"+data, roptions, options);
46
50
  }
47
51
 
48
52
  // prevent bubbling
@@ -54,14 +54,14 @@
54
54
  });
55
55
  }
56
56
  if(!clone) return this;
57
- clone.hide('fast');
57
+ clone.remove();
58
58
  return this;
59
59
  },
60
60
  };
61
61
 
62
62
  var defaultOptions = function() {
63
63
  if(default_options) return default_options;
64
- page_options = this.hjq('pageData');
64
+ var page_options = this.hjq('pageData');
65
65
  default_options = {};
66
66
  default_options['spinner-next-to'] = page_options['spinner-next-to'];
67
67
  default_options['spinner-at'] = page_options['spinner-at'];
@@ -71,6 +71,7 @@
71
71
  at: "left top"
72
72
  };
73
73
  default_options['message'] = page_options['message'];
74
+ return default_options;
74
75
  };
75
76
 
76
77
  $.fn.hjq_spinner = function( method ) {
@@ -8,7 +8,23 @@
8
8
 
9
9
  var methods = {
10
10
 
11
- init : function() {
11
+ /* call only once per document. */
12
+ initOnce: function() {
13
+ if(typeof History === 'object') { // History.js installed
14
+ $(window).on("statechange", function() {
15
+ var state = History.getState();
16
+ if(state.data.length==3) {
17
+ var form = $(state.data[0]);
18
+ var roptions = form.hjq('buildRequestCallbacks', state.data[1], state.data[2]);
19
+ $.ajax(state.url, roptions);
20
+ }
21
+ })
22
+ }
23
+ return true;
24
+ },
25
+
26
+ /* call for every new fragment */
27
+ init: function() {
12
28
  var top = this;
13
29
  this.find("[data-rapid-page-data]").each(function() {
14
30
  page_data = $(this).data('rapid-page-data');
@@ -152,6 +168,23 @@
152
168
  return function() { return eval(script); };
153
169
  },
154
170
 
171
+
172
+ /* returns a jQuery selector for an element. One option would
173
+ be to use something like
174
+ http://stackoverflow.com/questions/2206958/best-way-to-reference-an-element-with-jquery
175
+ However, if the DOM changes due to Ajax this isn't
176
+ necessarily stable. So instead we give the element a unique
177
+ ID if it doesn't already have one.
178
+ */
179
+
180
+ getPath: function() {
181
+ if(!this.attr("id")) {
182
+ this.attr("id", Math.random().toString().replace("0.", "id"))
183
+ }
184
+ return "#"+this.attr("id");
185
+ },
186
+
187
+
155
188
  /* Build an options object suitable for sending to
156
189
  * jQuery.ajax. (Note that the before & confirm callbacks
157
190
  * are called from this function, and the spinner is shown)
@@ -159,6 +192,12 @@
159
192
  * The returned object will include a 'data' value
160
193
  * populated with a hash.
161
194
  *
195
+ * This function has now been split into two parts to
196
+ * better support push_state. buildRequestData is the
197
+ * first part, which builds everything except the
198
+ * callbacks (but it does execute the before callbacks).
199
+ * buildRequestCallbacks builds the remaining callbacks.
200
+ *
162
201
  * Options:
163
202
  * type: POST, GET
164
203
  * attrs: a hash containing the standard Hobo ajax attributes & callbacks
@@ -171,10 +210,13 @@
171
210
  *
172
211
  */
173
212
  buildRequest: function(o) {
213
+ return methods.buildRequestCallbacks.call(this, methods.buildRequestData.call(this, o), o);
214
+ },
215
+
216
+ buildRequestData: function(o) {
174
217
  var that = this;
175
218
  if (!o.attrs) o.attrs = {};
176
- if (!o.extra_callbacks) o.extra_callbacks = {};
177
- var options = {};
219
+ var result = {};
178
220
 
179
221
  if(o.attrs.before) {
180
222
  if(!methods.createFunction.call(that, o.attrs.before).call(this)) {
@@ -194,15 +236,15 @@
194
236
  }
195
237
  }
196
238
 
197
- options.context = this;
198
- options.type = o.type || 'GET';
199
- options.data = {"render_options[preamble]": o.preamble || '',
239
+ result.context = this;
240
+ result.type = o.type || 'GET';
241
+ result.data = {"render_options[preamble]": o.preamble || '',
200
242
  "render_options[contexts_function]": 'hjq.ajax.updatePartContexts'
201
243
  };
202
- if(o.postamble) options.data["render_options[postamble]"] = o.postamble;
203
- if(o.content_type) options.data["render_options[content_type]"] = o.content_type;
204
- if(o.attrs.errors_ok) options.data["render_options[errors_ok]"] = 1;
205
- options.dataType = 'script';
244
+ if(o.postamble) result.data["render_options[postamble]"] = o.postamble;
245
+ if(o.content_type) result.data["render_options[content_type]"] = o.content_type;
246
+ if(o.attrs.errors_ok) result.data["render_options[errors_ok]"] = 1;
247
+ result.dataType = 'script';
206
248
  o.spec = jQuery.extend({'function': 'hjq.ajax.update', preamble: ''}, o.spec);
207
249
 
208
250
  var part_data = {};
@@ -214,11 +256,19 @@
214
256
  var ids=methods.getUpdateIds.call(this, o.attrs);
215
257
  for(var i=0; i<ids.length; i++) {
216
258
  if(part_data) $("#"+ids[i]).data('hjq-ajax', part_data);
217
- options.data["render["+i+"][part_context]"] = page_data.hobo_parts[ids[i]];
218
- options.data["render["+i+"][id]"] = ids[i];
219
- options.data["render["+i+"][function]"] = o['function'] || 'hjq.ajax.update';
259
+ result.data["render["+i+"][part_context]"] = page_data.hobo_parts[ids[i]];
260
+ result.data["render["+i+"][id]"] = ids[i];
261
+ result.data["render["+i+"][function]"] = o['function'] || 'hjq.ajax.update';
220
262
  }
221
263
 
264
+ return result;
265
+ },
266
+
267
+ buildRequestCallbacks: function(result, o) {
268
+ var that = this;
269
+ if (!o.attrs) o.attrs = {};
270
+ if (!o.extra_callbacks) o.extra_callbacks = {};
271
+
222
272
  this.hjq_spinner(o.attrs, "Saving...");
223
273
 
224
274
  var success_dfd = jQuery.Deferred();
@@ -232,7 +282,7 @@
232
282
  if(that.parents("body").length==0) $(document).trigger('rapid:ajax:success', [that]);
233
283
  else that.trigger('rapid:ajax:success', [that]);
234
284
  });
235
- options.success = success_dfd.resolve;
285
+ result.success = success_dfd.resolve;
236
286
 
237
287
  var error_dfd = jQuery.Deferred();
238
288
  if(o.attrs.error) error_dfd.done(methods.createFunction.call(that, o.attrs.error));
@@ -241,7 +291,7 @@
241
291
  if(that.parents("body").length==0) $(document).trigger('rapid:ajax:error', [that]);
242
292
  else that.trigger('rapid:ajax:error', [that]);
243
293
  });
244
- options.error = error_dfd.resolve;
294
+ result.error = error_dfd.resolve;
245
295
 
246
296
  var complete_dfd = jQuery.Deferred();
247
297
  if(o.attrs.complete) complete_dfd.done(methods.createFunction.call(that, o.attrs.complete));
@@ -252,11 +302,29 @@
252
302
  that.hjq_spinner('remove');
253
303
  if(o.attrs.refocus_form) that.find(":input[type!=hidden]:first").focus();
254
304
  });
255
- options.complete = complete_dfd.resolve;
305
+ result.complete = complete_dfd.resolve;
256
306
 
257
- jQuery.extend(options, o.extra_options);
307
+ jQuery.extend(result, o.extra_options);
308
+
309
+ return result;
310
+ },
258
311
 
259
- return options;
312
+ /*
313
+ this: element to receive callbacks
314
+ url: new location
315
+ ajax_options: output from buildRequestData
316
+ hobo_options: input to buildRequestData, buildRequestCallbacks
317
+ */
318
+ changeLocationAjax: function (url, ajax_options, hobo_options) {
319
+ if (hobo_options.attrs.push_state && typeof History==='object') {
320
+ // if the history plugin is installed, it will fire the
321
+ // changestate event immediately, which is where we
322
+ // actually execute the ajax
323
+ window.History.pushState([this.getPath(), ajax_options, hobo_options], hobo_options.attrs.new_title || null, url);
324
+ } else {
325
+ ajax_options = this.hjq('buildRequestCallbacks', ajax_options, hobo_options);
326
+ $.ajax(url, ajax_options);
327
+ }
260
328
  },
261
329
 
262
330
  // given ajax_attrs (update, updates and/or ajax), return DOM id's.
@@ -293,7 +361,7 @@
293
361
  if ( methods[method] ) {
294
362
  return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
295
363
  } else if ( typeof method === 'object' || ! method ) {
296
- return methods.init.apply( this, arguments );
364
+ return methods.initOnce.apply( this, arguments ) && methods.init.apply( this, arguments );
297
365
  } else {
298
366
  $.error( 'Method ' + method + ' does not exist on hjq' );
299
367
  }
@@ -0,0 +1,26 @@
1
+ // from Blixt @ http://stackoverflow.com/questions/2206958/best-way-to-reference-an-element-with-jquery
2
+
3
+ jQuery.fn.getPath = function () {
4
+ if (this.length != 1) throw 'Requires one element.';
5
+
6
+ if (this.attr("id")) return "#"+this.attr("id");
7
+
8
+ var path, node = this;
9
+ while (node.length) {
10
+ var realNode = node[0], name = realNode.localName;
11
+ if (!name) break;
12
+ name = name.toLowerCase();
13
+
14
+ var parent = node.parent();
15
+
16
+ var siblings = parent.children(name);
17
+ if (siblings.length > 1) {
18
+ name += ':eq(' + siblings.index(realNode) + ')';
19
+ }
20
+
21
+ path = name + (path ? '>' + path : '');
22
+ node = parent;
23
+ }
24
+
25
+ return path;
26
+ };
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: hobo_jquery
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 1.4.0.pre6
5
+ version: 1.4.0.pre7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Bryan Larsen
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-04-24 00:00:00 Z
13
+ date: 2012-07-05 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: jquery-rails
@@ -31,7 +31,7 @@ dependencies:
31
31
  requirements:
32
32
  - - "="
33
33
  - !ruby/object:Gem::Version
34
- version: 1.4.0.pre6
34
+ version: 1.4.0.pre7
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
37
  description: JQuery support for Hobo
@@ -69,6 +69,7 @@ files:
69
69
  - vendor/assets/javascripts/hobo-jquery/hjq.js
70
70
  - vendor/assets/javascripts/hobo_jquery.js
71
71
  - vendor/assets/javascripts/jquery.form.js
72
+ - vendor/assets/javascripts/jquery.getPath.js
72
73
  - vendor/assets/stylesheets/hobo_jquery.css
73
74
  homepage: http://hobocentral.net
74
75
  licenses: []
@@ -95,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
96
  requirements: []
96
97
 
97
98
  rubyforge_project:
98
- rubygems_version: 1.8.17
99
+ rubygems_version: 1.8.21
99
100
  signing_key:
100
101
  specification_version: 3
101
102
  summary: JQuery support for Hobo