hjg
2024-07-09 30304784e82d4bba24121328da8eb8490aec4f4f
提交 | 用户 | 时间
58d006 1 /* ==========================================================
A 2  * bootstrap-tag.js v2.2.5
3  * https://github.com/fdeschenes/bootstrap-tag
4  * ==========================================================
5  * Copyright 2012 Francois Deschenes.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================================================== */
19
20 !function ( $ ) {
21
22   'use strict' // jshint ;_;
23
24   var Tag = function ( element, options ) {
25     this.element = $(element)
26     this.options = $.extend(true, {}, $.fn.tag.defaults, options)
27     this.values = $.grep($.map(this.element.val().split(','), $.trim), function ( value ) { return value.length > 0 })
28     this.show()
29   }
30
31   Tag.prototype = {
32     constructor: Tag
33
34   , show: function () {
35       var that = this
36
37       that.element.parent().prepend(that.element.detach().hide())
38       that.element
39         .wrap($('<div class="tags">'))
40         .parent()
41         .on('click', function () {
42           that.input.focus()
43         })
44
45       if (that.values.length) {
46         $.each(that.values, function () {
47           that.createBadge(this)
48         })
49       }
50
51       that.input = $('<input type="text">')
52         .attr('placeholder', that.options.placeholder)
53         .insertAfter(that.element)
54         .on('focus', function () {
55           that.element.parent().addClass('tags-hover')
56         })
57         .on('blur', function () {
58           if (!that.skip) {
59             that.process()
60             that.element.parent().removeClass('tags-hover')
61             that.element.siblings('.tag').removeClass('tag-important')
62           }
63           that.skip = false
64         })
65         .on('keydown', function ( event ) {
66           if ( event.keyCode == 188 || event.keyCode == 13 || event.keyCode == 9 ) {
67             if ( $.trim($(this).val()) && ( !that.element.siblings('.typeahead').length || that.element.siblings('.typeahead').is(':hidden') ) ) {
68               if ( event.keyCode != 9 ) event.preventDefault()
69               that.process()
70             } else if ( event.keyCode == 188 ) {
71               if ( !that.element.siblings('.typeahead').length || that.element.siblings('.typeahead').is(':hidden') ) {
72                 event.preventDefault()
73               } else {
74                 that.input.data('typeahead').select()
75                 event.stopPropagation()
76                 event.preventDefault()
77               }
78             }
79           } else if ( !$.trim($(this).val()) && event.keyCode == 8 ) {
80             var count = that.element.siblings('.tag').length
81             if (count) {
82               var tag = that.element.siblings('.tag:eq(' + (count - 1) + ')')
83               if (tag.hasClass('tag-important')) that.remove(count - 1)
84               else tag.addClass('tag-important')
85             }
86           } else {
87             that.element.siblings('.tag').removeClass('tag-important')
88           }
89         })
90         .bs_typeahead({
91           source: that.options.source
92         , matcher: function ( value ) {
93             return ~value.toLowerCase().indexOf(this.query.toLowerCase()) && (that.inValues(value) == -1 || that.options.allowDuplicates)
94           }
95         , updater: $.proxy(that.add, that)
96         })
97
98       $(that.input.data('bs_typeahead').$menu).on('mousedown', function() {
99         that.skip = true
100       })
101
102       this.element.trigger('shown')
103     }
104   , inValues: function ( value ) {
105       if (this.options.caseInsensitive) {
106         var index = -1
107         $.each(this.values, function (indexInArray, valueOfElement) {
108           if ( valueOfElement.toLowerCase() == value.toLowerCase() ) {
109             index = indexInArray
110             return false
111           }
112         })
113         return index
114       } else {
115         return $.inArray(value, this.values)
116       }
117     }
118   , createBadge: function ( value ) {
119     var that = this
120
121       $('<span/>', {
122         'class' : "tag"
123       })
124       .text(value)
125       .append($('<button type="button" class="close">&times;</button>')
126         .on('click', function () {
127           that.remove(that.element.siblings('.tag').index($(this).closest('.tag')))
128         })
129       )
130       .insertBefore(that.element)
131   }
132   , add: function ( value ) {
133       var that = this
134
135       if ( !that.options.allowDuplicates ) {
136         var index = that.inValues(value)
137         if ( index != -1 ) {
138           var badge = that.element.siblings('.tag:eq(' + index + ')')
139           badge.addClass('tag-warning')
140           setTimeout(function () {
141             $(badge).removeClass('tag-warning')
142           }, 500)
143           return
144         }
145       }
146
147       this.values.push(value)
148       this.createBadge(value)
149
150       this.element.val(this.values.join(', '))
151       this.element.trigger('added', [value])
152     }
153   , remove: function ( index ) {
154       if ( index >= 0 ) {
155         var value = this.values.splice(index, 1)
156         this.element.siblings('.tag:eq(' + index + ')').remove()
157         this.element.val(this.values.join(', '))
158
159         this.element.trigger('removed', [value])
160       }
161     }
162   , process: function () {
163       var values = $.grep($.map(this.input.val().split(','), $.trim), function ( value ) { return value.length > 0 }),
164           that = this
165       $.each(values, function() {
166         that.add(this)
167       })
168       this.input.val('')
169     }
170   , skip: false
171   }
172
173   var old = $.fn.tag
174
175   $.fn.tag = function ( option ) {
176     return this.each(function () {
177       var that = $(this)
178         , data = that.data('tag')
179         , options = typeof option == 'object' && option
180       if (!data) that.data('tag', (data = new Tag(this, options)))
181       if (typeof option == 'string') data[option]()
182     })
183   }
184
185   $.fn.tag.defaults = {
186     allowDuplicates: false
187   , caseInsensitive: true
188   , placeholder: ''
189   , source: []
190   }
191
192   $.fn.tag.Constructor = Tag
193
194   $.fn.tag.noConflict = function () {
195     $.fn.tag = old
196     return this
197   }
198
199   $(window).on('load', function () {
200     $('[data-provide="tag"]').each(function () {
201       var that = $(this)
202       if (that.data('tag')) return
203       that.tag(that.data())
204     })
205   })
206 }(window.jQuery);