ajax_forms 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +34 -0
  3. data/app/assets/javascripts/ajax_forms/application.js +17 -0
  4. data/app/assets/javascripts/ajax_forms/fancybox.js +26 -0
  5. data/app/assets/javascripts/ajax_forms/select2.js +110 -0
  6. data/app/assets/stylesheets/ajax_forms/application.css +15 -0
  7. data/app/controllers/ajax_forms/application_controller.rb +4 -0
  8. data/app/helpers/ajax_forms/application_helper.rb +4 -0
  9. data/app/views/_error_messages.html.erb +10 -0
  10. data/app/views/layouts/_application.html.erb +9 -0
  11. data/app/views/quick_response.js.erb +7 -0
  12. data/config/routes.rb +24 -0
  13. data/lib/ajax_forms.rb +12 -0
  14. data/lib/ajax_forms/dsl.rb +68 -0
  15. data/lib/ajax_forms/engine.rb +5 -0
  16. data/lib/ajax_forms/version.rb +3 -0
  17. data/lib/tasks/ajax_forms_tasks.rake +4 -0
  18. data/test/ajax_forms_test.rb +7 -0
  19. data/test/dummy/README.rdoc +28 -0
  20. data/test/dummy/Rakefile +6 -0
  21. data/test/dummy/app/assets/javascripts/application.js +13 -0
  22. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  23. data/test/dummy/app/controllers/application_controller.rb +5 -0
  24. data/test/dummy/app/helpers/application_helper.rb +2 -0
  25. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  26. data/test/dummy/bin/bundle +3 -0
  27. data/test/dummy/bin/rails +4 -0
  28. data/test/dummy/bin/rake +4 -0
  29. data/test/dummy/config.ru +4 -0
  30. data/test/dummy/config/application.rb +23 -0
  31. data/test/dummy/config/boot.rb +5 -0
  32. data/test/dummy/config/database.yml +25 -0
  33. data/test/dummy/config/environment.rb +5 -0
  34. data/test/dummy/config/environments/development.rb +37 -0
  35. data/test/dummy/config/environments/production.rb +82 -0
  36. data/test/dummy/config/environments/test.rb +39 -0
  37. data/test/dummy/config/initializers/assets.rb +8 -0
  38. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  39. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  40. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  41. data/test/dummy/config/initializers/inflections.rb +16 -0
  42. data/test/dummy/config/initializers/mime_types.rb +4 -0
  43. data/test/dummy/config/initializers/session_store.rb +3 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +23 -0
  46. data/test/dummy/config/routes.rb +4 -0
  47. data/test/dummy/config/secrets.yml +22 -0
  48. data/test/dummy/public/404.html +67 -0
  49. data/test/dummy/public/422.html +67 -0
  50. data/test/dummy/public/500.html +66 -0
  51. data/test/dummy/public/favicon.ico +0 -0
  52. data/test/integration/navigation_test.rb +10 -0
  53. data/test/test_helper.rb +15 -0
  54. metadata +272 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cb8bf4ccb628a0de313670ba8a5b79a2c0d1be11
4
+ data.tar.gz: 1b60e47069ea4d1b83613e8d4823fc92f28d10c7
5
+ SHA512:
6
+ metadata.gz: 77fa34f3b1d3ea8e99f2247e921580f9ecb44cbd5518f3bef381551c8bee400574f64c937454616d8810134c172597f81985b0a3dd2f32710204176512933983
7
+ data.tar.gz: 41fe2eff4004f70b1f1e0ceb9d2338a6289afcc618e340f97b8a1703267dc27775cc3b4acc942b44541fd80a174b0469e7899863705299e3c647d6162f9f9dc6
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'AjaxForms'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,17 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
14
+
15
+ $(function () {
16
+ initSelect2();
17
+ });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * display fancybox by ajax (load href as url)
3
+ * @param href
4
+ */
5
+ function fancybox(href) {
6
+ $('#select2-drop').select2("close");
7
+ $.fancybox({
8
+ 'width': "600px", // set the width
9
+ 'height': "600px", // set the height
10
+ 'href': href,
11
+ 'type': 'ajax',
12
+ 'transitionIn': 'elastic',
13
+ 'ajax': {
14
+ complete: function(jqXHR, textStatus) {
15
+ initSelect2($('div.fancybox-skin'));
16
+ $(".chosen-input").chosen({
17
+ no_results_text: "No se han encontrado resultados...",
18
+ allow_single_deselect: true,
19
+ placeholder_text_single: "Seleccione una opción",
20
+ search_contains: true
21
+ });
22
+ }
23
+ }
24
+ }
25
+ );
26
+ }
@@ -0,0 +1,110 @@
1
+ function addslashes( str ) {
2
+ return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
3
+ }
4
+
5
+ function setSelectResult(destinationField, key, value) {
6
+ $(destinationField).select2('data', {id: key, text: value});
7
+ }
8
+
9
+ /**
10
+ * init Select2 over specific selectors
11
+ * If you pass specificSelector, only apply select2 over that selector elsewhere apply to all that has class select2-autocomplete => $('.select2-autocomplete');
12
+ *
13
+ * @param specificSelector
14
+ */
15
+ function initSelect2(specificSelector) {
16
+ var onlySpecificSelector = $(specificSelector).find('.select2-autocomplete');
17
+ var selectorWhereInitSelect2 = '';
18
+ if (onlySpecificSelector.length == 1) {
19
+ selectorWhereInitSelect2 = onlySpecificSelector;
20
+ }
21
+ else {
22
+ selectorWhereInitSelect2 = $('.select2-autocomplete');
23
+ }
24
+ selectorWhereInitSelect2.each(function (i, e) {
25
+ var select = $(e);
26
+ var defaultValue = select.val();
27
+ var sourcePath = select.data('source');
28
+ var dependent = select.data("dependent");
29
+
30
+ options = {};
31
+ options.width = 'auto';
32
+ options.allowClear = true;
33
+ options.placeholder = "Seleccione una opción";
34
+
35
+ var initSelectionForSingle = function (select, callback) {
36
+ if (defaultValue !== "") {
37
+ $.ajax(sourcePath, {
38
+ data: {
39
+ q_id: defaultValue
40
+ },
41
+ dataType: "json"
42
+ }).done(function (data) {
43
+ data = {id: data[0].id, text: data[0].text};
44
+ callback(data);
45
+ });
46
+ }
47
+ };
48
+
49
+ var initSelectionForMultiple = function (select, callback) {
50
+ select.val().split(",").each(function () {
51
+ data.push({id: this, text: this});
52
+ });
53
+ callback(data);
54
+ };
55
+
56
+ var data = [];
57
+ if (typeof select.data('multiple') !== 'undefined') { //multiple select with multiple=>true option
58
+ options.multiple = select.data('multiple');
59
+ if (options.multiple == true) {
60
+ options.initSelection = initSelectionForMultiple;
61
+ } else { //single select with multiple=>false option
62
+ options.initSelection = initSelectionForSingle;
63
+ }
64
+ }
65
+ else { // undefined -> single select by default
66
+ options.initSelection = initSelectionForSingle;
67
+ }
68
+
69
+ //options.minimumInputLength=3;
70
+ if (select.hasClass('ajax')) {
71
+ options.ajax = {
72
+ quietMillis: 1500,
73
+ url: sourcePath,
74
+ dataType: 'json',
75
+ data: function (term, page) {
76
+ selectorValue="";
77
+ ransackFilter="";
78
+ dependentField=select.data("dependent");
79
+ dependentSelectHash={}
80
+ if (dependentField) {
81
+ selectorValue=$("#"+dependentField.selectorId).val();
82
+ ransackFilter=dependentField.ransackFilter;
83
+ dependentSelectHash={"ransackFilter": ransackFilter, "selectorValue": selectorValue};
84
+ }
85
+ return {
86
+ q: term,
87
+ page_limit: page,
88
+ page: page,
89
+ dependentSelect: dependentSelectHash
90
+ }
91
+ },
92
+ results: function (data, page) {
93
+ return {
94
+ results: data
95
+ }
96
+ }
97
+ };
98
+ }
99
+
100
+ options.formatNoMatches = function (term) {
101
+ var destinationSelectorId=select.attr('id');
102
+ var modalPath = "'" + select.data('modal') + "/" + btoa(term)+"/"+encodeURI(destinationSelectorId) +"'";
103
+ return '<a href="#" class="btn btn-xs btn-primary add-item-button pull-right" onclick="return fancybox(' + modalPath + ');">Agregar y editar: "' + term + '"</a>';
104
+ };
105
+ options.escapeMarkup = function (m) {
106
+ return m;
107
+ };
108
+ select.select2(options);
109
+ });
110
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module AjaxForms
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AjaxForms
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ <% if object.errors.any? %>
2
+ <div class="alert alert-danger">
3
+ <a class="close" data-dismiss="alert">×</a>
4
+ <ul class="error-list">
5
+ <% object.errors.full_messages.each do |message| %>
6
+ <li><%= message %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <div class="bys-bootstrap">
2
+ <div class="container">
3
+ <div id="quick-add-errors"></div>
4
+ </div>
5
+ </div>
6
+ <div id="<%= @id %>">
7
+ <%= yield %>
8
+ </div>
9
+
@@ -0,0 +1,7 @@
1
+ <% if @model.errors.any? %>
2
+ var html = "<%= escape_javascript(render partial:'/error_messages', object: @model, as:'object') %>";
3
+ $('#quick-add-errors').html(html);
4
+ <% else %>
5
+ setSelectResult(<%= @selector %>, <%= @model.id%>, "<%= @model.name %>")
6
+ $('<%="div##{@id}"%>').closest("div.fancybox-skin").find("a.fancybox-close").click();
7
+ <% end %>
@@ -0,0 +1,24 @@
1
+ #ActiveAdmin::AjaxForms::Engine.routes.draw do
2
+ Rails.application.routes.draw do
3
+ # TODO: permitir levantar todos los nombres de espacios, no solamente admin:
4
+ #ActiveAdmin.application.namespaces.keys.resources
5
+ resource_collection = ActiveAdmin.application.namespaces[:admin].resources
6
+ resources = resource_collection.select { |resource| resource.respond_to? :resource_class }
7
+ pages = resource_collection.select { |resource| resource.is_a? ActiveAdmin::Page }
8
+
9
+ resources.each do |resource|
10
+ #TODO: Corregir la generación de la ruta para el quick_new
11
+ if resource.dsl.ajax_form_enabled
12
+ singular = resource.dsl.config.resource_name.singular
13
+ plural = resource.dsl.config.resource_name.plural
14
+ resource_name = resource.resource_class.to_s.downcase
15
+ collection_path = resource.route_collection_path.slice(1..-1)
16
+ prefix = resource.route_prefix
17
+
18
+ route = "/#{collection_path}"
19
+ collection_path_helper = "#{collection_path.gsub('/','_')}"
20
+ member_path_helper = "#{prefix}/#{resource_name}"
21
+ get "#{route}/quick_new(/:name/:selectorid)" => "#{collection_path}#quick_new", as: "quick_new_#{member_path_helper}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require "ajax_forms/version"
2
+ require "ajax_forms/engine"
3
+ require "ajax_forms/dsl"
4
+
5
+ # ensure that ActiveAdmin is loaded
6
+ require "active_admin"
7
+
8
+ module ActiveAdminAjaxForms
9
+ end
10
+
11
+ # Permite que los helpers estén accesibles desde los Resources de Active Admin
12
+ ActiveAdmin::ResourceDSL.send :include, ActiveAdminAjaxForms::DSL
@@ -0,0 +1,68 @@
1
+ module ActiveAdminAjaxForms
2
+ module DSL
3
+ attr_accessor :ajax_form_enabled
4
+
5
+ #todo: falta completar el pasaje de opciones de configuracion para especificar los partials a renderizar
6
+ def ajax_forms options={}
7
+ default_options = {
8
+ quick_new_partial: nil,
9
+ quick_create_partial: nil,
10
+ model: config.resource_class,
11
+ }
12
+ options = default_options.deep_merge(options)
13
+
14
+ @ajax_form_enabled = true
15
+
16
+ #todo: Posibilidad de especificar los atributos a devolver en el método find. Si no se especifica nada devolver todas las columnas
17
+ collection_action :find, :method => :get do
18
+ @model = resource_class
19
+ search_term=params[:q]
20
+ groupping_condition=params[:q][:g] rescue nil
21
+
22
+ if !params[:q_id].blank?
23
+ params[:q]={:id_equals => params[:q_id]} #selected element
24
+ elsif groupping_condition.nil?
25
+ params[:q]={
26
+ :g=>{
27
+ "0"=>{:name_cont_all=>search_term.split(" ")}
28
+ }
29
+ }
30
+ params[:q][:g]["1"]={params[:dependentSelect][:ransackFilter].to_sym=>params[:dependentSelect][:selectorValue]} if params[:dependentSelect] and !params[:dependentSelect][:selectorValue].empty?
31
+ end
32
+
33
+ @q = @model.search(params[:q])
34
+ @items = @q.result.order('id desc', 'name asc').limit(100).map { |item| {:id => item.id, :text => item.to_s} }
35
+ respond_to do |format|
36
+ format.json { render :json => @items }
37
+ end
38
+ end
39
+
40
+ collection_action :quick_new, :method => :get do
41
+ @model = resource_class.new(:name => Base64.decode64(params[:name]))
42
+ options[:selector]=params[:selectorid]
43
+ #crea una variable de instancia con el nombre del recurso para compatibilidad con partials normales
44
+ instance_variable_set("@#{resource_instance_name.to_s}", @model)
45
+ @remote = true
46
+ @form_url = eval "quick_create_admin_#{resource_collection_name.to_s}_path"
47
+
48
+ @id="#{Time.now.to_i.to_s}_#{resource_instance_name.to_s}"
49
+ options[:id]=@id
50
+
51
+ #todo: tiene que renderizar un formulario por defecto
52
+ if options.fetch(:quick_new_partial).nil?
53
+ render :nothing => true
54
+ else
55
+ render partial: options.fetch(:quick_new_partial), layout: 'application'
56
+ end
57
+ end
58
+
59
+ collection_action :quick_create, :method => :post do
60
+ @model = resource_class.new(params[resource_instance_name])
61
+ @selector=options[:selector]
62
+ @model.save
63
+ @id=options[:id]
64
+ render file: 'quick_response', layout: false
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveAdminAjaxForms
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace ActiveAdminAjaxForms
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module AjaxForms
2
+ VERSION = "0.0.16"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :ajax_forms do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class AjaxFormsTest < ActiveSupport::TestCase
4
+ test "truth" do
5
+ assert_kind_of Module, AjaxForms
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .