lolita 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/.rspec +2 -0
  2. data/GUIDELINE +20 -20
  3. data/VERSION +1 -1
  4. data/app/views/components/lolita/field/_boolean.html.erb +1 -0
  5. data/app/views/components/lolita/field/_select.html.erb +1 -1
  6. data/app/views/components/lolita/field/_text.html.erb +1 -1
  7. data/app/views/components/lolita/navigation/_display.html.erb +1 -1
  8. data/app/views/components/lolita/shared/_flash.html.erb +1 -1
  9. data/app/views/lolita/layouts/application.html.erb +3 -2
  10. data/lib/generators/lolita/{copy_assets_generator.rb → assets_generator.rb} +1 -1
  11. data/lib/generators/lolita/install_generator.rb +6 -3
  12. data/lib/lolita.rb +136 -135
  13. data/lib/lolita/adapter/active_record.rb +110 -110
  14. data/lib/lolita/adapter/mongoid.rb +104 -104
  15. data/lib/lolita/base_configuration.rb +49 -21
  16. data/lib/lolita/configuration/base.rb +76 -76
  17. data/lib/lolita/configuration/factory.rb +46 -0
  18. data/lib/lolita/configuration/field.rb +31 -45
  19. data/lib/lolita/configuration/field/boolean.rb +10 -0
  20. data/lib/lolita/configuration/{field_extensions → field}/collection.rb +25 -17
  21. data/lib/lolita/configuration/field/datetime.rb +10 -0
  22. data/lib/lolita/configuration/field/disabled.rb +10 -0
  23. data/lib/lolita/configuration/field/integer.rb +10 -0
  24. data/lib/lolita/configuration/field/password.rb +10 -0
  25. data/lib/lolita/configuration/field/string.rb +11 -0
  26. data/lib/lolita/configuration/field/text.rb +10 -0
  27. data/lib/lolita/configuration/tab.rb +5 -25
  28. data/lib/lolita/configuration/tab/default.rb +24 -0
  29. data/lib/lolita/configuration/tabs.rb +7 -3
  30. data/lib/lolita/controllers/component_helpers.rb +16 -1
  31. data/lib/lolita/errors.rb +2 -0
  32. data/lib/lolita/mapping.rb +17 -4
  33. data/lib/lolita/modules/rest.rb +1 -1
  34. data/lib/lolita/rails/routes.rb +21 -12
  35. data/lolita.gemspec +15 -5
  36. data/public/javascripts/lolita/main.js +7 -6
  37. data/public/javascripts/lolita/tab.js +36 -36
  38. data/spec/configuration/field_spec.rb +3 -3
  39. data/spec/configuration/tab_spec.rb +2 -2
  40. data/spec/configuration/tabs_spec.rb +7 -0
  41. data/spec/rails_app/public/javascripts/lolita/tab.js +36 -36
  42. data/spec/rails_app/public/javascripts/rails.js +137 -137
  43. metadata +16 -6
  44. data/lib/lolita/version.rb +0 -3
data/lib/lolita/errors.rb CHANGED
@@ -8,4 +8,6 @@ module Lolita
8
8
  class ModuleNotFound < ArgumentError; end
9
9
  class NotFound < ArgumentError; end
10
10
  class TabNotFoundError < NameError; end
11
+ class FieldNotFoundError < NameError; end
12
+ class AssociationError < ArgumentError; end
11
13
  end
@@ -1,4 +1,18 @@
1
1
  module Lolita
2
+ # Create mapping for routes.
3
+ # Each mapping has name, like :posts, :files etc.
4
+ # Also it accepts options:
5
+ # * <tt>:singular</tt> - singular form for route, by default it call #singularize on _name_.
6
+ # * <tt>:class_name</tt> - class that is related with route, by default it uses :singular, and classify it. It should be like "Post".
7
+ # * <tt>:path_prefix</tt> - path starts with path prefix, like /path_prefix/lolita/posts.
8
+ # * <tt>:path</tt> - path and path url methods starts with this path.
9
+ # =====Example
10
+ # lolita_for :posts, :path=>"admin"
11
+ # # add paths like this to routes
12
+ # # admin_posts GET /admin/posts {:controller=>"lolita/rest", :action=>:index}
13
+ # # edit_admin_posts GET /admin/post/1/edit {:controller=>"lolita/rest",:action=>:edit}
14
+ # * <tt>:module</tt> - change module for path, it changes :controller that is used for lolita, like,
15
+ # :module=>"admin", change controller to "admin/posts". If this is used without :path then no named routes will be generated
2
16
  class Mapping
3
17
  attr_reader :class_name,:path,:singular,:plural,:path_prefix,:module,:controllers,:as
4
18
  alias :name :singular
@@ -17,14 +31,13 @@ module Lolita
17
31
  h[k]="#{mod}#{k}"
18
32
  }
19
33
  end
20
- #
21
- # lolita/posts/new => lolita/crud/new :class=>Post
22
- # posts/new => posts/new
23
- #
34
+
35
+ # Return class that is related with mapping.
24
36
  def to
25
37
  @ref.get
26
38
  end
27
39
 
40
+ # full path of current mapping
28
41
  def fullpath
29
42
  "#{@path_prefix}/#{@path}".squeeze("/")
30
43
  end
@@ -1,7 +1,7 @@
1
1
  module ActionDispatch::Routing
2
2
  class Mapper
3
3
  protected
4
- def lolita_rest mapping, controllers
4
+ def lolita_rest_route mapping, controllers
5
5
  resources mapping.plural,:only=>[:index,:new,:create,:edit,:update,:destroy],
6
6
  :controller=>controllers[:rest],:module=>mapping.module
7
7
  end
@@ -15,24 +15,28 @@ module ActionDispatch::Routing
15
15
  #TODO refactor
16
16
  options = resources.extract_options!
17
17
 
18
- if as = options.delete(:as)
19
- ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
20
- options[:path] ||= as
21
- end
18
+ # if as = options.delete(:as)
19
+ # ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
20
+ # options[:path] ||= as
21
+ # end
22
22
 
23
- if scope = options.delete(:scope)
24
- ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
25
- options[:singular] ||= scope
26
- end
23
+ # if scope = options.delete(:scope)
24
+ # ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
25
+ # options[:singular] ||= scope
26
+ # end
27
27
 
28
28
  options[:as] ||= @scope[:as] if @scope[:as].present?
29
29
  options[:module] ||= @scope[:module] if @scope[:module].present?
30
30
  options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
31
31
  resources.map!(&:to_sym)
32
+ all_resource_classes=[]
32
33
  resources.each{|resource|
33
34
  mapping=Lolita.add_mapping(resource,options)
34
- target_class=mapping.to
35
+ Lolita.resources[mapping.name]=mapping
35
36
 
37
+ target_class=mapping.to
38
+ all_resource_classes<<target_class
39
+
36
40
  lolita_scope mapping.name do
37
41
  yield if block_given?
38
42
 
@@ -46,15 +50,20 @@ module ActionDispatch::Routing
46
50
  route=Lolita.routes[mapping.name] || Lolita.default_route
47
51
  end
48
52
  unless route
49
- raise Lolita::ModuleNotFound, "Module #{mapping.name.to_s.capitalize} not found! Add Lolita.use(:#{mapping.name}) to initializers/lolita.rb"
53
+ raise Lolita::ModuleNotFound, "Module #{mapping.name.to_s.capitalize} not found!"
50
54
  end
51
- send(:"lolita_#{route}",mapping,mapping.controllers)
55
+ send(:"lolita_#{route}_route",mapping,mapping.controllers)
56
+
52
57
  Lolita.conditional_routes(target_class).each do |route_name|
53
- send(:"lolita_#{route_name}",mapping,mapping.controllers)
58
+ send(:"lolita_#{route_name}_route",mapping,mapping.controllers)
54
59
  end
55
60
  end
61
+
56
62
  end
57
63
  }
64
+ Lolita.common_routes(all_resource_classes).each do |route_name|
65
+ send(:"lolita_#{route_name}_route")
66
+ end
58
67
  end
59
68
 
60
69
  protected
data/lolita.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{lolita}
8
- s.version = "3.0.5"
8
+ s.version = "3.0.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["ITHouse", "Arturs Meisters"]
12
- s.date = %q{2011-03-23}
12
+ s.date = %q{2011-03-29}
13
13
  s.description = %q{Great Rails CMS that allow you to start working with models right when you add this to your project.}
14
14
  s.email = %q{support@ithouse.lv}
15
15
  s.extra_rdoc_files = [
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.files = [
20
20
  ".document",
21
21
  ".project",
22
+ ".rspec",
22
23
  "GUIDELINE",
23
24
  "Gemfile",
24
25
  "IDEA",
@@ -29,6 +30,7 @@ Gem::Specification.new do |s|
29
30
  "app/controllers/lolita/rest_controller.rb",
30
31
  "app/helpers/components/lolita/list_component.rb",
31
32
  "app/helpers/lolita_helper.rb",
33
+ "app/views/components/lolita/field/_boolean.html.erb",
32
34
  "app/views/components/lolita/field/_collection.html.erb",
33
35
  "app/views/components/lolita/field/_date.html.erb",
34
36
  "app/views/components/lolita/field/_datetime.html.erb",
@@ -76,7 +78,7 @@ Gem::Specification.new do |s|
76
78
  "features/support/env.rb",
77
79
  "features/support/paths.rb",
78
80
  "lib/generators/helpers/file_helper.rb",
79
- "lib/generators/lolita/copy_assets_generator.rb",
81
+ "lib/generators/lolita/assets_generator.rb",
80
82
  "lib/generators/lolita/install_generator.rb",
81
83
  "lib/generators/templates/lolita.rb",
82
84
  "lib/lolita.rb",
@@ -88,13 +90,22 @@ Gem::Specification.new do |s|
88
90
  "lib/lolita/configuration/base.rb",
89
91
  "lib/lolita/configuration/column.rb",
90
92
  "lib/lolita/configuration/columns.rb",
93
+ "lib/lolita/configuration/factory.rb",
91
94
  "lib/lolita/configuration/field.rb",
92
- "lib/lolita/configuration/field_extensions/collection.rb",
95
+ "lib/lolita/configuration/field/boolean.rb",
96
+ "lib/lolita/configuration/field/collection.rb",
97
+ "lib/lolita/configuration/field/datetime.rb",
98
+ "lib/lolita/configuration/field/disabled.rb",
99
+ "lib/lolita/configuration/field/integer.rb",
100
+ "lib/lolita/configuration/field/password.rb",
101
+ "lib/lolita/configuration/field/string.rb",
102
+ "lib/lolita/configuration/field/text.rb",
93
103
  "lib/lolita/configuration/field_set.rb",
94
104
  "lib/lolita/configuration/list.rb",
95
105
  "lib/lolita/configuration/page.rb",
96
106
  "lib/lolita/configuration/tab.rb",
97
107
  "lib/lolita/configuration/tab/content.rb",
108
+ "lib/lolita/configuration/tab/default.rb",
98
109
  "lib/lolita/configuration/tabs.rb",
99
110
  "lib/lolita/controllers/component_helpers.rb",
100
111
  "lib/lolita/controllers/internal_helpers.rb",
@@ -116,7 +127,6 @@ Gem::Specification.new do |s|
116
127
  "lib/lolita/rails/routes.rb",
117
128
  "lib/lolita/ruby_ext/accessors.rb",
118
129
  "lib/lolita/test/matchers.rb",
119
- "lib/lolita/version.rb",
120
130
  "log/development.log",
121
131
  "lolita.gemspec",
122
132
  "public/images/lolita/plus.png",
@@ -1,6 +1,7 @@
1
- /*
2
- * To change this template, choose Tools | Templates
3
- * and open the template in the editor.
4
- */
5
-
6
-
1
+ $(function(){
2
+ $.ajaxSetup({
3
+ headers:{
4
+ "X-CSRF-Token": $("meta[name='csrf-token']").attr("content")
5
+ }
6
+ })
7
+ })
@@ -1,41 +1,41 @@
1
- $(function(){
2
- // Send ajax request with all forms data for given tabs block.
3
- function save_tab(tabs){
4
- var data=""
5
- tabs.find("form").each(function(){
6
- data=data+$(this).serialize()
7
- })
8
- //alert(data)
9
- $.ajax({
10
- url:tabs.attr("data-tabs-url"),
11
- dataType:"html",
12
- type:tabs.attr("data-method"),
13
- data:data,
14
- success:function(data){
15
- $("#content").html(data);
16
- load_tinymce();
17
- }
18
- })
19
- }
20
- // Submit all forms through Ajax when Save All button clicked.
21
- $("button.save-all").live('click',function(){
22
- //var tab=$(this).parents("div[data-tabs-url]")
23
- var tab = $("#content").children("div[data-tabs-url]")
24
- save_tab(tab)
25
- })
26
- // All tabs are closable when clicked on tab title.
27
- $(".tab .tab-title").live('click',function(){
28
- var tab_title=$(this)
29
- var closed=tab_title.data("closed") || (tab_title.attr("data-closed")=="false" ? false : true)
30
- if(closed){
31
- tab_title.parents(".tab").find(".tab-content").show("fast")
32
- }else{
33
- tab_title.parents(".tab").find(".tab-content").hide("fast")
34
- }
35
- tab_title.data("closed",!closed)
1
+ $(function(){
2
+ // Send ajax request with all forms data for given tabs block.
3
+ function save_tab(tabs){
4
+ var data=""
5
+ tabs.find("form").each(function(){
6
+ data=data+"&"+$(this).serialize()
7
+ })
8
+ //alert(data)
9
+ $.ajax({
10
+ url:tabs.attr("data-tabs-url"),
11
+ dataType:"html",
12
+ type:tabs.attr("data-method"),
13
+ data:data,
14
+ success:function(data){
15
+ $("#content").html(data);
16
+ load_tinymce();
17
+ }
18
+ })
19
+ }
20
+ // Submit all forms through Ajax when Save All button clicked.
21
+ $("button.save-all").live('click',function(){
22
+ //var tab=$(this).parents("div[data-tabs-url]")
23
+ var tab = $("#content").children("div[data-tabs-url]")
24
+ save_tab(tab)
25
+ })
26
+ // All tabs are closable when clicked on tab title.
27
+ $(".tab .tab-title").live('click',function(){
28
+ var tab_title=$(this)
29
+ var closed=tab_title.data("closed") || (tab_title.attr("data-closed")=="false" ? false : true)
30
+ if(closed){
31
+ tab_title.parents(".tab").find(".tab-content").show("fast")
32
+ }else{
33
+ tab_title.parents(".tab").find(".tab-content").hide("fast")
34
+ }
35
+ tab_title.data("closed",!closed)
36
36
  })
37
37
  // Flash is hidden when clicked on
38
38
  $("#flash").live("click", function(){
39
39
  $(this).slideUp("fast");
40
- })
40
+ })
41
41
  })
@@ -81,7 +81,7 @@ describe Lolita::Configuration::Field do
81
81
  end
82
82
 
83
83
  it "should set field type when not specified" do
84
- field=Lolita::Configuration::Field.new(@dbi,:title)
84
+ field=Lolita::Configuration::Field.add(@dbi,:title)
85
85
  field.type.should == "string"
86
86
  end
87
87
 
@@ -91,13 +91,13 @@ describe Lolita::Configuration::Field do
91
91
  end
92
92
 
93
93
  it "should allow set field that is referenced in (belongs_to) any class" do
94
- field=Lolita::Configuration::Field.new(@dbi2,:post)
94
+ field=Lolita::Configuration::Field.add(@dbi2,:post)
95
95
  field.type.should == "collection"
96
96
  field.association_type.should == :one
97
97
  end
98
98
 
99
99
  it "should allow set field that references to (has_many or has_one) any class" do
100
- field=Lolita::Configuration::Field.new(@dbi,:comments)
100
+ field=Lolita::Configuration::Field.add(@dbi,:comments)
101
101
  field.type.should == "collection"
102
102
  field.association_type.should == :many
103
103
  end
@@ -33,7 +33,7 @@ describe Lolita::Configuration::Tab do
33
33
 
34
34
  describe "add tab" do
35
35
  it "should recognize type of tab added and create it as a related class object" do
36
- Lolita::Configuration::Tab.add(@dbi){ field(:email)}.class.to_s.should=="Lolita::Configuration::Tab"
36
+ Lolita::Configuration::Tab.add(@dbi){ field(:email)}.class.to_s.should=="Lolita::Configuration::DefaultTab"
37
37
  Lolita::Configuration::Tab.add(@dbi,:my).class.to_s.should == "Lolita::Configuration::MyTab"
38
38
  Lolita::Configuration::Tab.add(@dbi) {
39
39
  type :my
@@ -65,7 +65,7 @@ describe Lolita::Configuration::Tab do
65
65
 
66
66
  it "should raise error when no fields are given for default type tab" do
67
67
  lambda{
68
- Lolita::Configuration::Tab.new(@dbi)
68
+ Lolita::Configuration::Tab.add(@dbi)
69
69
  }.should raise_error Lolita::NoFieldsGivenError
70
70
  end
71
71
 
@@ -1,5 +1,12 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
+ module Lolita
4
+ module Configuration
5
+ class ImagesTab < Lolita::Configuration::Tab
6
+ end
7
+ end
8
+ end
9
+
3
10
  describe Lolita::Configuration::Tabs do
4
11
  before(:each) do
5
12
  @dbi=Lolita::DBI::Base.new(Post)
@@ -1,41 +1,41 @@
1
- $(function(){
2
- // Send ajax request with all forms data for given tabs block.
3
- function save_tab(tabs){
4
- var data=""
5
- tabs.find("form").each(function(){
6
- data=data+$(this).serialize()
7
- })
8
- //alert(data)
9
- $.ajax({
10
- url:tabs.attr("data-tabs-url"),
11
- dataType:"html",
12
- type:tabs.attr("data-method"),
13
- data:data,
14
- success:function(data){
15
- $("#content").html(data);
16
- load_tinymce();
17
- }
18
- })
19
- }
20
- // Submit all forms through Ajax when Save All button clicked.
21
- $("button.save-all").live('click',function(){
22
- //var tab=$(this).parents("div[data-tabs-url]")
23
- var tab = $("#content").children("div[data-tabs-url]")
24
- save_tab(tab)
25
- })
26
- // All tabs are closable when clicked on tab title.
27
- $(".tab .tab-title").live('click',function(){
28
- var tab_title=$(this)
29
- var closed=tab_title.data("closed") || (tab_title.attr("data-closed")=="false" ? false : true)
30
- if(closed){
31
- tab_title.parents(".tab").find(".tab-content").show("fast")
32
- }else{
33
- tab_title.parents(".tab").find(".tab-content").hide("fast")
34
- }
35
- tab_title.data("closed",!closed)
1
+ $(function(){
2
+ // Send ajax request with all forms data for given tabs block.
3
+ function save_tab(tabs){
4
+ var data=""
5
+ tabs.find("form").each(function(){
6
+ data=data+$(this).serialize()
7
+ })
8
+ //alert(data)
9
+ $.ajax({
10
+ url:tabs.attr("data-tabs-url"),
11
+ dataType:"html",
12
+ type:tabs.attr("data-method"),
13
+ data:data,
14
+ success:function(data){
15
+ $("#content").html(data);
16
+ load_tinymce();
17
+ }
18
+ })
19
+ }
20
+ // Submit all forms through Ajax when Save All button clicked.
21
+ $("button.save-all").live('click',function(){
22
+ //var tab=$(this).parents("div[data-tabs-url]")
23
+ var tab = $("#content").children("div[data-tabs-url]")
24
+ save_tab(tab)
25
+ })
26
+ // All tabs are closable when clicked on tab title.
27
+ $(".tab .tab-title").live('click',function(){
28
+ var tab_title=$(this)
29
+ var closed=tab_title.data("closed") || (tab_title.attr("data-closed")=="false" ? false : true)
30
+ if(closed){
31
+ tab_title.parents(".tab").find(".tab-content").show("fast")
32
+ }else{
33
+ tab_title.parents(".tab").find(".tab-content").hide("fast")
34
+ }
35
+ tab_title.data("closed",!closed)
36
36
  })
37
37
  // Flash is hidden when clicked on
38
38
  $("#flash").live("click", function(){
39
39
  $(this).slideUp("fast");
40
- })
40
+ })
41
41
  })
@@ -1,137 +1,137 @@
1
- /**
2
- * Unobtrusive scripting adapter for jQuery
3
- *
4
- * Requires jQuery 1.4.3 or later.
5
- * https://github.com/rails/jquery-ujs
6
- */
7
-
8
- (function($) {
9
- // Triggers an event on an element and returns the event result
10
- function fire(obj, name, data) {
11
- var event = new $.Event(name);
12
- obj.trigger(event, data);
13
- return event.result !== false;
14
- }
15
-
16
- // Submits "remote" forms and links with ajax
17
- function handleRemote(element) {
18
- var method, url, data,
19
- dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
20
-
21
- if (element.is('form')) {
22
- method = element.attr('method');
23
- url = element.attr('action');
24
- data = element.serializeArray();
25
- // memoized value from clicked submit button
26
- var button = element.data('ujs:submit-button');
27
- if (button) {
28
- data.push(button);
29
- element.data('ujs:submit-button', null);
30
- }
31
- } else {
32
- method = element.attr('data-method');
33
- url = element.attr('href');
34
- data = null;
35
- }
36
-
37
- $.ajax({
38
- url: url, type: method || 'GET', data: data, dataType: dataType,
39
- // stopping the "ajax:beforeSend" event will cancel the ajax request
40
- beforeSend: function(xhr, settings) {
41
- if (settings.dataType === undefined) {
42
- xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
43
- }
44
- return fire(element, 'ajax:beforeSend', [xhr, settings]);
45
- },
46
- success: function(data, status, xhr) {
47
- element.trigger('ajax:success', [data, status, xhr]);
48
- },
49
- complete: function(xhr, status) {
50
- element.trigger('ajax:complete', [xhr, status]);
51
- },
52
- error: function(xhr, status, error) {
53
- element.trigger('ajax:error', [xhr, status, error]);
54
- }
55
- });
56
- }
57
-
58
- // Handles "data-method" on links such as:
59
- // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
60
- function handleMethod(link) {
61
- var href = link.attr('href'),
62
- method = link.attr('data-method'),
63
- csrf_token = $('meta[name=csrf-token]').attr('content'),
64
- csrf_param = $('meta[name=csrf-param]').attr('content'),
65
- form = $('<form method="post" action="' + href + '"></form>'),
66
- metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
67
-
68
- if (csrf_param !== undefined && csrf_token !== undefined) {
69
- metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
70
- }
71
-
72
- form.hide().append(metadata_input).appendTo('body');
73
- form.submit();
74
- }
75
-
76
- function disableFormElements(form) {
77
- form.find('input[data-disable-with]').each(function() {
78
- var input = $(this);
79
- input.data('ujs:enable-with', input.val())
80
- .val(input.attr('data-disable-with'))
81
- .attr('disabled', 'disabled');
82
- });
83
- }
84
-
85
- function enableFormElements(form) {
86
- form.find('input[data-disable-with]').each(function() {
87
- var input = $(this);
88
- input.val(input.data('ujs:enable-with')).removeAttr('disabled');
89
- });
90
- }
91
-
92
- function allowAction(element) {
93
- var message = element.attr('data-confirm');
94
- return !message || (fire(element, 'confirm') && confirm(message));
95
- }
96
-
97
- $('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
98
- var link = $(this);
99
- if (!allowAction(link)) return false;
100
-
101
- if (link.attr('data-remote')) {
102
- handleRemote(link);
103
- return false;
104
- } else if (link.attr('data-method')) {
105
- handleMethod(link);
106
- return false;
107
- }
108
- });
109
-
110
- $('form').live('submit.rails', function(e) {
111
- var form = $(this);
112
- if (!allowAction(form)) return false;
113
-
114
- if (form.attr('data-remote')) {
115
- handleRemote(form);
116
- return false;
117
- } else {
118
- disableFormElements(form);
119
- }
120
- });
121
-
122
- $('form input[type=submit], form button[type=submit], form button:not([type])').live('click.rails', function() {
123
- var button = $(this);
124
- if (!allowAction(button)) return false;
125
- // register the pressed submit button
126
- var name = button.attr('name'), data = name ? {name:name, value:button.val()} : null;
127
- button.closest('form').data('ujs:submit-button', data);
128
- });
129
-
130
- $('form').live('ajax:beforeSend.rails', function(event) {
131
- if (this == event.target) disableFormElements($(this));
132
- });
133
-
134
- $('form').live('ajax:complete.rails', function(event) {
135
- if (this == event.target) enableFormElements($(this));
136
- });
137
- })( jQuery );
1
+ /**
2
+ * Unobtrusive scripting adapter for jQuery
3
+ *
4
+ * Requires jQuery 1.4.3 or later.
5
+ * https://github.com/rails/jquery-ujs
6
+ */
7
+
8
+ (function($) {
9
+ // Triggers an event on an element and returns the event result
10
+ function fire(obj, name, data) {
11
+ var event = new $.Event(name);
12
+ obj.trigger(event, data);
13
+ return event.result !== false;
14
+ }
15
+
16
+ // Submits "remote" forms and links with ajax
17
+ function handleRemote(element) {
18
+ var method, url, data,
19
+ dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
20
+
21
+ if (element.is('form')) {
22
+ method = element.attr('method');
23
+ url = element.attr('action');
24
+ data = element.serializeArray();
25
+ // memoized value from clicked submit button
26
+ var button = element.data('ujs:submit-button');
27
+ if (button) {
28
+ data.push(button);
29
+ element.data('ujs:submit-button', null);
30
+ }
31
+ } else {
32
+ method = element.attr('data-method');
33
+ url = element.attr('href');
34
+ data = null;
35
+ }
36
+
37
+ $.ajax({
38
+ url: url, type: method || 'GET', data: data, dataType: dataType,
39
+ // stopping the "ajax:beforeSend" event will cancel the ajax request
40
+ beforeSend: function(xhr, settings) {
41
+ if (settings.dataType === undefined) {
42
+ xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
43
+ }
44
+ return fire(element, 'ajax:beforeSend', [xhr, settings]);
45
+ },
46
+ success: function(data, status, xhr) {
47
+ element.trigger('ajax:success', [data, status, xhr]);
48
+ },
49
+ complete: function(xhr, status) {
50
+ element.trigger('ajax:complete', [xhr, status]);
51
+ },
52
+ error: function(xhr, status, error) {
53
+ element.trigger('ajax:error', [xhr, status, error]);
54
+ }
55
+ });
56
+ }
57
+
58
+ // Handles "data-method" on links such as:
59
+ // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
60
+ function handleMethod(link) {
61
+ var href = link.attr('href'),
62
+ method = link.attr('data-method'),
63
+ csrf_token = $('meta[name=csrf-token]').attr('content'),
64
+ csrf_param = $('meta[name=csrf-param]').attr('content'),
65
+ form = $('<form method="post" action="' + href + '"></form>'),
66
+ metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
67
+
68
+ if (csrf_param !== undefined && csrf_token !== undefined) {
69
+ metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
70
+ }
71
+
72
+ form.hide().append(metadata_input).appendTo('body');
73
+ form.submit();
74
+ }
75
+
76
+ function disableFormElements(form) {
77
+ form.find('input[data-disable-with]').each(function() {
78
+ var input = $(this);
79
+ input.data('ujs:enable-with', input.val())
80
+ .val(input.attr('data-disable-with'))
81
+ .attr('disabled', 'disabled');
82
+ });
83
+ }
84
+
85
+ function enableFormElements(form) {
86
+ form.find('input[data-disable-with]').each(function() {
87
+ var input = $(this);
88
+ input.val(input.data('ujs:enable-with')).removeAttr('disabled');
89
+ });
90
+ }
91
+
92
+ function allowAction(element) {
93
+ var message = element.attr('data-confirm');
94
+ return !message || (fire(element, 'confirm') && confirm(message));
95
+ }
96
+
97
+ $('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
98
+ var link = $(this);
99
+ if (!allowAction(link)) return false;
100
+
101
+ if (link.attr('data-remote')) {
102
+ handleRemote(link);
103
+ return false;
104
+ } else if (link.attr('data-method')) {
105
+ handleMethod(link);
106
+ return false;
107
+ }
108
+ });
109
+
110
+ $('form').live('submit.rails', function(e) {
111
+ var form = $(this);
112
+ if (!allowAction(form)) return false;
113
+
114
+ if (form.attr('data-remote')) {
115
+ handleRemote(form);
116
+ return false;
117
+ } else {
118
+ disableFormElements(form);
119
+ }
120
+ });
121
+
122
+ $('form input[type=submit], form button[type=submit], form button:not([type])').live('click.rails', function() {
123
+ var button = $(this);
124
+ if (!allowAction(button)) return false;
125
+ // register the pressed submit button
126
+ var name = button.attr('name'), data = name ? {name:name, value:button.val()} : null;
127
+ button.closest('form').data('ujs:submit-button', data);
128
+ });
129
+
130
+ $('form').live('ajax:beforeSend.rails', function(event) {
131
+ if (this == event.target) disableFormElements($(this));
132
+ });
133
+
134
+ $('form').live('ajax:complete.rails', function(event) {
135
+ if (this == event.target) enableFormElements($(this));
136
+ });
137
+ })( jQuery );