diff --git a/app/assets/javascripts/tag_autocomplete.js.coffee b/app/assets/javascripts/tag_autocomplete.js.coffee
index 9e10c100e..be27cd81c 100644
--- a/app/assets/javascripts/tag_autocomplete.js.coffee
+++ b/app/assets/javascripts/tag_autocomplete.js.coffee
@@ -7,13 +7,18 @@ App.TagAutocomplete =
return (App.TagAutocomplete.split( term ).pop())
init_autocomplete: ->
- $('.js-tag-list').autocomplete
+ $('.tag-autocomplete').autocomplete
source: (request, response) ->
- response( $.ui.autocomplete.filter(["Arbol", "Becerro", "Caracol"], App.TagAutocomplete.extractLast( request.term ) ) );
+ $.ajax
+ url: $('.tag-autocomplete').data('js-url'),
+ data: {search: App.TagAutocomplete.extractLast( request.term )},
+ type: 'GET',
+ dataType: 'json'
+ success: ( data ) ->
+ response( data );
+
minLength: 0,
search: ->
- console.log(this.value);
- console.log(App.TagAutocomplete.extractLast( this.value ));
App.TagAutocomplete.extractLast( this.value );
focus: ->
return false;
diff --git a/app/assets/stylesheets/autocomplete_overrides.scss b/app/assets/stylesheets/autocomplete_overrides.scss
index 68537fd8a..9eac7162b 100644
--- a/app/assets/stylesheets/autocomplete_overrides.scss
+++ b/app/assets/stylesheets/autocomplete_overrides.scss
@@ -4,7 +4,6 @@
/* Autocomplete
----------------------------------*/
.ui-autocomplete { position: absolute; cursor: default; }
-.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }
/* workarounds */
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
@@ -13,29 +12,23 @@
----------------------------------*/
.ui-menu {
list-style:none;
- padding: 0px 5px;
- margin: 0;
+ padding: $line-height / 4 $line-height / 3;
display:block;
- /*width:227px;*/
background: white;
border: 1px solid $border;
-}
-.ui-menu .ui-menu {
- margin-top: -3px;
-}
-.ui-menu .ui-menu-item {
- margin:0;
- padding: 0;
- width: 200px;
-}
-.ui-menu .ui-menu-item a {
- /* text-decoration:none;
- display:block;*/
- padding:.2em .4em;
- /* line-height:1.5;
- zoom:1;*/
-}
-.ui-menu .ui-menu-item a.ui-state-hover,
-.ui-menu .ui-menu-item a.ui-state-active {
- margin: -1px;
+ font-size: $small-font-size;
+
+ .ui-menu-item {
+
+ .ui-menu-item-wrapper {
+ padding: $line-height / 4 $line-height / 3;
+ position: relative;
+ }
+
+ .ui-state-hover, .ui-state-active {
+ background: #ececec;
+ border-radius: rem-calc(6);
+ }
+ }
+
}
\ No newline at end of file
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
new file mode 100644
index 000000000..c58067048
--- /dev/null
+++ b/app/controllers/tags_controller.rb
@@ -0,0 +1,11 @@
+class TagsController < ApplicationController
+
+ load_and_authorize_resource class: ActsAsTaggableOn::Tag
+ respond_to :json
+
+ def suggest
+ @tags = ActsAsTaggableOn::Tag.search(params[:search]).map(&:name)
+ respond_with @tags
+ end
+
+end
diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb
index 620cfb212..0df92616d 100644
--- a/app/models/abilities/common.rb
+++ b/app/models/abilities/common.rb
@@ -24,6 +24,7 @@ module Abilities
can :suggest, Debate
can :suggest, Proposal
+ can :suggest, ActsAsTaggableOn::Tag
can [:flag, :unflag], Comment
cannot [:flag, :unflag], Comment, user_id: user.id
diff --git a/app/views/debates/_form.html.erb b/app/views/debates/_form.html.erb
index 28ef69804..a98611011 100644
--- a/app/views/debates/_form.html.erb
+++ b/app/views/debates/_form.html.erb
@@ -23,7 +23,8 @@
label: false,
placeholder: t("debates.form.tags_placeholder"),
aria: {describedby: "tag-list-help-text"},
- data: {js_url: tags_search_path}%>
+ data: {js_url: suggest_tags_path},
+ class: 'tag-autocomplete'%>
<% if @debate.new_record? %>
diff --git a/app/views/proposals/_form.html.erb b/app/views/proposals/_form.html.erb
index 73b39dfdb..b46dbc69e 100644
--- a/app/views/proposals/_form.html.erb
+++ b/app/views/proposals/_form.html.erb
@@ -70,8 +70,9 @@
<%= f.text_field :tag_list, value: @proposal.tag_list.to_s,
label: false,
placeholder: t("proposals.form.tags_placeholder"),
- class: 'js-tag-list',
- aria: {describedby: "tag-list-help-text"} %>
+ class: 'js-tag-list tag-autocomplete',
+ aria: {describedby: "tag-list-help-text"},
+ data: {js_url: suggest_tags_path} %>
<% if current_user.unverified? %>
diff --git a/config/initializers/acts_as_taggable_on.rb b/config/initializers/acts_as_taggable_on.rb
index 57766c8c9..018319442 100644
--- a/config/initializers/acts_as_taggable_on.rb
+++ b/config/initializers/acts_as_taggable_on.rb
@@ -43,6 +43,18 @@ module ActsAsTaggableOn
Tagging.public_for_api.pluck('DISTINCT taggings.tag_id'))
end
+ include PgSearch
+
+ pg_search_scope :pg_search, against: :name,
+ using: {
+ tsearch: {prefix: true}
+ },
+ ignoring: :accents
+
+ def self.search(term)
+ pg_search(term)
+ end
+
def increment_custom_counter_for(taggable_type)
Tag.increment_counter(custom_counter_field_name_for(taggable_type), id)
end
@@ -78,6 +90,7 @@ module ActsAsTaggableOn
end
private
+
def custom_counter_field_name_for(taggable_type)
"#{taggable_type.underscore.pluralize}_count"
end
diff --git a/config/routes.rb b/config/routes.rb
index 666285496..7b1c1cac0 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -6,17 +6,17 @@ Rails.application.routes.draw do
end
devise_for :users, controllers: {
- registrations: 'users/registrations',
- sessions: 'users/sessions',
- confirmations: 'users/confirmations',
- omniauth_callbacks: 'users/omniauth_callbacks'
- }
+ registrations: 'users/registrations',
+ sessions: 'users/sessions',
+ confirmations: 'users/confirmations',
+ omniauth_callbacks: 'users/omniauth_callbacks'
+ }
devise_for :organizations, class_name: 'User',
- controllers: {
- registrations: 'organizations/registrations',
- sessions: 'devise/sessions',
- },
- skip: [:omniauth_callbacks]
+ controllers: {
+ registrations: 'organizations/registrations',
+ sessions: 'devise/sessions'
+ },
+ skip: [:omniauth_callbacks]
devise_scope :organization do
get 'organizations/sign_up/success', to: 'organizations/registrations#success'
@@ -167,11 +167,12 @@ Rails.application.routes.draw do
resource :email, controller: "email", only: [:new, :show, :create]
resource :letter, controller: "letter", only: [:new, :create, :show, :edit, :update]
end
-
- namespace :tags do
- get :search
- end
+ resources :tags do
+ collection do
+ get :suggest
+ end
+ end
namespace :admin do
root to: "dashboard#index"
@@ -435,9 +436,7 @@ Rails.application.routes.draw do
get '/graphql', to: 'graphql#query'
post '/graphql', to: 'graphql#query'
- if Rails.env.development?
- mount LetterOpenerWeb::Engine, at: "/letter_opener"
- end
+ mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql'
diff --git a/spec/lib/acts_as_taggable_on_spec.rb b/spec/lib/acts_as_taggable_on_spec.rb
index 761e90553..de53b35e7 100644
--- a/spec/lib/acts_as_taggable_on_spec.rb
+++ b/spec/lib/acts_as_taggable_on_spec.rb
@@ -133,6 +133,21 @@ describe 'ActsAsTaggableOn' do
expect(ActsAsTaggableOn::Tag.public_for_api).to be_empty
end
end
+
+ describe "search" do
+ it "containing the word in the name" do
+ create(:tag, name: 'Familia')
+ create(:tag, name: 'Cultura')
+ create(:tag, name: 'Salud')
+ create(:tag, name: 'Famosos')
+
+ expect(ActsAsTaggableOn::Tag.pg_search('f').length).to eq(2)
+ expect(ActsAsTaggableOn::Tag.search('cultura').first.name).to eq('Cultura')
+ expect(ActsAsTaggableOn::Tag.search('sal').first.name).to eq('Salud')
+ expect(ActsAsTaggableOn::Tag.search('fami').first.name).to eq('Familia')
+ end
+ end
+
end
end