hobo_jquery 1.4.0.pre6 → 1.4.0.pre7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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