edifice-forms 0.3.0
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/README.md +4 -0
- data/Rakefile +3 -0
- data/app/assets/javascripts/edifice-forms.js +1 -0
- data/app/assets/javascripts/edifice-forms/rails_form.js +120 -0
- data/app/assets/javascripts/edifice-forms/show-errors.js +23 -0
- data/edifice-forms.gemspec +18 -0
- data/lib/edifice-forms.rb +12 -0
- data/lib/edifice-forms/controller.rb +11 -0
- data/lib/edifice-forms/form_model.rb +46 -0
- data/lib/edifice-forms/helper.rb +22 -0
- data/lib/edifice-forms/responder.rb +23 -0
- data/lib/edifice-forms/version.rb +3 -0
- metadata +90 -0
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= require_tree ./edifice-forms
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/**
|
2
|
+
* A small jQuery plugin to add 'rails-aware' form functionality.
|
3
|
+
*
|
4
|
+
* Basically, this understands the 'standard' rails way of structuring forms
|
5
|
+
* and makes some functions available to manipulate that.
|
6
|
+
*/
|
7
|
+
(function($) {
|
8
|
+
$.fn.rails_form = function(method) {
|
9
|
+
if (methods[method]) {
|
10
|
+
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
11
|
+
} else {
|
12
|
+
$.error('Method ' + method + ' does not exist on rails_form');
|
13
|
+
}
|
14
|
+
};
|
15
|
+
|
16
|
+
// in these 'this' is the $form
|
17
|
+
var methods = {
|
18
|
+
fields: function() {
|
19
|
+
return this.find('input, textarea, select');
|
20
|
+
},
|
21
|
+
|
22
|
+
error_fields: function() {
|
23
|
+
var $form = this;
|
24
|
+
return this.rails_form('fields').filter(function() {
|
25
|
+
return $form.rails_form('has_error', $(this));
|
26
|
+
});
|
27
|
+
},
|
28
|
+
|
29
|
+
submits: function() {
|
30
|
+
return this.find('input[type=submit], button[type=submit]');
|
31
|
+
},
|
32
|
+
|
33
|
+
label_for: function($field) {
|
34
|
+
return this.find('label[for=' + $field.attr('id') + ']');
|
35
|
+
},
|
36
|
+
|
37
|
+
error_on: function($field) {
|
38
|
+
return this.rails_form('label_for', $field).parents('.field_with_errors').next('.formError');
|
39
|
+
},
|
40
|
+
|
41
|
+
has_error: function($field) {
|
42
|
+
return $field.parent('.field_with_errors').length > 0;
|
43
|
+
},
|
44
|
+
|
45
|
+
clear_errors: function() {
|
46
|
+
var $form = this;
|
47
|
+
this.rails_form('fields').each(function() {
|
48
|
+
$form.rails_form('clear_error', $(this));
|
49
|
+
});
|
50
|
+
|
51
|
+
// clear base errors too
|
52
|
+
this.find('.errors').html('');
|
53
|
+
},
|
54
|
+
|
55
|
+
clear_error: function($field) {
|
56
|
+
var id = $field.attr('id');
|
57
|
+
if (this.rails_form('has_error', $field)) { $field.unwrap() }
|
58
|
+
|
59
|
+
this.find('.field_with_errors label[for=' + id + ']')
|
60
|
+
.unwrap()
|
61
|
+
.next('.formError').remove();
|
62
|
+
|
63
|
+
// remove from a .errors ul
|
64
|
+
this.find('.errors [data-for=' + id + ']').remove();
|
65
|
+
|
66
|
+
return this;
|
67
|
+
},
|
68
|
+
|
69
|
+
// display standard errors as returned by JSON
|
70
|
+
set_errors: function(errors) {
|
71
|
+
this.rails_form('clear_errors');
|
72
|
+
for (var name in errors) {
|
73
|
+
for (var i in errors[name]) {
|
74
|
+
this.rails_form('add_error', name, errors[name][i]);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
return this;
|
78
|
+
},
|
79
|
+
|
80
|
+
add_error: function(name, error) {
|
81
|
+
var $field = this.rails_form('fields').filter('[name*=' + name + ']');
|
82
|
+
$field.filter('.field_with_errors > *').unwrap();
|
83
|
+
$field.wrap('<div class="field_with_errors">');
|
84
|
+
|
85
|
+
// if there is a field, and it has a label, show the error after it
|
86
|
+
if ($field.length) {
|
87
|
+
var id = $field.attr('id');
|
88
|
+
var $label = this.rails_form('label_for', $field);
|
89
|
+
var $error = $label.parent().next('.formError');
|
90
|
+
|
91
|
+
if ($error.length) {
|
92
|
+
$error.text(function(i, text) {
|
93
|
+
return text + ', ' + error;
|
94
|
+
});
|
95
|
+
} else {
|
96
|
+
$label.after('<div class="formError">' + error + '</div>')
|
97
|
+
.wrap('<div class="field_with_errors">');
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
// if there is an .errors list, show the error there
|
102
|
+
var $errors = this.find('ul.errors');
|
103
|
+
if ($errors.length) {
|
104
|
+
var message = name.charAt(0).toUpperCase() + name.substring(1).replace('_', ' ') +
|
105
|
+
' ' + error;
|
106
|
+
|
107
|
+
var $li = $('<li>' + message + '</li>');
|
108
|
+
|
109
|
+
if ($field.length) {
|
110
|
+
$li.attr('data-for', $field.attr('id'));
|
111
|
+
}
|
112
|
+
|
113
|
+
$errors.append($li);
|
114
|
+
}
|
115
|
+
|
116
|
+
return this;
|
117
|
+
}
|
118
|
+
};
|
119
|
+
|
120
|
+
}(jQuery));
|
@@ -0,0 +1,23 @@
|
|
1
|
+
(function($) {
|
2
|
+
var showErrorSelector = 'form[data-show-errors]';
|
3
|
+
|
4
|
+
$(showErrorSelector).live('ajax:error', function(event, request, status, error) {
|
5
|
+
// CLIENT ERROR -- server-side validation failed. -- FIXME -should this be 422 only?
|
6
|
+
if (request.status >= 400 && request.status < 500) {
|
7
|
+
// if data is html, we replace this content of the form with the content
|
8
|
+
// of the form that we've just received back
|
9
|
+
var contentType = request.getResponseHeader('Content-Type');
|
10
|
+
if (/html/.test(contentType)) {
|
11
|
+
// wrap in a div incase there are a bunch of floating elements, pull the form out
|
12
|
+
var $new_form = $('<div>' + request.responseText + '</div>').find('#' + $(this).attr('id'));
|
13
|
+
$(this).html($new_form.html());
|
14
|
+
|
15
|
+
} else if (/json/.test(contentType)) {
|
16
|
+
// we will be receiving an error object back, we can pass it straight into rails_form.js
|
17
|
+
$(this).rails_form('set_errors', $.parseJSON(request.responseText));
|
18
|
+
} else {
|
19
|
+
throw "edifice-forms/show-errors: Don't know how to handle dataType " + request.dataType;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
});
|
23
|
+
}(jQuery));
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "edifice-forms/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'edifice-forms'
|
6
|
+
s.version = EdificeForms::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.author = 'Tom Coleman'
|
9
|
+
s.email = 'tom@percolatestudio.com'
|
10
|
+
s.summary = 'Unobtrusive JS Form extensions'
|
11
|
+
|
12
|
+
s.add_dependency 'jquery-rails'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'edifice-forms/helper'
|
2
|
+
require 'edifice-forms/controller'
|
3
|
+
require 'edifice-forms/form_model'
|
4
|
+
require 'edifice-forms/responder'
|
5
|
+
|
6
|
+
module EdificeForms
|
7
|
+
class Engine < Rails::Engine
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
ActionView::Base.send :include, EdificeForms::Helper
|
12
|
+
ActionController::Base.send :include, EdificeForms::Controller
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# kind of the evolution of the FormStruct
|
2
|
+
|
3
|
+
module EdificeForms
|
4
|
+
class FormModel
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include ActiveModel::Conversion
|
7
|
+
extend ActiveModel::Naming
|
8
|
+
extend ActiveModel::Callbacks
|
9
|
+
define_model_callbacks :save
|
10
|
+
|
11
|
+
# more or less the same as activerecord's one
|
12
|
+
class RecordInvalid < Exception
|
13
|
+
attr_reader :record
|
14
|
+
def initialize(record)
|
15
|
+
@record = record
|
16
|
+
errors = @record.errors.full_messages.join(", ")
|
17
|
+
super(errors)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(attributes = {})
|
22
|
+
attributes.each { |n, v| send("#{n}=", v) if respond_to?("#{n}=") }
|
23
|
+
end
|
24
|
+
|
25
|
+
# default implementation, override as necessary
|
26
|
+
def save
|
27
|
+
run_callbacks :save do
|
28
|
+
valid?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def save!
|
33
|
+
save || raise(RecordInvalid.new(self))
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.create(attributes = {})
|
37
|
+
form = new(attributes)
|
38
|
+
form.save
|
39
|
+
form
|
40
|
+
end
|
41
|
+
|
42
|
+
def persisted?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module EdificeForms
|
2
|
+
module Helper
|
3
|
+
# not sure why there isn't something like this in rails
|
4
|
+
#
|
5
|
+
# render the errors on an object in a fairly standard way:
|
6
|
+
#
|
7
|
+
# <ul class="errors">
|
8
|
+
# <li data-for="name">Name cannot be blank</li>
|
9
|
+
# </ul>
|
10
|
+
def render_errors(builder)
|
11
|
+
errors = builder.object.errors
|
12
|
+
messages = errors.full_messages
|
13
|
+
content_tag :ul, :class => :errors do
|
14
|
+
output = ''
|
15
|
+
errors.each_with_index do |error, i|
|
16
|
+
output << content_tag(:li, :'data-for' => "#{builder.object_name}_#{error[0]}") { messages[i] }
|
17
|
+
end
|
18
|
+
output.html_safe
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Basically a standard responder, but if
|
2
|
+
module EdificeForms
|
3
|
+
class Responder < ActionController::Responder
|
4
|
+
protected
|
5
|
+
# add the :u_e header to xhr error requests
|
6
|
+
def to_html
|
7
|
+
if controller.request.xhr? && !get? and has_errors? && default_action
|
8
|
+
render :action => default_action, :status => :unprocessable_entity, :layout => nil
|
9
|
+
else
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# actually render something on successful updates
|
15
|
+
def to_format
|
16
|
+
unless get? or has_errors? or post?
|
17
|
+
display resource, :status => :ok
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: edifice-forms
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Tom Coleman
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-17 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: jquery-rails
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description:
|
35
|
+
email: tom@percolatestudio.com
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- README.md
|
44
|
+
- Rakefile
|
45
|
+
- app/assets/javascripts/edifice-forms.js
|
46
|
+
- app/assets/javascripts/edifice-forms/rails_form.js
|
47
|
+
- app/assets/javascripts/edifice-forms/show-errors.js
|
48
|
+
- edifice-forms.gemspec
|
49
|
+
- lib/edifice-forms.rb
|
50
|
+
- lib/edifice-forms/controller.rb
|
51
|
+
- lib/edifice-forms/form_model.rb
|
52
|
+
- lib/edifice-forms/helper.rb
|
53
|
+
- lib/edifice-forms/responder.rb
|
54
|
+
- lib/edifice-forms/version.rb
|
55
|
+
homepage:
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.10
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Unobtrusive JS Form extensions
|
88
|
+
test_files: []
|
89
|
+
|
90
|
+
has_rdoc:
|