incline 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +186 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +208 -0
- data/Rakefile +37 -0
- data/app/assets/fonts/incline/.keep +0 -0
- data/app/assets/images/incline/.keep +0 -0
- data/app/assets/images/incline/barcode-B.svg +181 -0
- data/app/assets/javascripts/incline/activate_classed_items.js +11 -0
- data/app/assets/javascripts/incline/application.js +30 -0
- data/app/assets/javascripts/incline/bootstrap-datepicker.js +1800 -0
- data/app/assets/javascripts/incline/datatables.js +22193 -0
- data/app/assets/javascripts/incline/escapeHtml.js +10 -0
- data/app/assets/javascripts/incline/inline_actions.js +479 -0
- data/app/assets/javascripts/incline/jquery.doubleScroll.js +112 -0
- data/app/assets/javascripts/incline/jquery.number.js +764 -0
- data/app/assets/javascripts/incline/regexMask.js +27 -0
- data/app/assets/javascripts/incline/select2/i18n/en.js +3 -0
- data/app/assets/javascripts/incline/select2/select2.full.js +6436 -0
- data/app/assets/stylesheets/incline/application.css +18 -0
- data/app/assets/stylesheets/incline/bootstrap-theme.min.css +5 -0
- data/app/assets/stylesheets/incline/custom.scss +279 -0
- data/app/assets/stylesheets/incline/datatables.css +494 -0
- data/app/assets/stylesheets/incline/datepicker3.css +790 -0
- data/app/assets/stylesheets/incline/select2.css +484 -0
- data/app/controllers/incline/access_groups_controller.rb +127 -0
- data/app/controllers/incline/access_test_controller.rb +30 -0
- data/app/controllers/incline/account_activations_controller.rb +28 -0
- data/app/controllers/incline/application_controller.rb +11 -0
- data/app/controllers/incline/contact_controller.rb +34 -0
- data/app/controllers/incline/password_resets_controller.rb +113 -0
- data/app/controllers/incline/security_controller.rb +100 -0
- data/app/controllers/incline/sessions_controller.rb +50 -0
- data/app/controllers/incline/users_controller.rb +304 -0
- data/app/controllers/incline/welcome_controller.rb +19 -0
- data/app/helpers/incline/.keep +0 -0
- data/app/mailers/incline/application_mailer_base.rb +11 -0
- data/app/mailers/incline/contact_form.rb +19 -0
- data/app/mailers/incline/user_mailer.rb +45 -0
- data/app/models/incline/access_group.rb +121 -0
- data/app/models/incline/access_group_group_member.rb +12 -0
- data/app/models/incline/access_group_user_member.rb +10 -0
- data/app/models/incline/action_group.rb +12 -0
- data/app/models/incline/action_security.rb +222 -0
- data/app/models/incline/contact_message.rb +37 -0
- data/app/models/incline/disable_info.rb +20 -0
- data/app/models/incline/password_reset.rb +14 -0
- data/app/models/incline/password_reset_request.rb +14 -0
- data/app/models/incline/user.rb +437 -0
- data/app/models/incline/user_login_history.rb +30 -0
- data/app/views/incline/access_groups/_details.json.jbuilder +10 -0
- data/app/views/incline/access_groups/_form.html.erb +19 -0
- data/app/views/incline/access_groups/_list.html.erb +60 -0
- data/app/views/incline/access_groups/_messages.json.jbuilder +6 -0
- data/app/views/incline/access_groups/edit.html.erb +2 -0
- data/app/views/incline/access_groups/index.html.erb +6 -0
- data/app/views/incline/access_groups/index.json.jbuilder +16 -0
- data/app/views/incline/access_groups/new.html.erb +2 -0
- data/app/views/incline/access_groups/show.html.erb +9 -0
- data/app/views/incline/access_groups/show.json.jbuilder +11 -0
- data/app/views/incline/contact/new.html.erb +22 -0
- data/app/views/incline/contact_form/contact.html.erb +16 -0
- data/app/views/incline/contact_form/contact.text.erb +13 -0
- data/app/views/incline/password_resets/edit.html.erb +16 -0
- data/app/views/incline/password_resets/new.html.erb +12 -0
- data/app/views/incline/security/_details.json.jbuilder +7 -0
- data/app/views/incline/security/_form.html.erb +20 -0
- data/app/views/incline/security/_list.html.erb +89 -0
- data/app/views/incline/security/_messages.json.jbuilder +6 -0
- data/app/views/incline/security/edit.html.erb +2 -0
- data/app/views/incline/security/index.html.erb +6 -0
- data/app/views/incline/security/index.json.jbuilder +16 -0
- data/app/views/incline/security/show.html.erb +31 -0
- data/app/views/incline/security/show.json.jbuilder +11 -0
- data/app/views/incline/sessions/new.html.erb +26 -0
- data/app/views/incline/user_mailer/account_activation.html.erb +7 -0
- data/app/views/incline/user_mailer/account_activation.text.erb +6 -0
- data/app/views/incline/user_mailer/invalid_password_reset.html.erb +3 -0
- data/app/views/incline/user_mailer/invalid_password_reset.text.erb +5 -0
- data/app/views/incline/user_mailer/password_reset.html.erb +8 -0
- data/app/views/incline/user_mailer/password_reset.text.erb +7 -0
- data/app/views/incline/users/_details.json.jbuilder +32 -0
- data/app/views/incline/users/_form.html.erb +21 -0
- data/app/views/incline/users/_list.html.erb +102 -0
- data/app/views/incline/users/_messages.json.jbuilder +6 -0
- data/app/views/incline/users/disable_confirm.html.erb +19 -0
- data/app/views/incline/users/edit.html.erb +5 -0
- data/app/views/incline/users/index.html.erb +6 -0
- data/app/views/incline/users/index.json.jbuilder +16 -0
- data/app/views/incline/users/new.html.erb +5 -0
- data/app/views/incline/users/show.html.erb +12 -0
- data/app/views/incline/users/show.json.jbuilder +11 -0
- data/app/views/incline/welcome/home.html.erb +5 -0
- data/app/views/layouts/application.html.erb +1 -0
- data/app/views/layouts/incline/_account_menu.html.erb +18 -0
- data/app/views/layouts/incline/_app_menu_anon.html.erb +1 -0
- data/app/views/layouts/incline/_app_menu_authenticated.html.erb +1 -0
- data/app/views/layouts/incline/_footer.html.erb +13 -0
- data/app/views/layouts/incline/_header.html.erb +21 -0
- data/app/views/layouts/incline/_html_mailer.html.erb +5 -0
- data/app/views/layouts/incline/_incline_app.html.erb +25 -0
- data/app/views/layouts/incline/_messages.html.erb +3 -0
- data/app/views/layouts/incline/_shim.html.erb +3 -0
- data/app/views/layouts/incline/_text_mailer.text.erb +1 -0
- data/app/views/layouts/incline/application.html.erb +1 -0
- data/app/views/layouts/mailer.html.erb +2 -0
- data/app/views/layouts/mailer.text.erb +2 -0
- data/bin/rails +12 -0
- data/bin/test_scaffold.sh +10 -0
- data/config/routes.rb +61 -0
- data/db/migrate/20170511230126_create_incline_users.rb +26 -0
- data/db/migrate/20170515003052_create_incline_access_groups.rb +10 -0
- data/db/migrate/20170515003221_create_incline_user_login_histories.rb +12 -0
- data/db/migrate/20170515150908_create_incline_access_group_user_members.rb +11 -0
- data/db/migrate/20170515151058_create_incline_access_group_group_members.rb +11 -0
- data/db/migrate/20170517193432_add_comments_to_incline_user.rb +5 -0
- data/db/migrate/20170622132700_create_incline_action_securities.rb +16 -0
- data/db/migrate/20170622172712_create_incline_action_groups.rb +11 -0
- data/db/migrate/20170622195742_add_non_standard_to_action_security.rb +5 -0
- data/db/migrate/20170622230422_add_visible_to_action_security.rb +5 -0
- data/db/seeds.rb +81 -0
- data/exe/new_incline_app +42 -0
- data/lib/generators/incline/install_generator.rb +259 -0
- data/lib/generators/incline/templates/_app_menu_anon.html.erb +1 -0
- data/lib/generators/incline/templates/_app_menu_authenticated.html.erb +1 -0
- data/lib/generators/incline/templates/incline_application.css +17 -0
- data/lib/generators/incline/templates/incline_application.html.erb +1 -0
- data/lib/generators/incline/templates/incline_application.js +12 -0
- data/lib/generators/incline/templates/incline_database.yml +25 -0
- data/lib/generators/incline/templates/incline_email.yml +20 -0
- data/lib/generators/incline/templates/incline_mailer.html.erb +2 -0
- data/lib/generators/incline/templates/incline_mailer.text.erb +2 -0
- data/lib/generators/incline/templates/incline_users.yml +64 -0
- data/lib/generators/incline/templates/incline_version.rb +3 -0
- data/lib/incline/auth_engine_base.rb +52 -0
- data/lib/incline/data_tables_request.rb +336 -0
- data/lib/incline/date_time_formats.rb +6 -0
- data/lib/incline/engine.rb +212 -0
- data/lib/incline/errors.rb +15 -0
- data/lib/incline/extensions/action_controller_base.rb +526 -0
- data/lib/incline/extensions/action_mailer_base.rb +66 -0
- data/lib/incline/extensions/action_view_base.rb +489 -0
- data/lib/incline/extensions/active_record_base.rb +308 -0
- data/lib/incline/extensions/application.rb +137 -0
- data/lib/incline/extensions/application_configuration.rb +50 -0
- data/lib/incline/extensions/connection_adapter.rb +55 -0
- data/lib/incline/extensions/date_time_value.rb +123 -0
- data/lib/incline/extensions/date_value.rb +77 -0
- data/lib/incline/extensions/decimal_value.rb +55 -0
- data/lib/incline/extensions/erb_scaffold_generator.rb +31 -0
- data/lib/incline/extensions/float_value.rb +59 -0
- data/lib/incline/extensions/form_builder.rb +617 -0
- data/lib/incline/extensions/integer_value.rb +54 -0
- data/lib/incline/extensions/jbuilder_generator.rb +38 -0
- data/lib/incline/extensions/jbuilder_template.rb +39 -0
- data/lib/incline/extensions/main_app.rb +40 -0
- data/lib/incline/extensions/numeric.rb +63 -0
- data/lib/incline/extensions/object.rb +31 -0
- data/lib/incline/extensions/resource_route_generator.rb +53 -0
- data/lib/incline/extensions/session.rb +113 -0
- data/lib/incline/extensions/string.rb +50 -0
- data/lib/incline/extensions/test_case.rb +764 -0
- data/lib/incline/extensions/time_zone_converter.rb +40 -0
- data/lib/incline/global_status.rb +236 -0
- data/lib/incline/helpers/route_hash_formatter.rb +46 -0
- data/lib/incline/json_log_formatter.rb +96 -0
- data/lib/incline/json_logger.rb +17 -0
- data/lib/incline/log.rb +153 -0
- data/lib/incline/number_formats.rb +17 -0
- data/lib/incline/recaptcha.rb +346 -0
- data/lib/incline/user_manager.rb +212 -0
- data/lib/incline/validators/email_validator.rb +45 -0
- data/lib/incline/validators/ip_address_validator.rb +32 -0
- data/lib/incline/validators/recaptcha_validator.rb +37 -0
- data/lib/incline/validators/safe_name_validator.rb +31 -0
- data/lib/incline/version.rb +3 -0
- data/lib/incline/work_path.rb +75 -0
- data/lib/incline.rb +197 -0
- data/lib/tasks/incline_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +43 -0
- data/lib/templates/erb/scaffold/_list.html.erb +81 -0
- data/lib/templates/erb/scaffold/edit.html.erb +1 -0
- data/lib/templates/erb/scaffold/index.html.erb +6 -0
- data/lib/templates/erb/scaffold/new.html.erb +1 -0
- data/lib/templates/erb/scaffold/show.html.erb +34 -0
- data/lib/templates/jbuilder/scaffold/_details.json.jbuilder +20 -0
- data/lib/templates/jbuilder/scaffold/index.json.jbuilder +16 -0
- data/lib/templates/jbuilder/scaffold/show.json.jbuilder +16 -0
- data/lib/templates/rails/scaffold_controller/controller.rb +128 -0
- data/test/controllers/incline/access_groups_controller_test.rb +65 -0
- data/test/controllers/incline/access_test_controller_test.rb +53 -0
- data/test/controllers/incline/contact_controller_test.rb +32 -0
- data/test/controllers/incline/security_controller_test.rb +39 -0
- data/test/controllers/incline/welcome_controller_test.rb +16 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +12 -0
- data/test/dummy/app/assets/stylesheets/application.css +17 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.keep +0 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +1 -0
- data/test/dummy/app/views/layouts/incline/_app_menu_anon.html.erb +1 -0
- data/test/dummy/app/views/layouts/incline/_app_menu_authenticated.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +2 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +2 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +38 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +34 -0
- data/test/dummy/config/email.yml +24 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +45 -0
- data/test/dummy/config/environments/production.rb +85 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +108 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/extensions/action_controller_base_extensions_test.rb +21 -0
- data/test/extensions/action_mailer_base_extensions_test.rb +20 -0
- data/test/extensions/action_view_base_extensions_test.rb +267 -0
- data/test/extensions/active_record_extensions_test.rb +173 -0
- data/test/extensions/application_configuration_extensions_test.rb +46 -0
- data/test/extensions/application_extensions_test.rb +23 -0
- data/test/extensions/connection_adapter_extensions_test.rb +54 -0
- data/test/extensions/date_time_value_extensions_test.rb +104 -0
- data/test/extensions/date_value_extensions_test.rb +102 -0
- data/test/extensions/decimal_value_extensions_test.rb +85 -0
- data/test/extensions/erb_scaffold_generator_extensions_test.rb +17 -0
- data/test/extensions/float_value_extensions_test.rb +78 -0
- data/test/extensions/form_builder_extensions_test.rb +28 -0
- data/test/extensions/integer_value_extensions_test.rb +78 -0
- data/test/extensions/jbuilder_generator_extensions_test.rb +21 -0
- data/test/extensions/jbuilder_template_extensions_test.rb +47 -0
- data/test/extensions/main_app_extensions_test.rb +55 -0
- data/test/extensions/numeric_extensions_test.rb +76 -0
- data/test/extensions/object_extensions_test.rb +104 -0
- data/test/extensions/session_extensions_test.rb +69 -0
- data/test/extensions/string_extensions_test.rb +32 -0
- data/test/extensions/test_case_extensions_test.rb +538 -0
- data/test/extensions/time_zone_converter_extensions_test.rb +10 -0
- data/test/fixtures/incline/access_group_group_members.yml +1 -0
- data/test/fixtures/incline/access_group_user_members.yml +1 -0
- data/test/fixtures/incline/access_groups.yml +13 -0
- data/test/fixtures/incline/action_groups.yml +6 -0
- data/test/fixtures/incline/action_securities.yml +18 -0
- data/test/fixtures/incline/user_login_histories.yml +1 -0
- data/test/fixtures/incline/users.yml +64 -0
- data/test/incline_test.rb +63 -0
- data/test/integration/incline/users_edit_test.rb +180 -0
- data/test/integration/incline/users_login_test.rb +105 -0
- data/test/integration/incline/users_signup_test.rb +147 -0
- data/test/integration/navigation_test.rb +11 -0
- data/test/lib/data_tables_request_test.rb +245 -0
- data/test/lib/date_time_formats_test.rb +111 -0
- data/test/lib/global_status_test.rb +89 -0
- data/test/lib/json_log_formatter_test.rb +43 -0
- data/test/lib/log_test.rb +36 -0
- data/test/lib/recaptcha_test.rb +75 -0
- data/test/lib/user_manager_test.rb +47 -0
- data/test/lib/work_path_test.rb +18 -0
- data/test/models/incline/access_group_group_member_test.rb +30 -0
- data/test/models/incline/access_group_test.rb +60 -0
- data/test/models/incline/access_group_user_member_test.rb +29 -0
- data/test/models/incline/action_group_test.rb +27 -0
- data/test/models/incline/action_security_test.rb +176 -0
- data/test/models/incline/contact_message_test.rb +66 -0
- data/test/models/incline/disable_info_test.rb +29 -0
- data/test/models/incline/password_reset_request_test.rb +35 -0
- data/test/models/incline/password_reset_test.rb +51 -0
- data/test/models/incline/user_login_history_test.rb +31 -0
- data/test/models/incline/user_test.rb +91 -0
- data/test/test_helper.rb +42 -0
- data/test/validators/email_validator_test.rb +102 -0
- data/test/validators/ip_address_validator_test.rb +107 -0
- data/test/validators/recaptcha_validator_test.rb +57 -0
- data/test/validators/safe_name_validator_test.rb +101 -0
- metadata +584 -0
@@ -0,0 +1,479 @@
|
|
1
|
+
// Data Tables Helper Methods
|
2
|
+
// (C) 2017 Beau Barker (beau@barkerest.com)
|
3
|
+
|
4
|
+
/*
|
5
|
+
* JSON format:
|
6
|
+
* {
|
7
|
+
* // (optional) set to true to indicate an invalid request to the server, default is false.
|
8
|
+
* "invalidRequest": false,
|
9
|
+
* // (optional) an array of messages to display to the user.
|
10
|
+
* "messages": [
|
11
|
+
* {
|
12
|
+
* // (required) "info", "warning", "danger", "success"
|
13
|
+
* "type": "info",
|
14
|
+
* // (required) the message to display.
|
15
|
+
* "text": "The action was successful."
|
16
|
+
* }
|
17
|
+
* ],
|
18
|
+
* // (optional) an array of data to update the data table with.
|
19
|
+
* "data": [
|
20
|
+
* {
|
21
|
+
* // (required) the unique ID for this row.
|
22
|
+
* "DT_RowId": "my_model_1",
|
23
|
+
* // (required) the "show" path for the model.
|
24
|
+
* "DT_Path": "/incline/my_model/1",
|
25
|
+
* // (optional) "update" or "remove", default is "update".
|
26
|
+
* "DT_RowAction": "update",
|
27
|
+
* // (optional) "info", "warning", "danger", "success"
|
28
|
+
* "DT_RowClass": "info",
|
29
|
+
*
|
30
|
+
* // then model details such as:
|
31
|
+
* "name": "John Doe",
|
32
|
+
* "age": 35,
|
33
|
+
* "email": "jdoe@example.com",
|
34
|
+
* "occupation": "Mechanic"
|
35
|
+
* }
|
36
|
+
* ]
|
37
|
+
* }
|
38
|
+
*/
|
39
|
+
|
40
|
+
|
41
|
+
var inclineInline = {
|
42
|
+
action: function(path, method) {
|
43
|
+
if (!(method)) method = 'get';
|
44
|
+
if (path.indexOf('?') >= 0) {
|
45
|
+
path += '&inline=1';
|
46
|
+
} else {
|
47
|
+
path += '?inline=1';
|
48
|
+
}
|
49
|
+
$.ajax({
|
50
|
+
method: method.toUpperCase(),
|
51
|
+
url: path,
|
52
|
+
dataType: 'json',
|
53
|
+
success: function (data, status, xhr) {
|
54
|
+
inclineInline._handle_json_result(data);
|
55
|
+
},
|
56
|
+
error: function (xhr, status, error) {
|
57
|
+
inclineInline._handle_error(status, error);
|
58
|
+
}
|
59
|
+
});
|
60
|
+
},
|
61
|
+
|
62
|
+
form: function(req_path, req_method) {
|
63
|
+
if (!(req_method)) req_method = 'get';
|
64
|
+
if (req_path.indexOf('?') >= 0) {
|
65
|
+
req_path += '&inline=1';
|
66
|
+
} else {
|
67
|
+
req_path += '?inline=1';
|
68
|
+
}
|
69
|
+
|
70
|
+
// first request should return HTML.
|
71
|
+
$.ajax({
|
72
|
+
method: req_method.toUpperCase(),
|
73
|
+
url: req_path,
|
74
|
+
dataType: 'html',
|
75
|
+
success: function (data, status, xhr) {
|
76
|
+
inclineInline._handle_form_response(data, status, xhr);
|
77
|
+
},
|
78
|
+
error: function (xhr, status, error) {
|
79
|
+
inclineInline._handle_error(status, error);
|
80
|
+
}
|
81
|
+
});
|
82
|
+
},
|
83
|
+
|
84
|
+
_handle_json_result: function(data) {
|
85
|
+
var ts = Math.round((new Date().getTime() / 100) % 864000, 0);
|
86
|
+
var i;
|
87
|
+
if (data.invalidRequest) {
|
88
|
+
// Should probably come up with a more informative alert.
|
89
|
+
this._handle_error('invalid request', 'invalid request');
|
90
|
+
} else {
|
91
|
+
// build alerts that clear after 5 seconds.
|
92
|
+
if (data.messages) {
|
93
|
+
var messageCount = data.messages.length;
|
94
|
+
var alertDiv = $('#incline_dynamic_alerts');
|
95
|
+
for (i = 0; i < messageCount; i++) {
|
96
|
+
var message = data.messages[i];
|
97
|
+
var html = '<div id="alert-' + ts.toString() + '" class="alert alert-' + escapeHTML(message.type) + ' alert-dismissible fade in" role="alert">' +
|
98
|
+
'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>' +
|
99
|
+
escapeHTML(message.text) +
|
100
|
+
'</div>';
|
101
|
+
var close = '$(\'#alert-' + ts.toString() + '\').alert(\'close\');';
|
102
|
+
alertDiv.prepend(html);
|
103
|
+
window.setTimeout(close, 5000);
|
104
|
+
ts++;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
// update rows in the data table.
|
108
|
+
if (data.data) {
|
109
|
+
var dataCount = data.data.length;
|
110
|
+
for (i = 0; i < dataCount; i++) {
|
111
|
+
var item = data.data[i];
|
112
|
+
var row = $('#' + item.DT_RowId);
|
113
|
+
if (row.length > 0) {
|
114
|
+
var table = row.parents('table');
|
115
|
+
if ($.fn.dataTable.isDataTable(table))
|
116
|
+
{
|
117
|
+
var table_id = table.attr('id');
|
118
|
+
table = table.dataTable().api();
|
119
|
+
if (item.DT_RowAction === 'remove') {
|
120
|
+
table.row('#' + item.DT_RowId).remove(); // remove the row from the DT.
|
121
|
+
table.draw('page'); // refresh the current page.
|
122
|
+
} else {
|
123
|
+
table.row('#' + item.DT_RowId).data(item); // refresh the row in the DT.
|
124
|
+
inclineInline._go_to_record(item); // find and hilight the record.
|
125
|
+
}
|
126
|
+
}
|
127
|
+
} else if (dataCount == 1) {
|
128
|
+
// no row found and there is only one record returned, focus on that record.
|
129
|
+
inclineInline._go_to_record(item);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
}
|
134
|
+
},
|
135
|
+
|
136
|
+
_handle_form_response: function (data, status, xhr) {
|
137
|
+
var type = xhr.getResponseHeader('Content-Type').toLowerCase().trim();
|
138
|
+
if (type.indexOf(';') >= 0)
|
139
|
+
type = type.substring(0, type.indexOf(';')).trim();
|
140
|
+
|
141
|
+
if (type === 'application/json') {
|
142
|
+
// json response
|
143
|
+
this._destroy_dialog();
|
144
|
+
this._handle_json_result(data);
|
145
|
+
} else if (type === 'text/html') {
|
146
|
+
// html response
|
147
|
+
this._set_dialog(data);
|
148
|
+
} else {
|
149
|
+
// unsupported response
|
150
|
+
this._destroy_dialog();
|
151
|
+
this._handle_error('invalid response', 'invalid response');
|
152
|
+
}
|
153
|
+
},
|
154
|
+
|
155
|
+
_handle_error: function (status, error) {
|
156
|
+
this._destroy_dialog(); // no matter what, the dialog should be destroyed.
|
157
|
+
|
158
|
+
// Should probably come up with more informative error alerts.
|
159
|
+
if (status === 'error') {
|
160
|
+
alert(error);
|
161
|
+
} else {
|
162
|
+
alert(status);
|
163
|
+
}
|
164
|
+
},
|
165
|
+
|
166
|
+
_dialog: false,
|
167
|
+
|
168
|
+
_create_dialog: function () {
|
169
|
+
if (!(this._dialog))
|
170
|
+
{
|
171
|
+
var body = $('body');
|
172
|
+
var modal = $('<div class="modal fade" id="incline_inline_form" tabindex="-1" role="dialog" aria-labelledby="incline_inline_form_title" style="display: none;">' +
|
173
|
+
'<div class="modal-dialog" role="document">' +
|
174
|
+
'<div class="modal-content">' +
|
175
|
+
'<div class="modal-header">' +
|
176
|
+
'<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>' +
|
177
|
+
'<h4 class="modal-title" id="incline_inline_form_title"></h4>' +
|
178
|
+
'</div>' +
|
179
|
+
'<div class="modal-body" id="incline_inline_form_body"></div>' +
|
180
|
+
'<div class="modal-footer" id="incline_inline_form_footer"></div>' +
|
181
|
+
'</div></div></div>');
|
182
|
+
|
183
|
+
body.prepend(modal);
|
184
|
+
modal = $('#incline_inline_form');
|
185
|
+
modal.on('hidden.bs.modal', function (e) {
|
186
|
+
modal.remove();
|
187
|
+
inclineInline._dialog = false;
|
188
|
+
});
|
189
|
+
this._dialog = true;
|
190
|
+
}
|
191
|
+
},
|
192
|
+
|
193
|
+
_set_dialog: function (html) {
|
194
|
+
var title;
|
195
|
+
var body;
|
196
|
+
var footer;
|
197
|
+
var tmp;
|
198
|
+
var dup;
|
199
|
+
var panel;
|
200
|
+
var panel_parent;
|
201
|
+
var align_regex = /^(.*\s)?(row(\s.*)?|col-(xs|sm|md|lg)-.*)$/;
|
202
|
+
var panel_regex = /^(.*\s)?panel(\s.*)?$/;
|
203
|
+
|
204
|
+
// add html to DOM under a hidden div for processing.
|
205
|
+
tmp = $('<div></div>').css('display','none');
|
206
|
+
$('body').append(tmp);
|
207
|
+
tmp.html(html);
|
208
|
+
html = tmp;
|
209
|
+
|
210
|
+
this._create_dialog();
|
211
|
+
|
212
|
+
// get the parts of the modal to update.
|
213
|
+
title = $('#incline_inline_form_title');
|
214
|
+
body = $('#incline_inline_form_body');
|
215
|
+
footer = $('#incline_inline_form_footer');
|
216
|
+
|
217
|
+
// reset
|
218
|
+
title.text('');
|
219
|
+
body.empty();
|
220
|
+
footer.empty();
|
221
|
+
|
222
|
+
tmp = html.find('form');
|
223
|
+
if (tmp.length == 1) { // support one and only one form in the resulting HTML.
|
224
|
+
// we have a form in the html that needs to be modified accordingly.
|
225
|
+
var form_method = tmp.attr('method');
|
226
|
+
var form_url = tmp.attr('action');
|
227
|
+
var form_id = tmp.attr('id');
|
228
|
+
|
229
|
+
// make sure the inline parameter is set.
|
230
|
+
tmp.append('<input type="hidden" name="inline" value="1" />');
|
231
|
+
|
232
|
+
// override submit to make sure the submission occurs via ajax.
|
233
|
+
tmp.submit(function (e) {
|
234
|
+
var form_data = $('#' + form_id).serialize();
|
235
|
+
e.preventDefault();
|
236
|
+
|
237
|
+
// prevent double submission.
|
238
|
+
tmp.find('input,button,select,textarea').prop('disabled', true);
|
239
|
+
|
240
|
+
$.ajax({
|
241
|
+
type: form_method.toUpperCase(),
|
242
|
+
url: form_url,
|
243
|
+
data: form_data,
|
244
|
+
success: function(data, status, xhr) {
|
245
|
+
inclineInline._handle_form_response(data, status, xhr);
|
246
|
+
},
|
247
|
+
error: function(xhr, status, error) {
|
248
|
+
inclineInline._handle_error(status, error);
|
249
|
+
}
|
250
|
+
});
|
251
|
+
});
|
252
|
+
}
|
253
|
+
|
254
|
+
// cancel links and buttons
|
255
|
+
tmp = html.find('a,button,input[type=button]').filter(function() { return $(this).text().toLowerCase() === 'cancel'; });
|
256
|
+
if (tmp.length > 0) {
|
257
|
+
tmp.click(function (e) {
|
258
|
+
e.preventDefault();
|
259
|
+
inclineInline._destroy_dialog();
|
260
|
+
});
|
261
|
+
}
|
262
|
+
|
263
|
+
// global title recognition, first H1 or H2 element.
|
264
|
+
tmp = html.find('h1');
|
265
|
+
if (tmp.length < 1) tmp = html.find('h2');
|
266
|
+
if (tmp.length > 0) {
|
267
|
+
tmp = tmp.first();
|
268
|
+
title.text(tmp.text());
|
269
|
+
// only remove if there is no additional HTML markup.
|
270
|
+
if (tmp.html() === tmp.text())
|
271
|
+
{
|
272
|
+
tmp.remove();
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
// put the error messages in place.
|
277
|
+
tmp = html.find('#error_explanation');
|
278
|
+
if (tmp.length > 0) {
|
279
|
+
tmp.detach();
|
280
|
+
body.prepend(tmp);
|
281
|
+
}
|
282
|
+
|
283
|
+
// put the alert messages in place.
|
284
|
+
tmp = html.find('.alert');
|
285
|
+
if (tmp.length > 0) {
|
286
|
+
tmp.detach();
|
287
|
+
body.prepend(tmp);
|
288
|
+
}
|
289
|
+
|
290
|
+
// remove outside alignment DIVs.
|
291
|
+
while ((tmp = html.children()) && tmp.length == 1 && align_regex.test(tmp.attr('class'))) {
|
292
|
+
tmp.detach();
|
293
|
+
html.append(tmp.children());
|
294
|
+
}
|
295
|
+
|
296
|
+
// If the html has one child and that child is a form, then look inside the form.
|
297
|
+
panel_parent = html;
|
298
|
+
panel = panel_parent.children();
|
299
|
+
if (panel.length == 1 && panel[0].tagName.toUpperCase() === 'FORM') {
|
300
|
+
panel_parent = panel;
|
301
|
+
panel = panel_parent.children(':not(input[type=hidden])'); // ignore hidden inputs
|
302
|
+
}
|
303
|
+
|
304
|
+
// now if there is only one child and that child is a panel, we can rip it apart.
|
305
|
+
if (panel.length == 1 && panel[0].tagName.toUpperCase() === 'DIV' && panel_regex.test(panel.attr('class'))) {
|
306
|
+
panel.detach();
|
307
|
+
|
308
|
+
if ((tmp = panel.children('.panel-heading')) && tmp.length > 0) {
|
309
|
+
title.text(tmp.text());
|
310
|
+
}
|
311
|
+
|
312
|
+
tmp = panel.children('table,.panel-body');
|
313
|
+
if (tmp.length > 0) {
|
314
|
+
tmp.removeClass('panel-body');
|
315
|
+
tmp.detach();
|
316
|
+
panel_parent.append(tmp);
|
317
|
+
}
|
318
|
+
|
319
|
+
tmp = panel.children('.panel-footer');
|
320
|
+
if (tmp.length > 0) {
|
321
|
+
tmp.removeClass('panel-footer');
|
322
|
+
tmp.detach();
|
323
|
+
// now we have a conundrum.
|
324
|
+
if (panel_parent[0].tagName.toUpperCase() === 'FORM') {
|
325
|
+
// since the footer might contain controls for the form, we need it to be in the form.
|
326
|
+
panel_parent.append(tmp);
|
327
|
+
} else {
|
328
|
+
// or the form doesn't wrap the footer, so we can just use the footer.
|
329
|
+
footer.append(tmp.children());
|
330
|
+
}
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
334
|
+
// we are done modifying the HTML and we can add it.
|
335
|
+
html.detach();
|
336
|
+
body.append(html.contents());
|
337
|
+
|
338
|
+
// footer should only be visible if it has contents.
|
339
|
+
if (footer.children().length > 0 || footer.text() !== '') {
|
340
|
+
footer.show();
|
341
|
+
} else {
|
342
|
+
footer.hide();
|
343
|
+
}
|
344
|
+
|
345
|
+
// make sure the dialog is visible.
|
346
|
+
tmp = $('#incline_inline_form');
|
347
|
+
if (tmp.is(':hidden')) {
|
348
|
+
tmp.modal('show');
|
349
|
+
tmp.on('shown.bs.modal', function () {
|
350
|
+
activateClassedItems(tmp);
|
351
|
+
});
|
352
|
+
} else {
|
353
|
+
// make sure the classed items are activated.
|
354
|
+
activateClassedItems(tmp);
|
355
|
+
}
|
356
|
+
},
|
357
|
+
|
358
|
+
_destroy_dialog: function () {
|
359
|
+
if (this._dialog) {
|
360
|
+
var dlg = $('#incline_inline_form');
|
361
|
+
if (dlg.length > 0) {
|
362
|
+
if (dlg.is(':hidden')) {
|
363
|
+
dlg.remove();
|
364
|
+
} else {
|
365
|
+
dlg.modal('hide');
|
366
|
+
}
|
367
|
+
}
|
368
|
+
this._dialog = false;
|
369
|
+
}
|
370
|
+
},
|
371
|
+
|
372
|
+
_go_to_record: function (data) {
|
373
|
+
var table = $('table.dataTable');
|
374
|
+
var params;
|
375
|
+
var i;
|
376
|
+
var row_id = '#' + data.DT_RowId;
|
377
|
+
|
378
|
+
if (table.length < 1) return;
|
379
|
+
|
380
|
+
table = table.dataTable().api();
|
381
|
+
|
382
|
+
i = data.DT_RowId.lastIndexOf('_');
|
383
|
+
|
384
|
+
params = table.ajax.params();
|
385
|
+
params.draw = -1;
|
386
|
+
params.locate_id = data.DT_RowId.substring(i + 1);
|
387
|
+
|
388
|
+
$.ajax({
|
389
|
+
url: data.DT_Path + '/locate',
|
390
|
+
method: 'POST',
|
391
|
+
dataType: 'json',
|
392
|
+
data: params,
|
393
|
+
success: function(data) {
|
394
|
+
var recNum = data.record;
|
395
|
+
if (recNum > -1) {
|
396
|
+
var pageLen = table.page.len();
|
397
|
+
var pageNum;
|
398
|
+
|
399
|
+
if (pageLen < 1) return;
|
400
|
+
|
401
|
+
// avoid division by zero.
|
402
|
+
if (recNum === 0) {
|
403
|
+
pageNum = 0;
|
404
|
+
} else {
|
405
|
+
pageNum = Math.floor(recNum / pageLen);
|
406
|
+
}
|
407
|
+
|
408
|
+
// set the page number and refresh the datatable only if we are on a different page or the row isn't visible.
|
409
|
+
if (table.page() != pageNum || $(row_id).length < 1) {
|
410
|
+
table.page(pageNum).draw('page');
|
411
|
+
}
|
412
|
+
|
413
|
+
// hilite the row (give DOM a quick chance to update).
|
414
|
+
window.setTimeout(function() { inclineInline._hilite_fade(row_id); }, 250 );
|
415
|
+
}
|
416
|
+
}
|
417
|
+
});
|
418
|
+
|
419
|
+
},
|
420
|
+
|
421
|
+
_hilite_fade: function (selector) {
|
422
|
+
// 2s hilite pulse from any bg color to yellow and then back.
|
423
|
+
$(selector).addClass('cell-fade').addClass('cell-hilite');
|
424
|
+
window.setTimeout(function() {
|
425
|
+
$(selector).removeClass('cell-hilite');
|
426
|
+
window.setTimeout(function() {
|
427
|
+
$(selector).removeClass('cell-fade');
|
428
|
+
}, 1000);
|
429
|
+
}, 1000);
|
430
|
+
},
|
431
|
+
};
|
432
|
+
|
433
|
+
/*
|
434
|
+
* Generates an AJAX request to load an HTML fragment from the server.
|
435
|
+
* When the HTML fragment is returned, it is displayed in a modal dialog over the current page.
|
436
|
+
* If a form is present in the returned HTML, the 'submit' event is hooked to submit inline via AJAX.
|
437
|
+
* If the form submission returns HTML, the returned HTML overwrites the previous HTML.
|
438
|
+
* If the form submission returns JSON, the JSON is is used to update the page.
|
439
|
+
*/
|
440
|
+
function inlineForm(req_path,req_method) {
|
441
|
+
inclineInline.form(req_path, req_method);
|
442
|
+
}
|
443
|
+
|
444
|
+
/*
|
445
|
+
* Generates an AJAX request to the server and expects a JSON result.
|
446
|
+
* The JSON is used to update the page.
|
447
|
+
*/
|
448
|
+
function inlineAction(path, method) {
|
449
|
+
inclineInline.action(path, method);
|
450
|
+
}
|
451
|
+
|
452
|
+
(function ($){
|
453
|
+
// inlineAction should return JSON data.
|
454
|
+
// If "invalidRequest" is set in the response then an alert is generated.
|
455
|
+
// Otherwise, if "messages" are set in the response then we display them.
|
456
|
+
$.fn.inlineAction = function () {
|
457
|
+
var item = $(this);
|
458
|
+
var path = item.attr('href');
|
459
|
+
var method = item.attr('data-method');
|
460
|
+
if (!(method)) method = 'get';
|
461
|
+
|
462
|
+
item.click(function (e) {
|
463
|
+
e.preventDefault();
|
464
|
+
inclineInline.action(path, method);
|
465
|
+
});
|
466
|
+
};
|
467
|
+
$.fn.inlineForm = function () {
|
468
|
+
var item =$(this);
|
469
|
+
var path = item.attr('href');
|
470
|
+
var method = item.attr('data-method');
|
471
|
+
if (!(method)) method = 'get';
|
472
|
+
|
473
|
+
item.click(function (e) {
|
474
|
+
e.preventDefault();
|
475
|
+
inclineInline.form(path, method);
|
476
|
+
});
|
477
|
+
};
|
478
|
+
})(jQuery);
|
479
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
/*
|
2
|
+
* @name DoubleScroll
|
3
|
+
* @desc displays scroll bar on top and on the bottom of the div
|
4
|
+
* @requires jQuery
|
5
|
+
*
|
6
|
+
* @author Pawel Suwala - http://suwala.eu/
|
7
|
+
* @author Antoine Vianey - http://www.astek.fr/
|
8
|
+
* @version 0.4 (18-06-2014)
|
9
|
+
*
|
10
|
+
* Dual licensed under the MIT and GPL licenses:
|
11
|
+
* http://www.opensource.org/licenses/mit-license.php
|
12
|
+
* http://www.gnu.org/licenses/gpl.html
|
13
|
+
*
|
14
|
+
* Usage:
|
15
|
+
* https://github.com/avianey/jqDoubleScroll
|
16
|
+
*/
|
17
|
+
|
18
|
+
jQuery.fn.doubleScroll = function(userOptions) {
|
19
|
+
var $ = jQuery;
|
20
|
+
// Default options
|
21
|
+
var options = {
|
22
|
+
contentElement: undefined, // Widest element, if not specified first child element will be used
|
23
|
+
scrollCss: {
|
24
|
+
'overflow-x': 'auto',
|
25
|
+
'overflow-y': 'hidden'
|
26
|
+
},
|
27
|
+
contentCss: {
|
28
|
+
'overflow-x': 'auto',
|
29
|
+
'overflow-y': 'hidden'
|
30
|
+
},
|
31
|
+
onlyIfScroll: true, // top scrollbar is not shown if the bottom one is not present
|
32
|
+
resetOnWindowResize: false, // recompute the top ScrollBar requirements when the window is resized
|
33
|
+
timeToWaitForResize: 30 // wait for the last update event (usefull when browser fire resize event constantly during ressing)
|
34
|
+
};
|
35
|
+
$.extend(true, options, userOptions);
|
36
|
+
// do not modify
|
37
|
+
// internal stuff
|
38
|
+
$.extend(options, {
|
39
|
+
topScrollBarMarkup: '<div class="doubleScroll-scroll-wrapper" style="height: 20px;"><div class="doubleScroll-scroll" style="height: 20px;"></div></div>',
|
40
|
+
topScrollBarWrapperSelector: '.doubleScroll-scroll-wrapper',
|
41
|
+
topScrollBarInnerSelector: '.doubleScroll-scroll'
|
42
|
+
});
|
43
|
+
|
44
|
+
var _showScrollBar = function($self, options) {
|
45
|
+
|
46
|
+
if (options.onlyIfScroll && $self.get(0).scrollWidth <= $self.width()) {
|
47
|
+
// content doesn't scroll
|
48
|
+
// remove any existing occurrence...
|
49
|
+
$self.prev(options.topScrollBarWrapperSelector).remove();
|
50
|
+
return;
|
51
|
+
}
|
52
|
+
|
53
|
+
// add div that will act as an upper scroll only if not already added to the DOM
|
54
|
+
var $topScrollBar = $self.prev(options.topScrollBarWrapperSelector);
|
55
|
+
if ($topScrollBar.length == 0) {
|
56
|
+
|
57
|
+
// creating the scrollbar
|
58
|
+
// added before in the DOM
|
59
|
+
$topScrollBar = $(options.topScrollBarMarkup);
|
60
|
+
$self.before($topScrollBar);
|
61
|
+
|
62
|
+
// apply the css
|
63
|
+
$topScrollBar.css(options.scrollCss);
|
64
|
+
$self.css(options.contentCss);
|
65
|
+
|
66
|
+
// bind upper scroll to bottom scroll
|
67
|
+
$topScrollBar.bind('scroll.doubleScroll', function() {
|
68
|
+
$self.scrollLeft($topScrollBar.scrollLeft());
|
69
|
+
});
|
70
|
+
|
71
|
+
// bind bottom scroll to upper scroll
|
72
|
+
var selfScrollHandler = function() {
|
73
|
+
$topScrollBar.scrollLeft($self.scrollLeft());
|
74
|
+
};
|
75
|
+
$self.bind('scroll.doubleScroll', selfScrollHandler);
|
76
|
+
}
|
77
|
+
|
78
|
+
// find the content element (should be the widest one)
|
79
|
+
var $contentElement;
|
80
|
+
if (options.contentElement !== undefined && $self.find(options.contentElement).length !== 0) {
|
81
|
+
$contentElement = $self.find(options.contentElement);
|
82
|
+
} else {
|
83
|
+
$contentElement = $self.find('>:first-child');
|
84
|
+
}
|
85
|
+
|
86
|
+
// set the width of the wrappers
|
87
|
+
$(options.topScrollBarInnerSelector, $topScrollBar).width($contentElement.outerWidth());
|
88
|
+
$topScrollBar.width($self.width());
|
89
|
+
$topScrollBar.scrollLeft($self.scrollLeft());
|
90
|
+
|
91
|
+
};
|
92
|
+
|
93
|
+
return this.each(function() {
|
94
|
+
var $self = $(this);
|
95
|
+
_showScrollBar($self, options);
|
96
|
+
|
97
|
+
// bind the resize handler
|
98
|
+
// do it once
|
99
|
+
if (options.resetOnWindowResize) {
|
100
|
+
var id;
|
101
|
+
var handler = function(e) {
|
102
|
+
_showScrollBar($self, options);
|
103
|
+
};
|
104
|
+
$(window).bind('resize.doubleScroll', function() {
|
105
|
+
// adding/removing/replacing the scrollbar might resize the window
|
106
|
+
// so the resizing flag will avoid the infinite loop here...
|
107
|
+
clearTimeout(id);
|
108
|
+
id = setTimeout(handler, options.timeToWaitForResize);
|
109
|
+
});
|
110
|
+
}
|
111
|
+
});
|
112
|
+
};
|