Skip to content

Instantly share code, notes, and snippets.

@conspirator
Last active December 22, 2015 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save conspirator/6547343 to your computer and use it in GitHub Desktop.
Save conspirator/6547343 to your computer and use it in GitHub Desktop.
!function(b) {
var a = function(d, c, f) {
if (f) {
f.stopPropagation();
f.preventDefault()
}
this.$element = b(d);
this.$newElement = null;
this.button = null;
this.options = b.extend({}, b.fn.selectpicker.defaults, this.$element.data(), typeof c == "object" && c);
if (this.options.title == null) {
this.options.title = this.$element.attr("title")
}
this.val = a.prototype.val;
this.render = a.prototype.render;
this.refresh = a.prototype.refresh;
this.selectAll = a.prototype.selectAll;
this.deselectAll = a.prototype.deselectAll;
this.init()
};
a.prototype = {
constructor: a,
init: function(d) {
if (!this.options.container) {
this.$element.hide()
} else {
this.$element.css("visibility", "hidden")
}
this.multiple = this.$element.prop("multiple");
var f = this.$element.attr("class") !== undefined ? this.$element.attr("class").split(/\s+/) : "";
var h = this.$element.attr("id");
this.$element.after(this.createView());
this.$newElement = this.$element.next(".bootstrap-select");
if (this.options.container) {
this.selectPosition()
}
this.button = this.$newElement.find("> button");
if (h !== undefined) {
var g = this;
this.button.attr("data-id", h);
b('label[for="' + h + '"]').click(function() {
g.$newElement.find("button[data-id=" + h + "]").focus()
})
}
for (var c = 0; c < f.length; c++) {
if (f[c] != "selectpicker") {
this.$newElement.addClass(f[c])
}
}
if (this.multiple) {
this.$newElement.addClass("show-tick")
}
this.button.addClass(this.options.style);
this.checkDisabled();
this.checkTabIndex();
this.clickListener();
this.render();
this.setSize()
},
createDropdown: function() {
var c = "<div class='btn-group bootstrap-select'><button type='button' class='btn dropdown-toggle' data-toggle='dropdown'><span class='filter-option pull-left'></span>&nbsp;<span class='caret'></span></button><ul class='dropdown-menu' role='menu'></ul></div>";
return b(c)
},
createView: function() {
var c = this.createDropdown();
var d = this.createLi();
c.find("ul").append(d);
return c
},
reloadLi: function() {
this.destroyLi();
$li = this.createLi();
this.$newElement.find("ul").append($li)
},
destroyLi: function() {
this.$newElement.find("li").remove()
},
createLi: function() {
var h = this;
var e = [];
var g = [];
var c = "";
this.$element.find("option").each(function() {
e.push(b(this).text())
});
this.$element.find("option").each(function(k) {
var l = b(this);
var j = l.attr("class") !== undefined ? l.attr("class") : "";
var p = l.text();
var n = l.data("subtext") !== undefined ? '<small class="muted">' + l.data("subtext") + "</small>" : "";
var m = l.data("icon") !== undefined ? '<i class="' + l.data("icon") + '"></i> ' : "";
if (l.is(":disabled") || l.parent().is(":disabled")) {
m = "<span>" + m + "</span>"
}
p = m + '<span class="text">' + p + n + "</span>";
if (h.options.hideDisabled && (l.is(":disabled") || l.parent().is(":disabled"))) {
g.push('<a style="min-height: 0; padding: 0"></a>')
} else {
if (l.parent().is("optgroup") && l.data("divider") != true) {
if (l.index() == 0) {
var o = l.parent().attr("label");
var q = l.parent().data("subtext") !== undefined ? '<small class="muted">' + l.parent().data("subtext") + "</small>" : "";
var i = l.parent().data("icon") ? '<i class="' + l.parent().data("icon") + '"></i> ' : "";
o = i + '<span class="text">' + o + q + "</span>";
if (l[0].index != 0) {
g.push('<div class="div-contain"><div class="divider"></div></div><dt>' + o + "</dt>" + h.createA(p, "opt " + j))
} else {
g.push("<dt>" + o + "</dt>" + h.createA(p, "opt " + j))
}
} else {
g.push(h.createA(p, "opt " + j))
}
} else {
if (l.data("divider") == true) {
g.push('<div class="div-contain"><div class="divider"></div></div>')
} else {
if (b(this).data("hidden") == true) {
g.push("")
} else {
g.push(h.createA(p, j))
}
}
}
}
});
if (e.length > 0) {
for (var d = 0; d < e.length; d++) {
var f = this.$element.find("option").eq(d);
c += "<li rel=" + d + ">" + g[d] + "</li>"
}
}
if (!this.multiple && this.$element.find("option:selected").length == 0 && !h.options.title) {
this.$element.find("option").eq(0).prop("selected", true).attr("selected", "selected")
}
return b(c)
},
createA: function(d, c) {
return '<a tabindex="0" class="' + c + '">' + d + '<i class="icon-ok check-mark"></i></a>'
},
render: function() {
var f = this;
this.$element.find("option").each(function(g) {
f.setDisabled(g, b(this).is(":disabled") || b(this).parent().is(":disabled"));
f.setSelected(g, b(this).is(":selected"))
});
var e = this.$element.find("option:selected").map(function(g, h) {
if (b(this).attr("title") != undefined) {
return b(this).attr("title")
} else {
return b(this).text()
}
}).toArray();
var d = !this.multiple ? e[0] : e.join(", ");
if (f.multiple && f.options.selectedTextFormat.indexOf("count") > -1) {
var c = f.options.selectedTextFormat.split(">");
if ((c.length > 1 && e.length > c[1]) || (c.length == 1 && e.length >= 2)) {
d = e.length + " of " + this.$element.find("option").length + " selected"
}
}
if (!d) {
d = f.options.title != undefined ? f.options.title : f.options.noneSelectedText
}
f.$newElement.find(".filter-option").html(d)
},
setSize: function() {
var i = this;
var e = this.$newElement.find(".dropdown-menu");
var k = e.find("li > a");
var n = this.$newElement.addClass("open").find(".dropdown-menu li > a").outerHeight();
this.$newElement.removeClass("open");
var g = e.find("li .divider").outerHeight(true);
var f = this.$newElement.offset().top;
var j = this.$newElement.outerHeight();
var c = parseInt(e.css("padding-top")) + parseInt(e.css("padding-bottom")) + parseInt(e.css("border-top-width")) + parseInt(e.css("border-bottom-width"));
var d = this.options.hideDisabled ? ":not(.disabled)" : "";
if (this.options.size == "auto") {
function o() {
var p = /* WEBB MODIFY START */ i.$newElement.offset().top /* WEBB MODIFY END */ - b(window).scrollTop();
var s = window.innerHeight;
var q = c + parseInt(e.css("margin-top")) + parseInt(e.css("margin-bottom")) + 2;
/* WEBB INSERT START */ q = q == 3 ? 50 : q; /* WEBB INSERT END */
var r = s - p - j - q;
menuHeight = r;
if (i.$newElement.hasClass("dropup")) {
menuHeight = p - q
}
if ((e.find("li").length + e.find("dt").length) > 3) {
minHeight = n * 3 + q - 2
} else {
minHeight = 0
}
e.css({
"max-height": menuHeight + "px",
"overflow-y": "auto",
"min-height": minHeight + "px"
})
}
o();
b(window).resize(o);
b(window).scroll(o)
} else {
if (this.options.size && this.options.size != "auto" && e.find("li" + d).length > this.options.size) {
var m = e.find("li" + d + " > *").filter(":not(.div-contain)").slice(0, this.options.size).last().parent().index();
var l = e.find("li").slice(0, m + 1).find(".div-contain").length;
menuHeight = n * this.options.size + l * g + c;
e.css({
"max-height": menuHeight + "px",
"overflow-y": "auto"
})
}
}
if (this.options.width == "auto") {
this.$newElement.find(".dropdown-menu").css("min-width", "0");
var h = this.$newElement.find(".dropdown-menu").css("width");
this.$newElement.css("width", h);
if (this.options.container) {
this.$element.css("width", h)
}
} else {
if (this.options.width && this.options.width != "auto") {
this.$newElement.css("width", this.options.width);
if (this.options.container) {
this.$element.css("width", this.options.width)
}
}
}
},
selectPosition: function() {
var d = this.$element.offset().top;
var c = this.$element.offset().left;
this.$newElement.appendTo(this.options.container);
this.$newElement.css({
position: "absolute",
top: d + "px",
left: c + "px"
})
},
refresh: function() {
this.reloadLi();
this.render();
this.setSize();
this.checkDisabled();
if (this.options.container) {
this.selectPosition()
}
},
setSelected: function(c, d) {
if (d) {
this.$newElement.find("li").eq(c).addClass("selected")
} else {
this.$newElement.find("li").eq(c).removeClass("selected")
}
},
setDisabled: function(c, d) {
if (d) {
this.$newElement.find("li").eq(c).addClass("disabled").find("a").attr("href", "#").attr("tabindex", -1)
} else {
this.$newElement.find("li").eq(c).removeClass("disabled").find("a").removeAttr("href").attr("tabindex", 0)
}
},
isDisabled: function() {
return this.$element.is(":disabled") || this.$element.attr("readonly")
},
checkDisabled: function() {
if (this.isDisabled()) {
this.button.addClass("disabled");
this.button.click(function(c) {
c.preventDefault()
});
this.button.attr("tabindex", "-1")
} else {
if (!this.isDisabled() && this.button.hasClass("disabled")) {
this.button.removeClass("disabled");
this.button.click(function() {
return true
});
this.button.removeAttr("tabindex")
}
}
},
checkTabIndex: function() {
if (this.$element.is("[tabindex]")) {
var c = this.$element.attr("tabindex");
this.button.attr("tabindex", c)
}
},
clickListener: function() {
var c = this;
b("body").on("touchstart.dropdown", ".dropdown-menu", function(d) {
d.stopPropagation()
});
this.$newElement.on("click", "li a", function(j) {
var g = b(this).parent().index(),
i = b(this).parent(),
d = i.parents(".bootstrap-select"),
h = c.$element.val();
if (c.multiple) {
j.stopPropagation()
}
j.preventDefault();
if (c.$element.not(":disabled") && !b(this).parent().hasClass("disabled")) {
if (!c.multiple) {
c.$element.find("option").removeAttr("selected");
c.$element.find("option").eq(g).prop("selected", true).attr("selected", "selected")
} else {
var f = c.$element.find("option").eq(g).prop("selected");
if (f) {
c.$element.find("option").eq(g).removeAttr("selected")
} else {
c.$element.find("option").eq(g).prop("selected", true).attr("selected", "selected")
}
}
d.find(".filter-option").html(i.text());
d.find("button").focus();
if (h != c.$element.val()) {
c.$element.trigger("change")
}
c.render()
}
});
this.$newElement.on("click", "li.disabled a, li dt, li .div-contain", function(d) {
d.preventDefault();
d.stopPropagation();
$select = b(this).parent().parents(".bootstrap-select");
$select.find("button").focus()
});
this.$element.on("change", function(d) {
c.render()
})
},
val: function(c) {
if (c != undefined) {
this.$element.val(c);
this.$element.trigger("change");
return this.$element
} else {
return this.$element.val()
}
},
selectAll: function() {
this.$element.find("option").prop("selected", true).attr("selected", "selected");
this.render()
},
deselectAll: function() {
this.$element.find("option").prop("selected", false).removeAttr("selected");
this.render()
},
keydown: function(n) {
var o, m, h, l, j, i, p, d, g;
o = b(this);
h = o.parent();
m = b("[role=menu] li:not(.divider):visible a", h);
if (!m.length) {
return
}
if (/(38|40)/.test(n.keyCode)) {
l = m.index(m.filter(":focus"));
i = m.parent(":not(.disabled)").first().index();
p = m.parent(":not(.disabled)").last().index();
j = m.eq(l).parent().nextAll(":not(.disabled)").eq(0).index();
d = m.eq(l).parent().prevAll(":not(.disabled)").eq(0).index();
g = m.eq(j).parent().prevAll(":not(.disabled)").eq(0).index();
if (n.keyCode == 38) {
if (l != g && l > d) {
l = d
}
if (l < i) {
l = i
}
}
if (n.keyCode == 40) {
if (l != g && l < j) {
l = j
}
if (l > p) {
l = p
}
}
m.eq(l).focus()
} else {
var f = {
48: "0",
49: "1",
50: "2",
51: "3",
52: "4",
53: "5",
54: "6",
55: "7",
56: "8",
57: "9",
59: ";",
65: "a",
66: "b",
67: "c",
68: "d",
69: "e",
70: "f",
71: "g",
72: "h",
73: "i",
74: "j",
75: "k",
76: "l",
77: "m",
78: "n",
79: "o",
80: "p",
81: "q",
82: "r",
83: "s",
84: "t",
85: "u",
86: "v",
87: "w",
88: "x",
89: "y",
90: "z",
96: "0",
97: "1",
98: "2",
99: "3",
100: "4",
101: "5",
102: "6",
103: "7",
104: "8",
105: "9"
};
var c = [];
m.each(function() {
if (b(this).parent().is(":not(.disabled)")) {
if (b.trim(b(this).text().toLowerCase()).substring(0, 1) == f[n.keyCode]) {
c.push(b(this).parent().index())
}
}
});
var k = b(document).data("keycount");
k++;
b(document).data("keycount", k);
var q = b.trim(b(":focus").text().toLowerCase()).substring(0, 1);
if (q != f[n.keyCode]) {
k = 1;
b(document).data("keycount", k)
} else {
if (k >= c.length) {
b(document).data("keycount", 0)
}
}
m.eq(c[k - 1]).focus()
}
if (/(13)/.test(n.keyCode)) {
b(":focus").click();
h.addClass("open");
b(document).data("keycount", 0)
}
}
};
b.fn.selectpicker = function(e, f) {
var c = arguments;
var g;
var d = this.each(function() {
if (b(this).is("select")) {
var l = b(this),
k = l.data("selectpicker"),
h = typeof e == "object" && e;
if (!k) {
l.data("selectpicker", (k = new a(this, h, f)))
} else {
if (h) {
for (var j in h) {
k.options[j] = h[j]
}
}
}
if (typeof e == "string") {
property = e;
if (k[property] instanceof Function) {
[].shift.apply(c);
g = k[property].apply(k, c)
} else {
g = k.options[property]
}
}
}
});
if (g != undefined) {
return g
} else {
return d
}
};
b.fn.selectpicker.defaults = {
style: null,
size: "auto",
title: null,
selectedTextFormat: "values",
noneSelectedText: "Nothing selected",
width: null,
container: false,
hideDisabled: false
};
b(document).data("keycount", 0).on("keydown", "[data-toggle=dropdown], [role=menu]", a.prototype.keydown)
}(window.jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment