/*
* Select zhangjingwei
* Released under the MIT, BSD, and GPL Licenses.
*/
(function ($) {
$.tools = $.tools || {
version: '1.3'
};
var instances = [],
tool = $.tools.selectinput = {
conf: {
offset: 0, // 弹出菜单偏移量
trigger: false, // 默认触发
css: {
// ids
root: 0,
head: 0,
// classnames
list: 0, // liststyle ?
off: 0, // 鼠标移动上的样式
focus: 0, // 获取焦点样式
disabled: 0, // 禁止选择样式
trigger: 0, // 触发后的样式
current: 0, // 节点被选中的样式
mouseon: 0 // 鼠标移动触发样式
}
}
}
function Selects(select, conf, i) {
var self = this,
css = conf.css,
hid = css.head || "selhead_jQuery" + i,
rid = css.root || "selroot_jQuery" + i,
root = $("#" + rid),
head = $("#" + hid),
title,
index,
currentClass = css.current,
opened,
selstyle = select.offset(),
fire = select.add(self);
// 容灾处理
if (!root.length && !head.length) {
var body = $("body");
index = getSelectIndex(), title = getSelectText();
root = $('<ul />').css(selstyle).css({ "position": "absolute", "height": "auto" }).addClass(css.list).attr("id", rid).hide();
select.find("option").each(function (i, n) {
var val = n.value, text = n.firstChild.nodeValue || n.innerText;
root.append("<li data-value='" + val + "' data-index='" + i + "'><a href='#'>" + text + "</a></li>")
});
root.find("li").eq(index).addClass(currentClass);
head = $("<a />").attr("href", "#").html(title).css(selstyle).css({ "position": "absolute" }).addClass(css.off).attr("id", hid).click(function (e) {
self.show();
return e.preventDefault();
}).appendTo(body);
body.append(root);
select.css("visibility", "hidden");
$(window).resize(function () {
var pos = select.offset();
head.css(pos);
});
}
if (conf.trigger) {
self.show();
}
function onShow(ev) {
ev.type = "onShow";
fire.trigger(ev);
// click outside select
$(document).bind("click.sel", function (e) {
var el = e.target;
if (el != head[0]) {
self.hide(e);
}
});
}
// 选择函数
function selected(index, e) {
var elem = root.find("li"),
currentElem = elem.eq(index),
currentText = currentElem.text();
elem.removeClass(css.current);
currentElem.addClass(css.current);
head.html(currentText);
setSelected(index);
// change
e = e || $.Event("api");
e.type = "change";
fire.trigger(e, index);
if (e.isDefaultPrevented()) {
return;
}
self.hide(e);
}
/*
* 设置selectindex
*/
function setSelected(index) {
select[0].selectedIndex = index;
}
/*
* 获取选中项值
*/
function getSelectVal() {
return select.find("option:selected").val();
}
/*
* 获取选中项文本
*/
function getSelectText() {
return select.find("option:selected").text();
}
/*
* 获取selectindex
*/
function getSelectIndex() {
return select[0].selectedIndex;
}
$.extend(self, {
show: function (e) {
if (select.attr("disabled") || opened) {
return;
}
// onBeforeShow
e = e || $.Event();
e.type = "onBeforeShow";
fire.trigger(e);
if (e.isDefaultPrevented()) {
return;
}
// 关闭所有已打开select
$.each(instances, function () {
this.hide();
});
opened = true;
root.find("li").unbind("click mouseenter mouseleave").click(function (e) {
self.setValue($(this).index(), e);
return false;
}).hover(
function () {
$(this).addClass(css.mouseon);
},
function () {
$(this).removeClass(css.mouseon);
}
);
// show select
var pos = select.offset();
// iPad position fix
if (/iPad/i.test(navigator.userAgent)) {
pos.top -= $(window).scrollTop();
}
if (conf.offset) {
root.css({
top: pos.top + conf.offset[0],
left: pos.left + conf.offset[1]
});
}
root.show();
onShow(e);
return self;
},
hide: function (e, slis) {
if (opened) {
// onHide
e = $.Event();
e.type = "onHide";
fire.trigger(e);
$(document).unbind("click.sel").unbind("keydown.sel");
// cancelled ?
if (e.isDefaultPrevented()) {
return;
}
// do the hide
root.hide();
root.find("li").unbind("click");
opened = false;
}
return self;
},
setValue: function (index, evt) {
evt = evt || $.Event("api");
selected(index, evt, conf);
return self;
},
reflow: function () {
var pos = select.offset(),
headelem = select.data("selectinput");
if (headelem) {
head.css({ top: pos.top, left: pos.left });
}
return self;
},
getConf: function () {
return conf;
},
getRoot: function () {
return root;
},
getHead: function () {
return head;
},
getSelect: function () {
return select;
},
isOpen: function () {
return opened;
}
});
// callbacks
$.each(['onBeforeShow', 'onShow', 'change', 'onHide'], function (i, name) {
// configuration
if ($.isFunction(conf[name])) {
$(self).bind(name, conf[name]);
}
// API methods
self[name] = function (fn) {
if (fn) {
$(self).bind(name, fn);
}
return self;
};
});
}
$.fn.selectinput = function (conf) {
// 单例
if (this.data("selectinput")) {
return this;
}
//
conf = $.extend(true, {}, tool.conf, conf);
var els;
this.each(function (key) {
var el = new Selects($(this), conf, $.now() + key);
instances.push(el);
var sel = el.getSelect().data("selectinput", el);
els = els ? els.add(sel) : sel;
});
return els ? els : this;
};
})(jQuery);