beautiful_scaffold 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +12 -2
- data/Gemfile +1 -1
- data/lib/beautiful_scaffold/version.rb +1 -1
- data/lib/generators/USAGE +24 -12
- data/lib/generators/beautiful_jointable_generator.rb +2 -4
- data/lib/generators/beautiful_scaffold_common_methods.rb +5 -1
- data/lib/generators/beautiful_scaffold_generator.rb +0 -4
- data/lib/generators/templates/app/assets/javascripts/application-bs.js +0 -1
- data/lib/generators/templates/app/assets/javascripts/beautiful_scaffold.js +14 -28
- data/lib/generators/templates/app/assets/stylesheets/application-bs.css +0 -1
- data/lib/generators/templates/app/views/_form_habtm_tag.html.erb +3 -3
- data/lib/generators/templates/app/views/layout.html.erb +3 -0
- metadata +2 -4
- data/lib/generators/templates/app/assets/javascripts/tagit.js +0 -489
- data/lib/generators/templates/app/assets/stylesheets/tagit-dark-grey.css +0 -135
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c90c697cd1e3c71ed04460ed4f75cc9320e6a843fb3df59eb605dc294e46ce19
|
4
|
+
data.tar.gz: 7891a26affac91b9251b4364a279b2ecd340decf6b4ce34f5837006bfa995286
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98703dfffcad9793f1c3391c7016ed558f35f8fb4c6ffa0f2dcac9c501033dd40dbb18f7440c32662a0eb7d81cb0be8bfe512f4f0239c3af843e939583709903
|
7
|
+
data.tar.gz: dc4a1c435dc7117b840afc0d1b686f52790ca8203e64d6cb5d4463a5fc8a53c1128e227e01b5733c7763e7367a7855b092f3902ce3b2e09092a063a64d75bae9
|
data/CHANGELOG
CHANGED
@@ -4,10 +4,20 @@
|
|
4
4
|
|
5
5
|
* bugfix
|
6
6
|
|
7
|
-
|
8
|
-
== Soon
|
7
|
+
== TODO
|
9
8
|
|
10
9
|
ActionText / trix.
|
10
|
+
Include pg_search for fulltext field.
|
11
|
+
Remove "image_processing" specific version + add gem 'mini_magick' (pour la génération des variants)
|
12
|
+
|
13
|
+
== 2.0.3
|
14
|
+
|
15
|
+
* bugfix
|
16
|
+
* _ids in permitted_attributes (beautiful_jointable)
|
17
|
+
|
18
|
+
* enhancement
|
19
|
+
* Replace tagit by select2 (+ _ids in permitted_attributes)
|
20
|
+
* Bootstrap 4.3 -> 5.1
|
11
21
|
|
12
22
|
== 2.0.2
|
13
23
|
|
data/Gemfile
CHANGED
@@ -14,7 +14,7 @@ group :test do
|
|
14
14
|
'prawn' => nil, #'2.1.0',
|
15
15
|
'prawn-table' => nil, #'0.2.2',
|
16
16
|
'sanitize' => nil,
|
17
|
-
'bootstrap' => '~>
|
17
|
+
'bootstrap' => '~> 5.1.0',
|
18
18
|
'font-awesome-rails' => '4.7.0.7',
|
19
19
|
'momentjs-rails' => '>= 2.9.0',
|
20
20
|
'bootstrap4-datetime-picker-rails' => nil,
|
data/lib/generators/USAGE
CHANGED
@@ -1,18 +1,30 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#
|
2
|
+
# How to test Beautiful-Scaffold in a fresh rails app
|
3
|
+
#
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
rails generate beautiful_migration AddColorToProducts color:string
|
5
|
+
rails new my_test_app
|
6
|
+
cd my_test_app
|
7
|
+
echo "gem 'beautiful_scaffold', '2.0.2'" >> Gemfile
|
8
|
+
bundle update
|
10
9
|
|
11
|
-
|
10
|
+
rails generate beautiful_scaffold family name:string description:wysiwyg
|
11
|
+
rails generate beautiful_scaffold product family:references price:price name:string visible:boolean description:wysiwyg
|
12
|
+
rails generate beautiful_scaffold user pseudo:string email:string
|
13
|
+
rails generate beautiful_scaffold tag name:string
|
12
14
|
|
13
|
-
|
15
|
+
rails generate beautiful_jointable product tag
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
rails generate beautiful_migration AddColorSecToProducts color_secondary:color
|
18
|
+
|
19
|
+
rails generate beautiful_locale fr
|
20
|
+
|
21
|
+
rails generate beautiful_sorcery
|
22
|
+
rails generate beautiful_cancancan
|
23
|
+
|
24
|
+
rake db:migrate
|
25
|
+
rails server
|
26
|
+
|
27
|
+
# Open a web browser http://localhost:3000/
|
28
|
+
# Register, and copy/paste the link you see in the rails server log : e.g. http://localhost:3000/users/axfEQ8i38ZtXTi-oTzuw/activate
|
17
29
|
|
18
30
|
|
@@ -42,10 +42,8 @@ class BeautifulJointableGenerator < Rails::Generators::Base
|
|
42
42
|
# Add habtm relation
|
43
43
|
inject_into_file("app/models/#{engine_name}#{sorted_model[0]}.rb", "\n #{engine_name.present? ? ' ' : ''}has_and_belongs_to_many :#{sorted_model[1].pluralize}", :after => "ApplicationRecord")
|
44
44
|
inject_into_file("app/models/#{engine_name}#{sorted_model[1]}.rb", "\n #{engine_name.present? ? ' ' : ''}has_and_belongs_to_many :#{sorted_model[0].pluralize}", :after => "ApplicationRecord")
|
45
|
-
inject_into_file("app/models/#{engine_name}#{sorted_model[0]}.rb", "{ :#{sorted_model[1]}_ids => [] }, ", :after =>
|
46
|
-
return
|
47
|
-
inject_into_file("app/models/#{engine_name}#{sorted_model[1]}.rb", "{ :#{sorted_model[0]}_ids => [] }, ", :after => "permitted_attributes
|
48
|
-
return ")
|
45
|
+
inject_into_file("app/models/#{engine_name}#{sorted_model[0]}.rb", "{ :#{sorted_model[1]}_ids => [] }, ", :after => /permitted_attributes#{regexp_an_string}return /)
|
46
|
+
inject_into_file("app/models/#{engine_name}#{sorted_model[1]}.rb", "{ :#{sorted_model[0]}_ids => [] }, ", :after => /permitted_attributes#{regexp_an_string}return /)
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
@@ -51,6 +51,10 @@ module BeautifulScaffoldCommonMethods
|
|
51
51
|
return result
|
52
52
|
end
|
53
53
|
|
54
|
+
def regexp_an_string
|
55
|
+
'\s*\R\s*'
|
56
|
+
end
|
57
|
+
|
54
58
|
############
|
55
59
|
# Models
|
56
60
|
############
|
@@ -195,7 +199,7 @@ module BeautifulScaffoldCommonMethods
|
|
195
199
|
'prawn-table' => nil, #'0.2.2',
|
196
200
|
'sanitize' => nil,
|
197
201
|
#'twitter-bootstrap-rails' => '3.2.2', # Bootstrap 3 for Rails 6+
|
198
|
-
'bootstrap' => '~>
|
202
|
+
'bootstrap' => '~> 5.1.0', # Bootstrap 4 for Rails 6+
|
199
203
|
'font-awesome-sass' => '~> 5.13.0',
|
200
204
|
'momentjs-rails' => '>= 2.9.0',
|
201
205
|
'bootstrap4-datetime-picker-rails' => nil,
|
@@ -62,7 +62,6 @@ class BeautifulScaffoldGenerator < Rails::Generators::Base
|
|
62
62
|
# Css
|
63
63
|
bc_css = [
|
64
64
|
"beautiful-scaffold.css.scss",
|
65
|
-
"tagit-dark-grey.css",
|
66
65
|
"bootstrap-wysihtml5.css"
|
67
66
|
]
|
68
67
|
|
@@ -79,7 +78,6 @@ class BeautifulScaffoldGenerator < Rails::Generators::Base
|
|
79
78
|
|
80
79
|
if !engine_name.blank?
|
81
80
|
['beautiful-scaffold',
|
82
|
-
'tagit-dark-grey',
|
83
81
|
'bootstrap-wysihtml5'].each do |fileassets|
|
84
82
|
gsub_file File.join(stylesheetspath_dest, "application-bs.scss"), " *= require #{fileassets}", " *= require #{engine_name}#{fileassets}"
|
85
83
|
end
|
@@ -100,7 +98,6 @@ class BeautifulScaffoldGenerator < Rails::Generators::Base
|
|
100
98
|
"bootstrap-datetimepicker-for-beautiful-scaffold.js",
|
101
99
|
"jquery-barcode.js",
|
102
100
|
"jstree.min.js",
|
103
|
-
"tagit.js",
|
104
101
|
"a-wysihtml5-0.3.0.min.js",
|
105
102
|
"bootstrap-wysihtml5.js",
|
106
103
|
"fixed_menu.js"
|
@@ -114,7 +111,6 @@ class BeautifulScaffoldGenerator < Rails::Generators::Base
|
|
114
111
|
['a-wysihtml5-0.3.0.min',
|
115
112
|
'bootstrap-datetimepicker-for-beautiful-scaffold',
|
116
113
|
'bootstrap-wysihtml5',
|
117
|
-
'tagit.js',
|
118
114
|
'jstree.min.js',
|
119
115
|
'jquery-barcode',
|
120
116
|
'beautiful_scaffold',
|
@@ -18,37 +18,23 @@ function bs_init(){
|
|
18
18
|
return false;
|
19
19
|
});
|
20
20
|
|
21
|
-
//
|
21
|
+
// habtm (select2 - tag)
|
22
22
|
$('.bs-tagit').each(function( index ) {
|
23
23
|
var tagitelt = this;
|
24
|
-
$(tagitelt).
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
data: data_to_send,
|
38
|
-
dataType: "json",
|
39
|
-
success: function( data ) {
|
40
|
-
response( $.map( data, function( item ) {
|
41
|
-
return { label: item[result], value: item.id };
|
42
|
-
}));
|
43
|
-
}
|
44
|
-
});
|
45
|
-
},
|
46
|
-
triggerKeys:['enter', 'comma', 'tab'],
|
47
|
-
select : true,
|
48
|
-
allowNewTags : false
|
24
|
+
$(tagitelt).select2({
|
25
|
+
ajax: {
|
26
|
+
processResults: function (data) {
|
27
|
+
// Transforms the top-level key of the response object from 'items' to 'results'
|
28
|
+
return {
|
29
|
+
results: $.map(data, function (obj) {
|
30
|
+
obj.id = obj.id;
|
31
|
+
obj.text = obj.caption;
|
32
|
+
return obj;
|
33
|
+
})
|
34
|
+
};
|
35
|
+
}
|
36
|
+
}
|
49
37
|
});
|
50
|
-
// Bootstrap...
|
51
|
-
$('.tagit-input').addClass("form-control");
|
52
38
|
});
|
53
39
|
|
54
40
|
// Wysiwyg field
|
@@ -20,13 +20,13 @@
|
|
20
20
|
<div class="form-group">
|
21
21
|
<%= f.label plural_linked_model_name.to_sym, t(plural_linked_model_name.to_sym, :default => plural_linked_model_name.capitalize), :class => "control-label" %>
|
22
22
|
<div>
|
23
|
-
<
|
23
|
+
<select multiple="multiple" class="form-control bs-tagit" id="<%= model_name %>_<%= linked_model_name %>_ids" name="<%= model_name %>[<%= linked_model_name %>_ids][]" data-tags="true" data-placeholder="<%= t('select-an-option', default: 'Select an option') %>" data-allow-clear="true" data-ajax--cache="true" data-ajax--url="<%= path_namespace %><%= plural_linked_model_name %>/search_and_filter.json" data-param="q[<%= field_to_search_for_linked_model %>_cont]" data-result="<%= attr_to_show %>">
|
24
24
|
<% begin %>
|
25
25
|
<% for elt in model_class.send(plural_linked_model_name) %>
|
26
|
-
<
|
26
|
+
<option selected="selected" data-value="<%= elt.id %>"><%= elt.caption %></option>
|
27
27
|
<% end %>
|
28
28
|
<% rescue %>
|
29
29
|
<% end %>
|
30
|
-
</
|
30
|
+
</select>
|
31
31
|
</div>
|
32
32
|
</div>
|
@@ -15,6 +15,9 @@
|
|
15
15
|
<%%= stylesheet_link_tag "<%= engine_name %>application-bs" %>
|
16
16
|
<%%= javascript_include_tag "<%= engine_name %>application-bs" %>
|
17
17
|
|
18
|
+
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
19
|
+
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
20
|
+
|
18
21
|
<%%= csrf_meta_tags %>
|
19
22
|
<%%= yield :head %>
|
20
23
|
</head>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beautiful_scaffold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sylvain Claudel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Beautiful Scaffold generate a complete scaffold (sort, export, paginate
|
14
14
|
and filter data) http://beautiful-scaffold.rivsc.ovh
|
@@ -49,11 +49,9 @@ files:
|
|
49
49
|
- lib/generators/templates/app/assets/javascripts/jquery-barcode.js
|
50
50
|
- lib/generators/templates/app/assets/javascripts/jstree.min.js
|
51
51
|
- lib/generators/templates/app/assets/javascripts/modernizr.custom.js
|
52
|
-
- lib/generators/templates/app/assets/javascripts/tagit.js
|
53
52
|
- lib/generators/templates/app/assets/stylesheets/application-bs.css
|
54
53
|
- lib/generators/templates/app/assets/stylesheets/beautiful-scaffold.css.scss
|
55
54
|
- lib/generators/templates/app/assets/stylesheets/bootstrap-wysihtml5.css
|
56
|
-
- lib/generators/templates/app/assets/stylesheets/tagit-dark-grey.css
|
57
55
|
- lib/generators/templates/app/assets/stylesheets/themes/default-dark/32px.png
|
58
56
|
- lib/generators/templates/app/assets/stylesheets/themes/default-dark/40px.png
|
59
57
|
- lib/generators/templates/app/assets/stylesheets/themes/default-dark/style.scss
|
@@ -1,489 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* INFORMATION
|
3
|
-
* ---------------------------
|
4
|
-
* Owner: jquery.webspirited.com
|
5
|
-
* Developer: Matthew Hailwood
|
6
|
-
* ---------------------------
|
7
|
-
*/
|
8
|
-
|
9
|
-
(function ($) {
|
10
|
-
$.widget("ui.tagit", {
|
11
|
-
|
12
|
-
// default options
|
13
|
-
options:{
|
14
|
-
//Maps directly to the jQuery-ui Autocomplete option
|
15
|
-
tagSource:[],
|
16
|
-
//What keys should trigger the completion of a tag
|
17
|
-
triggerKeys:['enter', 'space', 'comma', 'tab'],
|
18
|
-
//array method for setting initial tags
|
19
|
-
initialTags:[],
|
20
|
-
//minimum length of tags
|
21
|
-
minLength:1,
|
22
|
-
//should an html select be rendered to allow for normal form submission
|
23
|
-
select:false,
|
24
|
-
//if false only tags from `tagSource` are able to be entered
|
25
|
-
allowNewTags:true,
|
26
|
-
//should tag and Tag be treated as identical
|
27
|
-
caseSensitive:false,
|
28
|
-
//should tags be drag-and-drop sortable?
|
29
|
-
//true: entire tag is draggable
|
30
|
-
//'handle': a handle is rendered which is draggable
|
31
|
-
sortable:false,
|
32
|
-
//color to highlight text when a duplicate tag is entered
|
33
|
-
highlightOnExistColor:'#0F0',
|
34
|
-
//empty search on focus
|
35
|
-
emptySearch:true,
|
36
|
-
//callback function for when tags are changed
|
37
|
-
//tagValue: value of tag that was changed
|
38
|
-
//action e.g. removed, added, sorted
|
39
|
-
tagsChanged:function (tagValue, action, element) {
|
40
|
-
;
|
41
|
-
},
|
42
|
-
maxTags:undefined,
|
43
|
-
//should 'paste' event trigger 'blur', thus potentially adding a new tag
|
44
|
-
// (true for backwards compatibility)
|
45
|
-
blurOnPaste:true
|
46
|
-
},
|
47
|
-
|
48
|
-
_splitAt:/\ |,/g,
|
49
|
-
_existingAtIndex:0,
|
50
|
-
_keys:{
|
51
|
-
backspace:[8],
|
52
|
-
enter:[13],
|
53
|
-
space:[32],
|
54
|
-
comma:[44, 188],
|
55
|
-
tab:[9]
|
56
|
-
},
|
57
|
-
|
58
|
-
_sortable:{
|
59
|
-
sorting:-1
|
60
|
-
},
|
61
|
-
|
62
|
-
//initialization function
|
63
|
-
_create:function () {
|
64
|
-
|
65
|
-
var self = this;
|
66
|
-
this.tagsArray = [];
|
67
|
-
this.timer = null;
|
68
|
-
|
69
|
-
//add class "tagit" for theming
|
70
|
-
this.element.addClass("tagit");
|
71
|
-
|
72
|
-
//add any initial tags added through html to the array
|
73
|
-
this.element.children('li').each(function () {
|
74
|
-
var tag = $(this);
|
75
|
-
var tagValue = tag.attr('tagValue') || tag.data('value');
|
76
|
-
self.options.initialTags.push({label:tag.text(), value:(tagValue ? tagValue : tag.text())});
|
77
|
-
});
|
78
|
-
|
79
|
-
//setup split according to the trigger keys
|
80
|
-
self._splitAt = null;
|
81
|
-
if ($.inArray('space', self.options.triggerKeys) > 0 && $.inArray('comma', self.options.triggerKeys) > 0)
|
82
|
-
self._splitAt = /\ |,/g;
|
83
|
-
else if ($.inArray('space', self.options.triggerKeys) > 0)
|
84
|
-
self._splitAt = /\ /g;
|
85
|
-
else if ($.inArray('comma', self.options.triggerKeys) > 0)
|
86
|
-
self._splitAt = /,/g;
|
87
|
-
|
88
|
-
//add the html input
|
89
|
-
this.element.html('<li class="tagit-new"><input class="tagit-input" type="text" /></li>');
|
90
|
-
|
91
|
-
this.input = this.element.find(".tagit-input");
|
92
|
-
|
93
|
-
//setup click handler
|
94
|
-
$(this.element).click(function (e) {
|
95
|
-
if ($(e.target).hasClass('tagit-close')) {
|
96
|
-
// Removes a tag when the little 'x' is clicked.
|
97
|
-
var parent = $(e.target).parent();
|
98
|
-
|
99
|
-
var tag = self.tagsArray[parent.index()];
|
100
|
-
|
101
|
-
tag.element.remove();
|
102
|
-
self._popTag(tag);
|
103
|
-
}
|
104
|
-
else {
|
105
|
-
self.input.focus();
|
106
|
-
if (self.options.emptySearch && $(e.target).hasClass('tagit-input') && self.input.val() == '' && self.input.autocomplete != undefined) {
|
107
|
-
self.input.autocomplete('search');
|
108
|
-
}
|
109
|
-
}
|
110
|
-
});
|
111
|
-
|
112
|
-
//setup autocomplete handler
|
113
|
-
var os = this.options.select;
|
114
|
-
this.options.appendTo = this.element;
|
115
|
-
this.options.source = this.options.tagSource;
|
116
|
-
this.options.select = function (event, ui) {
|
117
|
-
self.input.data('autoCompleteTag', true);
|
118
|
-
clearTimeout(self.timer);
|
119
|
-
if (self.options.maxTags !== undefined && self.tagsArray.length == self.options.maxTags) {
|
120
|
-
self.input.val("");
|
121
|
-
}
|
122
|
-
else {
|
123
|
-
if (ui.item.label === undefined)
|
124
|
-
self._addTag(ui.item.value);
|
125
|
-
else
|
126
|
-
self._addTag(ui.item.label, ui.item.value);
|
127
|
-
}
|
128
|
-
|
129
|
-
return false;
|
130
|
-
},
|
131
|
-
|
132
|
-
this.options.focus = function (event, ui) {
|
133
|
-
if (ui.item.label !== undefined && /^key/.test(event.originalEvent.originalEvent.type)) {
|
134
|
-
self.input.val(ui.item.label);
|
135
|
-
self.input.data('value', ui.item.value);
|
136
|
-
return false;
|
137
|
-
}
|
138
|
-
};
|
139
|
-
this.options.autoFocus = !this.options.allowNewTags;
|
140
|
-
this.input.autocomplete(this.options);
|
141
|
-
this.options.select = os;
|
142
|
-
|
143
|
-
//setup keydown handler
|
144
|
-
this.input.keydown(function (e) {
|
145
|
-
var lastLi = self.element.children(".tagit-choice:last");
|
146
|
-
if (e.which == self._keys.backspace)
|
147
|
-
return self._backspace(lastLi);
|
148
|
-
|
149
|
-
if (self._isInitKey(e.which) && !(self._isTabKey(e.which) && this.value == '' && !self.input.data('autoCompleteTag'))) {
|
150
|
-
e.preventDefault();
|
151
|
-
|
152
|
-
self.input.data('autoCompleteTag', false);
|
153
|
-
|
154
|
-
if (!self.options.allowNewTags || (self.options.maxTags !== undefined && self.tagsArray.length == self.options.maxTags)) {
|
155
|
-
self.input.val("");
|
156
|
-
}
|
157
|
-
else if (self.options.allowNewTags && $(this).val().length >= self.options.minLength) {
|
158
|
-
self._addTag($(this).val());
|
159
|
-
}
|
160
|
-
}
|
161
|
-
|
162
|
-
if (self.options.maxLength !== undefined && self.input.val().length == self.options.maxLength) {
|
163
|
-
e.preventDefault();
|
164
|
-
}
|
165
|
-
|
166
|
-
if (lastLi.hasClass('selected'))
|
167
|
-
lastLi.removeClass('selected');
|
168
|
-
|
169
|
-
self.lastKey = e.which;
|
170
|
-
});
|
171
|
-
|
172
|
-
this.input.bind("paste", function (e) {
|
173
|
-
if (self.options.blurOnPaste) {
|
174
|
-
var input = $(this);
|
175
|
-
self.timer = setTimeout(function () { input.blur(); }, 0);
|
176
|
-
}
|
177
|
-
});
|
178
|
-
|
179
|
-
//setup blur handler
|
180
|
-
this.input.blur(function (e) {
|
181
|
-
self.currentLabel = $(this).val();
|
182
|
-
self.currentValue = $(this).data('value');
|
183
|
-
if (self.options.allowNewTags) {
|
184
|
-
self.timer = setTimeout(function () {
|
185
|
-
self._addTag(self.currentLabel, self.currentValue);
|
186
|
-
self.currentValue = '';
|
187
|
-
self.currentLabel = '';
|
188
|
-
}, 400);
|
189
|
-
}
|
190
|
-
$(this).val('').removeData('value');
|
191
|
-
return false;
|
192
|
-
});
|
193
|
-
|
194
|
-
//define missing trim function for strings
|
195
|
-
if (!String.prototype.trim) {
|
196
|
-
String.prototype.trim = function () {
|
197
|
-
return this.replace(/^\s+|\s+$/g, '');
|
198
|
-
};
|
199
|
-
}
|
200
|
-
|
201
|
-
if (this.options.select) {
|
202
|
-
this.select = $('<select class="tagit-hiddenSelect" name="' +
|
203
|
-
(this.element.attr('name') || this.element.data('name')) +
|
204
|
-
'" multiple="multiple"></select>');
|
205
|
-
this.element.after(this.select);
|
206
|
-
}
|
207
|
-
this._initialTags();
|
208
|
-
|
209
|
-
//setup sortable handler
|
210
|
-
if (self.options.sortable !== false) {
|
211
|
-
|
212
|
-
var soptions = {
|
213
|
-
items:'.tagit-choice',
|
214
|
-
containment:'parent',
|
215
|
-
opacity: 0.6,
|
216
|
-
tolerance: 'pointer',
|
217
|
-
start:function (event, ui) {
|
218
|
-
self._sortable.tag = $(ui.item);
|
219
|
-
self._sortable.origIndex = self._sortable.tag.index();
|
220
|
-
},
|
221
|
-
update:function (event, ui) {
|
222
|
-
self._sortable.newIndex = self._sortable.tag.index();
|
223
|
-
self._moveTag(self._sortable.origIndex, self._sortable.newIndex);
|
224
|
-
if(self.options.tagsChanged){
|
225
|
-
var tag = self.tagsArray[self._sortable.newIndex];
|
226
|
-
self.options.tagsChanged(tag.value, 'moved', tag.element);
|
227
|
-
}
|
228
|
-
}
|
229
|
-
};
|
230
|
-
|
231
|
-
if (self.options.sortable == 'handle') {
|
232
|
-
soptions.handle = 'a.ui-icon';
|
233
|
-
soptions.cursor = 'move';
|
234
|
-
}
|
235
|
-
|
236
|
-
self.element.sortable(soptions);
|
237
|
-
}
|
238
|
-
|
239
|
-
},
|
240
|
-
|
241
|
-
_popSelect:function (tag) {
|
242
|
-
$('option:eq(' + tag.index + ')', this.select).remove();
|
243
|
-
this.select.change();
|
244
|
-
},
|
245
|
-
|
246
|
-
_addSelect:function (tag) {
|
247
|
-
this.select.append('<option selected="selected" value="' + tag.value + '">' + tag.label + '</option>');
|
248
|
-
this.select.change();
|
249
|
-
},
|
250
|
-
|
251
|
-
_popTag:function (tag) {
|
252
|
-
|
253
|
-
//are we removing the last tag or a specific tag?
|
254
|
-
if (tag === undefined)
|
255
|
-
tag = this.tagsArray.pop();
|
256
|
-
else
|
257
|
-
this.tagsArray.splice(tag.index, 1);
|
258
|
-
|
259
|
-
|
260
|
-
//maintain the indexes
|
261
|
-
for (var ind in this.tagsArray)
|
262
|
-
this.tagsArray[ind].index = ind;
|
263
|
-
|
264
|
-
if (this.options.select)
|
265
|
-
this._popSelect(tag);
|
266
|
-
if (this.options.tagsChanged)
|
267
|
-
this.options.tagsChanged(tag.value || tag.label, 'popped', tag);
|
268
|
-
return;
|
269
|
-
},
|
270
|
-
|
271
|
-
_addTag:function (label, value) {
|
272
|
-
this.input.autocomplete('close').val("");
|
273
|
-
|
274
|
-
//are we trying to add a tag that should be split?
|
275
|
-
if (this._splitAt && label.search(this._splitAt) > 0) {
|
276
|
-
var result = label.split(this._splitAt);
|
277
|
-
for (var i = 0; i < result.length; i++)
|
278
|
-
this._addTag(result[i], value);
|
279
|
-
return;
|
280
|
-
}
|
281
|
-
|
282
|
-
label = label.replace(/,+$/, "").trim();
|
283
|
-
|
284
|
-
if (label == "")
|
285
|
-
return false;
|
286
|
-
|
287
|
-
var tagExists = this._exists(label, value);
|
288
|
-
if (tagExists !== false) {
|
289
|
-
this._highlightExisting(tagExists);
|
290
|
-
return false;
|
291
|
-
}
|
292
|
-
|
293
|
-
var tag = this.tag(label, value);
|
294
|
-
tag.element = $('<li class="tagit-choice"'
|
295
|
-
+ (value !== undefined ? ' tagValue="' + value + '"' : '') + '>'
|
296
|
-
+ (this.options.sortable == 'handle' ? '<a class="ui-icon ui-icon-grip-dotted-vertical" style="float:left"></a>' : '')
|
297
|
-
+ label + '<a class="tagit-close">x</a></li>');
|
298
|
-
tag.element.insertBefore(this.input.parent());
|
299
|
-
this.tagsArray.push(tag);
|
300
|
-
|
301
|
-
this.input.val("");
|
302
|
-
|
303
|
-
if (this.options.select)
|
304
|
-
this._addSelect(tag);
|
305
|
-
if (this.options.tagsChanged)
|
306
|
-
this.options.tagsChanged(tag.label, 'added', tag.element);
|
307
|
-
return true;
|
308
|
-
},
|
309
|
-
|
310
|
-
_exists:function (label, value) {
|
311
|
-
if (this.tagsArray.length == 0)
|
312
|
-
return false;
|
313
|
-
|
314
|
-
label = this._lowerIfCaseInsensitive(label);
|
315
|
-
value = this._lowerIfCaseInsensitive(value);
|
316
|
-
|
317
|
-
for (var ind in this.tagsArray) {
|
318
|
-
if (this._lowerIfCaseInsensitive(this.tagsArray[ind].label) == label) {
|
319
|
-
if (value !== undefined) {
|
320
|
-
if (this._lowerIfCaseInsensitive(this.tagsArray[ind].value) == value)
|
321
|
-
return ind;
|
322
|
-
} else {
|
323
|
-
return ind;
|
324
|
-
}
|
325
|
-
}
|
326
|
-
}
|
327
|
-
|
328
|
-
return false;
|
329
|
-
},
|
330
|
-
|
331
|
-
_highlightExisting:function (index) {
|
332
|
-
if (this.options.highlightOnExistColor === undefined)
|
333
|
-
return;
|
334
|
-
var tag = this.tagsArray[index];
|
335
|
-
tag.element.stop();
|
336
|
-
|
337
|
-
var initialColor = tag.element.css('color');
|
338
|
-
tag.element.animate({color:this.options.highlightOnExistColor}, 100).animate({'color':initialColor}, 800);
|
339
|
-
},
|
340
|
-
|
341
|
-
_isInitKey:function (keyCode) {
|
342
|
-
var keyName = "";
|
343
|
-
for (var key in this._keys)
|
344
|
-
if ($.inArray(keyCode, this._keys[key]) != -1)
|
345
|
-
keyName = key;
|
346
|
-
|
347
|
-
if ($.inArray(keyName, this.options.triggerKeys) != -1)
|
348
|
-
return true;
|
349
|
-
return false;
|
350
|
-
},
|
351
|
-
|
352
|
-
_isTabKey:function (keyCode) {
|
353
|
-
var tabKeys = this._keys['tab'];
|
354
|
-
return $.inArray(keyCode, tabKeys) > -1;
|
355
|
-
},
|
356
|
-
|
357
|
-
_removeTag:function () {
|
358
|
-
this._popTag();
|
359
|
-
this.element.children(".tagit-choice:last").remove();
|
360
|
-
},
|
361
|
-
|
362
|
-
_backspace:function (li) {
|
363
|
-
if (this.input.val() == "") {
|
364
|
-
// When backspace is pressed, the last tag is deleted.
|
365
|
-
if (this.lastKey == this._keys.backspace) {
|
366
|
-
this._popTag();
|
367
|
-
li.remove();
|
368
|
-
this.lastKey = null;
|
369
|
-
} else {
|
370
|
-
li.addClass('selected');
|
371
|
-
this.lastKey = this._keys.backspace;
|
372
|
-
}
|
373
|
-
}
|
374
|
-
return true;
|
375
|
-
},
|
376
|
-
|
377
|
-
_initialTags:function () {
|
378
|
-
var input = this;
|
379
|
-
var _temp;
|
380
|
-
if (this.options.tagsChanged)
|
381
|
-
_temp = this.options.tagsChanged;
|
382
|
-
this.options.tagsChanged = null;
|
383
|
-
|
384
|
-
if (this.options.initialTags.length != 0) {
|
385
|
-
$(this.options.initialTags).each(function (i, element) {
|
386
|
-
if (typeof (element) == "object")
|
387
|
-
input._addTag(element.label, element.value);
|
388
|
-
else
|
389
|
-
input._addTag(element);
|
390
|
-
});
|
391
|
-
}
|
392
|
-
this.options.tagsChanged = _temp;
|
393
|
-
},
|
394
|
-
|
395
|
-
_lowerIfCaseInsensitive:function (inp) {
|
396
|
-
|
397
|
-
if (inp === undefined || typeof(inp) != typeof("a"))
|
398
|
-
return inp;
|
399
|
-
|
400
|
-
if (this.options.caseSensitive)
|
401
|
-
return inp;
|
402
|
-
|
403
|
-
return inp.toLowerCase();
|
404
|
-
|
405
|
-
},
|
406
|
-
|
407
|
-
_moveTag: function (old_index, new_index) {
|
408
|
-
this.tagsArray.splice(new_index, 0, this.tagsArray.splice(old_index, 1)[0]);
|
409
|
-
for (var ind in this.tagsArray)
|
410
|
-
this.tagsArray[ind].index = ind;
|
411
|
-
|
412
|
-
if(this.options.select){
|
413
|
-
$('option:eq(' + old_index + ')', this.select).insertBefore($('option:eq(' + new_index + ')', this.select));
|
414
|
-
}
|
415
|
-
},
|
416
|
-
tags:function () {
|
417
|
-
return this.tagsArray;
|
418
|
-
},
|
419
|
-
|
420
|
-
destroy:function () {
|
421
|
-
$.Widget.prototype.destroy.apply(this, arguments); // default destroy
|
422
|
-
this.tagsArray = [];
|
423
|
-
},
|
424
|
-
|
425
|
-
reset:function () {
|
426
|
-
this.element.find(".tagit-choice").remove();
|
427
|
-
this.tagsArray = [];
|
428
|
-
if (this.options.select) {
|
429
|
-
this.select.children().remove();
|
430
|
-
this.select.change();
|
431
|
-
}
|
432
|
-
this._initialTags();
|
433
|
-
if (this.options.tagsChanged)
|
434
|
-
this.options.tagsChanged(null, 'reset', null);
|
435
|
-
},
|
436
|
-
|
437
|
-
fill:function (tags) {
|
438
|
-
|
439
|
-
if (tags !== undefined)
|
440
|
-
this.options.initialTags = tags;
|
441
|
-
this.reset();
|
442
|
-
},
|
443
|
-
|
444
|
-
add:function (label, value) {
|
445
|
-
if(typeof(label) == "object")
|
446
|
-
return this._addTag(label.label, label.value);
|
447
|
-
else
|
448
|
-
return this._addTag(label, value);
|
449
|
-
},
|
450
|
-
|
451
|
-
autocomplete: function(){
|
452
|
-
return this.input.data("autocomplete");
|
453
|
-
},
|
454
|
-
|
455
|
-
tag:function (label, value, element) {
|
456
|
-
var self = this;
|
457
|
-
return {
|
458
|
-
label:label,
|
459
|
-
value:(value === undefined ? label : value),
|
460
|
-
element:element,
|
461
|
-
index:self.tagsArray.length
|
462
|
-
};
|
463
|
-
},
|
464
|
-
|
465
|
-
remove:function (label, value) {
|
466
|
-
if (this.tagsArray.length == 0)
|
467
|
-
return false;
|
468
|
-
|
469
|
-
label = this._lowerIfCaseInsensitive(label);
|
470
|
-
value = this._lowerIfCaseInsensitive(value);
|
471
|
-
|
472
|
-
for (var i = 0; i < this.tagsArray.length; i++) {
|
473
|
-
if (this._lowerIfCaseInsensitive(this.tagsArray[i].value) == value || this._lowerIfCaseInsensitive(this.tagsArray[i].label) == label) {
|
474
|
-
break;
|
475
|
-
}
|
476
|
-
}
|
477
|
-
|
478
|
-
if (i >= 0 && i < this.tagsArray.length) {
|
479
|
-
var tag = this.tagsArray[i];
|
480
|
-
tag.element.remove();
|
481
|
-
this._popTag(tag);
|
482
|
-
return true;
|
483
|
-
}
|
484
|
-
return false;
|
485
|
-
}
|
486
|
-
|
487
|
-
|
488
|
-
});
|
489
|
-
})(jQuery);
|
@@ -1,135 +0,0 @@
|
|
1
|
-
.ui-autocomplete {
|
2
|
-
background-color: #fff;
|
3
|
-
position: absolute;
|
4
|
-
cursor: default;
|
5
|
-
list-style: none;
|
6
|
-
margin: 25px 0 0;
|
7
|
-
padding: 0;
|
8
|
-
border: 1px solid #E5E5E5;
|
9
|
-
border-top: none;
|
10
|
-
-moz-border-radius: 0 0 10px 10px;
|
11
|
-
border-radius: 0 0 10px 10px;
|
12
|
-
-moz-box-shadow: 0 3px 5px #888;
|
13
|
-
-webkit-box-shadow: 0 3px 5px #888;
|
14
|
-
box-shadow: 0 3px 5px #888;
|
15
|
-
font-size: 12px;
|
16
|
-
}
|
17
|
-
|
18
|
-
.ui-autocomplete .ui-menu-item {
|
19
|
-
padding: 0;
|
20
|
-
margin: 0;
|
21
|
-
}
|
22
|
-
|
23
|
-
.ui-autocomplete .ui-menu-item a {
|
24
|
-
display: block;
|
25
|
-
padding: 4px 6px;
|
26
|
-
margin: 0;
|
27
|
-
text-decoration: none;
|
28
|
-
line-height: 12px;
|
29
|
-
border-bottom: 1px solid #E5E5E5;
|
30
|
-
border-top: 1px solid #fff;
|
31
|
-
color: #78959D;
|
32
|
-
|
33
|
-
}
|
34
|
-
|
35
|
-
.ui-autocomplete .ui-menu-item a.ui-state-hover,
|
36
|
-
.ui-autocomplete .ui-menu-item a.ui-state-active {
|
37
|
-
background-color: #c0d1e2;
|
38
|
-
color: #555;
|
39
|
-
border-color: #a6cef7;
|
40
|
-
}
|
41
|
-
|
42
|
-
.ui-autocomplete-loading {
|
43
|
-
background: white url(/assets/ui-anim_basic_16x16.gif) right center no-repeat;
|
44
|
-
}
|
45
|
-
|
46
|
-
ul.tagit {
|
47
|
-
cursor: text;
|
48
|
-
overflow: auto;
|
49
|
-
font-size: 14px;
|
50
|
-
width: 97%;
|
51
|
-
padding: 0px;
|
52
|
-
margin: 0px;
|
53
|
-
background: #fff;
|
54
|
-
color: #fff;
|
55
|
-
}
|
56
|
-
|
57
|
-
ul.tagit li {
|
58
|
-
-moz-border-radius: 5px;
|
59
|
-
border-radius: 5px;
|
60
|
-
display: block;
|
61
|
-
float: left;
|
62
|
-
margin: 2px 5px 2px 0;
|
63
|
-
position: relative;
|
64
|
-
}
|
65
|
-
|
66
|
-
ul.tagit.ui-sortable li.tagit-choice a.ui-icon.ui-icon-grip-dotted-vertical{
|
67
|
-
float: left;
|
68
|
-
width: 12px;
|
69
|
-
margin-left: -5px;
|
70
|
-
cursor: move;
|
71
|
-
}
|
72
|
-
|
73
|
-
ul.tagit li.tagit-choice {
|
74
|
-
background-color: #333;
|
75
|
-
border: 1px solid #333;
|
76
|
-
padding: 2px 13px 3px 4px;
|
77
|
-
}
|
78
|
-
|
79
|
-
ul.tagit li.tagit-choice.selected {
|
80
|
-
background-color: #633;
|
81
|
-
border-color: #f76464;
|
82
|
-
}
|
83
|
-
|
84
|
-
ul.tagit li.tagit-choice:hover {
|
85
|
-
background-color: #555;
|
86
|
-
border-color: #444;
|
87
|
-
}
|
88
|
-
|
89
|
-
ul.tagit li.tagit-new {
|
90
|
-
clear: left;
|
91
|
-
padding: 2px 4px 3px;
|
92
|
-
padding: 2px 4px 1px;
|
93
|
-
padding: 2px 4px 1px 0;
|
94
|
-
}
|
95
|
-
|
96
|
-
ul.tagit li.tagit-choice input {
|
97
|
-
display: block;
|
98
|
-
float: left;
|
99
|
-
margin: 0 5px 0 0;
|
100
|
-
padding-top: 2px;
|
101
|
-
padding-bottom: 2px;
|
102
|
-
}
|
103
|
-
|
104
|
-
ul.tagit li.tagit-choice a.tagit-close {
|
105
|
-
color: #ccc;
|
106
|
-
cursor: pointer;
|
107
|
-
font-size: 12px;
|
108
|
-
font-weight: bold;
|
109
|
-
outline: medium none;
|
110
|
-
padding: 2px 0 2px 3px;
|
111
|
-
text-decoration: none;
|
112
|
-
position: absolute;
|
113
|
-
display: block;
|
114
|
-
top: 0;
|
115
|
-
right: 3px;
|
116
|
-
text-shadow: 1px 1px 0 rgba(100, 100, 100, 0.7);
|
117
|
-
}
|
118
|
-
|
119
|
-
ul.tagit li.tagit-choice a.tagit-close:hover {
|
120
|
-
color: #fff;
|
121
|
-
text-shadow: none;
|
122
|
-
}
|
123
|
-
/*
|
124
|
-
ul.tagit input[type="text"] {
|
125
|
-
-moz-box-sizing: border-box;
|
126
|
-
border: none !important;
|
127
|
-
margin: 0 !important;
|
128
|
-
padding: 0 !important;
|
129
|
-
width: inherit !important;
|
130
|
-
outline: none;
|
131
|
-
}
|
132
|
-
*/
|
133
|
-
select.tagit-hiddenSelect {
|
134
|
-
display:none;
|
135
|
-
}
|