创建版本

This commit is contained in:
2021-02-22 12:17:00 +08:00
commit af555f49c3
2332 changed files with 369202 additions and 0 deletions
@@ -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);