bootbox_crud 0.1.1

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