pg_rails 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +73 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/javascripts/pg_rails/asociacion_creable.js +85 -0
  6. data/app/assets/javascripts/pg_rails/best_in_place_datepicker.js +58 -0
  7. data/app/assets/javascripts/pg_rails/librerias.js +13 -0
  8. data/app/assets/javascripts/pg_rails/librerias_b3.js +14 -0
  9. data/app/assets/javascripts/pg_rails/validaciones.js +44 -0
  10. data/app/assets/javascripts/pg_rails.js +318 -0
  11. data/app/assets/stylesheets/pg_rails/librerias.scss +5 -0
  12. data/app/assets/stylesheets/pg_rails/pg_chosen.scss +29 -0
  13. data/app/assets/stylesheets/pg_rails/pg_rails.scss +199 -0
  14. data/app/assets/stylesheets/pg_rails_b3.scss +10 -0
  15. data/app/assets/stylesheets/pg_rails_b4.scss +12 -0
  16. data/app/assets/stylesheets/pg_rails_b5.scss +1 -0
  17. data/app/controllers/pg_rails/application_controller.rb +316 -0
  18. data/app/controllers/pg_rails/editar_en_lugar_controller.rb +24 -0
  19. data/app/decorators/pg_rails/base_decorator.rb +120 -0
  20. data/app/helpers/pg_rails/editar_en_lugar_helper.rb +106 -0
  21. data/app/helpers/pg_rails/form_helper.rb +25 -0
  22. data/app/helpers/pg_rails/postgres_helper.rb +15 -0
  23. data/app/helpers/pg_rails/print_helper.rb +176 -0
  24. data/app/inputs/pg_rails/asociacion_creable_input.rb +72 -0
  25. data/app/inputs/pg_rails/fecha_input.rb +20 -0
  26. data/app/inputs/pg_rails/selects_dependientes_input.rb +9 -0
  27. data/app/lib/pg_form_builder.rb +31 -0
  28. data/app/lib/pg_rails/filtros_builder.rb +338 -0
  29. data/app/models/pg_rails/application_record.rb +51 -0
  30. data/app/policies/pg_rails/application_policy.rb +104 -0
  31. data/app/views/application/_abrir_modal.js.erb +14 -0
  32. data/app/views/application/_actualizar_smart_listing.html.slim +3 -0
  33. data/app/views/application/_cerrar_modal.js.erb +8 -0
  34. data/app/views/application/_modal_ajax_form.js.erb +7 -0
  35. data/config/brakeman.ignore +42 -0
  36. data/config/locales/es.yml +17 -0
  37. data/config/routes.rb +3 -0
  38. data/config/spring.rb +1 -0
  39. data/lib/pg_rails/configuracion.rb +24 -0
  40. data/lib/pg_rails/core_ext.rb +17 -0
  41. data/lib/pg_rails/engine.rb +42 -0
  42. data/lib/pg_rails/simple_form/initializer.rb +583 -0
  43. data/lib/pg_rails/utils/logueador.rb +39 -0
  44. data/lib/pg_rails/version.rb +5 -0
  45. data/lib/pg_rails.rb +23 -0
  46. data/lib/tasks/auto_anotar_modelos.rake +34 -0
  47. data/lib/tasks/pg_rails_tasks.rake +5 -0
  48. metadata +89 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7c90f078b433e7dd978b63f547224e2a1d101d106ac6a8427b69878f3a2a206d
4
+ data.tar.gz: f215ee9ca33ed7598e2251877b2ee3b0c3694349aded4515b0a24e2a0362b100
5
+ SHA512:
6
+ metadata.gz: 5e0cd23bbf7ce79fb2e5dcaa73b7c0d9c24ca87811b46daf20c73dc72315a4d707145f178a976bcb89ea23a55431ff31d951a140ab5838771a0b3d35f95169c1
7
+ data.tar.gz: 85f3141ae4506303936a93b078e8d0f6a9254c2b50784b9f158672db90e6f446e2087624229f1e4ef682beb4c4ccd41d94785454d991ec2b5c4572997395826d
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Martín Rosso
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,73 @@
1
+ [![CircleCI](https://circleci.com/gh/programandoarg/pg_rails.svg?style=shield)](https://circleci.com/gh/programandoarg/pg_rails)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/2a3081a26ca2ab9feac6/maintainability)](https://codeclimate.com/github/programandoarg/pg_rails/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/2a3081a26ca2ab9feac6/test_coverage)](https://codeclimate.com/github/programandoarg/pg_rails/test_coverage)
4
+ # PgRails
5
+ Plugin de Programando para Rails
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'pg_rails', git: 'https://github.com/programandoarg/pg_rails.git', ref: '<commit hash>'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+ ## Uso
19
+
20
+ ### Asociación creable
21
+
22
+ ```
23
+ f.asociacion_creable(campo, index_url, new_url, opciones)
24
+ ```
25
+
26
+ Opciones:
27
+ - label: Texto para la label o false para que no haya label
28
+
29
+ Ejemplo:
30
+ ```
31
+ = pg_form_for(@cosa) do |f|
32
+ = f.asociacion_creable(:categoria_de_cosa, categoria_de_cosas_url, new_categoria_de_cosa_url, crear_asociado: true)
33
+ ```
34
+
35
+ ## Contributing
36
+
37
+ ### Setup
38
+
39
+ 1. Ingresar a la consola de postgres:
40
+ ```
41
+ sudo -u postgres psql template1
42
+ ```
43
+ 2. Crear el rol
44
+ ```
45
+ create role pgrails password 'pgrails' login superuser;
46
+ ```
47
+
48
+ 3. Ejecutar el script `bin/setup`. This script will:
49
+
50
+ * Check you have the required Ruby version
51
+ * Install dependencies using Bundler
52
+ * Create a `.env.development` file
53
+ * Create, migrate, and seed the database
54
+
55
+ ### Testear y ejecutar
56
+
57
+ 1. Instalar overcommit: `gem install overcommit`
58
+ 2. Correr los linters con `overcommit -r`
59
+ 3. Correr los tests con `bundle exec rspec`
60
+ 4. Instalar foreman: `gem install foreman`
61
+ 5. `cd spec/dummy`
62
+ 6. `foreman start`
63
+
64
+ Acceder a la app en <http://localhost:3000/>.
65
+
66
+ ### Regenerar modelos dummy
67
+
68
+ 1. `bundle exec rails destroy Cosa`
69
+ 2. `bundle exec rails destroy CategoriaDeCosa`
70
+ 3. Borrar policies
71
+ 4. `rails g pg_scaffold CategoriaDeCosa nombre:string{required} "tipo:integer{enum,required}" fecha:date tiempo:datetime --discard`
72
+ 5. `rails g pg_scaffold Cosa nombre:string{required} "tipo:integer{enum,required}" categoria_de_cosa:references{required} --discard`
73
+ 6. Setup asociacion creable en cosas/_form
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rdoc/task'
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = 'rdoc'
13
+ rdoc.title = 'PgRails'
14
+ rdoc.options << '--line-numbers'
15
+ rdoc.rdoc_files.include('README.md')
16
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
+ end
18
+
19
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
20
+ load 'rails/tasks/engine.rake'
21
+
22
+ load 'rails/tasks/statistics.rake'
23
+
24
+ require 'bundler/gem_tasks'
25
+
26
+ require 'rake/testtask'
27
+
28
+ load 'lib/tasks/auto_anotar_modelos.rake'
29
+
30
+ # Rake::TestTask.new(:test) do |t|
31
+ # t.libs << 'test'
32
+ # t.pattern = 'test/**/*_test.rb'
33
+ # t.verbose = false
34
+ # end
35
+
36
+ task default: :test
@@ -0,0 +1,85 @@
1
+ window.AsociacionCreable = new function() {
2
+ asociacion_creable = this;
3
+ asociacion_creable.bindear = function(contexto) {
4
+ $(contexto).find('.crear_asociado').click(function() {
5
+ var boton_crear = this;
6
+ $.get($(this).data('url') + "?sin_layout=true").done(function(response) {
7
+ var modal = pg_rails.abrir_modal(response);
8
+ PgRails.bindear(modal);
9
+ modal.find('form').ajaxForm({
10
+ dataType: 'json',
11
+ success: function(responseJSON, statusText, xhr) {
12
+ var input_oculto = $(boton_crear).closest('.form-group').find('input.oculto');
13
+ var input_visible = $(boton_crear).closest('.form-group').find('input:not(.oculto)');
14
+ input_oculto.val(responseJSON['id']);
15
+ input_visible.val(responseJSON['to_s']);
16
+ $(modal).modal('hide');
17
+ // $(modal).modal('dispose');
18
+ $(modal).remove();
19
+ $(boton_crear).closest('.asociacion_creable').trigger('change', responseJSON);
20
+ PgRails.showToast('Elemento creado.')
21
+ },
22
+ error: function(response, status, statusText) {
23
+ for( var i in response.responseJSON) {
24
+ pg_rails.showToast(response.responseJSON[i]);
25
+ }
26
+ modal.find('form input[type=submit]').attr('disabled', null)
27
+ }
28
+ });
29
+ })
30
+ });
31
+
32
+ $(contexto).find('.borrar_seleccion').click(function() {
33
+ var input_oculto = $(this).closest('.form-group').find('input.oculto');
34
+ var input_visible = $(this).closest('.form-group').find('input:not(.oculto)');
35
+ $(this).closest('.form-group').removeClass('completado');
36
+ input_oculto.val(null);
37
+ input_visible.val(null);
38
+ $(this).closest('.asociacion_creable').trigger('change', null);
39
+ });
40
+ $(contexto).find('.seleccionar_asociado').click(function() {
41
+ var boton_seleccionar = this;
42
+ var url = new URL($(this).data('url'));
43
+ url.searchParams.set("sin_layout", "true");
44
+ $.get(url, null, null, 'html').done(function(response) {
45
+ var modal = pg_rails.abrir_modal(response, "Seleccionar", { dialog_class: 'modal-xl modal-lg modal-seleccionar-asociado' });
46
+ PgRails.bindear(modal);
47
+ var elemento_seleccionado = function() {
48
+ var id = $(this).closest('tr').data('id');
49
+ if(!id) {
50
+ console.error("La fila no tiene ID")
51
+ return
52
+ }
53
+ var url = new URL($(boton_seleccionar).data('url'));
54
+ url.pathname += "/" + id + '.json';
55
+ $.get(url).done(function(response) {
56
+ var input_oculto = $(boton_seleccionar).closest('.form-group').find('input.oculto');
57
+ var input_visible = $(boton_seleccionar).closest('.form-group').find('input:not(.oculto)');
58
+ input_oculto.val(id);
59
+ if( response.to_s ) {
60
+ input_visible.val(response.to_s);
61
+ } else {
62
+ console.error('El JSON no tiene to_s')
63
+ input_visible.val("#" + response.id);
64
+ }
65
+ $(boton_seleccionar).closest('.form-group').addClass('completado');
66
+ // select.html('<option value="'+id+'">'+response.to_s+'</option>');
67
+ $(modal).modal('hide');
68
+ // $(modal).modal('dispose');
69
+ $(modal).remove();
70
+ $(boton_seleccionar).closest('.asociacion_creable').trigger('change', response);
71
+ }).fail(function() {
72
+ pg_rails.error_toast("Hubo un error");
73
+ });
74
+ }
75
+
76
+ modal.find(SmartListing.config.class_name("main")).smart_listing()
77
+ modal.find(SmartListing.config.class_name("controls")).smart_listing_controls()
78
+ modal.find(SmartListing.config.class_name("main")).on('ajax:success smart_listing:update_list', function() {
79
+ $(this).find('td').click(elemento_seleccionado);
80
+ })
81
+ modal.find('td').click(elemento_seleccionado);
82
+ })
83
+ });
84
+ }
85
+ }
@@ -0,0 +1,58 @@
1
+ // Datepicker para los editores de fecha de best_in_place
2
+ // Es una copia modificada de best_in_place.jquery-ui
3
+
4
+ BestInPlaceEditor.forms.date = {
5
+ activateForm: function () {
6
+ 'use strict';
7
+ var that = this,
8
+ output = jQuery(document.createElement('form'))
9
+ .addClass('form_in_place')
10
+ .attr('action', 'javascript:void(0);')
11
+ .attr('style', 'display:inline'),
12
+ input_elt = jQuery(document.createElement('input'))
13
+ .attr('type', 'text')
14
+ .attr('name', this.attributeName)
15
+ .attr('value', this.sanitizeValue(this.display_value));
16
+ // .attr('value', this.sanitizeValue(moment(this.display_value).format('DD/MM/YYYY')));
17
+ if (this.inner_class !== null) {
18
+ input_elt.addClass(this.inner_class);
19
+ }
20
+ output.append(input_elt);
21
+
22
+ this.element.html(output);
23
+ this.setHtmlAttributes();
24
+ this.element.find('input')[0].select();
25
+ this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.input.submitHandler);
26
+ this.element.find("input").bind('keyup', {editor: this}, BestInPlaceEditor.forms.input.keyupHandler);
27
+
28
+ this.element.find('input')
29
+ .datepicker({
30
+ 'format': 'dd/mm/yyyy',
31
+ 'todayBtn': 'linked',
32
+ 'autoclose': 'true',
33
+ 'language': 'es',
34
+ }).on('changeDate', function () {
35
+ $(this).datepicker('destroy');
36
+ that.update();
37
+ }).datepicker('show');
38
+ },
39
+
40
+ getValue: function () {
41
+ 'use strict';
42
+ return this.sanitizeValue(this.element.find("input").val());
43
+ },
44
+
45
+ submitHandler: function (event) {
46
+ 'use strict';
47
+ event.data.editor.update();
48
+ },
49
+
50
+ keyupHandler: function (event) {
51
+ 'use strict';
52
+ if (event.keyCode === 27) {
53
+ event.data.editor.abort();
54
+ }
55
+ }
56
+ }
57
+
58
+
@@ -0,0 +1,13 @@
1
+ //= require jquery3
2
+ //= require jquery_ujs
3
+ //= require bootstrap.bundle-4.4.1.min
4
+ //= require smart_listing
5
+ //= require best_in_place
6
+ //= require bootstrap-datepicker/core
7
+ //= require bootstrap-datepicker/locales/bootstrap-datepicker.es.js
8
+ //= require selectize
9
+ //= require jquery_nested_form
10
+ //= require jquery.form.min.js
11
+ //= require handlebars-4.7.6.min
12
+ //= require chosen
13
+ //= require pg_rails/best_in_place_datepicker
@@ -0,0 +1,14 @@
1
+ // Librerias javascript para proyectos con Bootstrap 3
2
+
3
+ //= require jquery3
4
+ //= require jquery_ujs
5
+ //= require smart_listing
6
+ //= require best_in_place
7
+ //= require bootstrap-datepicker/core
8
+ //= require bootstrap-datepicker/locales/bootstrap-datepicker.es.js
9
+ //= require selectize
10
+ //= require jquery_nested_form
11
+ //= require jquery.form.min.js
12
+ //= require handlebars-4.7.6.min
13
+ //= require chosen
14
+ //= require best_in_place_datepicker
@@ -0,0 +1,44 @@
1
+ //= require jquery-validation
2
+
3
+ $.extend( $.validator.messages, {
4
+ required: "Este campo es obligatorio.",
5
+ remote: "Por favor, completá este campo.",
6
+ email: "Por favor, escribí una dirección de correo válida.",
7
+ url: "Por favor, escribí una URL válida.",
8
+ date: "Por favor, escribí una fecha válida.",
9
+ dateISO: "Por favor, escribí una fecha (ISO) válida.",
10
+ number: "Por favor, escribí un número entero válido.",
11
+ digits: "Por favor, escribí sólo dígitos.",
12
+ creditcard: "Por favor, escribí un número de tarjeta válido.",
13
+ equalTo: "Por favor, escribí el mismo valor de nuevo.",
14
+ extension: "Por favor, escribí un valor con una extensión aceptada.",
15
+ maxlength: $.validator.format( "Por favor, no escribas más de {0} caracteres." ),
16
+ minlength: $.validator.format( "Por favor, no escribas menos de {0} caracteres." ),
17
+ rangelength: $.validator.format( "Por favor, escribí un valor entre {0} y {1} caracteres." ),
18
+ range: $.validator.format( "Por favor, escribí un valor entre {0} y {1}." ),
19
+ max: $.validator.format( "Por favor, escribí un valor menor o igual a {0}." ),
20
+ min: $.validator.format( "Por favor, escribí un valor mayor o igual a {0}." ),
21
+ nifES: "Por favor, escribí un NIF válido.",
22
+ nieES: "Por favor, escribí un NIE válido.",
23
+ cifES: "Por favor, escribí un CIF válido."
24
+ } );
25
+
26
+ $.validator.setDefaults({
27
+ ignore: ":hidden:not(select.chosen-select):not(.hidden-validation-field),.ignore-validation",
28
+ errorPlacement: function(error, element) {
29
+ var group = element.closest('.form-group');
30
+ if( group ) {
31
+ if( group.hasClass('row') ) {
32
+ error.appendTo( element.parent() );
33
+ } else {
34
+ error.appendTo( element.closest('.form-group') );
35
+ }
36
+ } else {
37
+ error.appendTo( element.parent() );
38
+ }
39
+ }
40
+ })
41
+ $.validator.addMethod("nestedPresence", function(value, element) {
42
+ return $(element).closest('.nested-container').find('.fields:not(.removed)').length > 0
43
+ }, "Este campo es obligatorio.");
44
+ $.validator.addClassRules("nested_presence", { nestedPresence: true });
@@ -0,0 +1,318 @@
1
+ //= require pg_rails/validaciones
2
+ //= require pg_rails/asociacion_creable
3
+
4
+ document.addEventListener("DOMContentLoaded", function(event) {
5
+ window.PgRails = new function() {
6
+ pg_rails = this
7
+ pg_rails.campo_dependiente_hacer = function(principal, dependiente, valor) {
8
+ if( principal.val() == valor ) {
9
+ dependiente.closest('.form-group').removeClass('ocultar')
10
+ } else {
11
+ dependiente.closest('.form-group').addClass('ocultar')
12
+ }
13
+ }
14
+ pg_rails.encolumnar = function(principal, dependiente) {
15
+ var fila = $('<div class="row">');
16
+ fila = fila.insertBefore(principal.closest('.form-group'));
17
+ var col1 = $('<div class="col-sm-6">');
18
+ var col2 = $('<div class="col-sm-6">');
19
+ col1.append(principal.closest('.form-group'));
20
+ col2.append(dependiente.closest('.form-group'));
21
+ fila.append(col1);
22
+ fila.append(col2);
23
+ }
24
+ pg_rails.campo_dependiente = function(campo, depende_de, valor) {
25
+ var principal = $('form.simple_form *[name*=' + depende_de + ']');
26
+ var dependiente = $('form.simple_form *[name*=' + campo + ']');
27
+ pg_rails.encolumnar(principal, dependiente)
28
+ principal.change(function() {
29
+ pg_rails.campo_dependiente_hacer(principal, dependiente, valor);
30
+ })
31
+ pg_rails.campo_dependiente_hacer(principal, dependiente, valor);
32
+ }
33
+ pg_rails.bindear = function(contexto) {
34
+ if(contexto == null) {
35
+ contexto = $('body');
36
+ } else {
37
+ contexto = $(contexto);
38
+ }
39
+ AsociacionCreable.bindear(contexto);
40
+ $(contexto).find('.listado a[data-method=delete]').click(function(e) {
41
+ var boton = this;
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+ var url = $(this).attr('href');
45
+ var confirmar = $(this).data('confirm');
46
+ if(!confirmar) {
47
+ confirmar = "¿Estás seguro?"
48
+ }
49
+ if( confirm(confirmar) ) {
50
+ $.ajax(url, {
51
+ dataType: 'json',
52
+ method: 'DELETE',
53
+ }).done(function(response) {
54
+ if($(boton).closest('.smart-listing').length > 0) {
55
+ $(boton).closest('.smart-listing').smart_listing().reload()
56
+ } else {
57
+ window.location.reload();
58
+ }
59
+ pg_rails.showToast("Elemento borrado");
60
+ }).fail(function(response) {
61
+ pg_rails.error_toast(response.responseJSON.error);
62
+ });
63
+ }
64
+ })
65
+ // $('.tooltip').remove();
66
+ // $("[rel=tooltip]").tooltip({ boundary: 'window' });
67
+ // $(contexto).find("[rel=tooltip]").tooltip();
68
+ $(contexto).find('form.pg-form').each(function(i,e) {
69
+ // $(e).validate();
70
+ });
71
+ if( typeof $.fn.best_in_place == 'function' ) {
72
+ $(contexto).find('table:has(.best_in_place)').css('table-layout', 'fixed');
73
+ $(contexto).find(".best_in_place").best_in_place();
74
+ $(contexto).find(".best_in_place").on('ajax:error', function(event, response) {
75
+ pg_rails.showToast("error", response.responseText)
76
+ });
77
+ $(contexto).find(".best_in_place").on('best_in_place:activate', function(event, response) {
78
+ var textarea = $(this).find('textarea');
79
+ if( textarea.length > 0 ) {
80
+ var valor = textarea.val();
81
+ valor = valor.replace(/<br>/g, "\n")
82
+ textarea.val(valor)
83
+ }
84
+ });
85
+ }
86
+ // $(".best_in_place").on('ajax:success', function(event, response) {
87
+ // pg_rails.showToast("success", "👍")
88
+ // });
89
+ if( typeof $.fn.datepicker == 'function' ) {
90
+ $.fn.datepicker.defaults.format = 'dd/mm/yyyy';
91
+ $(contexto).find('.datefield').datepicker({
92
+ 'format': 'dd/mm/yyyy',
93
+ 'todayBtn': 'linked',
94
+ 'autoclose': 'true',
95
+ 'language': 'es',
96
+ 'zIndexOffset': 2000,
97
+ });
98
+ $(contexto).find('.datefield').on('changeDate', function() {
99
+ $(this).keydown();
100
+ });
101
+ }
102
+
103
+ if( typeof($.fn.selectize) == 'function' ) {
104
+ $(contexto).find('select[multiple=multiple]').selectize();
105
+ }
106
+ if( typeof($.fn.chosen) == 'function' ) {
107
+ $(contexto).find(".chosen-select:visible").chosen('destroy');
108
+ $(contexto).find(".chosen-select:visible").chosen();
109
+ contexto.on('shown.bs.collapse', function() {
110
+ // Cuando hay un chosen en un collapse, lo inicializo al mostrarse
111
+ contexto.find('.chosen-select:visible').chosen();
112
+ })
113
+ }
114
+ $(contexto).find('form').dependent_fields();
115
+ contexto.find('.pg_ajax_link:not(.bindeado)').each(function(i, elem) {
116
+ $(this).addClass('bindeado');
117
+ $(this).click(function() {
118
+ $.get($(this).data('url'))
119
+ })
120
+ });
121
+ }
122
+
123
+ pg_rails.insert_options = function(element, options, default_option, template_id, atributo_nombre) {
124
+ if (options.length === 0) {
125
+ default_option = '-';
126
+ }
127
+
128
+ var template_html;
129
+ if( template_id != null ) {
130
+ template_html = $(template_id).html();
131
+ } else {
132
+ template_html = '<option value="">{{default_option}}</option>{{#each array}}<option value="{{id}}">{{' + atributo_nombre + '}}</option>{{/each}}'
133
+ }
134
+ var template = Handlebars.compile(template_html);
135
+ element.html(template({array: options, default_option: default_option}));
136
+ element.trigger("chosen:updated");
137
+ }
138
+
139
+ pg_rails.abrir_modal = function(contenido, titulo = '', opciones = {}) {
140
+ var header = '<div class="modal-header">' +
141
+ ' <h5 class="modal-title">' + titulo + '</h5>' +
142
+ ' <button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
143
+ ' <span aria-hidden="true">&times;</span>' +
144
+ ' </button>' +
145
+ '</div>';
146
+ if( opciones['dialog_class'] ) {
147
+ var dialog_class = 'modal-dialog ' + opciones['dialog_class'];
148
+ } else {
149
+ var dialog_class = 'modal-dialog';
150
+ }
151
+ var modal = $('<div class="modal"><div class="' + dialog_class + '"><div class="modal-content">' + header + '<div class="modal-body">');
152
+ modal.find('.modal-body').html(contenido);
153
+ $('body').append(modal);
154
+ modal.on('hidden.bs.modal', function() {
155
+ // $(this).modal('dispose');
156
+ $(this).remove();
157
+ })
158
+ modal.modal('show');
159
+ return modal;
160
+ }
161
+
162
+ pg_rails.error_toast = function(message) {
163
+ pg_rails.showToast("error", message);
164
+ }
165
+
166
+ pg_rails.showToast = function (type, message) {
167
+ var title = null;
168
+ if (type === "notice" || type === "success") {
169
+ type="success";
170
+ title = "Notificación";
171
+ } else if (type === "alert" || type === "error") {
172
+ type="error";
173
+ title = "Error";
174
+ } else if (type === "warning" ) {
175
+ type="warning";
176
+ title = "Advertencia";
177
+ } else if (type === "info" ) {
178
+ type="info";
179
+ title = "Notificación";
180
+ } else {
181
+ message = type;
182
+ title = "Notificación";
183
+ type = "success";
184
+ }
185
+
186
+ if (typeof $.fn.toast == "function") {
187
+ var template_html = "\
188
+ <div class='toast toast-{{type}}' role='alert' aria-live='assertive' aria-atomic='true'>\
189
+ <div class='toast-header'>\
190
+ <strong class='mr-auto'>{{title}}</strong>\
191
+ <button type='button' class='ml-2 mb-1 close' data-dismiss='toast' aria-label='Close'>\
192
+ <span aria-hidden='true'>&times;</span>\
193
+ </button>\
194
+ </div>\
195
+ <div class='toast-body'>\
196
+ {{message}}\
197
+ </div>\
198
+ </div>";
199
+
200
+ var template = Handlebars.compile(template_html);
201
+ var toast = $(template({message: message, title: title, type: type}));
202
+ $("#toast-container").append(toast);
203
+ $(toast).toast({
204
+ delay: 3000,
205
+ // autohide: false,
206
+ });
207
+ $(toast).toast('show');
208
+ $(toast).on('hidden.bs.toast', function () {
209
+ $(toast).remove();
210
+ })
211
+ } else {
212
+ if (window.toastr) {
213
+ var shortCutFunction = type;
214
+
215
+ title = "";
216
+
217
+ window.toastr.options = {
218
+ closeButton: true,
219
+ debug: false,
220
+ progressBar: true,
221
+ preventDuplicates: false,
222
+ positionClass: "toast-top-right",
223
+ onclick: null,
224
+ showDuration: "400",
225
+ hideDuration: "1000",
226
+ timeOut: "7000",
227
+ extendedTimeOut: "1000",
228
+ showEasing: "swing",
229
+ hideEasing: "linear",
230
+ showMethod: "fadeIn",
231
+ hideMethod: "fadeOut"
232
+ };
233
+
234
+ $("#toastrOptions").text("Command: toastr["
235
+ + shortCutFunction
236
+ + "](\""
237
+ + message
238
+ + (title ? "\", \"" + title : '')
239
+ + "\")\n\ntoastr.options = "
240
+ + JSON.stringify(toastr.options, null, 2)
241
+ );
242
+ var $toast = window.toastr[shortCutFunction](message, title);
243
+ } else {
244
+ alert(message);
245
+ }
246
+ }
247
+ }
248
+
249
+ window.jQuery.fn.ocultar_campo = function() {
250
+ this.hide();
251
+ this.find('.chosen-select').addClass('ignore-validation');
252
+ this.find("input:not(.keep-disabled), select:not(.keep-disabled)").attr("disabled",true);
253
+ this.find("input, select").trigger("change"); //Esto es por si hay dependencias internas que se acomoden
254
+ }
255
+
256
+ window.jQuery.fn.mostrar_campo = function() {
257
+ this.show();
258
+ this.find('.chosen-select').removeClass('ignore-validation');
259
+ this.find("input:not(.keep-disabled), select:not(.keep-disabled)").attr("disabled",false);
260
+ this.find("input, select").trigger("change"); //Esto es por si hay dependencias internas que se acomoden
261
+ }
262
+
263
+ window.jQuery.fn.dependent_fields = function() {
264
+ var that = this;
265
+
266
+ var update_dependent = function() {
267
+ var target = this;
268
+ var options = {};
269
+ options[$(target).data('key')] = $(this).val().toString();
270
+ $.getJSON($(target).data('url'), options)
271
+ .done(function(response) {
272
+ // var id = $(target).data('id')
273
+ // var siguiente_select = $("[data-id='"+id+"'] ~ select").first();
274
+ var siguiente_select = $(target).nextAll('select').first()
275
+ pg_rails.insert_options(siguiente_select, response, 'Seleccione una opción', null, 'to_s');
276
+ $(siguiente_select).trigger('change');
277
+ }).fail(function(response) { });
278
+ }
279
+
280
+ var bind_events = function(target) {
281
+ var main = $(target).find('select').last();
282
+ var selectores = $(target).find('select').not(main); // Todos menos el último
283
+ $(selectores).each(function(i, selector) {
284
+ $(selector).on('change', update_dependent);
285
+ })
286
+ }
287
+
288
+ // TODO: Polemic
289
+ $(that).on('nested:fieldAdded', function(event){
290
+ var field = event.field;
291
+ bind_events(field);
292
+ });
293
+
294
+ $(that).find('.form-group.dependent_fields').each(function(i, field) {
295
+ bind_events(field);
296
+ })
297
+ }
298
+ }
299
+
300
+ $(document).on('nested:fieldAdded', function(event){
301
+ PgRails.bindear(event.field);
302
+ });
303
+
304
+
305
+ // para que no se submiteen los forms al apretar enter en inputs que no son de submit
306
+ $(document).ready(function() {
307
+ $(window).keydown(function(event){
308
+ if(event.keyCode == 13) {
309
+ if( event.target.tagName == 'INPUT' && $(event.target).attr('type') != 'submit' &&
310
+ !$(event.target).hasClass('allow-enter-submit')) {
311
+ event.preventDefault();
312
+ return false;
313
+ }
314
+ }
315
+ });
316
+ });
317
+
318
+ });
@@ -0,0 +1,5 @@
1
+ @import "bootstrap-datepicker.css";
2
+ @import "chosen";
3
+ @import "fontawesome-free-5.10.1-web/css/all";
4
+ @import 'selectize';
5
+ @import 'selectize.bootstrap3';