bootstrap-combobox 1.2
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.
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Bootstrap Combobox
|
2
|
+
|
3
|
+
We had need of a combobox at work and after looking around at the available options I was not happy with any of them. The project had all it's styling based on Twitter's Bootstrap, so building on that made sense.
|
4
|
+
|
5
|
+
## How to use it
|
6
|
+
|
7
|
+
The dependencies are the Bootstrap stylesheet(CSS or LESS) and also the typeahead javascript plugin. Include them and then the stylesheet(CSS or LESS) and javascript.
|
8
|
+
|
9
|
+
Then just activate the plugin on a normal select box(suggest having a blank option first):
|
10
|
+
|
11
|
+
<select class="combobox">
|
12
|
+
<option></option>
|
13
|
+
<option value="PA">Pennsylvania</option>
|
14
|
+
<option value="CT">Connecticut</option>
|
15
|
+
<option value="NY">New York</option>
|
16
|
+
<option value="MD">Maryland</option>
|
17
|
+
<option value="VA">Virginia</option>
|
18
|
+
</select>
|
19
|
+
|
20
|
+
<script type="text/javascript">
|
21
|
+
$(document).ready(function(){
|
22
|
+
$('.combobox').combobox();
|
23
|
+
});
|
24
|
+
</script>
|
25
|
+
|
26
|
+
## Live Example
|
27
|
+
|
28
|
+
http://dl.dropbox.com/u/21368/bootstrap-combobox/index.html
|
29
|
+
|
30
|
+
## Ruby
|
31
|
+
|
32
|
+
This is published/publishable as a ruby gem as well.
|
@@ -0,0 +1,240 @@
|
|
1
|
+
/* =============================================================
|
2
|
+
* bootstrap-combobox.js v1.1.3
|
3
|
+
* =============================================================
|
4
|
+
* Copyright 2012 Daniel Farrell
|
5
|
+
*
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
* you may not use this file except in compliance with the License.
|
8
|
+
* You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
* ============================================================ */
|
18
|
+
|
19
|
+
!function( $ ) {
|
20
|
+
|
21
|
+
"use strict";
|
22
|
+
|
23
|
+
var Combobox = function ( element, options ) {
|
24
|
+
this.options = $.extend({}, $.fn.combobox.defaults, options)
|
25
|
+
this.$source = $(element)
|
26
|
+
this.$container = this.setup()
|
27
|
+
this.$element = this.$container.find('input[type=text]')
|
28
|
+
this.$target = this.$container.find('input[type=hidden]')
|
29
|
+
this.$button = this.$container.find('.dropdown-toggle')
|
30
|
+
this.$menu = $(this.options.menu).appendTo('body')
|
31
|
+
this.matcher = this.options.matcher || this.matcher
|
32
|
+
this.sorter = this.options.sorter || this.sorter
|
33
|
+
this.highlighter = this.options.highlighter || this.highlighter
|
34
|
+
this.shown = false
|
35
|
+
this.selected = false
|
36
|
+
this.refresh()
|
37
|
+
this.transferAttributes()
|
38
|
+
this.listen()
|
39
|
+
}
|
40
|
+
|
41
|
+
/* NOTE: COMBOBOX EXTENDS BOOTSTRAP-TYPEAHEAD.js
|
42
|
+
========================================== */
|
43
|
+
|
44
|
+
Combobox.prototype = $.extend({}, $.fn.typeahead.Constructor.prototype, {
|
45
|
+
|
46
|
+
constructor: Combobox
|
47
|
+
|
48
|
+
, setup: function () {
|
49
|
+
var combobox = $(this.options.template)
|
50
|
+
this.$source.before(combobox)
|
51
|
+
this.$source.hide()
|
52
|
+
return combobox
|
53
|
+
}
|
54
|
+
|
55
|
+
, parse: function () {
|
56
|
+
var that = this
|
57
|
+
, map = {}
|
58
|
+
, source = []
|
59
|
+
, selected = false
|
60
|
+
this.$source.find('option').each(function() {
|
61
|
+
var option = $(this)
|
62
|
+
if (option.val() === '') {
|
63
|
+
that.options.placeholder = option.text()
|
64
|
+
return
|
65
|
+
}
|
66
|
+
map[option.text()] = option.val()
|
67
|
+
source.push(option.text())
|
68
|
+
if(option.attr('selected')) selected = option.text()
|
69
|
+
})
|
70
|
+
this.map = map
|
71
|
+
if (selected) {
|
72
|
+
this.$element.val(selected)
|
73
|
+
this.$container.addClass('combobox-selected')
|
74
|
+
this.selected = true
|
75
|
+
}
|
76
|
+
return source
|
77
|
+
}
|
78
|
+
|
79
|
+
, transferAttributes: function() {
|
80
|
+
this.options.placeholder = this.$source.attr('data-placeholder') || this.options.placeholder
|
81
|
+
this.$element.attr('placeholder', this.options.placeholder)
|
82
|
+
this.$target.prop('name', this.$source.prop('name'))
|
83
|
+
this.$target.val(this.$source.val())
|
84
|
+
this.$source.removeAttr('name') // Remove from source otherwise form will pass parameter twice.
|
85
|
+
this.$element.attr('required', this.$source.attr('required'))
|
86
|
+
this.$element.attr('rel', this.$source.attr('rel'))
|
87
|
+
this.$element.attr('title', this.$source.attr('title'))
|
88
|
+
this.$element.attr('class', this.$source.attr('class'))
|
89
|
+
this.$element.attr('tabindex', this.$source.attr('tabindex'))
|
90
|
+
this.$source.removeAttr('tabindex')
|
91
|
+
}
|
92
|
+
|
93
|
+
, toggle: function () {
|
94
|
+
if (this.$container.hasClass('combobox-selected')) {
|
95
|
+
this.clearTarget()
|
96
|
+
this.triggerChange()
|
97
|
+
this.clearElement()
|
98
|
+
} else {
|
99
|
+
if (this.shown) {
|
100
|
+
this.hide()
|
101
|
+
} else {
|
102
|
+
this.clearElement()
|
103
|
+
this.lookup()
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
, clearElement: function () {
|
109
|
+
this.$element.val('').focus()
|
110
|
+
}
|
111
|
+
|
112
|
+
, clearTarget: function () {
|
113
|
+
this.$source.val('')
|
114
|
+
this.$target.val('')
|
115
|
+
this.$container.removeClass('combobox-selected')
|
116
|
+
this.selected = false
|
117
|
+
}
|
118
|
+
|
119
|
+
, triggerChange: function () {
|
120
|
+
this.$source.trigger('change')
|
121
|
+
}
|
122
|
+
|
123
|
+
, refresh: function () {
|
124
|
+
this.source = this.parse()
|
125
|
+
this.options.items = this.source.length
|
126
|
+
}
|
127
|
+
|
128
|
+
// modified typeahead function adding container and target handling
|
129
|
+
, select: function () {
|
130
|
+
var val = this.$menu.find('.active').attr('data-value')
|
131
|
+
this.$element.val(this.updater(val)).trigger('change')
|
132
|
+
this.$source.val(this.map[val]).trigger('change')
|
133
|
+
this.$target.val(this.map[val]).trigger('change')
|
134
|
+
this.$container.addClass('combobox-selected')
|
135
|
+
this.selected = true
|
136
|
+
return this.hide()
|
137
|
+
}
|
138
|
+
|
139
|
+
// modified typeahead function removing the blank handling and source function handling
|
140
|
+
, lookup: function (event) {
|
141
|
+
this.query = this.$element.val()
|
142
|
+
return this.process(this.source)
|
143
|
+
}
|
144
|
+
|
145
|
+
// modified typeahead function adding button handling and remove mouseleave
|
146
|
+
, listen: function () {
|
147
|
+
this.$element
|
148
|
+
.on('focus', $.proxy(this.focus, this))
|
149
|
+
.on('blur', $.proxy(this.blur, this))
|
150
|
+
.on('keypress', $.proxy(this.keypress, this))
|
151
|
+
.on('keyup', $.proxy(this.keyup, this))
|
152
|
+
|
153
|
+
if (this.eventSupported('keydown')) {
|
154
|
+
this.$element.on('keydown', $.proxy(this.keydown, this))
|
155
|
+
}
|
156
|
+
|
157
|
+
this.$menu
|
158
|
+
.on('click', $.proxy(this.click, this))
|
159
|
+
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
160
|
+
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
|
161
|
+
|
162
|
+
this.$button
|
163
|
+
.on('click', $.proxy(this.toggle, this))
|
164
|
+
}
|
165
|
+
|
166
|
+
// modified typeahead function to clear on type and prevent on moving around
|
167
|
+
, keyup: function (e) {
|
168
|
+
switch(e.keyCode) {
|
169
|
+
case 40: // down arrow
|
170
|
+
case 39: // right arrow
|
171
|
+
case 38: // up arrow
|
172
|
+
case 37: // left arrow
|
173
|
+
case 36: // home
|
174
|
+
case 35: // end
|
175
|
+
case 16: // shift
|
176
|
+
case 17: // ctrl
|
177
|
+
case 18: // alt
|
178
|
+
break
|
179
|
+
|
180
|
+
case 9: // tab
|
181
|
+
case 13: // enter
|
182
|
+
if (!this.shown) return
|
183
|
+
this.select()
|
184
|
+
break
|
185
|
+
|
186
|
+
case 27: // escape
|
187
|
+
if (!this.shown) return
|
188
|
+
this.hide()
|
189
|
+
break
|
190
|
+
|
191
|
+
default:
|
192
|
+
this.clearTarget()
|
193
|
+
this.lookup()
|
194
|
+
}
|
195
|
+
|
196
|
+
e.stopPropagation()
|
197
|
+
e.preventDefault()
|
198
|
+
}
|
199
|
+
|
200
|
+
// modified typeahead function to force a match and add a delay on hide
|
201
|
+
, blur: function (e) {
|
202
|
+
var that = this
|
203
|
+
this.focused = false
|
204
|
+
var val = this.$element.val()
|
205
|
+
if (!this.selected && val !== '' ) {
|
206
|
+
this.$element.val('')
|
207
|
+
this.$source.val('').trigger('change')
|
208
|
+
this.$target.val('').trigger('change')
|
209
|
+
}
|
210
|
+
if (!this.mousedover && this.shown) setTimeout(function () { that.hide() }, 200)
|
211
|
+
}
|
212
|
+
|
213
|
+
// modified typeahead function to not hide
|
214
|
+
, mouseleave: function (e) {
|
215
|
+
this.mousedover = false
|
216
|
+
}
|
217
|
+
})
|
218
|
+
|
219
|
+
/* COMBOBOX PLUGIN DEFINITION
|
220
|
+
* =========================== */
|
221
|
+
|
222
|
+
$.fn.combobox = function ( option ) {
|
223
|
+
return this.each(function () {
|
224
|
+
var $this = $(this)
|
225
|
+
, data = $this.data('combobox')
|
226
|
+
, options = typeof option == 'object' && option
|
227
|
+
if(!data) $this.data('combobox', (data = new Combobox(this, options)))
|
228
|
+
if (typeof option == 'string') data[option]()
|
229
|
+
})
|
230
|
+
}
|
231
|
+
|
232
|
+
$.fn.combobox.defaults = {
|
233
|
+
template: '<div class="combobox-container"><input type="hidden" /><input type="text" autocomplete="off" /><span class="add-on btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"/><span class="combobox-clear"><i class="icon-remove"/></span></span></div>'
|
234
|
+
, menu: '<ul class="typeahead typeahead-long dropdown-menu"></ul>'
|
235
|
+
, item: '<li><a href="#"></a></li>'
|
236
|
+
}
|
237
|
+
|
238
|
+
$.fn.combobox.Constructor = Combobox
|
239
|
+
|
240
|
+
}( window.jQuery );
|
@@ -0,0 +1,150 @@
|
|
1
|
+
.combobox-container {
|
2
|
+
margin-bottom: 5px;
|
3
|
+
*zoom: 1;
|
4
|
+
}
|
5
|
+
.combobox-container:before,
|
6
|
+
.combobox-container:after {
|
7
|
+
display: table;
|
8
|
+
content: "";
|
9
|
+
}
|
10
|
+
.combobox-container:after {
|
11
|
+
clear: both;
|
12
|
+
}
|
13
|
+
.combobox-container input,
|
14
|
+
.combobox-container .uneditable-input {
|
15
|
+
-webkit-border-radius: 0 3px 3px 0;
|
16
|
+
-moz-border-radius: 0 3px 3px 0;
|
17
|
+
border-radius: 0 3px 3px 0;
|
18
|
+
}
|
19
|
+
.combobox-container input:focus,
|
20
|
+
.combobox-container .uneditable-input:focus {
|
21
|
+
position: relative;
|
22
|
+
z-index: 2;
|
23
|
+
}
|
24
|
+
.combobox-container .uneditable-input {
|
25
|
+
border-left-color: #ccc;
|
26
|
+
}
|
27
|
+
.combobox-container .add-on {
|
28
|
+
float: left;
|
29
|
+
display: inline-block;
|
30
|
+
width: auto;
|
31
|
+
min-width: 16px;
|
32
|
+
height: inherit !important;
|
33
|
+
margin-right: -1px;
|
34
|
+
padding: 4px 5px;
|
35
|
+
font-weight: normal;
|
36
|
+
color: #999999;
|
37
|
+
text-align: center;
|
38
|
+
text-shadow: 0 1px 0 #ffffff;
|
39
|
+
background-color: #f5f5f5;
|
40
|
+
border: 1px solid #ccc;
|
41
|
+
-webkit-border-radius: 3px 0 0 3px;
|
42
|
+
-moz-border-radius: 3px 0 0 3px;
|
43
|
+
border-radius: 3px 0 0 3px;
|
44
|
+
|
45
|
+
}
|
46
|
+
.combobox-container .active {
|
47
|
+
background-color: #a9dba9;
|
48
|
+
border-color: #46a546;
|
49
|
+
}
|
50
|
+
.combobox-container input,
|
51
|
+
.combobox-container .uneditable-input {
|
52
|
+
float: left;
|
53
|
+
-webkit-border-radius: 3px 0 0 3px;
|
54
|
+
-moz-border-radius: 3px 0 0 3px;
|
55
|
+
border-radius: 3px 0 0 3px;
|
56
|
+
}
|
57
|
+
.combobox-container .uneditable-input {
|
58
|
+
border-left-color: #eee;
|
59
|
+
border-right-color: #ccc;
|
60
|
+
}
|
61
|
+
.combobox-container .add-on {
|
62
|
+
margin-right: 0;
|
63
|
+
margin-left: -1px;
|
64
|
+
-webkit-border-radius: 0 3px 3px 0;
|
65
|
+
-moz-border-radius: 0 3px 3px 0;
|
66
|
+
border-radius: 0 3px 3px 0;
|
67
|
+
}
|
68
|
+
.combobox-container input:first-child {
|
69
|
+
*margin-left: -160px;
|
70
|
+
}
|
71
|
+
.combobox-container input:first-child + .add-on {
|
72
|
+
*margin-left: -21px;
|
73
|
+
}
|
74
|
+
.combobox-container select {
|
75
|
+
display: inline-block;
|
76
|
+
width: 0;
|
77
|
+
height: 0;
|
78
|
+
border: 0;
|
79
|
+
padding: 0;
|
80
|
+
margin: 0;
|
81
|
+
text-indent: -99999px;
|
82
|
+
*text-indent: 0;
|
83
|
+
}
|
84
|
+
.form-search .combobox-container,
|
85
|
+
.form-inline .combobox-container {
|
86
|
+
display: inline-block;
|
87
|
+
margin-bottom: 0;
|
88
|
+
vertical-align: top;
|
89
|
+
}
|
90
|
+
.form-search .combobox-container .add-on,
|
91
|
+
.form-inline .combobox-container .add-on {
|
92
|
+
vertical-align: middle;
|
93
|
+
}
|
94
|
+
.combobox-selected .combobox-clear {
|
95
|
+
display: inline-block;
|
96
|
+
}
|
97
|
+
.combobox-selected .caret {
|
98
|
+
display: none;
|
99
|
+
}
|
100
|
+
.combobox-clear {
|
101
|
+
display: none;
|
102
|
+
width: 14px;
|
103
|
+
height: 14px;
|
104
|
+
line-height: 14px;
|
105
|
+
vertical-align: top;
|
106
|
+
opacity: 0.3;
|
107
|
+
filter: alpha(opacity=30);
|
108
|
+
}
|
109
|
+
.dropdown:hover .combobox-clear,
|
110
|
+
.open.dropdown .combobox-clear {
|
111
|
+
opacity: 1;
|
112
|
+
filter: alpha(opacity=100);
|
113
|
+
}
|
114
|
+
.btn .combobox-clear {
|
115
|
+
margin-top: 1px;
|
116
|
+
margin-left: 1px;
|
117
|
+
}
|
118
|
+
.btn:hover .combobox-clear,
|
119
|
+
.open.btn-group .combobox-clear {
|
120
|
+
opacity: 1;
|
121
|
+
filter: alpha(opacity=100);
|
122
|
+
}
|
123
|
+
.typeahead-long {
|
124
|
+
max-height: 300px;
|
125
|
+
overflow-y: auto;
|
126
|
+
}
|
127
|
+
.control-group.error .combobox-container .add-on {
|
128
|
+
color: #B94A48;
|
129
|
+
border-color: #B94A48;
|
130
|
+
}
|
131
|
+
.control-group.error .combobox-container .caret {
|
132
|
+
border-top-color: #B94A48;
|
133
|
+
}
|
134
|
+
.control-group.warning .combobox-container .add-on {
|
135
|
+
color: #C09853;
|
136
|
+
border-color: #C09853;
|
137
|
+
}
|
138
|
+
.control-group.warning .combobox-container .caret {
|
139
|
+
border-top-color: #C09853;
|
140
|
+
}
|
141
|
+
.control-group.success .combobox-container .add-on {
|
142
|
+
color: #468847;
|
143
|
+
border-color: #468847;
|
144
|
+
}
|
145
|
+
.control-group.success .combobox-container .caret {
|
146
|
+
border-top-color: #468847;
|
147
|
+
}
|
148
|
+
.btn .combobox-clear [class^="icon-"] {
|
149
|
+
line-height: 1.4em;
|
150
|
+
}
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bootstrap-combobox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.2'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- danielfarrell
|
9
|
+
- denishaskin
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2013-07-22 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: railties
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3.1'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '3.1'
|
31
|
+
description: Combobox for Bootstrap, based on Bootstrap typeahead
|
32
|
+
email:
|
33
|
+
- danielfarrell76@gmail.com
|
34
|
+
- denis@constantorbit.com
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- lib/bootstrap-combobox/version.rb
|
40
|
+
- lib/bootstrap-combobox.rb
|
41
|
+
- vendor/assets/javascripts/bootstrap-combobox.js
|
42
|
+
- vendor/assets/stylesheets/bootstrap-combobox.css
|
43
|
+
- README.md
|
44
|
+
homepage: https://github.com/danielfarrell/bootstrap-combobox
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.8.25
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Combobox for Bootstrap, based on Bootstrap typeahead
|
69
|
+
test_files: []
|