From 42d9db526d3aef2e08848d6bc587feaf3700db42 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 7 Jul 2018 16:23:04 -0400 Subject: Added tags Blogs and streams can now be tagged. Records now show the appropriate tags for an entry. Updates work oddly, because their records show the stream's tags, since updates do not have tags themselves. refs #2 --- .gitignore | 1 + Gemfile | 1 + Gemfile.lock | 3 ++ app/assets/javascripts/admin/records.coffee | 2 ++ app/assets/javascripts/application.js | 1 + app/assets/stylesheets/admin.css.scss | 1 + app/assets/stylesheets/admin/layout.scss | 8 +++++ app/assets/stylesheets/main/records.scss | 2 ++ app/controllers/admin/blogs_controller.rb | 2 +- app/controllers/admin/streams_controller.rb | 2 +- app/models/blog.rb | 6 ++++ app/models/stream.rb | 6 ++++ app/models/update.rb | 4 +++ app/views/admin/blogs/_form.html.haml | 4 +++ app/views/admin/streams/_form.html.haml | 4 +++ app/views/records/_record.html.haml | 7 +++++ app/views/records/index.html.haml | 8 +---- ...able_on_migration.acts_as_taggable_on_engine.rb | 36 ++++++++++++++++++++++ ...ng_unique_indices.acts_as_taggable_on_engine.rb | 26 ++++++++++++++++ ...ter_cache_to_tags.acts_as_taggable_on_engine.rb | 20 ++++++++++++ ...ng_taggable_index.acts_as_taggable_on_engine.rb | 15 +++++++++ ...ion_for_tag_names.acts_as_taggable_on_engine.rb | 15 +++++++++ ...dexes_on_taggings.acts_as_taggable_on_engine.rb | 23 ++++++++++++++ db/schema.rb | 27 +++++++++++++++- vendor/assets/javascripts/tags-input.js | 2 ++ vendor/assets/stylesheets/tags-input.css | 2 ++ 26 files changed, 218 insertions(+), 10 deletions(-) create mode 100644 app/views/records/_record.html.haml create mode 100644 db/migrate/20180707142415_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb create mode 100644 db/migrate/20180707142416_add_missing_unique_indices.acts_as_taggable_on_engine.rb create mode 100644 db/migrate/20180707142417_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb create mode 100644 db/migrate/20180707142418_add_missing_taggable_index.acts_as_taggable_on_engine.rb create mode 100644 db/migrate/20180707142419_change_collation_for_tag_names.acts_as_taggable_on_engine.rb create mode 100644 db/migrate/20180707142420_add_missing_indexes_on_taggings.acts_as_taggable_on_engine.rb create mode 100755 vendor/assets/javascripts/tags-input.js create mode 100755 vendor/assets/stylesheets/tags-input.css diff --git a/.gitignore b/.gitignore index 09230f9..702ff9b 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ /tmux*.log *.swp tags +!tags/ .byebug_history .DS_Store diff --git a/Gemfile b/Gemfile index aee427f..f0c7c76 100644 --- a/Gemfile +++ b/Gemfile @@ -69,3 +69,4 @@ gem 'ckeditor' gem 'paperclip' gem 'jquery-rails' gem 'pokeviewer', github: "hatkirby/pokeviewer" +gem 'acts-as-taggable-on' diff --git a/Gemfile.lock b/Gemfile.lock index 9fb12d0..09ff6ef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -55,6 +55,8 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) + acts-as-taggable-on (6.0.0) + activerecord (~> 5.0) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) airbrussh (1.3.0) @@ -269,6 +271,7 @@ PLATFORMS ruby DEPENDENCIES + acts-as-taggable-on byebug capistrano (~> 3.0) capistrano-bundler diff --git a/app/assets/javascripts/admin/records.coffee b/app/assets/javascripts/admin/records.coffee index 3a1ed51..7a11ce1 100644 --- a/app/assets/javascripts/admin/records.coffee +++ b/app/assets/javascripts/admin/records.coffee @@ -23,3 +23,5 @@ $(document).on "turbolinks:load", -> create_record_toggle($(this).prop("checked")) $(".published-field input[type=checkbox]").change -> published_field_toggle($(this).prop("checked")) + $("input[type=tags]").each -> + tagsInput(this) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index f902906..a81b3b2 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,4 +14,5 @@ //= require jquery_ujs //= require turbolinks //= require ckeditor/init +//= require tags-input //= require_tree ./admin diff --git a/app/assets/stylesheets/admin.css.scss b/app/assets/stylesheets/admin.css.scss index 5235c4b..95d1ed0 100644 --- a/app/assets/stylesheets/admin.css.scss +++ b/app/assets/stylesheets/admin.css.scss @@ -1,4 +1,5 @@ /* *= require normalize-rails + *= require tags-input *= require_tree ./admin */ diff --git a/app/assets/stylesheets/admin/layout.scss b/app/assets/stylesheets/admin/layout.scss index b825c25..220dcd5 100644 --- a/app/assets/stylesheets/admin/layout.scss +++ b/app/assets/stylesheets/admin/layout.scss @@ -196,6 +196,14 @@ body { } } +.tags-field { + label { + font-size: .75em; + display: block; + margin-bottom: 0.5em; + } +} + .record-description-field { display: none; margin-top: 1em; diff --git a/app/assets/stylesheets/main/records.scss b/app/assets/stylesheets/main/records.scss index f57dded..350fb16 100644 --- a/app/assets/stylesheets/main/records.scss +++ b/app/assets/stylesheets/main/records.scss @@ -31,6 +31,7 @@ .tags { margin: .25em; display: flex; + flex-wrap: wrap; padding-left: 0; li { @@ -58,6 +59,7 @@ } } + &.entry-tag { & + li { margin-left: 1em; } diff --git a/app/controllers/admin/blogs_controller.rb b/app/controllers/admin/blogs_controller.rb index 1035c12..e79dd81 100644 --- a/app/controllers/admin/blogs_controller.rb +++ b/app/controllers/admin/blogs_controller.rb @@ -56,7 +56,7 @@ class Admin::BlogsController < Admin::AdminController private def blog_params - params.require(:blog).permit(:title, :body, :slug, :published, records_attributes: [:description, :_destroy]) + params.require(:blog).permit(:title, :body, :slug, :published, :tag_list, records_attributes: [:description, :_destroy]) end def set_section diff --git a/app/controllers/admin/streams_controller.rb b/app/controllers/admin/streams_controller.rb index 86dec06..252ebfa 100644 --- a/app/controllers/admin/streams_controller.rb +++ b/app/controllers/admin/streams_controller.rb @@ -42,7 +42,7 @@ class Admin::StreamsController < Admin::AdminController private def stream_params - params.require(:stream).permit(:title, :body, :slug, records_attributes: [:description, :_destroy]) + params.require(:stream).permit(:title, :body, :slug, :tag_list, records_attributes: [:description, :_destroy]) end def set_section diff --git a/app/models/blog.rb b/app/models/blog.rb index 5742879..18f63f1 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb @@ -1,6 +1,8 @@ class Blog < ApplicationRecord include Recordable + acts_as_taggable + validates :title, presence: true validates :body, presence: true, if: :published validates :slug, presence: true, format: /\A[-a-z0-9]+\z/, if: :published @@ -12,6 +14,10 @@ class Blog < ApplicationRecord "/says/#{slug}" end + def taggable + self + end + private def set_draft_title if self.title.blank? and not self.published diff --git a/app/models/stream.rb b/app/models/stream.rb index 1398b75..0773143 100644 --- a/app/models/stream.rb +++ b/app/models/stream.rb @@ -1,6 +1,8 @@ class Stream < ApplicationRecord include Recordable + acts_as_taggable + has_many :updates validates :title, presence: true @@ -9,4 +11,8 @@ class Stream < ApplicationRecord def path "/thinks/#{slug}" end + + def taggable + self + end end diff --git a/app/models/update.rb b/app/models/update.rb index 73c4911..01907d8 100644 --- a/app/models/update.rb +++ b/app/models/update.rb @@ -8,4 +8,8 @@ class Update < ApplicationRecord def path "/thinks/#{stream.slug}\#update-#{id}" end + + def taggable + stream + end end diff --git a/app/views/admin/blogs/_form.html.haml b/app/views/admin/blogs/_form.html.haml index 12f7a82..36925af 100644 --- a/app/views/admin/blogs/_form.html.haml +++ b/app/views/admin/blogs/_form.html.haml @@ -21,6 +21,10 @@ = link_to "View post", blog_url(f.object.slug_was), target: "entry-preview" - else = link_to "Preview post", admin_blog_url(f.object), target: "entry-preview" + .details-module + .tags-field + = f.label :tag_list, "Tags" + = f.text_field :tag_list, type: :tags, value: f.object.tag_list.join(",") .details-module .published-field = f.check_box :published diff --git a/app/views/admin/streams/_form.html.haml b/app/views/admin/streams/_form.html.haml index ce457cb..e04a3fb 100644 --- a/app/views/admin/streams/_form.html.haml +++ b/app/views/admin/streams/_form.html.haml @@ -15,6 +15,10 @@ %ul - f.object.errors.full_messages.each do |error| %li= error + .details-module + .tags-field + = f.label :tag_list, "Tags" + = f.text_field :tag_list, type: :tags, value: f.object.tag_list.join(",") .details-module = f.fields_for :records, Record.new do |builder| .should-create-record-field diff --git a/app/views/records/_record.html.haml b/app/views/records/_record.html.haml new file mode 100644 index 0000000..80a365c --- /dev/null +++ b/app/views/records/_record.html.haml @@ -0,0 +1,7 @@ +%li + %span.description= link_to record.description, record.recordable.path + %ul.tags + %li.record-date= record.created_at.strftime("%m.%d.%y") + %li.entry-type{ class: "entry-type-#{record.recordable_type.downcase}" }= record.recordable_type + - record.recordable.taggable.tag_list.each do |tag| + %li.entry-tag= tag diff --git a/app/views/records/index.html.haml b/app/views/records/index.html.haml index 200321e..4ceed2c 100644 --- a/app/views/records/index.html.haml +++ b/app/views/records/index.html.haml @@ -1,7 +1 @@ -%ul#records - - @records.each do |record| - %li - %span.description= link_to record.description, record.recordable.path - %ul.tags - %li.record-date= record.created_at.strftime("%m.%d.%y") - %li.entry-type{ class: "entry-type-#{record.recordable_type.downcase}" }= record.recordable_type +%ul#records= render @records diff --git a/db/migrate/20180707142415_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb b/db/migrate/20180707142415_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb new file mode 100644 index 0000000..461eae4 --- /dev/null +++ b/db/migrate/20180707142415_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb @@ -0,0 +1,36 @@ +# This migration comes from acts_as_taggable_on_engine (originally 1) +if ActiveRecord.gem_version >= Gem::Version.new('5.0') + class ActsAsTaggableOnMigration < ActiveRecord::Migration[4.2]; end +else + class ActsAsTaggableOnMigration < ActiveRecord::Migration; end +end +ActsAsTaggableOnMigration.class_eval do + def self.up + create_table :tags do |t| + t.string :name + end + + create_table :taggings do |t| + t.references :tag + + # You should make sure that the column created is + # long enough to store the required class names. + t.references :taggable, polymorphic: true + t.references :tagger, polymorphic: true + + # Limit is created to prevent MySQL error on index + # length for MyISAM table type: http://bit.ly/vgW2Ql + t.string :context, limit: 128 + + t.datetime :created_at + end + + add_index :taggings, :tag_id + add_index :taggings, [:taggable_id, :taggable_type, :context] + end + + def self.down + drop_table :taggings + drop_table :tags + end +end diff --git a/db/migrate/20180707142416_add_missing_unique_indices.acts_as_taggable_on_engine.rb b/db/migrate/20180707142416_add_missing_unique_indices.acts_as_taggable_on_engine.rb new file mode 100644 index 0000000..514ac57 --- /dev/null +++ b/db/migrate/20180707142416_add_missing_unique_indices.acts_as_taggable_on_engine.rb @@ -0,0 +1,26 @@ +# This migration comes from acts_as_taggable_on_engine (originally 2) +if ActiveRecord.gem_version >= Gem::Version.new('5.0') + class AddMissingUniqueIndices < ActiveRecord::Migration[4.2]; end +else + class AddMissingUniqueIndices < ActiveRecord::Migration; end +end +AddMissingUniqueIndices.class_eval do + def self.up + add_index :tags, :name, unique: true + + remove_index :taggings, :tag_id if index_exists?(:taggings, :tag_id) + remove_index :taggings, [:taggable_id, :taggable_type, :context] + add_index :taggings, + [:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type], + unique: true, name: 'taggings_idx' + end + + def self.down + remove_index :tags, :name + + remove_index :taggings, name: 'taggings_idx' + + add_index :taggings, :tag_id unless index_exists?(:taggings, :tag_id) + add_index :taggings, [:taggable_id, :taggable_type, :context] + end +end diff --git a/db/migrate/20180707142417_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb b/db/migrate/20180707142417_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb new file mode 100644 index 0000000..1d9b556 --- /dev/null +++ b/db/migrate/20180707142417_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb @@ -0,0 +1,20 @@ +# This migration comes from acts_as_taggable_on_engine (originally 3) +if ActiveRecord.gem_version >= Gem::Version.new('5.0') + class AddTaggingsCounterCacheToTags < ActiveRecord::Migration[4.2]; end +else + class AddTaggingsCounterCacheToTags < ActiveRecord::Migration; end +end +AddTaggingsCounterCacheToTags.class_eval do + def self.up + add_column :tags, :taggings_count, :integer, default: 0 + + ActsAsTaggableOn::Tag.reset_column_information + ActsAsTaggableOn::Tag.find_each do |tag| + ActsAsTaggableOn::Tag.reset_counters(tag.id, :taggings) + end + end + + def self.down + remove_column :tags, :taggings_count + end +end diff --git a/db/migrate/20180707142418_add_missing_taggable_index.acts_as_taggable_on_engine.rb b/db/migrate/20180707142418_add_missing_taggable_index.acts_as_taggable_on_engine.rb new file mode 100644 index 0000000..5f46569 --- /dev/null +++ b/db/migrate/20180707142418_add_missing_taggable_index.acts_as_taggable_on_engine.rb @@ -0,0 +1,15 @@ +# This migration comes from acts_as_taggable_on_engine (originally 4) +if ActiveRecord.gem_version >= Gem::Version.new('5.0') + class AddMissingTaggableIndex < ActiveRecord::Migration[4.2]; end +else + class AddMissingTaggableIndex < ActiveRecord::Migration; end +end +AddMissingTaggableIndex.class_eval do + def self.up + add_index :taggings, [:taggable_id, :taggable_type, :context] + end + + def self.down + remove_index :taggings, [:taggable_id, :taggable_type, :context] + end +end diff --git a/db/migrate/20180707142419_change_collation_for_tag_names.acts_as_taggable_on_engine.rb b/db/migrate/20180707142419_change_collation_for_tag_names.acts_as_taggable_on_engine.rb new file mode 100644 index 0000000..f119b16 --- /dev/null +++ b/db/migrate/20180707142419_change_collation_for_tag_names.acts_as_taggable_on_engine.rb @@ -0,0 +1,15 @@ +# This migration comes from acts_as_taggable_on_engine (originally 5) +# This migration is added to circumvent issue #623 and have special characters +# work properly +if ActiveRecord.gem_version >= Gem::Version.new('5.0') + class ChangeCollationForTagNames < ActiveRecord::Migration[4.2]; end +else + class ChangeCollationForTagNames < ActiveRecord::Migration; end +end +ChangeCollationForTagNames.class_eval do + def up + if ActsAsTaggableOn::Utils.using_mysql? + execute("ALTER TABLE tags MODIFY name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin;") + end + end +end diff --git a/db/migrate/20180707142420_add_missing_indexes_on_taggings.acts_as_taggable_on_engine.rb b/db/migrate/20180707142420_add_missing_indexes_on_taggings.acts_as_taggable_on_engine.rb new file mode 100644 index 0000000..94e1f2e --- /dev/null +++ b/db/migrate/20180707142420_add_missing_indexes_on_taggings.acts_as_taggable_on_engine.rb @@ -0,0 +1,23 @@ +# This migration comes from acts_as_taggable_on_engine (originally 6) +if ActiveRecord.gem_version >= Gem::Version.new('5.0') + class AddMissingIndexesOnTaggings < ActiveRecord::Migration[4.2]; end +else + class AddMissingIndexesOnTaggings < ActiveRecord::Migration; end +end +AddMissingIndexesOnTaggings.class_eval do + def change + add_index :taggings, :tag_id unless index_exists? :taggings, :tag_id + add_index :taggings, :taggable_id unless index_exists? :taggings, :taggable_id + add_index :taggings, :taggable_type unless index_exists? :taggings, :taggable_type + add_index :taggings, :tagger_id unless index_exists? :taggings, :tagger_id + add_index :taggings, :context unless index_exists? :taggings, :context + + unless index_exists? :taggings, [:tagger_id, :tagger_type] + add_index :taggings, [:tagger_id, :tagger_type] + end + + unless index_exists? :taggings, [:taggable_id, :taggable_type, :tagger_id, :context], name: 'taggings_idy' + add_index :taggings, [:taggable_id, :taggable_type, :tagger_id, :context], name: 'taggings_idy' + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 0279d8e..192c9c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180704144707) do +ActiveRecord::Schema.define(version: 20180707142420) do create_table "blogs", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin" do |t| t.string "title" @@ -238,6 +238,31 @@ ActiveRecord::Schema.define(version: 20180704144707) do t.datetime "updated_at", null: false end + create_table "taggings", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" do |t| + t.integer "tag_id" + t.string "taggable_type" + t.integer "taggable_id" + t.string "tagger_type" + t.integer "tagger_id" + t.string "context", limit: 128 + t.datetime "created_at" + t.index ["context"], name: "index_taggings_on_context" + t.index ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], name: "taggings_idx", unique: true + t.index ["tag_id"], name: "index_taggings_on_tag_id" + t.index ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context" + t.index ["taggable_id", "taggable_type", "tagger_id", "context"], name: "taggings_idy" + t.index ["taggable_id"], name: "index_taggings_on_taggable_id" + t.index ["taggable_type"], name: "index_taggings_on_taggable_type" + t.index ["tagger_id", "tagger_type"], name: "index_taggings_on_tagger_id_and_tagger_type" + t.index ["tagger_id"], name: "index_taggings_on_tagger_id" + end + + create_table "tags", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" do |t| + t.string "name", limit: 255, collation: "utf8_bin" + t.integer "taggings_count", default: 0 + t.index ["name"], name: "index_tags_on_name", unique: true + end + create_table "updates", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" do |t| t.bigint "stream_id" t.text "body" diff --git a/vendor/assets/javascripts/tags-input.js b/vendor/assets/javascripts/tags-input.js new file mode 100755 index 0000000..878339e --- /dev/null +++ b/vendor/assets/javascripts/tags-input.js @@ -0,0 +1,2 @@ +(function(global,factory){if(typeof define === 'function' && define.amd){define(['exports','module'],factory);}else if(typeof exports !== 'undefined' && typeof module !== 'undefined'){factory(exports,module);}else {var mod={exports:{}};factory(mod.exports,mod);global.tagsInput = mod.exports;}})(this,function(exports,module){'use strict';module.exports = tagsInput;var BACKSPACE=8,TAB=9,ENTER=13,LEFT=37,RIGHT=39,DELETE=46,COMMA=188;var SEPERATOR=',';var COPY_PROPS='placeholder pattern spellcheck autocomplete autocapitalize autofocus accessKey accept lang minLength maxLength required'.split(' ');function tagsInput(input){function createElement(type,name,text,attributes){var el=document.createElement(type);if(name)el.className = name;if(text)el.textContent = text;for(var key in attributes) {el.setAttribute('data-' + key,attributes[key]);}return el;}function $(selector,all){return all === true?Array.prototype.slice.call(base.querySelectorAll(selector)):base.querySelector(selector);}function getValue(){return $('.tag',true).map(function(tag){return tag.textContent;}).concat(base.input.value || []).join(SEPERATOR);}function setValue(value){$('.tag',true).forEach(function(t){return base.removeChild(t);});savePartialInput(value);}function save(){input.value = getValue();input.dispatchEvent(new Event('change'));}function addTag(text){if(~text.indexOf(SEPERATOR))text = text.split(SEPERATOR);if(Array.isArray(text))return text.forEach(addTag);var tag=text && text.trim();if(!tag)return false;if(!input.getAttribute('duplicates')){var _ret=(function(){var exisingTag=$('[data-tag="' + tag + '"]');if(exisingTag){exisingTag.classList.add('dupe');setTimeout(function(){return exisingTag.classList.remove('dupe');},100);return {v:false};}})();if(typeof _ret === 'object')return _ret.v;}base.insertBefore(createElement('span','tag',tag,{tag:tag}),base.input);}function select(el){var sel=$('.selected');if(sel)sel.classList.remove('selected');if(el)el.classList.add('selected');}function setInputWidth(){var last=$('.tag',true).pop(),w=base.offsetWidth;if(!w)return;base.input.style.width = Math.max(w - (last?last.offsetLeft + last.offsetWidth:5) - 5,w / 4) + 'px';}function savePartialInput(value){if(typeof value !== 'string' && !Array.isArray(value)){value = base.input.value || input.value;}if(addTag(value) !== false){base.input.value = '';save();setInputWidth();}}function refocus(e){if(e.target.classList.contains('tag'))select(e.target);if(e.target === base.input)return select();base.input.focus();e.preventDefault();return false;}var base=createElement('div','tags-input'),sib=input.nextSibling;input.parentNode[sib?'insertBefore':'appendChild'](base,sib);input.style.cssText = 'position:absolute;left:0;top:-99px;width:1px;height:1px;opacity:0.01;';input.tabIndex = -1;base.input = createElement('input');base.input.setAttribute('type','text');COPY_PROPS.forEach(function(prop){if(input[prop] !== base.input[prop]){base.input[prop] = input[prop];try{delete input[prop];}catch(e) {}}});base.appendChild(base.input);input.addEventListener('focus',function(){base.input.focus();});base.input.addEventListener('focus',function(){base.classList.add('focus');select();});base.input.addEventListener('blur',function(){base.classList.remove('focus');select();savePartialInput();});base.input.addEventListener('keydown',function(e){var el=base.input,key=e.keyCode || e.which,selectedTag=$('.tag.selected'),pos=el.selectionStart === el.selectionEnd && el.selectionStart,last=$('.tag',true).pop();setInputWidth();if(key === ENTER || key === COMMA || key === TAB){if(!el.value && key !== COMMA)return;savePartialInput();}else if(key === DELETE && selectedTag){if(selectedTag.nextSibling !== base.input)select(selectedTag.nextSibling);base.removeChild(selectedTag);setInputWidth();save();}else if(key === BACKSPACE){if(selectedTag){select(selectedTag.previousSibling);base.removeChild(selectedTag);setInputWidth();save();}else if(last && pos === 0){select(last);}else {return;}}else if(key === LEFT){if(selectedTag){if(selectedTag.previousSibling){select(selectedTag.previousSibling);}}else if(pos !== 0){return;}else {select(last);}}else if(key === RIGHT){if(!selectedTag)return;select(selectedTag.nextSibling);}else {return select();}e.preventDefault();return false;});base.input.addEventListener('input',function(){input.value = getValue();input.dispatchEvent(new Event('input'));});base.input.addEventListener('paste',function(){return setTimeout(savePartialInput,0);});base.addEventListener('mousedown',refocus);base.addEventListener('touchstart',refocus);base.setValue = setValue;base.getValue = getValue;savePartialInput();}tagsInput.enhance = tagsInput.tagsInput = tagsInput;}); +//# sourceMappingURL=tags-input.js.map \ No newline at end of file diff --git a/vendor/assets/stylesheets/tags-input.css b/vendor/assets/stylesheets/tags-input.css new file mode 100755 index 0000000..ef4477b --- /dev/null +++ b/vendor/assets/stylesheets/tags-input.css @@ -0,0 +1,2 @@ +.tags-input{display:inline-block;padding:0 2px;background:#FFF;border:1px solid #CCC;width:16em;border-radius:2px;box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.tags-input .tag{display:inline-block;background:#EEE;color:#444;padding:0 4px;margin:2px;border:1px solid #CCC;border-radius:2px;font:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;transition:all .1s ease}.tags-input .tag.selected{background-color:#777;border-color:#777;color:#EEE}.tags-input .tag.dupe{-webkit-transform:scale3d(1.2,1.2,1.2);transform:scale3d(1.2,1.2,1.2);background-color:#FCC;border-color:#700}.tags-input input{-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;display:inline-block!important;padding:3px;margin:0!important;background:0 0!important;border:none!important;box-shadow:none!important;font:inherit!important;font-size:100%!important;outline:0!important}.tags-input .selected~input{opacity:.3} +/*# sourceMappingURL=tags-input.css.map */ \ No newline at end of file -- cgit 1.4.1