edifice 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module Edifice
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -0,0 +1,103 @@
1
+ // add methods to a form element so it can be easily manipulated
2
+ //
3
+ // add client side validation
4
+ // understands:
5
+ // - rails form structures
6
+ // - rails form errors in JSON
7
+ // - etc
8
+ (function($) {
9
+ $.fn.edifice_form = function() {
10
+ $.extend(this, methods);
11
+ return this;
12
+ };
13
+
14
+ // VALIDATORS:
15
+ // validators expect a form element and return true or an error message
16
+ $.fn.edifice_form.validators = {
17
+ not_empty: function($input) {
18
+ return $input.val() ? true : 'must not be empty';
19
+ }
20
+ };
21
+
22
+
23
+ // in these 'this' is the $form
24
+ var methods = {
25
+ fields: function() {
26
+ return this.find('input, textarea, select');
27
+ },
28
+
29
+ error_fields: function() {
30
+ var $form = this;
31
+ return this.fields().filter(function() {
32
+ return $form.has_error($(this));
33
+ });
34
+ },
35
+
36
+ submits: function() {
37
+ return this.find('input[type=submit], button[type=submit]');
38
+ },
39
+
40
+ valid: function() {
41
+ var $form = this, valid = true;
42
+
43
+ this.fields().each(function() {
44
+ if (!$form.validate($(this))) { valid = false; }
45
+ });
46
+
47
+ return valid;
48
+ },
49
+
50
+ // 'prepare' a validator --> validator returns true or an error string
51
+ set_validator: function($field, validator) {
52
+ if (typeof validator === 'string') {
53
+ validator = $.fn.edifice_form.validators[validator] || validator;
54
+ if (typeof validator !== 'function') { throw "Validator not defined: '" + validator + "'"; }
55
+ };
56
+ $field.data('validator', validator);
57
+ },
58
+
59
+ // validate a single field
60
+ validate: function($field) {
61
+ var validator;
62
+ if (validator = $field.data('validator')) {
63
+ var error = validator($field), valid = error === true;
64
+ this.clear_error($field);
65
+ if (!valid) {
66
+ this.add_error($field, error);
67
+ }
68
+
69
+ return valid;
70
+ } else {
71
+ return true;
72
+ }
73
+ },
74
+
75
+ has_error: function($field) {
76
+ return $field.parent('.field_with_errors').length > 0;
77
+ },
78
+
79
+ clear_error: function($field) {
80
+ var id = $field.attr('id');
81
+ if (this.has_error($field)) { $field.unwrap() }
82
+
83
+ this.find('.field_with_errors label[for=' + id + ']')
84
+ .unwrap()
85
+ .next('.formError').remove();
86
+ },
87
+
88
+ add_error: function($field, error) {
89
+ var id = $field.attr('id');
90
+ $field.wrap('<div class="field_with_errors">');
91
+ this.find('label[for=' + id + ']')
92
+ .wrap('<div class="field_with_errors">')
93
+ .after('<div class="formError">' + error + '</div>');
94
+ },
95
+
96
+ set_errors: function(errors) {
97
+ for (var name in errors) {
98
+ this.add_error(this.fields().filter('[name*=' + name + ']'), errors[name][0]);
99
+ }
100
+ }
101
+ };
102
+
103
+ }(jQuery));
@@ -1,105 +1,138 @@
1
1
  (function($) {
2
- $.edifice = $.edifice || {};
3
-
4
- // add methods to a form element so it can be easily manipulated
5
- //
6
- // add client side validation
7
- // understands:
8
- // - rails form structures
9
- // - rails form errors in JSON
10
- // - etc
11
- $.fn.edifice_form = function() {
12
- $.extend(this, methods);
13
- return this;
14
- };
15
-
16
- // VALIDATORS:
17
- // validators expect a form element and return true or an error message
18
- $.fn.edifice_form.validators = {
19
- not_empty: function($input) {
20
- return $input.val() ? true : 'must not be empty';
21
- }
2
+ var defaults = {
3
+ status_element: this, // element to set to .submitting/.success/.error as we submit
4
+ // a hash of input selector -> validation functions/names
5
+ validators: {},
6
+ // stop the form from submitting and use ajax
7
+ ajax: true,
8
+ // type of data to pass around (and thus what's seen by e.g. success)
9
+ dataType: 'html'
22
10
  };
23
11
 
12
+ // EVENTS that fire during the course of the life of the submission:
13
+ // submit, invalid, success | error (+ user_error | server_error), complete
14
+ //
15
+ // -> success,errors + complete are all passed the data you would expect from
16
+ // jQuery.ajax
17
+ //
18
+ // obviously on submit + invalid fire for non-ajax forms
24
19
 
25
- // in these 'this' is the $form
26
- var methods = {
27
- fields: function() {
28
- return this.find('input, textarea, select');
29
- },
20
+ $.edifice_widgets.form = function() { return this.each(form); }
30
21
 
31
- error_fields: function() {
32
- var $form = this;
33
- return this.fields().filter(function() {
34
- return $form.has_error($(this));
35
- });
36
- },
22
+ function form() {
23
+ var $form = $(this).edifice_form();
24
+ $form.settings = $form.read_options(defaults);
25
+ $.extend($form, methods);
37
26
 
38
- submits: function() {
39
- return this.find('input[type=submit], button[type=submit]');
27
+ $form.initialize();
28
+ }
29
+ var methods = {
30
+ initialize: function() {
31
+ this.prepare_validators();
32
+ this.prepare_submit();
40
33
  },
41
34
 
42
- valid: function() {
43
- var $form = this, valid = true;
35
+ prepare_validators: function() {
36
+ var $form = this;
44
37
 
45
- this.fields().each(function() {
46
- if (!$form.validate($(this))) { valid = false; }
38
+ // setup validators from settings
39
+ for (var selector in $form.settings.validators) {
40
+ $form.set_validator($(selector), $form.settings.validators[selector]);
41
+ }
42
+
43
+ // setup validators from html
44
+ $form.fields().filter('[data-widget-validator]').each(function() {
45
+ $form.set_validator($(this), $(this).attr('data-widget-validator'));
47
46
  });
48
47
 
49
- return valid;
50
- },
51
-
52
- // 'prepare' a validator --> validator returns true or an error string
53
- set_validator: function($field, validator) {
54
- if (typeof validator === 'string') {
55
- validator = $.fn.edifice_form.validators[validator] || validator;
56
- if (typeof validator !== 'function') { throw "Validator not defined: '" + validator + "'"; }
57
- };
58
- $field.data('validator', validator);
48
+ // listen to validator
49
+ this.fields().live('change.ajax_form focusout.ajax_form', function() {
50
+ $form.validate($(this));
51
+ });
59
52
  },
60
53
 
61
- // validate a single field
62
- validate: function($field) {
63
- var validator;
64
- if (validator = $field.data('validator')) {
65
- var error = validator($field), valid = error === true;
66
- this.clear_error($field);
67
- if (!valid) {
68
- this.add_error($field, error);
54
+ prepare_submit: function() {
55
+ var $form = this;
56
+ this.submit(function(event) {
57
+ // do pre-submit validations
58
+ if (!$form.valid()) {
59
+ $form.trigger('invalid');
60
+ $form.focus_error();
61
+ return false; // we are done.
69
62
  }
63
+
64
+ $form.submits().attr('disabled', true); // disable submit buttons
65
+
66
+ // TODO - set status class
67
+ if ($form.settings.ajax && $form.settings.ajax !== 'false') {
68
+ // send up the form and process the results
69
+ $.ajax({
70
+ url: $form.attr('action'), type: $form.attr('method'),
71
+ dataType: $form.settings.dataType,
72
+ data: $.param($form.serializeArray()),
73
+ cache: false,
74
+ error: function (x, t, e) { $form.error(x, t, e); },
75
+ success: function (data, status) {
76
+ $form.trigger('success', data, status);
77
+ },
78
+ complete: function (request, text_status) {
79
+ $form.trigger('complete', request, text_status);
70
80
 
71
- return valid;
72
- } else {
73
- return true;
74
- }
75
- },
76
-
77
- has_error: function($field) {
78
- return $field.parent('.field_with_errors').length > 0;
81
+ $form.submits().removeAttr('disabled');
82
+ }
83
+ });
84
+ event.preventDefault();
85
+ return false;
86
+ }
87
+
88
+ });
79
89
  },
80
90
 
81
- clear_error: function($field) {
82
- var id = $field.attr('id');
83
- if (this.has_error($field)) { $field.unwrap() }
84
-
85
- this.find('.field_with_errors label[for=' + id + ']')
86
- .unwrap()
87
- .next('.formError').remove();
91
+ // focus the first error
92
+ focus_error: function() {
93
+ this.error_fields().eq(0).focus();
88
94
  },
89
95
 
90
- add_error: function($field, error) {
91
- var id = $field.attr('id');
92
- $field.wrap('<div class="field_with_errors">');
93
- this.find('label[for=' + id + ']')
94
- .wrap('<div class="field_with_errors">')
95
- .after('<div class="formError">' + error + '</div>');
96
+ error: function(request, text_status, error) {
97
+ this.trigger('error', request, status, error);
98
+
99
+ // handle the different possible errors that we can see
100
+ if (request.status >= 400 && request.status < 500) {
101
+ // CLIENT ERROR -- server-side validation failed.
102
+ this.trigger('client_error', request, status, error);
103
+
104
+ // if data is html, we replace this content of the form with the content
105
+ // of the form that we've just received back
106
+ if (this.settings.dataType === 'html') {
107
+ // wrap in a div incase there are a bunch of floating elements, pull the form out
108
+ var $new_form = $('<div>').append(request.responseText).find('#' + this.attr('id'));
109
+
110
+ this.html($new_form.html());
111
+ this.prepare_validators();
112
+
113
+ } else if (this.settings.dataType === 'json') {
114
+ // we will be receiving an error object back, we can pass it straight into form.js
115
+ this.set_errors($.parseJSON(request.responseText));
116
+ } else {
117
+ throw "Don't know how to handle dataType " + this.settings.dataType;
118
+ }
119
+
120
+ this.focus_error();
121
+ } else if (x.status >= 500 && x.status < 600) {
122
+ // a SERVER ERROR -- something unrecoverable happened on the server
123
+ this.trigger('server_error', request, status, error);
124
+
125
+ // we aren't going to do anything here.
126
+ // FIXME: we should probably have a way to set this behaviour at the application level.
127
+ // for instance, you probably just want to redirect to somewhere, or show a dialog,
128
+ // or popup something or.....?
129
+ } else {
130
+ // some other kind of error. Revisit
131
+ alert('Form failed. Please try again.');
132
+ }
133
+
134
+
96
135
  },
136
+ }
97
137
 
98
- set_errors: function(errors) {
99
- for (var name in errors) {
100
- this.add_error(this.fields().filter('[name*=' + name + ']'), errors[name][0]);
101
- }
102
- }
103
- };
104
-
105
138
  }(jQuery));
@@ -1,5 +1,5 @@
1
1
  <h1>Edit your Post</h1>
2
- <%= form_for @post, :html => {:'data-widget' => 'ajax_form', :'data-widget-dataType' => 'json',
2
+ <%= form_for @post, :html => {:'data-widget' => 'form', :'data-widget-ajax' => false,
3
3
  :'data-widget-validators' => ActiveSupport::JSON.encode({'#post_title' => 'not_empty'})} do |f| %>
4
4
  <%= f.label :email %>
5
5
  <%= f.error_message_on :email %>
@@ -38,7 +38,7 @@ module Rails3
38
38
 
39
39
  # JavaScript files you want as :defaults (application.js is always included).
40
40
  config.action_view.javascript_expansions[:defaults] = %w(
41
- jquery-1.5.1 edifice/framework edifice/form edifice/ajax_form
41
+ jquery-1.5.1 edifice/framework edifice/edifice_form edifice/form
42
42
  )
43
43
 
44
44
  # Configure the default encoding used in templates for Ruby 1.9.
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: edifice
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 5
8
+ - 6
9
9
  - 0
10
- version: 0.5.0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tom Coleman
@@ -48,7 +48,7 @@ files:
48
48
  - lib/edifice/railtie.rb
49
49
  - lib/edifice/responder.rb
50
50
  - lib/edifice/version.rb
51
- - lib/public/javascripts/edifice/ajax_form.js
51
+ - lib/public/javascripts/edifice/edifice_form.js
52
52
  - lib/public/javascripts/edifice/form.js
53
53
  - lib/public/javascripts/edifice/framework.js
54
54
  - lib/tasks/edifice.rake
@@ -1,127 +0,0 @@
1
- (function($) {
2
- var defaults = {
3
- status_element: this, // element to set to .submitting/.success/.error as we submit
4
- // a hash of input selector -> validation functions/names
5
- validators: {},
6
- // type of data to pass around (and thus what's seen by e.g. success)
7
- dataType: 'html'
8
- };
9
-
10
- // EVENTS that fire during the course of the life of the submission:
11
- // submit, invalid, success | error (+ user_error | server_error), complete
12
- //
13
- // -> success,errors + complete are all passed the data you would expect from
14
- // jQuery.ajax
15
-
16
- $.edifice_widgets.ajax_form = function() { return this.each(ajax_form); }
17
-
18
- function ajax_form() {
19
- var $form = $(this).edifice_form();
20
- $form.settings = $form.read_options(defaults);
21
- $.extend($form, methods);
22
-
23
- $form.initialize();
24
- }
25
- var methods = {
26
- initialize: function() {
27
- this.prepare_validators();
28
- this.prepare_submit();
29
- },
30
-
31
- prepare_validators: function() {
32
- var $form = this;
33
-
34
- // setup validators from settings
35
- for (var selector in $form.settings.validators) {
36
- $form.set_validator($(selector), $form.settings.validators[selector]);
37
- }
38
-
39
- // setup validators from html
40
- $form.fields().filter('[data-widget-validator]').each(function() {
41
- $form.set_validator($(this), $(this).attr('data-widget-validator'));
42
- });
43
-
44
- // listen to validator
45
- this.fields().live('change.ajax_form focusout.ajax_form', function() {
46
- $form.validate($(this));
47
- });
48
- },
49
-
50
- prepare_submit: function() {
51
- var $form = this;
52
- this.submit(function(event) {
53
- event.preventDefault();
54
-
55
- // do pre-submit validations
56
- if (!$form.valid()) {
57
- $form.trigger('invalid');
58
- $form.error_fields().eq(0).focus(); // focus the first error
59
- return false; // we are done.
60
- }
61
-
62
- $form.submits().attr('disabled', true); // disable submit buttons
63
-
64
- // TODO - set status class
65
-
66
- // send up the form and process the results
67
- $.ajax({
68
- url: $form.attr('action'), type: $form.attr('method'),
69
- dataType: $form.settings.dataType,
70
- data: $.param($form.serializeArray()),
71
- cache: false,
72
- error: function (x, t, e) { $form.error(x, t, e); },
73
- success: function (data, status) {
74
- $form.trigger('success', data, status);
75
- },
76
- complete: function (request, text_status) {
77
- $form.trigger('complete', request, text_status);
78
-
79
- $form.submits().removeAttr('disabled');
80
- }
81
- });
82
-
83
- return false;
84
- });
85
- },
86
-
87
- error: function(request, text_status, error) {
88
- this.trigger('error', request, status, error);
89
-
90
- // handle the different possible errors that we can see
91
- if (request.status >= 400 && request.status < 500) {
92
- // CLIENT ERROR -- server-side validation failed.
93
- this.trigger('client_error', request, status, error);
94
-
95
- // if data is html, we replace this content of the form with the content
96
- // of the form that we've just received back
97
- if (this.settings.dataType === 'html') {
98
- // wrap in a div incase there are a bunch of floating elements, pull the form out
99
- var $new_form = $('<div>').append(request.responseText).find('#' + this.attr('id'));
100
-
101
- this.html($new_form.html());
102
- this.prepare_validators();
103
-
104
- } else if (this.settings.dataType === 'json') {
105
- // we will be receiving an error object back, we can pass it straight into form.js
106
- this.set_errors($.parseJSON(request.responseText));
107
- } else {
108
- throw "Don't know how to handle dataType " + this.settings.dataType;
109
- }
110
- } else if (x.status >= 500 && x.status < 600) {
111
- // a SERVER ERROR -- something unrecoverable happened on the server
112
- this.trigger('server_error', request, status, error);
113
-
114
- // we aren't going to do anything here.
115
- // FIXME: we should probably have a way to set this behaviour at the application level.
116
- // for instance, you probably just want to redirect to somewhere, or show a dialog,
117
- // or popup something or.....?
118
- } else {
119
- // some other kind of error. Revisit
120
- alert('Form failed. Please try again.');
121
- }
122
-
123
-
124
- },
125
- }
126
-
127
- }(jQuery));