创建版本
This commit is contained in:
@@ -0,0 +1,454 @@
|
||||
(function ($, undefined) {
|
||||
|
||||
var pluginName = 'agDropdownCellEditor',
|
||||
dataKey = 'ag.dropdown.celleditor';
|
||||
|
||||
var defaults = {
|
||||
maxHeight: 200
|
||||
};
|
||||
|
||||
// Utility functions
|
||||
var keys = {
|
||||
ESC: 27,
|
||||
TAB: 9,
|
||||
RETURN: 13,
|
||||
LEFT: 37,
|
||||
UP: 38,
|
||||
RIGHT: 39,
|
||||
DOWN: 40,
|
||||
ENTER: 13,
|
||||
SHIFT: 16
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param {[Node]} element [Select element]
|
||||
* @param {[Object]} options [Option object]
|
||||
*/
|
||||
var Plugin = function (input, options) {
|
||||
this.grid = options.grid;
|
||||
this.config = options.config;
|
||||
this.items = options.data.items;
|
||||
this.selected = options.data.selected;
|
||||
this.hook = options.hook;
|
||||
|
||||
this.arrow = options.arrow || 'icon-search';
|
||||
|
||||
this.name = options.name;
|
||||
|
||||
this.onSelect = options.select || function() {};
|
||||
|
||||
this.$input = $(input);
|
||||
|
||||
// Settings
|
||||
this.settings = $.extend({}, defaults, options);
|
||||
|
||||
// Initialize
|
||||
this.init();
|
||||
|
||||
$.fn[pluginName].instances.push(this);
|
||||
|
||||
};
|
||||
|
||||
$.extend(Plugin.prototype, {
|
||||
init: function () {
|
||||
// Construct the comboselect
|
||||
this._construct();
|
||||
|
||||
// Add event bindings
|
||||
this._events();
|
||||
},
|
||||
_construct: function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
// Wrap the Select
|
||||
this.$container = $('<div class="combo-select combo-open combo-'+ me.name +'" />');
|
||||
|
||||
// Append dropdown arrow
|
||||
this.$arrow = $('<div class="combo-arrow"><i class="fa '+ this.arrow + '"></i></div>');
|
||||
|
||||
// Append dropdown
|
||||
this.$dropdown = $('<ul class="combo-dropdown" />').appendTo(this.$container);
|
||||
|
||||
// Create dropdown options
|
||||
this._build();
|
||||
|
||||
this.$input.after(this.$arrow);
|
||||
|
||||
$('body').append(this.$container);
|
||||
|
||||
var height = this.$input.outerHeight();
|
||||
var width = this.$input.outerWidth();
|
||||
var offset = this.$input.offset();
|
||||
this.$container.css({width: width + 2, left: offset.left - 1, top: offset.top + height + 1});
|
||||
},
|
||||
_build: function () {
|
||||
|
||||
var me = this;
|
||||
|
||||
var o = '', k = 0;
|
||||
|
||||
o += '<li class="option-item-empty">无匹配选项</li>';
|
||||
|
||||
$.each(this.items, function (i, e) {
|
||||
|
||||
if (e == 'optgroup') {
|
||||
return o += '<li class="option-group">' + this.label + '</li>';
|
||||
}
|
||||
o += '<li class="' + (this.disabled ? 'option-disabled' : "option-item") + ' ' + (this.id == me.selected ? 'option-selected' : '') + '" data-index="' + (k) + '" data-value="' + this.id + '">' + (this.name) + '<i>' + this.code + '</i></li>';
|
||||
k++;
|
||||
})
|
||||
|
||||
this.$dropdown.html(o)
|
||||
// Items
|
||||
this.$items = this.$dropdown.children();
|
||||
},
|
||||
|
||||
_events: function () {
|
||||
var me = this;
|
||||
|
||||
this.$arrow.off();
|
||||
this.$container.off();
|
||||
this.$input.off();
|
||||
|
||||
// Dropdown Arrow: click
|
||||
this.$arrow.on('click.arrow', $.proxy(this._toggle, this));
|
||||
|
||||
// Dropdown: close
|
||||
this.$container.on('dropdown:close', $.proxy(this._close, this));
|
||||
|
||||
// Dropdown: open
|
||||
this.$container.on('dropdown:open', $.proxy(this._open, this));
|
||||
|
||||
// Dropdown: update
|
||||
this.$container.on('dropdown:update', $.proxy(this._update, this));
|
||||
|
||||
// Input: keydown
|
||||
this.$input.on('keydown', $.proxy(this._keydown, this));
|
||||
|
||||
// Input: keyup
|
||||
this.$input.on('keyup', $.proxy(this._keyup, this));
|
||||
|
||||
// Dropdown item: click
|
||||
this.$container.on('click.item', '.option-item', $.proxy(this._select, this));
|
||||
},
|
||||
_keydown: function (event) {
|
||||
|
||||
switch (event.which) {
|
||||
case keys.ESC:
|
||||
this.$container.trigger('dropdown:close');
|
||||
break;
|
||||
|
||||
case keys.UP:
|
||||
this._move('up', event);
|
||||
event.stopPropagation();
|
||||
break;
|
||||
|
||||
case keys.DOWN:
|
||||
this._move('down', event);
|
||||
event.stopPropagation();
|
||||
break;
|
||||
|
||||
case keys.TAB:
|
||||
this._enter(event);
|
||||
break;
|
||||
|
||||
case keys.RIGHT:
|
||||
//this._autofill(event);
|
||||
break;
|
||||
|
||||
case keys.ENTER:
|
||||
this._enter(event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_keyup: function (event) {
|
||||
|
||||
switch (event.which) {
|
||||
|
||||
case keys.ESC:
|
||||
case keys.ENTER:
|
||||
case keys.UP:
|
||||
case keys.DOWN:
|
||||
case keys.LEFT:
|
||||
case keys.RIGHT:
|
||||
case keys.TAB:
|
||||
case keys.SHIFT:
|
||||
break;
|
||||
|
||||
default:
|
||||
this._filter(event.target.value);
|
||||
break;
|
||||
}
|
||||
},
|
||||
_enter: function (event) {
|
||||
var item = this._getHovered();
|
||||
this._select(item);
|
||||
},
|
||||
_move: function (dir, event) {
|
||||
var items = this._getVisible(),
|
||||
current = this._getHovered(),
|
||||
index = current.prevAll('.option-item').filter(':visible').length,
|
||||
total = items.length;
|
||||
|
||||
switch (dir) {
|
||||
case 'up':
|
||||
index--;
|
||||
(index < 0) && (index = (total - 1));
|
||||
break;
|
||||
|
||||
case 'down':
|
||||
index++;
|
||||
(index >= total) && (index = 0);
|
||||
break;
|
||||
}
|
||||
|
||||
items.removeClass('option-hover')
|
||||
.eq(index)
|
||||
.addClass('option-hover');
|
||||
|
||||
if (!this.opened) this.$container.trigger('dropdown:open');
|
||||
|
||||
this._fixScroll();
|
||||
},
|
||||
|
||||
_select: function (event) {
|
||||
|
||||
var item = event.currentTarget ? $(event.currentTarget) : $(event);
|
||||
|
||||
//if (!item.length) return;
|
||||
|
||||
var index = item.data('index');
|
||||
this._selectByIndex(index);
|
||||
this.$container.trigger('dropdown:close');
|
||||
},
|
||||
|
||||
/**
|
||||
* Set selected index and trigger change
|
||||
* @type {[type]}
|
||||
*/
|
||||
_selectByIndex: function (index) {
|
||||
|
||||
if (typeof index == 'undefined') {
|
||||
// 为空设置不选中
|
||||
index = -1;
|
||||
}
|
||||
|
||||
this._getAll()
|
||||
.removeClass('option-selected')
|
||||
.filter(function() {
|
||||
return $(this).data('index') == index
|
||||
}).addClass('option-selected')
|
||||
|
||||
this._change();
|
||||
},
|
||||
|
||||
_autofill: function () {
|
||||
var item = this._getHovered();
|
||||
if (item.length) {
|
||||
var index = item.data('index');
|
||||
this._selectByIndex(index);
|
||||
}
|
||||
},
|
||||
_filter: function (search) {
|
||||
|
||||
var self = this,
|
||||
items = this._getAll(),
|
||||
needle = $.trim(search).toLowerCase(),
|
||||
reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g'),
|
||||
pattern = '(' + search.replace(reEscape, '\\$1') + ')';
|
||||
|
||||
// Unwrap all markers
|
||||
$('.combo-marker', items).contents().unwrap();
|
||||
// Search
|
||||
if (needle) {
|
||||
// Hide Disabled and optgroups
|
||||
this.$items.filter('.option-group, .option-disabled').hide();
|
||||
items
|
||||
.hide()
|
||||
.filter(function () {
|
||||
|
||||
var $this = $(this),
|
||||
text = $.trim($this.text()).toLowerCase();
|
||||
|
||||
// Found
|
||||
if (text.toString().indexOf(needle) != -1) {
|
||||
|
||||
// Wrap the selection
|
||||
$this
|
||||
.html(function (index, oldhtml) {
|
||||
return oldhtml.replace(new RegExp(pattern, 'gi'), '<span class="combo-marker">$1</span>');
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
items.show();
|
||||
}
|
||||
|
||||
// Open the dropdown
|
||||
this.$container.trigger('dropdown:open');
|
||||
|
||||
// 搜索结果为不存在时候显示
|
||||
if(this._getVisible().length == 0) {
|
||||
this.$items.filter('.option-item-empty').show();
|
||||
} else {
|
||||
this.$items.filter('.option-item-empty').hide();
|
||||
}
|
||||
},
|
||||
|
||||
_highlight: function() {
|
||||
/*
|
||||
1. Check if there is a selected item
|
||||
2. Add hover class to it
|
||||
3. If not add hover class to first item
|
||||
*/
|
||||
var visible = this._getVisible().removeClass('option-hover'),
|
||||
$selected = visible.filter('.option-selected');
|
||||
|
||||
if ($selected.length) {
|
||||
$selected.addClass('option-hover');
|
||||
} else {
|
||||
visible.removeClass('option-hover')
|
||||
.first()
|
||||
.addClass('option-hover');
|
||||
}
|
||||
},
|
||||
|
||||
_updateInput: function() {
|
||||
var item = this._getAll().filter('.option-selected');
|
||||
var index = item.data('index');
|
||||
|
||||
this.onSelect.call(this, this.items[index]);
|
||||
/*
|
||||
if (index) {
|
||||
this.onSelect.call(this, this.items[index]);
|
||||
} else {
|
||||
this.onSelect.call(this, this.items[index]);
|
||||
}*/
|
||||
},
|
||||
_focus: function (event) {
|
||||
// Toggle focus class
|
||||
this.$container.toggleClass('combo-focus', !this.opened);
|
||||
// Open combo
|
||||
if (!this.opened) this.$container.trigger('dropdown:open');
|
||||
},
|
||||
_change: function () {
|
||||
this._updateInput();
|
||||
},
|
||||
_getAll: function () {
|
||||
return this.$items.filter('.option-item');
|
||||
},
|
||||
_getVisible: function () {
|
||||
return this.$items.filter('.option-item').filter(':visible')
|
||||
},
|
||||
_getHovered: function () {
|
||||
return this._getVisible().filter('.option-hover');
|
||||
},
|
||||
_open: function () {
|
||||
var self = this
|
||||
this.$container.addClass('combo-open');
|
||||
this.$arrow.addClass('combo-arrow-open');
|
||||
this.opened = true;
|
||||
|
||||
// Highligh the items
|
||||
this._highlight();
|
||||
|
||||
// Fix scroll
|
||||
this._fixScroll();
|
||||
|
||||
// Close all others
|
||||
$.each($.fn[pluginName].instances, function(i, plugin) {
|
||||
if (plugin != self && plugin.opened) plugin.$container.trigger('dropdown:close');
|
||||
})
|
||||
},
|
||||
|
||||
_toggle: function(e) {
|
||||
this.opened ? this._close.call(this) : this._open.call(this);
|
||||
this.$input.focus();
|
||||
e.stopPropagation();
|
||||
},
|
||||
_close: function() {
|
||||
this.$container.removeClass('combo-open combo-focus');
|
||||
this.$arrow.removeClass('combo-arrow-open');
|
||||
this.$container.trigger('dropdown:closed');
|
||||
this.opened = false;
|
||||
// Show all items
|
||||
this.$items.filter('.option-item').show();
|
||||
},
|
||||
_fixScroll: function() {
|
||||
|
||||
// If dropdown is hidden
|
||||
if (this.$dropdown.is(':hidden')) return;
|
||||
|
||||
// Else
|
||||
var item = this._getHovered();
|
||||
|
||||
if (!item.length) return;
|
||||
|
||||
// Scroll
|
||||
var offsetTop,
|
||||
upperBound,
|
||||
lowerBound,
|
||||
heightDelta = item.outerHeight();
|
||||
|
||||
offsetTop = item[0].offsetTop;
|
||||
upperBound = this.$dropdown.scrollTop();
|
||||
lowerBound = upperBound + this.settings.maxHeight - heightDelta;
|
||||
|
||||
if (offsetTop < upperBound) {
|
||||
this.$dropdown.scrollTop(offsetTop);
|
||||
} else if (offsetTop > lowerBound) {
|
||||
this.$dropdown.scrollTop(offsetTop - this.settings.maxHeight + heightDelta);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
_update: function() {
|
||||
this.$dropdown.empty();
|
||||
this._build();
|
||||
},
|
||||
|
||||
/**
|
||||
* 销毁
|
||||
*/
|
||||
dispose: function() {
|
||||
// 删除dom
|
||||
this.$arrow.remove();
|
||||
this.$input.remove();
|
||||
this.$dropdown.remove();
|
||||
}
|
||||
});
|
||||
|
||||
$.fn[pluginName] = function(options, args) {
|
||||
|
||||
this.each(function() {
|
||||
|
||||
var $e = $(this),
|
||||
instance = $e.data('plugin_' + dataKey);
|
||||
|
||||
if (typeof options === 'string') {
|
||||
if (instance && typeof instance[options] === 'function') {
|
||||
instance[options](args);
|
||||
}
|
||||
} else {
|
||||
if (instance && instance.dispose) {
|
||||
instance.dispose();
|
||||
}
|
||||
$.data(this, "plugin_" + dataKey, new Plugin(this, options));
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
$.fn[pluginName].instances = [];
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,451 @@
|
||||
;(function($) {
|
||||
|
||||
var inputLock; // 用于中文输入法输入时锁定搜索
|
||||
var grid = null;
|
||||
|
||||
/**
|
||||
* 设置或获取输入框的 alt 值
|
||||
*/
|
||||
function setOrGetAlt($input, val) {
|
||||
return val !== undefined ? $input.attr('alt', val) : $input.attr('alt');
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字段名是否在 options.effectiveFields 配置项中
|
||||
* @param {String} field 要判断的字段名
|
||||
* @param {Object} options
|
||||
* @return {Boolean} effectiveFields 为空时始终返回 true
|
||||
*/
|
||||
function inEffectiveFields(field, options) {
|
||||
var effectiveFields = options.effectiveFields;
|
||||
|
||||
return !(field === '__index' || effectiveFields.length && !~$.inArray(field, effectiveFields));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字段名是否在 options.searchFields 搜索字段配置中
|
||||
*/
|
||||
function inSearchFields(field, options) {
|
||||
return ~$.inArray(field, options.searchFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示下拉列表
|
||||
*/
|
||||
function showDropMenu($input, options) {
|
||||
var $dropdownMenu = $('#gdoo-gird-suggest');
|
||||
if (!$dropdownMenu.is(':visible')) {
|
||||
$dropdownMenu.show();
|
||||
$input.trigger('onShowDropdown', [options ? options.data : []]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏下拉列表
|
||||
*/
|
||||
function hideDropMenu($input, options) {
|
||||
var $dropdownMenu = $('#gdoo-gird-suggest');
|
||||
if ($dropdownMenu.is(':visible')) {
|
||||
$dropdownMenu.hide();
|
||||
$input.trigger('onHideDropdown', [options ? options.data : []]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉列表刷新
|
||||
* 作为 fnGetData 的 callback 函数调用
|
||||
*/
|
||||
function refreshDropMenu($input, data, options) {
|
||||
showDropMenu($input, options);
|
||||
grid.remoteParams.q = $input.val();
|
||||
// 读取数据
|
||||
grid.remoteData();
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉列表刷新
|
||||
* 作为 fnGetData 的 callback 函数调用
|
||||
*/
|
||||
function refreshDropMenu2($input, options) {
|
||||
|
||||
var params = options.query;
|
||||
params.suggest = true;
|
||||
|
||||
var $dropdownMenu = $('#gdoo-gird-suggest');
|
||||
$dropdownMenu.html('<div style="height:180px;overflow:auto;width:auto;"><div id="suggest-'+ params.id +'" class="ag-theme-balham" style="width:100%;height:180px;border-left:1px solid #BDC3C7;border-right:1px solid #BDC3C7;"></div></div>');
|
||||
|
||||
var option = gdoo.formKey(params);
|
||||
var event = gdoo.event.get(option.key);
|
||||
event.trigger('query', params);
|
||||
event.trigger('open', params);
|
||||
|
||||
var sid = params.prefix == 1 ? 'sid' : 'id';
|
||||
var gridDiv = document.querySelector("#suggest-" + params.id);
|
||||
grid = new agGridOptions();
|
||||
var multiple = params.multi == 0 ? false : true;
|
||||
grid.remoteDataUrl = app.url(params.url);
|
||||
grid.remoteParams = params;
|
||||
grid.rowSelection = multiple ? 'multiple' : 'single';
|
||||
|
||||
grid.suppressRowClickSelection = true;
|
||||
grid.columnDefs = [
|
||||
//{suppressMenu: true, cellClass:'text-center', checkboxSelection: true, headerCheckboxSelection: multiple, suppressSizeToFit: true, sortable: false, width: 40},
|
||||
//{suppressMenu: true, cellClass:'text-center', sortable: false, suppressSizeToFit: true, cellRenderer: 'htmlCellRenderer', field: 'images', headerName: '图片', width: 40},
|
||||
{suppressMenu: true, cellClass:'text-center', sortable: true, field: 'code', headerName: '存货编码', width: 100},
|
||||
{suppressMenu: true, cellClass:'text-left', sortable: true, field: 'name', headerName: '产品名称', minWidth: 140},
|
||||
{suppressMenu: true, cellClass:'text-center', sortable: true, field: 'spec', headerName: '规格型号', width: 100},
|
||||
{suppressMenu: true, cellClass:'text-center', sortable: true, field: 'barcode', headerName: '产品条码', width: 120},
|
||||
{suppressMenu: true, cellClass:'text-center', sortable: true, field: 'unit_id_name', headerName: '计量单位', width: 80},
|
||||
{suppressMenu: true, cellClass:'text-right', field: 'price', headerName: '价格', width: 80}
|
||||
];
|
||||
|
||||
grid.onRowClicked = function (row) {
|
||||
var ret = grid.writeSelected(row.data);
|
||||
if (ret) {
|
||||
hideDropMenu($input, options);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 写入选中
|
||||
*/
|
||||
grid.writeSelected = function(selectedRow) {
|
||||
var ret = true;
|
||||
var list = gdoo.forms[params.form_id];
|
||||
var links = list.links[params.id];
|
||||
var item = options.item;
|
||||
// 如果传入的行id为0
|
||||
if (query.grid_id == 0) {
|
||||
query.grid_id = list.lastEditCell.data.id;
|
||||
}
|
||||
for (key in links) {
|
||||
item[key] = selectedRow[links[key]];
|
||||
}
|
||||
|
||||
if (event.exist('onSelect')) {
|
||||
ret = event.trigger('onSelect', item, selectedRow);
|
||||
}
|
||||
|
||||
list.lastEditCell.data = item;
|
||||
list.api.memoryStore.update(item);
|
||||
$input.trigger('onSelect', [item]);
|
||||
list.generatePinnedBottomData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
new agGrid.Grid(gridDiv, grid);
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测 keyword 与 value 是否存在互相包含
|
||||
* @param {String} keyword 用户输入的关键字
|
||||
* @param {String} key 匹配字段的 key
|
||||
* @param {String} value key 字段对应的值
|
||||
* @param {Object} options
|
||||
* @return {Boolean} 包含/不包含
|
||||
*/
|
||||
function isInWord(keyword, key, value, options) {
|
||||
value = $.trim(value);
|
||||
|
||||
if (options.ignorecase) {
|
||||
keyword = keyword.toLocaleLowerCase();
|
||||
value = value.toLocaleLowerCase();
|
||||
}
|
||||
|
||||
return value &&
|
||||
(inEffectiveFields(key, options) || inSearchFields(key, options)) && // 必须在有效的搜索字段中
|
||||
(
|
||||
~value.indexOf(keyword) || // 匹配值包含关键字
|
||||
options.twoWayMatch && ~keyword.indexOf(value) // 关键字包含匹配值
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 ajax 或 json 参数获取数据
|
||||
*/
|
||||
function getData(keyword, $input, callback, options) {
|
||||
var data, validData, filterData = [], i, key, len;
|
||||
|
||||
keyword = keyword || '';
|
||||
|
||||
// 给了url参数,则从服务器 ajax 请求
|
||||
if (options.url) {
|
||||
callback($input, options.data, options);
|
||||
} else {
|
||||
data = options.data;
|
||||
validData = data;
|
||||
// 本地的 data 数据,则在本地过滤
|
||||
if (validData) {
|
||||
if (keyword) {
|
||||
// 输入不为空时则进行匹配
|
||||
len = data.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
for (key in data[i]) {
|
||||
if (data[i][key] && isInWord(keyword, key, data[i][key] + '', options)) {
|
||||
filterData.push(data[i]);
|
||||
filterData[filterData.length - 1].__index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filterData = data;
|
||||
}
|
||||
}
|
||||
callback($input, filterData, options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得 clearable 清除按钮
|
||||
*/
|
||||
function getIClear($input, options) {
|
||||
var $iClear = $input.prev('i.clearable');
|
||||
|
||||
// 是否可清除已输入的内容(添加清除按钮)
|
||||
if (options.clearable && !$iClear.length) {
|
||||
$iClear = $('<i class="clearable glyphicon glyphicon-remove"></i>')
|
||||
.prependTo($input.parent());
|
||||
}
|
||||
|
||||
return $iClear.css({
|
||||
position: 'absolute',
|
||||
top: 12,
|
||||
// right: options.showBtn ? Math.max($input.next('.input-group-btn').width(), 33) + 2 : 12,
|
||||
zIndex: 4,
|
||||
cursor: 'pointer',
|
||||
fontSize: 12
|
||||
}).hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认的配置选项
|
||||
* @type {Object}
|
||||
*/
|
||||
var defaultOptions = {
|
||||
query: {},
|
||||
item: {},
|
||||
data: [],
|
||||
allowNoKeyword: true,
|
||||
ignorecase: false,
|
||||
searchFields: [],
|
||||
twoWayMatch: true,
|
||||
delay: 300,
|
||||
showBtn: true,
|
||||
clearable: false,
|
||||
/* key */
|
||||
keyLeft: 37,
|
||||
keyUp: 38,
|
||||
keyRight: 39,
|
||||
keyDown: 40,
|
||||
keyEnter: 13,
|
||||
fnGetData: getData
|
||||
};
|
||||
|
||||
var methods = {
|
||||
init: function(options) {
|
||||
// 参数设置
|
||||
var self = this;
|
||||
options = options || {};
|
||||
|
||||
options = $.extend(true, {}, defaultOptions, options);
|
||||
|
||||
return self.each(function() {
|
||||
var $input = $(this),
|
||||
$parent = $input.parent(),
|
||||
$iClear = getIClear($input, options),
|
||||
isMouseenterMenu,
|
||||
keyupTimer; // keyup 与 input 事件延时定时器
|
||||
|
||||
var $dropdownMenu = $('#gdoo-gird-suggest');
|
||||
if ($dropdownMenu.length === 0) {
|
||||
$dropdownMenu = $('<div class="gdoo-gird-suggest" id="gdoo-gird-suggest" style="position:absolute;display:none;box-shadow:0 2px 5px 0 rgb(0 0 0 / 26%);"></div>');
|
||||
$('body').append($dropdownMenu);
|
||||
}
|
||||
refreshDropMenu2($input, options);
|
||||
|
||||
/*
|
||||
var offset = $input.offset();
|
||||
var height = $input.outerHeight();
|
||||
$dropdownMenu.css({left: offset.left - 1, top: offset.top + height - 1});
|
||||
*/
|
||||
|
||||
$input.off();
|
||||
|
||||
// 是否显示 button 按钮
|
||||
if (!options.showBtn) {
|
||||
$input.css('borderRadius', 4);
|
||||
$parent.css('width', '100%').find('.btn:eq(0)').hide();
|
||||
}
|
||||
|
||||
// 移除 disabled 类,并禁用自动完成
|
||||
$input.removeClass('disabled').prop('disabled', false).attr('autocomplete', 'off');
|
||||
|
||||
// 开始事件处理
|
||||
$input.on('keydown', function(event) {
|
||||
// 当提示层显示时才对键盘事件处理
|
||||
if (!$dropdownMenu.is(':visible')) {
|
||||
return;
|
||||
}
|
||||
if (event.keyCode === options.keyEnter) {
|
||||
hideDropMenu($input, options);
|
||||
}
|
||||
|
||||
}).on('compositionstart', function(event) {
|
||||
// 中文输入开始,锁定
|
||||
inputLock = true;
|
||||
}).on('compositionend', function(event) {
|
||||
// 中文输入结束,解除锁定
|
||||
inputLock = false;
|
||||
}).on('keyup input paste', function(event) {
|
||||
var word;
|
||||
|
||||
// 如果弹起的键是回车、向上或向下方向键则返回
|
||||
if (~$.inArray(event.keyCode, [options.keyDown, options.keyUp, options.keyEnter])) {
|
||||
$input.val($input.val()); // 让鼠标输入跳到最后
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(keyupTimer);
|
||||
keyupTimer = setTimeout(function() {
|
||||
// 锁定状态,返回
|
||||
if (inputLock) {
|
||||
return;
|
||||
}
|
||||
|
||||
word = $input.val();
|
||||
|
||||
// 若输入框值没有改变则返回
|
||||
if ($.trim(word) && word === setOrGetAlt($input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 是否允许空数据查询
|
||||
if (!word.length && !options.allowNoKeyword) {
|
||||
return;
|
||||
}
|
||||
|
||||
options.fnGetData($.trim(word), $input, refreshDropMenu, options);
|
||||
}, options.delay || 300);
|
||||
|
||||
}).on('blur', function() {
|
||||
// 不是进入下拉列表状态,则隐藏列表
|
||||
if (!isMouseenterMenu) {
|
||||
hideDropMenu($input, options);
|
||||
}
|
||||
}).on('focus', function() {
|
||||
|
||||
$dropdownMenu.off();
|
||||
|
||||
var w = $(window).width();
|
||||
var h = $(window).height();
|
||||
|
||||
var width = $input.outerWidth();
|
||||
var height = $input.outerHeight();
|
||||
var offset = $input.offset();
|
||||
|
||||
var dw = $dropdownMenu.outerWidth();
|
||||
var dh = $dropdownMenu.outerHeight();
|
||||
|
||||
var css = {top: offset.top + height};
|
||||
// 判断是否小于768
|
||||
if (w < 768) {
|
||||
css.minWidth = 360;
|
||||
css.left = 14;
|
||||
css.right = 14;
|
||||
} else {
|
||||
css.left = offset.left - 1;
|
||||
// 右边超出
|
||||
if (w < offset.left + dw + 10) {
|
||||
css.left = offset.left - dw + width + 1;
|
||||
}
|
||||
// 下边超出
|
||||
if (h < offset.top + dh + 10) {
|
||||
css.top = offset.top - dh;
|
||||
}
|
||||
}
|
||||
$dropdownMenu.css(css);
|
||||
|
||||
// 列表中滑动时,输入框失去焦点
|
||||
$dropdownMenu.on('mouseenter', function() {
|
||||
isMouseenterMenu = 1;
|
||||
$input.blur();
|
||||
}).on('mouseleave', function() {
|
||||
isMouseenterMenu = 0;
|
||||
$input.focus();
|
||||
}).on('click', function() {
|
||||
// 阻止冒泡
|
||||
return false;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// 存在清空按钮
|
||||
if ($iClear.length) {
|
||||
$iClear.click(function () {
|
||||
});
|
||||
|
||||
$parent.mouseenter(function() {
|
||||
if (!$input.prop('disabled')) {
|
||||
$iClear.css('right', options.showBtn ? Math.max($input.next('.input-group-btn').width(), 33) + 2 : 12).show();
|
||||
}
|
||||
}).mouseleave(function() {
|
||||
$iClear.hide();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
show: function() {
|
||||
return this.each(function() {
|
||||
$(this).click();
|
||||
});
|
||||
},
|
||||
hide: function() {
|
||||
return this.each(function() {
|
||||
hideDropMenu($(this));
|
||||
});
|
||||
},
|
||||
disable: function() {
|
||||
return this.each(function() {
|
||||
$(this).attr('disabled', true).parent().find('.btn:eq(0)').prop('disabled', true);
|
||||
});
|
||||
},
|
||||
enable: function() {
|
||||
return this.each(function() {
|
||||
$(this).attr('disabled', false).parent().find('.btn:eq(0)').prop('disabled', false);
|
||||
});
|
||||
},
|
||||
destroy: function() {
|
||||
return this.each(function() {
|
||||
$(this).off().removeData('gdooSuggest').removeAttr('style')
|
||||
.parent().find('.btn:eq(0)').off().show().attr('data-toggle', 'dropdown').prop('disabled', false) // .addClass(disabled);
|
||||
.next().css('display', '').off();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.fn['gdooSuggest'] = function(options) {
|
||||
// 方法判断
|
||||
if (typeof options === 'string' && methods[options]) {
|
||||
var inited = true;
|
||||
this.each(function() {
|
||||
if (!$(this).data('gdooSuggest')) {
|
||||
return inited = false;
|
||||
}
|
||||
});
|
||||
// 只要有一个未初始化,则全部都不执行方法,除非是 init 或 version
|
||||
if (!inited && 'init' !== options && 'version' !== options) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// 如果是方法,则参数第一个为函数名,从第二个开始为函数参数
|
||||
return methods[options].apply(this, [].slice.call(arguments, 1));
|
||||
} else {
|
||||
// 调用初始化方法
|
||||
return methods.init.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user