bootbox_crud 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +31 -0
  3. data/MIT.license +20 -0
  4. data/README.md +301 -0
  5. data/app/views/layouts/_bb_alert.html.haml +2 -0
  6. data/app/views/layouts/_show_link_to.html.haml +5 -0
  7. data/app/views/layouts/_show_link_to_array.html.haml +6 -0
  8. data/app/views/layouts/_show_value.html.haml +4 -0
  9. data/app/views/modals/_alert.js.erb +5 -0
  10. data/app/views/modals/_create.js.erb +1 -0
  11. data/app/views/modals/_destroy.js.erb +1 -0
  12. data/app/views/modals/_form.js.erb +16 -0
  13. data/app/views/modals/_update.js.erb +1 -0
  14. data/bootbox_crud.gemspec +28 -0
  15. data/lib/bootbox_crud.rb +7 -0
  16. data/lib/bootbox_crud/action_view/helpers.rb +37 -0
  17. data/lib/bootbox_crud/engine.rb +23 -0
  18. data/lib/bootbox_crud/version.rb +5 -0
  19. data/lib/generators/bootbox_crud/install_generator.rb +16 -0
  20. data/lib/generators/bootbox_crud/templates/README +6 -0
  21. data/lib/generators/bootbox_crud/templates/app/assets/javascripts/models.js +7 -0
  22. data/lib/generators/bootbox_crud/templates/config/initializers/simple_form.rb +142 -0
  23. data/lib/generators/bootbox_crud/templates/config/initializers/simple_form_bootstrap.rb +163 -0
  24. data/lib/generators/rails/haml_modal_crud/USAGE +15 -0
  25. data/lib/generators/rails/haml_modal_crud/haml_modal_crud_generator.rb +30 -0
  26. data/lib/generators/rails/haml_modal_crud/templates/create.js.erb +2 -0
  27. data/lib/generators/rails/haml_modal_crud/templates/destroy.js.erb +1 -0
  28. data/lib/generators/rails/haml_modal_crud/templates/update.js.erb +1 -0
  29. data/lib/generators/rails/modal_crud_route/USAGE +9 -0
  30. data/lib/generators/rails/modal_crud_route/modal_crud_route_generator.rb +21 -0
  31. data/lib/generators/rails/modal_crud_route/templates/models.js +7 -0
  32. data/lib/templates/haml/scaffold/_form.html.haml +12 -0
  33. data/lib/templates/haml/scaffold/edit.html.haml +2 -0
  34. data/lib/templates/haml/scaffold/index.html.haml +51 -0
  35. data/lib/templates/haml/scaffold/new.html.haml +2 -0
  36. data/lib/templates/haml/scaffold/show.html.haml +7 -0
  37. data/lib/templates/rails/scaffold_controller/controller.rb +102 -0
  38. data/vendor/assets/javascripts/bootbox_crud_main.js +6 -0
  39. data/vendor/assets/javascripts/bootbox_crud_modals.js +206 -0
  40. data/vendor/assets/javascripts/sortable.js +177 -0
  41. data/vendor/assets/stylesheets/bootbox_crud.css.scss +25 -0
  42. data/vendor/assets/stylesheets/bootbox_crud_main.css.scss +2 -0
  43. data/vendor/assets/stylesheets/sortable-theme-minimal.css +47 -0
  44. metadata +255 -0
@@ -0,0 +1,2 @@
1
+ <%%= render partial: 'modals/create', locals: { model: @<%= singular_table_name %>, form_path: '<%= plural_table_name %>/form' } %>
2
+
@@ -0,0 +1 @@
1
+ <%%= render partial: 'modals/destroy', locals: { model: @<%= singular_table_name %>, form_path: '<%= plural_table_name %>/form' } %>
@@ -0,0 +1 @@
1
+ <%%= render partial: 'modals/update', locals: { model: @<%= singular_table_name %>, form_path: '<%= plural_table_name %>/form' } %>
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Adds model definition to app/assets/javascripts/models.js for CRUD modals and invokes resource_route generator to add route to routes.rb
3
+
4
+ Example:
5
+ rails generate modal_crud_route Thing name size:integer
6
+
7
+ This will create:
8
+ insert app/assets/javascripts/models.js
9
+ generate resource_route
@@ -0,0 +1,21 @@
1
+ class Rails::ModalCrudRouteGenerator < Rails::Generators::NamedBase
2
+ include Rails::Generators::ResourceHelpers
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def add_resource_route
6
+ if Rails.application.assets.find_asset('models.js').blank?
7
+ copy_file "models.js", "app/assets/javascripts/models.js"
8
+ end
9
+ inject_into_file 'app/assets/javascripts/models.js', after: "//!!! Generator adds after this line, do not delete it !!!\n" do
10
+ "BBCrud.Models.add('#{name}', '/#{controller_name.underscore}/', '#{name.underscore}');\n"
11
+ end
12
+ run_resource_route
13
+ end
14
+
15
+ protected
16
+
17
+ def run_resource_route
18
+ generate 'resource_route', name
19
+ end
20
+
21
+ end
@@ -0,0 +1,7 @@
1
+ // Put custom actions below this line
2
+ // e.g. BBCrud.Models.addAction('Event', '/events/', 'event', 'close');
3
+
4
+
5
+ //!!! Generator adds after this line, do not delete it !!!
6
+ // e.g. BBCrud.Models.add('Customer', '/customers/', 'customer');
7
+
@@ -0,0 +1,12 @@
1
+ .container-fluid
2
+ = simple_form_for(@<%= singular_table_name %>, remote_form_options) do |f|
3
+ = f.error_notification
4
+ = f.error :base, :error_method => :to_sentence
5
+
6
+ .form-inputs
7
+ <%- attributes.each do |attribute| -%>
8
+ = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>
9
+ <%- end -%>
10
+
11
+ .form-actions.col-sm-7.col-sm-offset-5
12
+ = f.button :submit
@@ -0,0 +1,2 @@
1
+ #content
2
+ = render 'form'
@@ -0,0 +1,51 @@
1
+ .container-fluid
2
+ %h1 Listing <%= plural_table_name %>
3
+
4
+ <% has_name = attributes.find {|a| a.name == 'name'}.present? -%>
5
+
6
+ .table_responsive
7
+ %table.table.table-hover.table-striped.sortable-theme-minimal{data: {sortable: ''}}
8
+ %thead
9
+ %tr
10
+ <% if has_name -%>
11
+ %th
12
+ ID
13
+ %th{data:{sorted: 'true', sorted_direction: 'ascending' }}
14
+ Name
15
+ <% else -%>
16
+ %th{data:{sorted: 'true', sorted_direction: 'ascending' }}
17
+ ID
18
+ <% end -%>
19
+ <% for attribute in attributes -%>
20
+ <% next if %w{name id}.include? attribute.name -%>
21
+ %th <%= attribute.human_name %>
22
+ <% end -%>
23
+ %th{data:{sortable: 'false'}}
24
+
25
+ %tbody
26
+ - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
27
+ %tr
28
+ <% if has_name -%>
29
+ %td
30
+ = <%= singular_table_name %>.id
31
+ %td{data:{value: <%= singular_table_name %>.name.gsub(' ', '').downcase, entity: '<%= singular_table_name.capitalize %>', action: 'show', id: (<%= singular_table_name %>.id) }}
32
+ = link_to <%= singular_table_name %>.name, '#'
33
+ <% else -%>
34
+ %td{data:{ entity: '<%= singular_table_name.capitalize %>', action: 'show', id: (<%= singular_table_name %>.id) }}
35
+ = link_to <%= singular_table_name %>.id, '#'
36
+ <% end -%>
37
+
38
+ <% for attribute in attributes -%>
39
+ <% next if %w{name id}.include? attribute.name -%>
40
+ %td= <%= singular_table_name %>.<%= attribute.name %>
41
+ <% end -%>
42
+ %td
43
+ = link_to '#', :class => 'btn-sm btn-primary', data: { entity: '<%= singular_table_name.capitalize %>', action: 'update', id: (<%= singular_table_name %>.id) } do
44
+ %i.fa.fa-edit
45
+ EDIT
46
+
47
+ %hr
48
+ %p
49
+ = link_to '#', :class => 'btn btn-success', data: { entity: '<%= singular_table_name.capitalize %>', action: 'create' } do
50
+ %i.fa.fa-plus
51
+ = 'New <%= human_name %>'
@@ -0,0 +1,2 @@
1
+ #content
2
+ = render 'form'
@@ -0,0 +1,7 @@
1
+ #content.show
2
+ %p#notice= notice
3
+
4
+ .form-horizontal
5
+ <% for attribute in attributes -%>
6
+ = show_value '<%= attribute.human_name %>', @<%= singular_table_name %>.<%= attribute.name %>
7
+ <% end -%>
@@ -0,0 +1,102 @@
1
+ <% if namespaced? -%>
2
+ require_dependency "<%= namespaced_file_path %>/application_controller"
3
+
4
+ <% end -%>
5
+ <% module_namespacing do -%>
6
+ class <%= controller_class_name %>Controller < ApplicationController
7
+ before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]
8
+
9
+ # GET <%= route_url %>
10
+ def index
11
+ @<%= plural_table_name %> = <%= attributes_names.select { |attr| attr == 'name' }.present? ? "#{class_name}.order('lower(name)').all" : orm_class.all(class_name) %>
12
+ respond_to do |format|
13
+ format.html
14
+ format.json { render json: @<%= plural_table_name %> }
15
+ end
16
+ end
17
+
18
+ # GET <%= route_url %>/1
19
+ def show
20
+ respond_to do |format|
21
+ format.html { render layout: false }
22
+ format.json { render json: @<%= singular_table_name %> }
23
+ end
24
+ end
25
+
26
+ # GET <%= route_url %>/new
27
+ def new
28
+ @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
29
+ respond_to do |format|
30
+ format.html { render layout: false }
31
+ format.json { render json: @<%= singular_table_name %> }
32
+ end
33
+ end
34
+
35
+ # GET <%= route_url %>/1/edit
36
+ def edit
37
+ render layout: false
38
+ end
39
+
40
+ # POST <%= route_url %>
41
+ def create
42
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
43
+
44
+ respond_to do |format|
45
+ if @<%= orm_instance.save %>
46
+ format.html { redirect_to @<%= singular_table_name %> }
47
+ format.json { render json: @<%= singular_table_name %>, status: :created }
48
+ format.js
49
+ else
50
+ format.html { render :new }
51
+ format.json { render json: @<%= singular_table_name %>.errors, status: :unprocessable_entity }
52
+ format.js
53
+ end
54
+ end
55
+ end
56
+
57
+ # PATCH/PUT <%= route_url %>/1
58
+ def update
59
+ respond_to do |format|
60
+ if @<%= orm_instance.update("#{singular_table_name}_params") %>
61
+ format.html { redirect_to @<%= singular_table_name %> }
62
+ format.json { head :no_content }
63
+ format.js
64
+ else
65
+ format.html { render :edit }
66
+ format.json { render json: @<%= singular_table_name %>.errors, status: :unprocessable_entity }
67
+ format.js
68
+ end
69
+ end
70
+ end
71
+
72
+ # DELETE <%= route_url %>/1
73
+ def destroy
74
+ respond_to do |format|
75
+ if @<%= orm_instance.destroy %>
76
+ format.html { redirect_to <%= index_helper %>_url }
77
+ format.json { head :no_content }
78
+ format.js
79
+ else
80
+ format.html { redirect_to <%= index_helper %>_url }
81
+ format.json { render json: @<%= singular_table_name %>.errors, status: :forbidden }
82
+ format.js { render status: :forbidden }
83
+ end
84
+ end
85
+ end
86
+
87
+ private
88
+ # Use callbacks to share common setup or constraints between actions.
89
+ def set_<%= singular_table_name %>
90
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
91
+ end
92
+
93
+ # Only allow a trusted parameter "white list" through.
94
+ def <%= "#{singular_table_name}_params" %>
95
+ <%- if attributes_names.empty? -%>
96
+ params[:<%= singular_table_name %>]
97
+ <%- else -%>
98
+ params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
99
+ <%- end -%>
100
+ end
101
+ end
102
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ //= require bootstrap/modal
2
+ //= require jquery.remotipart
3
+ //= require bootbox
4
+ //= require ./bootbox_crud_modals
5
+ //= require ./sortable
6
+ //= require models
@@ -0,0 +1,206 @@
1
+ var BBCrud = BBCrud || {};
2
+
3
+ BBCrud.Modals = function () {
4
+
5
+ var modals = {
6
+ form: function(id, title, btnLabel, url, exec, timeout, timeoutExec, options) {
7
+ var buttons = {
8
+ close: {
9
+ "label" : "Close"
10
+ },
11
+ submit: {
12
+ "label" : btnLabel,
13
+ "className" : "btn-success",
14
+ "callback": function() {
15
+ if (options.dontSubmit !== true) {
16
+ $('.bootbox.modal').find('input[type="submit"]').closest('form').submit();
17
+ }
18
+ if (timeoutExec !== null && typeof timeoutExec != 'undefined') { setTimeout(timeoutExec, timeout); }
19
+ return false;
20
+ }
21
+ }
22
+ };
23
+ if (id !== -1 && options.showDeleteBtn !== false) {
24
+ $.extend(buttons, {
25
+ delete: {
26
+ "label" : "Delete",
27
+ "className" : "btn-danger",
28
+ "callback" : function() {
29
+ modals.delete(id, options.baseUrl);
30
+ return false;
31
+ }
32
+ }
33
+ })
34
+ }
35
+
36
+ var modal = bootbox.dialog({
37
+ message : "Loading form...",
38
+ title : title,
39
+ backdrop : "static",
40
+ keyboard : false,
41
+ show : true,
42
+ header : title,
43
+ buttons: buttons
44
+ });
45
+ $.get(url, options.data, function(data) {
46
+ var result = $(data);
47
+ var content = result.attr('id') === 'content' ? result : result.find('#content');
48
+ modal.find('.modal-body').html(content);
49
+ modal.find('.form-actions').hide();
50
+ if (exec !== null && typeof exec != 'undefined') { exec(); }
51
+ });
52
+ },
53
+ create: function (title, baseUrl, exec, data) {
54
+ modals.update(-1, title, baseUrl, exec, true, undefined, undefined, data);
55
+ },
56
+ update: function (id, title, baseUrl, exec, createMode, timeout, timeoutExec, data) {
57
+ if (typeof id === 'object') id = id.id;
58
+ var primaryBtnLabel = createMode ? 'Create' : 'Update';
59
+ var url = createMode ? baseUrl + 'new' : baseUrl + id + '/edit';
60
+ modals.form(id, title, primaryBtnLabel, url, exec, timeout, timeoutExec, { baseUrl: baseUrl, data: data });
61
+ },
62
+ other: function (id, title, baseUrl, actionName, exec, timeout, timeoutExec, data) {
63
+ if (typeof id === 'object') id = id.id;
64
+ var url = baseUrl + id + '/' + actionName;
65
+ modals.form(id, title, actionName.charAt(0).toUpperCase() + actionName.slice(1), url, exec, timeout, timeoutExec, { baseUrl: baseUrl, data: data, showDeleteBtn: false });
66
+ },
67
+ delete: function (id, baseUrl, exec) {
68
+ bootbox.confirm('Are you sure?', function(result) {
69
+ if (result === true) {
70
+ $.ajax({
71
+ url: baseUrl + id,
72
+ contentType: "application/javascript",
73
+ dataType: 'script',
74
+ type: 'DELETE'
75
+ }).success(function () {
76
+ if (typeof exec != 'undefined') { exec(); }
77
+ VM.Alert.show('Deleted');
78
+ }).error(function () {
79
+ VM.Alert.show('Something went wrong!');
80
+ });
81
+ }
82
+ });
83
+ },
84
+ show: function(id, title, baseUrl) {
85
+ var modal = bootbox.dialog({
86
+ message : "Loading form...",
87
+ title : title,
88
+ backdrop : "static",
89
+ keyboard : false,
90
+ show : true,
91
+ header : title,
92
+ buttons: {
93
+ close: {
94
+ "label" : "Close"
95
+ }
96
+ }
97
+ });
98
+ $.get(baseUrl + id, function(data) {
99
+ handleResponse(data);
100
+ }).error(function (response) {
101
+ if (response.status === 200) {
102
+ handleResponse(response.responseText);
103
+ }
104
+ console.log(response);
105
+ });
106
+ function handleResponse(data) {
107
+ var result = $(data);
108
+ var content = result.attr('id') === 'content' ? result : result.find('#content');
109
+ modal.find('.modal-body').html(content);
110
+ }
111
+ },
112
+ // general click handler displaying create or update form in modal
113
+ initBtnHandler: function() {
114
+ $(document).on('click', '[data-entity]', function() {
115
+ var link = $(this);
116
+ var args = $.extend({}, link.data());
117
+ delete args['entity'];
118
+ delete args['action'];
119
+ BBCrud[link.data('entity')][link.data('action')].call(link, args);
120
+ return false;
121
+ });
122
+ }
123
+ };
124
+ return modals;
125
+ }();
126
+
127
+ BBCrud.Modals.initBtnHandler();
128
+
129
+ BBCrud.Models = function () {
130
+ function defineModelActions(modelName, actions) {
131
+ if (typeof BBCrud[modelName] === 'undefined') {
132
+ BBCrud[modelName] = actions;
133
+ } else {
134
+ $.extend(BBCrud[modelName], actions);
135
+ }
136
+ }
137
+
138
+ var models = {
139
+ add: function(modelName, url, titleName) {
140
+ var modelCRUD = function () {
141
+ var baseUrl = url;
142
+
143
+ var methods = {
144
+ create: function (data) {
145
+ BBCrud.Modals.create('Create ' + titleName, baseUrl, null, data);
146
+ },
147
+ update: function (data) {
148
+ BBCrud.Modals.update(data.id, 'Edit ' + titleName, baseUrl);
149
+ },
150
+ show: function (data) {
151
+ BBCrud.Modals.show(data.id, titleName.charAt(0).toUpperCase() + titleName.slice(1) + ' detail', baseUrl);
152
+ }
153
+ };
154
+ return methods;
155
+ }();
156
+
157
+ defineModelActions(modelName, modelCRUD);
158
+ },
159
+ addAction: function(modelName, url, titleName, actionName) {
160
+ var action = function () {
161
+ var baseUrl = url;
162
+ var modelAction = {};
163
+ modelAction[actionName] = function (data) {
164
+ BBCrud.Modals.other(data.id, actionName.charAt(0).toUpperCase() + actionName.slice(1) + ' ' + titleName,
165
+ baseUrl, actionName, null, 0, null, data);
166
+ };
167
+ return modelAction;
168
+ }();
169
+ defineModelActions(modelName, action);
170
+ }
171
+
172
+ };
173
+ return models;
174
+ }();
175
+
176
+
177
+ BBCrud.Alert = function() {
178
+ var elem,
179
+ hideHandler,
180
+ alert = {};
181
+
182
+ alert.init = function(options) {
183
+ elem = $(options.selector);
184
+ };
185
+
186
+ alert.show = function(text) {
187
+ clearTimeout(hideHandler);
188
+
189
+ elem.find("span").html(text);
190
+ elem.fadeIn();
191
+
192
+ hideHandler = setTimeout(function() {
193
+ alert.hide();
194
+ }, 4000);
195
+ };
196
+
197
+ alert.hide = function() {
198
+ elem.fadeOut();
199
+ };
200
+
201
+ return alert;
202
+ }();
203
+
204
+ $(function() {
205
+ BBCrud.Alert.init({selector: '.bb-alert'});
206
+ });