-
Notifications
You must be signed in to change notification settings - Fork 8
/
jquery.editable.select.js
180 lines (168 loc) · 5.97 KB
/
jquery.editable.select.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
* @description This plugin allows you to make a select box editable like a text box while keeping it's select-option features
* @description no stylesheets or images are required to run the plugin
*
* @version 0.0.1
* @author Martin Mende
* @license Attribution-NonCommercial 3.0 Unported (CC BY-NC 3.0)
* @license For comercial use please contact me: martin.mende(at)aristech.de
*
* @requires jQuery 1.9+
*
* @class editableSelect
* @memberOf jQuery.fn
*
* @example
*
* var selectBox = $("select").editableSelect();
* selectBox.addOption("I am dynamically added");
*/
(function ( $ ) {
$.fn.editableSelect = function() {
var instanceVar;
this.each(function(){
var originalSelect = $(this);
//check if element is a select
if(originalSelect[0].tagName.toUpperCase()==="SELECT"){
//wrap the original select
originalSelect.wrap($("<div/>"));
var wrapper = originalSelect.parent();
wrapper.css({display: "inline-block"});
//place an input which will represent the editable select
var inputSelect = $("<input/>").insertBefore(originalSelect);
//get and remove the original id
var objID = originalSelect.attr("id");
originalSelect.removeAttr("id");
//add the attributes from the original select
inputSelect.attr({
alt: originalSelect.attr("alt"),
title: originalSelect.attr("title"),
class: originalSelect.attr("class"),
name: originalSelect.attr("name"),
disabled: originalSelect.attr("disabled"),
tabindex: originalSelect.attr("tabindex"),
id: objID
});
//get the editable css properties from the select
var rightPadding = 15;
inputSelect.css({
width: originalSelect.width()-rightPadding,
height: originalSelect.height(),
fontFamily: originalSelect.css("fontFamily"),
fontSize: originalSelect.css("fontSize"),
background: originalSelect.css("background"),
paddingRight: rightPadding
});
inputSelect.val(originalSelect.val());
//add the triangle at the right
var triangle = $("<div/>").css({
height: 0, width: 0,
borderLeft: "5px solid transparent",
borderRight: "5px solid transparent",
borderTop: "7px solid #999",
position: "relative",
top: -(inputSelect.height()/2)-5,
left: inputSelect.width()+rightPadding-10,
marginBottom: "-7px",
pointerEvents: "none"
}).insertAfter(inputSelect);
//create the selectable list that will appear when the input gets focus
var selectList = $("<ol/>").css({
display: "none",
listStyleType: "none",
width: inputSelect.outerWidth()-2,
padding: 0,
margin: 0,
border: "solid 1px #ccc",
fontFamily: inputSelect.css("fontFamily"),
fontSize: inputSelect.css("fontSize"),
background: "#fff",
position: "absolute",
zIndex: 1000000
}).insertAfter(triangle);
//add options
originalSelect.children().each(function(index, value){
prepareOption($(value).text(), wrapper);
});
//bind the focus handler
inputSelect.focus(function(){
selectList.fadeIn(100);
}).blur(function(){
selectList.fadeOut(100);
}).keyup(function(e){
if(e.which==13) inputSelect.trigger("blur");
});
//hide original element
originalSelect.css({visibility: "hidden", display: "none"});
//save this instance to return it
instanceVar = inputSelect
}else{
//not a select
return false;
}
});//-end each
/** public methods **/
/**
* Adds an option to the editable select
* @param {String} value - the options value
* @returns {void}
*/
instanceVar.addOption = function(value){
prepareOption(value, instanceVar.parent());
};
/**
* Removes a specific option from the editable select
* @param {String, Number} value - the value or the index to delete
* @returns {void}
*/
instanceVar.removeOption = function(value){
switch(typeof(value)){
case "number":
instanceVar.parent().children("ol").children(":nth("+value+")").remove();
break;
case "string":
instanceVar.parent().children("ol").children().each(function(index, optionValue){
if($(optionValue).text()==value){
$(optionValue).remove();
}
});
break;
}
};
/**
* Resets the select to it's original
* @returns {void}
*/
instanceVar.restoreSelect = function(){
var originalSelect = instanceVar.parent().children("select");
var objID = instanceVar.attr("id");
instanceVar.parent().before(originalSelect);
instanceVar.parent().remove();
originalSelect.css({visibility: "visible", display: "inline-block"});
originalSelect.attr({id: objID});
};
//return the instance
return instanceVar;
};
/** private methods **/
function prepareOption(value, wrapper){
var selectOption = $("<li>"+value+"</li>").appendTo(wrapper.children("ol"));
var inputSelect = wrapper.children("input");
selectOption.css({
padding: "3px",
textAlign: "left",
cursor: "pointer"
}).hover(
function(){
selectOption.css({backgroundColor: "#eee"});
},
function(){
selectOption.css({backgroundColor: "#fff"});
});
//bind click on this option
selectOption.click(function(){
inputSelect.val(selectOption.text());
inputSelect.trigger("change");
});
}
}( jQuery ));