lolita 3.0.5 → 3.0.6

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.
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 );