You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2314 lines
81 KiB
2314 lines
81 KiB
/**
|
|
* @summary SelectPage
|
|
* @desc 基于jQuery及使用Bootstrap环境开发的,下拉列表带输入快速查找及结果分页展示的多功能选择器
|
|
* @file selectpage.js
|
|
* @version 2.7
|
|
* @author TerryZeng
|
|
* @contact https://terryz.github.io/
|
|
* @license MIT License
|
|
*
|
|
* 插件的部分功能使用、借鉴了
|
|
* jQuery Plugin: jquery.ajax-combobox
|
|
* 作者:Yuusaku Miyazaki <toumin.m7@gmail.com>(宮崎 雄策)
|
|
*
|
|
* 插件依赖:
|
|
* jQuery1.x
|
|
* font-awesome(图标库)
|
|
*
|
|
* 基本功能:
|
|
* 可实时搜索的下拉列表
|
|
* 对待选择的下拉项目可进行分页
|
|
* 可使用键盘快捷分页操作
|
|
* 使用标签的方式支持下拉项目多选
|
|
*
|
|
* 修改记录:
|
|
* 2016.04.20
|
|
* 增加参数autoSelectFirst(是否自动选择列表中的第一项内容)
|
|
* 解决下拉分页有初始化内容,并删除部分关键字时显示的结果集列表不足一页时,分页栏没有被生成的问题
|
|
* 增加参数autoFillResult(是否自动填充内容)
|
|
* 增加参数noResultClean(是否清空无匹配结果的输入关键字)
|
|
* 2016.06.29
|
|
* 修复分页栏鼠标点击时跳转的页数不正常的问题
|
|
* 2016.08.04
|
|
* 修复因宽度变化导致下拉触发按钮位置在出现下拉列表后发生偏移,原因是原控件的触发按钮是在输入框外部扩展,现已移入输入框内部
|
|
* 2016.08.10
|
|
* 弹出下拉列表时,若有已选中的项目,则将已选中的项目进行高亮,否则对第一行进行高亮
|
|
* 下拉列表展开时,鼠标点击列表区域外,若当前列表已有选中项目,则直接隐藏列表;若当前列表没有默认选中项目,则使用当前高亮项目的内容进行设置
|
|
* 2016.08.12
|
|
* 解决控件对于原始input设置的样式(bootstrap原生提供的宽度样式),宽度显示不正常的问题
|
|
* 增加若设置了formatItem格式函数,则进行匹配的数据源从showField改为formatItem后的结果进行匹配
|
|
* 2016.10
|
|
* 增加光标进入输入框时,打开下拉列表的功能
|
|
* 2017.01.16
|
|
* 解决输入关键进行搜索并有匹配结果时,失去焦点后,没有自动选中第一项
|
|
* 2017.01.19
|
|
* 取消在输入状态时,判断到输入框里内容为空时,隐藏下拉列表的操作
|
|
* 在展示下拉列表时,判断默认与输入框左对齐的列表是否会超出屏幕边界,是则右对齐,否则默认左对齐
|
|
* 2017.01.20
|
|
* 增加下拉列表展示之前判断列表的面板是否会超出底部区域,若超出则将列表向上对齐展示
|
|
* 处理下拉列表显示一次操作显示多次的问题
|
|
* 增加控件已有选中值时,在显示下拉列表时,直接跳转到该项目所在的页
|
|
* 修复一些点击输入框出现下拉列表的Bug
|
|
* 2017.03.24
|
|
* 解决下拉分页插件向上浮动时位置不正确的问题
|
|
* 解决下拉分页插件在已有选中值时,再次点击输入框后,打开的列表分页栏翻页功能无效的问题
|
|
* 2017.04.21
|
|
* 解决打开noResultClean参数,没有匹配输入关键词的项目时,列表不隐藏的问题
|
|
* 2017.04.24
|
|
* 解决控件在设置disabled="disabled"禁用状态时,点击向下的三角尖也可以打开列表的问题
|
|
* 增加控件在已有选中项目时,直接删除输入框中的内容,作为清空控件内容的功能
|
|
* 修改失去焦点的范围从document.body到document
|
|
* 优化键盘输入捕捉的方式
|
|
* 原列表有多页的情况下,再输入关键字,没有匹配到任何项目时,分页条的下一页,最后一页为可点击的样式,且分页信息的内容也不正确
|
|
* 2017.05
|
|
* 代码重构
|
|
* 增加多项选择东西,并以标签(Tag)的形式展现在输入框中
|
|
* 修正插件外框宽度问题
|
|
* 修改选中事件回调的入参从key,value改为选中行的原始数据对象,以便更灵活的数据处理
|
|
* 2017.06
|
|
* 修复部分样式问题
|
|
* 2017.06.13
|
|
* 改名SelectPage
|
|
* 2017.06.24
|
|
* 增加Bootstrap3样式支持
|
|
* 2017.08.08
|
|
* 修复界面上排版内容较少时,列表会向上展示开的问题
|
|
* 增加多选模式下的控制按钮区域,功能:“全选本页”、“取消本页”、“清空全部”
|
|
* 修复最大宽度下超出父容器的宽度问题
|
|
* 修复ajax模式报错的问题
|
|
* 增加eAjaxSuccess请求成功后的数据处理回调
|
|
* 2017.08.13(v2.0)
|
|
* 代码重构
|
|
* 修改默认样式,使用更简洁的风格
|
|
* 增加maxSelectLimit参数,设置多选模式下最大选择个数限制
|
|
* 增加eTagRemove回调函数,在多选模式下,移除标签时触发的回调
|
|
* 优化错误信息展示的交互方式
|
|
* 增加初始化选中项目时(多选模式),允许设置多个内容,例如:data-init="1,2,3,4"
|
|
* 修复键盘操作分页部分情况下会失效的问题
|
|
* 增加selectToCloseList参数,用于设置在多选模式下,选择项目后不关闭列表
|
|
* 修复selectToCloseList:false状态下,键盘操作会失去焦点,操作不连贯的问题
|
|
* 增加$.fn.selectPageClear的API,用于清空控件所有已选中的项目
|
|
* 增加$.fn.selectPageText的API,用于获得已选择的项目文本内容
|
|
* 增加$.fn.selectPageData的API,用于动态修改插件数据源
|
|
* 增加$.fn.SelectedRefresh的API,用于在使用.val()的方式修改了插件的选中项目后,刷新显示在输入框中的文本内容
|
|
* 优化控件内部对象缓存机制
|
|
* 去除快速使用脚本b.selectpage.js
|
|
* 初始化入口从原来的$('').bSelectPage({})修改为$('').selectPage({})
|
|
* 重新调整参数名称
|
|
* 修正Bootstrap3下控件宽度、高度应用的BUG
|
|
* 2017.08.19(v2.2)
|
|
* 增加为原始输入框的value属性设置初始化值,以初始化插件选中项目
|
|
* 修复多选模式下关闭标签出错的问题
|
|
* 修复输入查询关键字后失去焦点,再次获得焦点时,插件没有根据已存在的关键进行过滤
|
|
* 增加inputDelay配置项目,设置ajax数据源模式下,延迟输入查询的时间,避免在单位时间内连续输入发起的连续ajax查询,单位:秒,默认值:0.5
|
|
* 修正对数字类型的列进行排序时,仍然以字符串的方式进行排序
|
|
* 2017.08.23(v2.3)
|
|
* 修复在查询关键字状态下,分页数据没有被更新,导致分页按钮功能不正常问题
|
|
* 清理整理内部对象
|
|
* 修复多选模式下,若设置了最大选中项目个数,点击“全选本页”按钮时,仅选中指定的最大数量
|
|
* 增加selectpage.base.css兼容无UI框架的方案,但建议要至少使用normalize.css
|
|
* 2017.08.26(v2.4)
|
|
* 增加pagination参数,指定稿件是否使用分页加载数据,以及显示分页栏
|
|
* 增加listSize参数,指定了不使用分页的列表,显示的高度,单位为个(选项个数),默认显示10个项目的高度
|
|
* 设置selectOnly:true的情况下,输入框为只读模式,不允许输入查询过滤
|
|
* 修复多选模式下及设置了最大选中项目时,选中了项目再次点击“全选本页”按钮会在已选择的基础上增加最大选中项目个数的项目
|
|
* 调整下拉列表样式及位置
|
|
* 增加单选模式下,选中项目后,自动显示清空按钮
|
|
* 修复多选模式下,移除本页和清除所有两个按钮点击后,回调出错的问题
|
|
* 增加搜索无结果时显示提示信息
|
|
* 2017.09.07(v2.5)
|
|
* 修复多选模式下,初始化项目的显示文本没有使用formatItem回调进行格式化
|
|
* 修复ajax数据源模式下,输入查询关键字时,翻页始终为第一页的问题
|
|
* 2017.09.07(v2.6)
|
|
* 修复单选模式下初始化项目的显示文本没有使用formatItem回调格式化的问题
|
|
* 修复单选模式存在初始化项目时,再打开下拉列表时,仅显示匹配的项目一条数据的问题
|
|
* 修复多选模式下,动态修改选中值selectPageRefresh功能无效
|
|
* 2017.09.12(v2.7)
|
|
* 增加eClear回调,单选模式下,清除按钮的功能回调
|
|
* 单选,多选模式下,输入框禁用或只读状态,不显示清除按钮
|
|
* 2017.09.23(v2.8)
|
|
* 调整部分样式
|
|
* 修复可视区域高度较小时,列表始终会向上展开的问题
|
|
* 分离键盘事件处理,对键盘输入精准控制
|
|
* 优化区域外点击处理
|
|
* 优化数据展示渲染效率
|
|
* 优化列表位置定位的准确性
|
|
*/
|
|
;(function($){
|
|
"use strict";
|
|
/**
|
|
* @desc 默认参数集
|
|
*/
|
|
var defaults = {
|
|
/**
|
|
* @desc 数据源(String:Ajax查询的URL|Object:JSON格式的数据源)
|
|
* @type {string|Object}
|
|
* @example
|
|
* string:服务端请求的URL地址
|
|
* Object:JSON格式数组,推荐格式:[{a:1,b:2,c:3},{...}]
|
|
*/
|
|
data: undefined,
|
|
/**
|
|
* @desc 插件显示语言 ('ja', 'en', 'es', 'pt-br'等)
|
|
* @type string 默认'cn'
|
|
*/
|
|
lang: 'cn',
|
|
/**
|
|
* @desc 是否为多选模式(标签模式)
|
|
* @type boolean 默认值false
|
|
*/
|
|
multiple: false,
|
|
/**
|
|
* @desc 是否分页
|
|
* @type boolean 默认值 true
|
|
*/
|
|
pagination: true,
|
|
/**
|
|
* @desc 关闭分页的状态下,列表显示的项目个数,其它的项目以滚动条滚动方式展现
|
|
* @type number 默认值 10
|
|
*/
|
|
listSize : 10,
|
|
/**
|
|
* @desc 是否启用多选模式的控制按钮区域
|
|
* 仅multiple: true模式下可用
|
|
* @type boolean 默认值true
|
|
*/
|
|
multipleControlbar: true,
|
|
/**
|
|
* @desc 多选模式下最大选择个数,0为不限制
|
|
* @type number 默认0
|
|
*/
|
|
maxSelectLimit: 0,
|
|
/**
|
|
* @desc 选中项目后关闭列表
|
|
* 该设置仅在多选模式下multiple:true有效
|
|
* @type boolean 默认值true
|
|
*/
|
|
selectToCloseList: true,
|
|
/**
|
|
* @desc 插件初始值指定,该值会与option.keyField字段进行匹配,若匹配到,则自动设置选中并高亮
|
|
* @type string
|
|
*/
|
|
initRecord: undefined,
|
|
/**
|
|
* @desc 使用ajax方式获取数据时,使用该参数设置对应的数据表名
|
|
* @type string
|
|
*/
|
|
dbTable: 'tbl',
|
|
/**
|
|
* @desc 值字段,通常该字段的内容会自动保存在隐藏域中
|
|
* @type string 默认值为'id'
|
|
*/
|
|
keyField: 'id',
|
|
/**
|
|
* @desc 结果集中用于显示的属性名
|
|
* @type string 默认字段为'name'
|
|
*/
|
|
showField: 'name',
|
|
/**
|
|
* @desc 查询字段,仅为使用URL(ajax)方式查询服务端时,设置后端查询的字段,不设置则默认使用showField设置的字段
|
|
* @type string
|
|
*/
|
|
searchField : undefined,
|
|
/**
|
|
* @desc 查询方式 ('AND' or 'OR')
|
|
* @type string 默认为'AND'
|
|
*/
|
|
andOr: 'AND',
|
|
/**
|
|
* @desc 数据排序方式
|
|
* @type array 若不设置则默认对showField指定的字段进行排序
|
|
* @example
|
|
* orderBy : ['id desc']//对ID字段进行降序排序
|
|
*/
|
|
orderBy: undefined,
|
|
/**
|
|
* @desc 每页显示的记录数
|
|
* @type number
|
|
*/
|
|
pageSize: 10,
|
|
/**
|
|
* @desc 使用URL进行AJAX查询时,可传递查询参数
|
|
* @type function
|
|
* @return object
|
|
* @example params : function(){return {'name':'aa','sex':1};}
|
|
*/
|
|
params : undefined,
|
|
/**
|
|
* 列表项目显示内容格式化
|
|
* 参数类型:function
|
|
* @type boolean
|
|
* @param data {object} 行数据object格式
|
|
* @return string
|
|
*/
|
|
formatItem : undefined,
|
|
/**
|
|
* 是否在输入框获得焦点时,展开下拉窗口
|
|
* @type boolean 默认值true
|
|
*/
|
|
focusDropList : true,
|
|
/**
|
|
* 是否自动选择列表中的第一项内容(输入关键字查询模式,直接使用鼠标下拉并不触发)
|
|
* @type boolean 默认值false
|
|
*/
|
|
autoSelectFirst: true,
|
|
/**
|
|
* 是否自动填充内容
|
|
* 若有列表项目被高亮显示,在焦点离开控件后,自动设置该项为选中内容
|
|
* @type boolean 默认值false
|
|
*/
|
|
autoFillResult: true,
|
|
/**
|
|
* 是否清空输入关键字
|
|
* 在输入框中输入内容进行查询,但没有匹配的内容返回,在焦点离开控件后,自动清空输入框输入的内容
|
|
* @type boolean 默认值false
|
|
*/
|
|
noResultClean: true,
|
|
/**
|
|
* @desc 只选择模式
|
|
* @type boolean
|
|
*/
|
|
selectOnly: false,
|
|
/**
|
|
* @desc 输入关键字查询延迟(仅ajax数据源模式下可用)
|
|
* @type number 默认值:0.5秒
|
|
*/
|
|
inputDelay: 0.5,
|
|
/**
|
|
* -----------------------------------------事件回调--------------------------------------------
|
|
*/
|
|
/**
|
|
* @type function
|
|
* @param object
|
|
* @param dom
|
|
*/
|
|
eSelect : undefined,
|
|
/**
|
|
* ajax请求模式,请求成功后的数据处理回调
|
|
* 回调的功能用于自定义处理服务端返回的数据
|
|
* @type function
|
|
* @param data {object} ajax服务端返回的json数据
|
|
* @return {object} 函数返回的数据结构如下:
|
|
* @example
|
|
* {
|
|
* list : [{name:'aa',sex:1},{name:'bb',sex:1}...],
|
|
* totalRow : 100
|
|
* }
|
|
*/
|
|
eAjaxSuccess : undefined,
|
|
/**
|
|
* 多选模式下,关闭标签是的回调函数
|
|
* @type function
|
|
* @param removeCount 被移除的个数
|
|
*/
|
|
eTagRemove : undefined,
|
|
/**
|
|
* 单选模式下,选中项目后的清除按钮功能回调
|
|
* @type function
|
|
*/
|
|
eClear : undefined
|
|
};
|
|
|
|
|
|
/**
|
|
* @constructor
|
|
* @classdesc 插件初始化
|
|
* @param {Object} input - 插件的初始化输入框元素。
|
|
* @param {Object} option - 初始化参数
|
|
*/
|
|
var SelectPage = function(input, option) {
|
|
this.setOption(option);
|
|
this.setLanguage();
|
|
this.setCssClass();
|
|
this.setProp();
|
|
this.setElem(input,option);
|
|
|
|
this.setButtonAttrDefault();
|
|
this.setInitRecord();
|
|
|
|
this.eDropdownButton();
|
|
this.eInput();
|
|
this.eWhole();
|
|
};
|
|
/**
|
|
* 插件版本号
|
|
*/
|
|
SelectPage.version = '2.7';
|
|
/**
|
|
* 插件缓存内部对象的KEY
|
|
*/
|
|
SelectPage.dataKey = 'selectPageObject';
|
|
/**
|
|
* 全局范围设置当前点击是否为插件自身的标识
|
|
*/
|
|
SelectPage.objStatusKey = 'selectPage-self-mark';
|
|
/**
|
|
* 全局范围设置当前点击的selectpage的索引下标
|
|
*/
|
|
SelectPage.objStatusIndex = 'selectPage-self-index';
|
|
/**
|
|
* @desc 参数初始化
|
|
* @param {Object} option - 参数集
|
|
*/
|
|
SelectPage.prototype.setOption = function(option) {
|
|
//若没有设置搜索字段,则使用显示字段作为搜索字段
|
|
option.searchField = (option.searchField === undefined) ? option.showField: option.searchField;
|
|
|
|
//统一大写
|
|
option.andOr = option.andOr.toUpperCase();
|
|
if(option.andOr!=='AND' && option.andOr!=='OR') option.andOr = 'AND';
|
|
|
|
//将参数内容从使用","分隔的字符串转换为数组
|
|
var arr = ['searchField'];
|
|
for (var i = 0; i < arr.length; i++) {
|
|
option[arr[i]] = this.strToArray(option[arr[i]]);
|
|
}
|
|
|
|
//设置排序字段
|
|
option.orderBy = (option.orderBy === undefined) ? option.searchField: option.orderBy;
|
|
|
|
//设置多字段排序
|
|
//例: [ ['id', 'ASC'], ['name', 'DESC'] ]
|
|
option.orderBy = this.setOrderbyOption(option.orderBy, option.showField);
|
|
//多选模式下,若设置了选择项目不关闭列表功能,则强制关闭自动选择第一项功能和自动选中高亮的项目功能
|
|
//原因是打开了会总是莫明选择了第一项,体验不佳
|
|
if(option.multiple && !option.selectToCloseList){
|
|
option.autoFillResult = false;
|
|
option.autoSelectFirst = false;
|
|
}
|
|
|
|
if($.type(option.data) === 'string'){
|
|
option.autoSelectFirst = false;
|
|
}
|
|
//若不需要分页功能,则将所有数据都显示出来,上限200项
|
|
if(!option.pagination) option.pageSize = 200;
|
|
if($.type(option.listSize) !== 'number' || option.listSize < 0) option.listSize = 10;
|
|
|
|
this.option = option;
|
|
};
|
|
|
|
/**
|
|
* @desc 字符串转换为数组
|
|
* @param str {string} - 字符串
|
|
* @return {Array} - 数组
|
|
*/
|
|
SelectPage.prototype.strToArray = function(str) {
|
|
if(!str) return '';
|
|
return str.replace(/[\s ]+/g, '').split(',');
|
|
};
|
|
|
|
/**
|
|
* @desc 设置多字段排序
|
|
* @param {Array} arg_order - 排序顺序
|
|
* @param {string} arg_field - 字段
|
|
* @return {Array} - 处理后的排序字段内容
|
|
*/
|
|
SelectPage.prototype.setOrderbyOption = function(arg_order, arg_field) {
|
|
var arr = [],orders = [];
|
|
if (typeof arg_order == 'object') {
|
|
for (var i = 0; i < arg_order.length; i++) {
|
|
orders = $.trim(arg_order[i]).split(' ');
|
|
arr[i] = (orders.length == 2) ? orders: [orders[0], 'ASC'];
|
|
}
|
|
} else {
|
|
orders = $.trim(arg_order).split(' ');
|
|
arr[0] = (orders.length == 2) ? orders: (orders[0].match(/^(ASC|DESC)$/i)) ? [arg_field, orders[0]] : [orders[0], 'ASC'];
|
|
}
|
|
return arr;
|
|
};
|
|
|
|
/**
|
|
* @desc 界面文字国际化
|
|
*/
|
|
SelectPage.prototype.setLanguage = function() {
|
|
var message;
|
|
switch (this.option.lang) {
|
|
// German
|
|
case 'de':
|
|
message = {
|
|
add_btn: 'Hinzufügen-Button',
|
|
add_title: 'Box hinzufügen',
|
|
del_btn: 'Löschen-Button',
|
|
del_title: 'Box löschen',
|
|
next: 'Nächsten',
|
|
next_title: 'Nächsten' + this.option.pageSize + ' (Pfeil-rechts)',
|
|
prev: 'Vorherigen',
|
|
prev_title: 'Vorherigen' + this.option.pageSize + ' (Pfeil-links)',
|
|
first_title: 'Ersten (Umschalt + Pfeil-links)',
|
|
last_title: 'Letzten (Umschalt + Pfeil-rechts)',
|
|
get_all_btn: 'alle (Pfeil-runter)',
|
|
get_all_alt: '(Button)',
|
|
close_btn: 'Schließen (Tab)',
|
|
close_alt: '(Button)',
|
|
loading: 'lade...',
|
|
loading_alt: '(lade)',
|
|
page_info: 'num_page_top - num_page_end von cnt_whole',
|
|
select_ng: 'Achtung: Bitte wählen Sie aus der Liste aus.',
|
|
select_ok: 'OK : Richtig ausgewählt.',
|
|
not_found: 'nicht gefunden',
|
|
ajax_error: 'Bei der Verbindung zum Server ist ein Fehler aufgetreten.'
|
|
};
|
|
break;
|
|
|
|
// English
|
|
case 'en':
|
|
message = {
|
|
add_btn: 'Add button',
|
|
add_title: 'add a box',
|
|
del_btn: 'Del button',
|
|
del_title: 'delete a box',
|
|
next: 'Next',
|
|
next_title: 'Next' + this.option.pageSize + ' (Right key)',
|
|
prev: 'Prev',
|
|
prev_title: 'Prev' + this.option.pageSize + ' (Left key)',
|
|
first_title: 'First (Shift + Left key)',
|
|
last_title: 'Last (Shift + Right key)',
|
|
get_all_btn: 'Get All (Down key)',
|
|
get_all_alt: '(button)',
|
|
close_btn: 'Close (Tab key)',
|
|
close_alt: '(button)',
|
|
loading: 'loading...',
|
|
loading_alt: '(loading)',
|
|
page_info: 'num_page_top - num_page_end of cnt_whole',
|
|
select_ng: 'Attention : Please choose from among the list.',
|
|
select_ok: 'OK : Correctly selected.',
|
|
not_found: 'not found',
|
|
ajax_error: 'An error occurred while connecting to server.'
|
|
};
|
|
break;
|
|
|
|
// 中文
|
|
case 'cn':
|
|
message = {
|
|
add_btn: '添加按钮',
|
|
add_title: '添加区域',
|
|
del_btn: '删除按钮',
|
|
del_title: '删除区域',
|
|
next: '下一页',
|
|
next_title: '下' + this.option.pageSize + ' (→)',
|
|
prev: '上一页',
|
|
prev_title: '上' + this.option.pageSize + ' (←)',
|
|
first_title: '首页 (Shift + ←)',
|
|
last_title: '尾页 (Shift + →)',
|
|
get_all_btn: '获得全部 (↓)',
|
|
get_all_alt: '(按钮)',
|
|
close_btn: '关闭 (Tab键)',
|
|
close_alt: '(按钮)',
|
|
loading: '读取中...',
|
|
loading_alt: '(读取中)',
|
|
page_info: 'num_page_top - num_page_end (共 cnt_whole)',
|
|
select_ng: '请注意:请从列表中选择.',
|
|
select_ok: 'OK : 已经选择.',
|
|
not_found: '无查询结果',
|
|
ajax_error: '连接到服务器时发生错误!'
|
|
};
|
|
break;
|
|
|
|
// Spanish
|
|
case 'es':
|
|
message = {
|
|
add_btn: 'Agregar boton',
|
|
add_title: 'Agregar una opcion',
|
|
del_btn: 'Borrar boton',
|
|
del_title: 'Borrar una opcion',
|
|
next: 'Siguiente',
|
|
next_title: 'Proximas ' + this.option.pageSize + ' (tecla derecha)',
|
|
prev: 'Anterior',
|
|
prev_title: 'Anteriores ' + this.option.pageSize + ' (tecla izquierda)',
|
|
first_title: 'Primera (Shift + Left)',
|
|
last_title: 'Ultima (Shift + Right)',
|
|
get_all_btn: 'Ver todos (tecla abajo)',
|
|
get_all_alt: '(boton)',
|
|
close_btn: 'Cerrar (tecla TAB)',
|
|
close_alt: '(boton)',
|
|
loading: 'Cargando...',
|
|
loading_alt: '(Cargando)',
|
|
page_info: 'num_page_top - num_page_end de cnt_whole',
|
|
select_ng: 'Atencion: Elija una opcion de la lista.',
|
|
select_ok: 'OK: Correctamente seleccionado.',
|
|
not_found: 'no encuentre',
|
|
ajax_error: 'Un error ocurrió mientras conectando al servidor.'
|
|
};
|
|
break;
|
|
|
|
// Brazilian Portuguese
|
|
case 'pt-br':
|
|
message = {
|
|
add_btn: 'Adicionar botão',
|
|
add_title: 'Adicionar uma caixa',
|
|
del_btn: 'Apagar botão',
|
|
del_title: 'Apagar uma caixa',
|
|
next: 'Próxima',
|
|
next_title: 'Próxima ' + this.option.pageSize + ' (tecla direita)',
|
|
prev: 'Anterior',
|
|
prev_title: 'Anterior ' + this.option.pageSize + ' (tecla esquerda)',
|
|
first_title: 'Primeira (Shift + Left)',
|
|
last_title: 'Última (Shift + Right)',
|
|
get_all_btn: 'Ver todos (Seta para baixo)',
|
|
get_all_alt: '(botão)',
|
|
close_btn: 'Fechar (tecla TAB)',
|
|
close_alt: '(botão)',
|
|
loading: 'Carregando...',
|
|
loading_alt: '(Carregando)',
|
|
page_info: 'num_page_top - num_page_end de cnt_whole',
|
|
select_ng: 'Atenção: Escolha uma opção da lista.',
|
|
select_ok: 'OK: Selecionado Corretamente.',
|
|
not_found: 'não encontrado',
|
|
ajax_error: 'Um erro aconteceu enquanto conectando a servidor.'
|
|
};
|
|
break;
|
|
|
|
// Japanese
|
|
case 'ja':
|
|
message = {
|
|
add_btn: '追加ボタン',
|
|
add_title: '入力ボックスを追加します',
|
|
del_btn: '削除ボタン',
|
|
del_title: '入力ボックスを削除します',
|
|
next: '次へ',
|
|
next_title: '次の' + this.option.pageSize + '件 (右キー)',
|
|
prev: '前へ',
|
|
prev_title: '前の' + this.option.pageSize + '件 (左キー)',
|
|
first_title: '最初のページへ (Shift + 左キー)',
|
|
last_title: '最後のページへ (Shift + 右キー)',
|
|
get_all_btn: '全件取得 (下キー)',
|
|
get_all_alt: '画像:ボタン',
|
|
close_btn: '閉じる (Tabキー)',
|
|
close_alt: '画像:ボタン',
|
|
loading: '読み込み中...',
|
|
loading_alt: '画像:読み込み中...',
|
|
page_info: 'num_page_top - num_page_end 件 (全 cnt_whole 件)',
|
|
select_ng: '注意 : リストの中から選択してください',
|
|
select_ok: 'OK : 正しく選択されました。',
|
|
not_found: '(0 件)',
|
|
ajax_error: 'サーバとの通信でエラーが発生しました。'
|
|
};
|
|
break;
|
|
}
|
|
this.message = message;
|
|
};
|
|
|
|
/**
|
|
* @desc CSS样式表名称字义
|
|
*/
|
|
SelectPage.prototype.setCssClass = function() {
|
|
var css_class = {
|
|
container: 'sp_container',
|
|
// SelectPage最外层DIV的打开状态
|
|
container_open: 'sp_container_open',
|
|
re_area: 'sp_result_area',
|
|
control_box: 'sp_control_box',
|
|
//标签及输入框的
|
|
element_box: 'sp_element_box',
|
|
// 分页导航
|
|
navi: 'sp_navi',
|
|
// 下拉结果列表
|
|
results: 'sp_results',
|
|
re_off: 'sp_results_off',
|
|
select: 'sp_over',
|
|
select_ok: 'sp_select_ok',
|
|
select_ng: 'sp_select_ng',
|
|
selected: 'sp_selected',
|
|
input_off: 'sp_input_off',
|
|
message_box: 'sp_message_box',
|
|
// 多选模式的禁用状态样式
|
|
disabled: 'sp_disabled',
|
|
|
|
button: 'sp_button',
|
|
btn_on: 'sp_btn_on',
|
|
btn_out: 'sp_btn_out',
|
|
input: 'sp_input',
|
|
clear_btn : 'sp_clear_btn'
|
|
};
|
|
this.css_class = css_class;
|
|
};
|
|
|
|
/**
|
|
* @desc 设置属性默认值
|
|
*/
|
|
SelectPage.prototype.setProp = function() {
|
|
this.prop = {
|
|
//当前页
|
|
current_page: 1,
|
|
//总页数
|
|
max_page: 1,
|
|
//是否正在Ajax请求
|
|
is_loading: false,
|
|
xhr: false,
|
|
//使用键盘进行分页
|
|
key_paging: false,
|
|
//使用键盘进行选择
|
|
key_select: false,
|
|
//上一个选择的项目值
|
|
prev_value: '',
|
|
//选中项目的文本内容
|
|
selected_text : '',
|
|
//上一次键盘输入的时间
|
|
last_input_time: undefined
|
|
};
|
|
this.template = {
|
|
tag : {
|
|
content : '<li class="selected_tag" itemvalue="#item_value#">#item_text#<span class="tag_close">×</span></li>',
|
|
textKey : '#item_text#',
|
|
valueKey : '#item_value#'
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @desc 插件HTML结构生成
|
|
* @param {Object} combo_input - 输入框源对象
|
|
* @param {Object} option - 插件参数
|
|
*/
|
|
SelectPage.prototype.setElem = function(combo_input,option) {
|
|
// 1. 生成、替换DOM对象
|
|
var elem = {};//本体
|
|
var orgWidth = $(combo_input).outerWidth();
|
|
|
|
elem.combo_input = $(combo_input).attr({'autocomplete':'off'}).addClass(this.css_class.input).wrap('<div>');
|
|
//只选择模式设置输入框为只读状态
|
|
if(option.selectOnly) $(elem.combo_input).prop('readonly',true);
|
|
elem.container = $(elem.combo_input).parent().addClass(this.css_class.container);
|
|
if($(elem.combo_input).prop('disabled')) {
|
|
if(option.multiple) $(elem.container).addClass(this.css_class.disabled);
|
|
else $(elem.combo_input).addClass(this.css_class.input_off);
|
|
}
|
|
|
|
|
|
|
|
$(elem.container).width(orgWidth);
|
|
|
|
elem.button = $('<div>').addClass(this.css_class.button);
|
|
//bootstrap风格的向下三角箭头
|
|
elem.dropdown = $('<span class="bs-caret"><span class="caret"></span></span>');
|
|
//单选模式下清除的按钮X
|
|
elem.clear_btn = $('<div>').append('×').addClass(this.css_class.clear_btn).attr('title','清除内容');
|
|
|
|
//多选模式下带标签显示及文本输入的组合框
|
|
elem.element_box = $('<ul>').addClass(this.css_class.element_box);
|
|
if(option.multiple && option.multipleControlbar)
|
|
elem.control = $('<div>').addClass(this.css_class.control_box);
|
|
//结果集列表
|
|
elem.result_area = $('<div>').addClass(this.css_class.re_area);
|
|
//列表中的分页栏pagination
|
|
if(option.pagination) elem.navi = $('<div>').addClass('pagination').append('<ul>');
|
|
elem.results = $('<ul>').addClass(this.css_class.results);
|
|
|
|
/**
|
|
* 将原输入框的Name交换到Hidden中,因为具体需要保存传递到后端的是ID,而非Title
|
|
*/
|
|
var namePrefix = '_text';
|
|
//将keyField的值放入"input:hidden"
|
|
var input_id = ($(elem.combo_input).attr('id') !== undefined) ? $(elem.combo_input).attr('id') : $(elem.combo_input).attr('name');
|
|
var input_name = ($(elem.combo_input).attr('name') !== undefined) ? $(elem.combo_input).attr('name') : 'selectPage';
|
|
var hidden_name = input_name,
|
|
hidden_id = input_id;
|
|
|
|
// CakePHP使用的措施 例:data[search][user] -> data[search][user_primary_key]
|
|
if (input_name.match(/\]$/)) input_name = input_name.replace(/\]?$/, namePrefix);
|
|
else input_name += namePrefix;
|
|
if (input_id.match(/\]$/)) input_id = input_id.replace(/\]?$/, namePrefix);
|
|
else input_id += namePrefix;
|
|
|
|
//将输入框的Name与Hidden的Name进行交换,使得可以将项目的具体ID被保存到后端进行处理
|
|
elem.hidden = $('<input type="hidden" class="sp_hidden" />').attr({
|
|
name: hidden_name,
|
|
id: hidden_id
|
|
}).val('');
|
|
$(elem.combo_input).attr({
|
|
name: input_name,
|
|
id: input_id
|
|
});
|
|
|
|
// 2. DOM内容放置
|
|
$(elem.container).append(elem.button).append(elem.result_area).append(elem.hidden);
|
|
$(elem.button).append(elem.dropdown);
|
|
$(elem.result_area).append(elem.results);
|
|
if(option.pagination) $(elem.result_area).append(elem.navi);
|
|
|
|
//多选模式下的特殊处理
|
|
if(option.multiple){
|
|
if(option.multipleControlbar){
|
|
$(elem.control).append('<button type="button" class="btn btn-default sp_select_all" ><i class="fa fa-check-square-o"></i> 全选本页</button>');
|
|
$(elem.control).append('<button type="button" class="btn btn-default sp_unselect_all" ><i class="fa fa-square-o"></i> 取消本页</button>');
|
|
$(elem.control).append('<button type="button" class="btn btn-default sp_clear_all" ><i class="fa fa-ban"></i> 清除全部</button>');
|
|
$(elem.result_area).prepend(elem.control);
|
|
}
|
|
$(elem.container).addClass('sp_container_combo');
|
|
$(elem.combo_input).addClass('sp_combo_input').before($(elem.element_box));
|
|
var li = $('<li>').addClass('input_box');
|
|
$(li).append($(elem.combo_input));
|
|
$(elem.element_box).append($(li));
|
|
if($(elem.combo_input).attr('placeholder')) $(elem.combo_input).attr('placeholder_bak',$(elem.combo_input).attr('placeholder'));
|
|
}
|
|
|
|
this.elem = elem;
|
|
};
|
|
|
|
/**
|
|
* @desc 将控件的部分内容设置为默认状态
|
|
*/
|
|
SelectPage.prototype.setButtonAttrDefault = function() {
|
|
/*
|
|
if (this.option.selectOnly) {
|
|
if ($(this.elem.combo_input).val() !== '') {
|
|
if ($(this.elem.hidden).val() !== '') {
|
|
//选择条件
|
|
$(this.elem.combo_input).attr('title', this.message.select_ok).removeClass(this.css_class.select_ng).addClass(this.css_class.select_ok);
|
|
} else {
|
|
//输入方式
|
|
$(this.elem.combo_input).attr('title', this.message.select_ng).removeClass(this.css_class.select_ok).addClass(this.css_class.select_ng);
|
|
}
|
|
} else {
|
|
$(this.elem.hidden).val('');
|
|
$(this.elem.combo_input).removeAttr('title').removeClass(this.css_class.select_ng);
|
|
}
|
|
}
|
|
*/
|
|
$(this.elem.button).attr('title', this.message.get_all_btn);
|
|
//按钮的title属性修改
|
|
$(this.elem.button).attr('title', this.message.close_btn);
|
|
};
|
|
|
|
/**
|
|
* @desc 为插件设置初始化的选中值(若有指定的话),执行第一步,数据匹配
|
|
*/
|
|
SelectPage.prototype.setInitRecord = function(refresh) {
|
|
var self = this;
|
|
if($.type($(self.elem.combo_input).data('init')) != 'undefined')
|
|
self.option.initRecord = String($(self.elem.combo_input).data('init'));
|
|
//若在输入框中放入了初始化值,则将它放到隐藏域中进行选中项目初始化
|
|
//若输入框设置了初始值,同时又设置了data-init属性,那么以data-init属性为优先选择
|
|
if(!self.option.initRecord)
|
|
if($(self.elem.combo_input).val()) self.option.initRecord = $(self.elem.combo_input).val();
|
|
$(self.elem.combo_input).val('');
|
|
if((refresh && $(self.elem.hidden).val()) || $.type(self.option.initRecord) === 'string'){
|
|
// 初始的KEY值放入隐藏域
|
|
if(!refresh) $(self.elem.hidden).val(self.option.initRecord);
|
|
//将初始值放入控件
|
|
if (typeof self.option.data === 'object') {//json数据源模式
|
|
var data = new Array();
|
|
var keyarr = refresh ? $(self.elem.hidden).val().split(',') : self.option.initRecord.split(',');
|
|
$.each(keyarr,function(index,row){
|
|
for (var i = 0; i < self.option.data.length; i++) {
|
|
if (self.option.data[i][self.option.keyField] == row) {
|
|
data.push(self.option.data[i]);
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
//在单选模式下,若使用了多选模式的初始化值(“key1,key2,...”多选方式),则不进行初始化选中操作
|
|
if(!self.option.multiple && data.length > 1) data = null;
|
|
self.afterInit(self, data);
|
|
} else {//ajax数据源模式
|
|
$.ajax({
|
|
dataType: 'json',
|
|
type: 'POST',
|
|
url: self.option.data,
|
|
data: {
|
|
searchTable: self.option.dbTable,
|
|
searchKey: self.option.keyField,
|
|
searchValue: refresh ? $(self.elem.hidden).val() : self.option.initRecord
|
|
},
|
|
success: function(json) {
|
|
var d = null;
|
|
if(self.option.eAjaxSuccess && $.isFunction(self.option.eAjaxSuccess))
|
|
d = self.option.eAjaxSuccess(json);
|
|
self.afterInit(self, d.list);
|
|
},
|
|
error: function(jqXHR, textStatus, errorThrown) {
|
|
self.ajaxErrorNotify(self, errorThrown);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 匹配后的数据在插件中进行展示
|
|
* @param {Object} self - 插件的内部对象
|
|
* @param {Object} data - 列表数据
|
|
*/
|
|
SelectPage.prototype.afterInit = function(self, data) {
|
|
if(!data) return;
|
|
if(!$.isArray(data)) data = [data];
|
|
|
|
var getText = function(row){
|
|
var text = row[self.option.showField];
|
|
if(self.option.formatItem && $.isFunction(self.option.formatItem)){
|
|
try{
|
|
text = self.option.formatItem(row);
|
|
}catch(e){}
|
|
}
|
|
return text;
|
|
};
|
|
|
|
if(self.option.multiple){//多选模式初始化
|
|
self.clearAll(self);
|
|
$.each(data,function(i,row){
|
|
var item = {text:getText(row),value:row[self.option.keyField]};
|
|
if(!self.isAlreadySelected(self,item)) self.addNewTag(self,item);
|
|
});
|
|
self.tagValuesSet(self);
|
|
self.inputResize(self);
|
|
}else{//单选模式初始化
|
|
var row = data[0];
|
|
$(self.elem.combo_input).val(getText(row));
|
|
$(self.elem.hidden).val(row[self.option.keyField]);
|
|
self.prop.prev_value = getText(row);
|
|
self.prop.selected_text = getText(row);
|
|
if (self.option.selectOnly) {
|
|
$(self.elem.combo_input).attr('title', self.message.select_ok).removeClass(self.css_class.select_ng).addClass(self.css_class.select_ok);
|
|
}
|
|
self.putClearButton();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 下拉按钮的事件处理
|
|
*/
|
|
SelectPage.prototype.eDropdownButton = function() {
|
|
var self = this;
|
|
$(self.elem.button).mouseup(function(ev) {
|
|
ev.stopPropagation();
|
|
if ($(self.elem.result_area).is(':hidden') && !$(self.elem.combo_input).prop('disabled')) {
|
|
$(self.elem.combo_input).focus();
|
|
} else self.hideResults(self);
|
|
}).mouseout(); // default: mouseout
|
|
};
|
|
|
|
/**
|
|
* @desc 输入框的事件绑定
|
|
*/
|
|
SelectPage.prototype.eInput = function() {
|
|
var self = this;
|
|
var showList = function(){
|
|
self.prop.page_move = false;
|
|
self.suggest(self);
|
|
self.setCssFocusedInput(self);
|
|
};
|
|
$(self.elem.combo_input).keyup(function(e) {
|
|
self.processKey(self, e);
|
|
}).keydown(function(e) {
|
|
self.processControl(self, e);
|
|
}).focus(function(e) {
|
|
//增加输入框获得焦点后,显示数据列表
|
|
if ($(self.elem.result_area).is(':hidden')) {
|
|
e.stopPropagation();
|
|
self.prop.first_show = true;
|
|
showList();
|
|
}
|
|
});
|
|
$(self.elem.container).on('click.SelectPage','div.'+self.css_class.clear_btn,function(e){
|
|
e.stopPropagation();
|
|
self.clearAll(self);
|
|
$(self.elem.clear_btn).remove();
|
|
if(self.option.eClear && $.isFunction(self.option.eClear)) self.option.eClear();
|
|
});
|
|
if(self.option.multiple){
|
|
if(self.option.multipleControlbar){
|
|
//全选本页按钮
|
|
$('.sp_select_all',self.elem.control).on('click.SelectPage',function(e){
|
|
self.selectAllLine(self);
|
|
});
|
|
//取消全选本页按钮
|
|
$('.sp_unselect_all',self.elem.control).on('click.SelectPage',function(e){
|
|
self.unselectAllLine(self);
|
|
});
|
|
//清除全部按钮
|
|
$('.sp_clear_all',self.elem.control).on('click.SelectPage',function(e){
|
|
self.clearAll(self);
|
|
});
|
|
}
|
|
$(self.elem.element_box).on('click.SelectPage',function(e){
|
|
var srcEl = e.target || e.srcElement;
|
|
if($(srcEl).is('ul')) $(self.elem.combo_input).focus();
|
|
});
|
|
//标签关闭操作
|
|
//关闭同时需要将该标签的key从已保存的隐藏域中删除
|
|
$(self.elem.element_box).on('click.SelectPage','span.tag_close',function(){
|
|
var li = $(this).closest('li');
|
|
self.removeTag(self,li);
|
|
showList();
|
|
if(self.option.eTagRemove && $.isFunction(self.option.eTagRemove))
|
|
self.option.eTagRemove(1);
|
|
});
|
|
self.inputResize(self);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 插件之外区域的事件处理
|
|
*/
|
|
SelectPage.prototype.eWhole = function() {
|
|
var self = this;
|
|
/*
|
|
//如果是点击了控件本身则不响应外部鼠标点击事件
|
|
$(self.elem.container).mousedown(function() {
|
|
var thisindex = $('div.sp_container').index(this);
|
|
var lastindex = $(document.body).data(SelectPage.objStatusIndex);
|
|
if(lastindex != undefined && thisindex != lastindex)
|
|
$(document.body).data(SelectPage.objStatusKey,false);
|
|
else
|
|
$(document.body).data(SelectPage.objStatusKey,true);
|
|
$(document.body).data(SelectPage.objStatusIndex,thisindex);
|
|
});
|
|
*/
|
|
//控件外部的鼠标点击事件处理
|
|
$(document).off('mousedown.selectPage').on('mousedown.selectPage',function(e) {
|
|
var ele = e.target || e.srcElement;
|
|
var sm = $(ele).closest('div.' + self.css_class.container);
|
|
|
|
//清除内容
|
|
var cleanContent = function(obj){
|
|
$(obj.elem.combo_input).val('');
|
|
if(!obj.option.multiple) $(obj.elem.hidden).val('');
|
|
obj.prop.selected_text = '';
|
|
};
|
|
|
|
//列表是打开的状态
|
|
$('div.' + self.css_class.container + '.' + self.css_class.container_open).each(function(){
|
|
if(this == sm[0]) return;
|
|
var d = $('input.'+self.css_class.input,this).data(SelectPage.dataKey);
|
|
|
|
|
|
//若控件已有选中的的项目,而文本输入框中清空了关键字,则清空控件已选中的项目
|
|
if(!$(d.elem.combo_input).val() && $(d.elem.hidden).val() && !d.option.multiple){
|
|
d.prop.current_page = 1;//重置当前页为1
|
|
cleanContent(d);
|
|
d.hideResults(d);
|
|
return true;
|
|
}
|
|
//匹配项且高亮时,下拉分页控件失去焦点后,自动选择该项目
|
|
if ($('li', $(d.elem.results)).size() > 0) {
|
|
if(d.option.autoFillResult) {//打开自动内容填充功能
|
|
//若已有选中项目,则直接隐藏列表
|
|
if ($('li.sp_selected', $(d.elem.results)).size() > 0) {
|
|
d.hideResults(d);
|
|
}else if($('li.sp_over', $(d.elem.results)).size() > 0){
|
|
//若控件已有选中的值,则忽略高亮的项目
|
|
if($(d.elem.hidden).val()) d.hideResults(d);
|
|
//若没有已选中的项目,且列表中有高亮项目时,选中当前高亮的行
|
|
else d.selectCurrentLine(d, true);
|
|
}else if(d.option.autoSelectFirst){
|
|
//若控件已有选中的值,则忽略自动选择第一项的功能
|
|
if($(d.elem.hidden).val()) d.hideResults(d);
|
|
else{
|
|
//对于没有选中,没有高亮的情况,若插件设置了自动选中第一项时,则选中第一项
|
|
d.nextLine(d);
|
|
//self.nextLine(self);
|
|
d.selectCurrentLine(d, true);
|
|
}
|
|
}else d.hideResults(d);
|
|
}else d.hideResults(d);
|
|
} else {
|
|
//无匹配项目时,自动清空用户输入的关键词
|
|
if (d.option.noResultClean) cleanContent(d);
|
|
else{
|
|
if(!d.option.multiple) $(d.elem.hidden).val('');
|
|
}
|
|
d.hideResults(d);
|
|
}
|
|
});
|
|
/*
|
|
if ($(document.body).data(SelectPage.objStatusKey)) $(document.body).data(SelectPage.objStatusKey,false);
|
|
else {
|
|
//清除内容
|
|
var cleanContent = function(obj){
|
|
$(obj.elem.combo_input).val('');
|
|
if(!obj.option.multiple) $(obj.elem.hidden).val('');
|
|
obj.prop.selected_text = '';
|
|
};
|
|
//列表是打开的状态
|
|
$('div.' + self.css_class.container + '.' + self.css_class.container_open).each(function(){
|
|
var d = $('input.'+self.css_class.input,this).data(SelectPage.dataKey);
|
|
|
|
//若控件已有选中的的项目,而文本输入框中清空了关键字,则清空控件已选中的项目
|
|
if(!$(d.elem.combo_input).val() && $(d.elem.hidden).val() && !d.option.multiple){
|
|
d.prop.current_page = 1;//重置当前页为1
|
|
cleanContent(d);
|
|
d.hideResults(d);
|
|
return true;
|
|
}
|
|
//匹配项且高亮时,下拉分页控件失去焦点后,自动选择该项目
|
|
if ($('li', $(d.elem.results)).size() > 0) {
|
|
if(d.option.autoFillResult) {//打开自动内容填充功能
|
|
//若已有选中项目,则直接隐藏列表
|
|
if ($('li.sp_selected', $(d.elem.results)).size() > 0) {
|
|
d.hideResults(d);
|
|
}else if($('li.sp_over', $(d.elem.results)).size() > 0){
|
|
//若控件已有选中的值,则忽略高亮的项目
|
|
if($(d.elem.hidden).val()) d.hideResults(d);
|
|
//若没有已选中的项目,且列表中有高亮项目时,选中当前高亮的行
|
|
else d.selectCurrentLine(d, true);
|
|
}else if(d.option.autoSelectFirst){
|
|
//若控件已有选中的值,则忽略自动选择第一项的功能
|
|
if($(d.elem.hidden).val()) d.hideResults(d);
|
|
else{
|
|
//对于没有选中,没有高亮的情况,若插件设置了自动选中第一项时,则选中第一项
|
|
d.nextLine(d);
|
|
//self.nextLine(self);
|
|
d.selectCurrentLine(d, true);
|
|
}
|
|
}else d.hideResults(d);
|
|
}else d.hideResults(d);
|
|
} else {
|
|
//无匹配项目时,自动清空用户输入的关键词
|
|
if (d.option.noResultClean) cleanContent(d);
|
|
else{
|
|
if(!d.option.multiple) $(d.elem.hidden).val('');
|
|
}
|
|
d.hideResults(d);
|
|
}
|
|
});
|
|
}
|
|
*/
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @desc 结果列表的事件处理
|
|
*/
|
|
SelectPage.prototype.eResultList = function() {
|
|
var self = this;
|
|
$(self.elem.results).children('li').mouseenter(function() {
|
|
if (self.prop.key_select) {
|
|
self.prop.key_select = false;
|
|
return;
|
|
}
|
|
if(!$(this).hasClass(self.css_class.selected) && !$(this).hasClass('sp_message_box')){
|
|
$(this).addClass(self.css_class.select);
|
|
self.setCssFocusedResults(self);
|
|
}
|
|
}).mouseleave(function(){
|
|
$(this).removeClass(self.css_class.select);
|
|
}).click(function(e) {
|
|
if (self.prop.key_select) {
|
|
self.prop.key_select = false;
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if(!$(this).hasClass(self.css_class.selected)) self.selectCurrentLine(self, false);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @desc 分页导航按钮的事件处理
|
|
*/
|
|
SelectPage.prototype.ehNaviPaging = function() {
|
|
var self = this;
|
|
if(!self.option.pagination) return;
|
|
$('li.csFirstPage', $(self.elem.navi)).off('click').on('click',function(ev) {
|
|
//$(self.elem.combo_input).focus();
|
|
ev.preventDefault();
|
|
self.firstPage(self);
|
|
});
|
|
|
|
$('li.csPreviousPage', $(self.elem.navi)).off('click').on('click',function(ev) {
|
|
//$(self.elem.combo_input).focus();
|
|
ev.preventDefault();
|
|
self.prevPage(self);
|
|
});
|
|
|
|
$('li.csNextPage', $(self.elem.navi)).off('click').on('click',function(ev) {
|
|
//$(self.elem.combo_input).focus();
|
|
ev.preventDefault();
|
|
self.nextPage(self);
|
|
});
|
|
|
|
$('li.csLastPage', $(self.elem.navi)).off('click').on('click',function(ev) {
|
|
//$(self.elem.combo_input).focus();
|
|
ev.preventDefault();
|
|
self.lastPage(self);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @desc Ajax请求失败的处理
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {string} errorThrown - Ajax的错误输出内容
|
|
*/
|
|
SelectPage.prototype.ajaxErrorNotify = function(self, errorThrown) {
|
|
self.showMessage(self.message.ajax_error);
|
|
};
|
|
|
|
/**
|
|
* @desc 交互消息显示
|
|
* @param {Object} self - 插件内部对象
|
|
* @param msg {string} 需要提示的文本
|
|
*/
|
|
SelectPage.prototype.showMessage = function(self,msg){
|
|
if(!msg) return;
|
|
var msgLi = '<li class="sp_message_box"><i class="fa fa-exclamation-triangle"></i> '+msg+'</li>';
|
|
$(self.elem.results).empty().append(msgLi);
|
|
self.calcResultsSize(self);
|
|
$(self.elem.container).addClass(self.css_class.container_open);
|
|
$(self.elem.control).hide();
|
|
if(self.option.pagination) $(self.elem.navi).hide();
|
|
};
|
|
|
|
/**
|
|
* @desc 窗口滚动处理
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {boolean} enforce - 是否定位到输入框的位置
|
|
*/
|
|
SelectPage.prototype.scrollWindow = function(self, enforce) {
|
|
var current_result = self.getCurrentLine(self);
|
|
|
|
var target_top = (current_result && !enforce) ? current_result.offset().top: $(self.elem.container).offset().top;
|
|
var target_size;
|
|
|
|
self.prop.size_li = $(self.elem.results).children('li:first').outerHeight();
|
|
target_size = self.prop.size_li;
|
|
|
|
var client_height = $(window).height();
|
|
var scroll_top = $(window).scrollTop();
|
|
var scroll_bottom = scroll_top + client_height - target_size;
|
|
|
|
// 滚动处理
|
|
var gap;
|
|
if ($(current_result).length) {
|
|
if (target_top < scroll_top || target_size > client_height) {
|
|
//滚动到顶部
|
|
gap = target_top - scroll_top;
|
|
} else if (target_top > scroll_bottom) {
|
|
//向下滚动
|
|
gap = target_top - scroll_bottom;
|
|
} else return; //不进行滚动
|
|
} else if (target_top < scroll_top) gap = target_top - scroll_top;
|
|
window.scrollBy(0, gap);
|
|
};
|
|
|
|
/**
|
|
* @desc 输入框获得焦点的样式设置
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.setCssFocusedInput = function(self) {
|
|
//$(self.elem.results).addClass(self.css_class.re_off);
|
|
//$(self.elem.combo_input).removeClass(self.css_class.input_off);
|
|
};
|
|
|
|
/**
|
|
* @desc 设置结果列表高亮,输入框失去焦点
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.setCssFocusedResults = function(self) {
|
|
//$(self.elem.results).removeClass(self.css_class.re_off);
|
|
//$(self.elem.combo_input).addClass(self.css_class.input_off);
|
|
};
|
|
|
|
/**
|
|
* @desc 输入框输入值的变化监控
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.checkValue = function(self) {
|
|
var now_value = $(self.elem.combo_input).val();
|
|
if (now_value != self.prop.prev_value) {
|
|
self.prop.prev_value = now_value;
|
|
self.prop.first_show = false;
|
|
|
|
if(self.option.selectOnly) self.setButtonAttrDefault();
|
|
if(!self.option.multiple && !now_value){
|
|
self.clearAll(self);
|
|
$(self.elem.clear_btn).remove();
|
|
}
|
|
|
|
self.suggest(self);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 文本输入框键盘事件处理(普通字符输入处理)
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} e - 事件event对象
|
|
*/
|
|
SelectPage.prototype.processKey = function(self, e) {
|
|
if($.inArray(e.keyCode, [37, 38, 39, 40, 27, 9, 13]) === -1){
|
|
if(e.keyCode != 16) self.setCssFocusedInput(self); // except Shift(16)
|
|
self.inputResize(self);
|
|
if($.type(self.option.data) === 'string'){
|
|
self.prop.last_input_time = e.timeStamp;
|
|
setTimeout(function(){
|
|
if((e.timeStamp - self.prop.last_input_time) === 0)
|
|
self.checkValue(self);
|
|
},self.option.inputDelay * 1000);
|
|
}else{
|
|
self.checkValue(self);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @desc 文本输入框键盘事件处理(控制键处理)
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} e - 事件event对象
|
|
*/
|
|
SelectPage.prototype.processControl = function(self, e) {
|
|
if (($.inArray(e.keyCode, [37, 38, 39, 40, 27, 9]) > -1 && $(self.elem.result_area).is(':visible')) ||
|
|
($.inArray(e.keyCode, [13, 9]) > -1 && self.getCurrentLine(self))) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
e.cancelBubble = true;
|
|
e.returnValue = false;
|
|
switch (e.keyCode) {
|
|
case 37:
|
|
// left
|
|
if (e.shiftKey) self.firstPage(self);
|
|
else self.prevPage(self);
|
|
break;
|
|
|
|
case 38:
|
|
// up
|
|
self.prop.key_select = true;
|
|
self.prevLine(self);
|
|
break;
|
|
|
|
case 39:
|
|
// right
|
|
if (e.shiftKey) self.lastPage(self);
|
|
else self.nextPage(self);
|
|
break;
|
|
|
|
case 40:
|
|
// down
|
|
if ($(self.elem.results).children('li').length) {
|
|
self.prop.key_select = true;
|
|
self.nextLine(self);
|
|
} else self.suggest(self);
|
|
break;
|
|
|
|
case 9:
|
|
// tab
|
|
self.prop.key_paging = true;
|
|
self.selectCurrentLine(self, true);
|
|
//self.hideResults(self);
|
|
break;
|
|
|
|
case 13:
|
|
// return
|
|
self.selectCurrentLine(self, true);
|
|
break;
|
|
|
|
case 27:
|
|
// escape
|
|
self.prop.key_paging = true;
|
|
self.hideResults(self);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 中断Ajax请求
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.abortAjax = function(self) {
|
|
if (self.prop.xhr) {
|
|
self.prop.xhr.abort();
|
|
self.prop.xhr = false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 数据查询
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.suggest = function(self) {
|
|
//搜索关键字
|
|
var q_word;
|
|
var val = $.trim($(self.elem.combo_input).val());
|
|
if(self.option.multiple) q_word = val;
|
|
else{
|
|
if(val && val === self.prop.selected_text) q_word = '';
|
|
else q_word = val;
|
|
}
|
|
q_word = q_word.split(/[\s ]+/);
|
|
self.abortAjax(self);
|
|
self.setLoading(self);
|
|
var which_page_num = self.prop.current_page > 0 ? self.prop.current_page : 1;
|
|
|
|
// 数据查询
|
|
if (typeof self.option.data == 'object') self.searchForJson(self, q_word, which_page_num);
|
|
else self.searchForDb(self, q_word, which_page_num);
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* @desc 读取中状态显示
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.setLoading = function(self) {
|
|
//加载中的状态提示
|
|
if ($(self.elem.results).html() === '') {
|
|
//self.calcResultsSize(self);
|
|
$(self.elem.container).addClass(self.css_class.container_open);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 服务端数据查询
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Array} q_word - 查询关键字
|
|
* @param {number} which_page_num - 目标页
|
|
*/
|
|
SelectPage.prototype.searchForDb = function(self, q_word, which_page_num) {
|
|
if(!self.option.eAjaxSuccess || !$.isFunction(self.option.eAjaxSuccess)) self.hideResults(self);
|
|
/**
|
|
* 增加自定义查询参数
|
|
*/
|
|
var _paramsFunc = self.option.params;
|
|
var _params = {};
|
|
//原始参数
|
|
var searchKey = self.option.searchField;
|
|
//若有查询关键字,则重置当前页码为1
|
|
if(q_word.length > 0 && q_word[0] && q_word[0] !== self.prop.prev_value) which_page_num = 1;
|
|
var _orgParams = {
|
|
q_word: q_word,
|
|
pageNumber: which_page_num,
|
|
pageSize: self.option.pageSize,
|
|
andOr: self.option.andOr,
|
|
orderBy: self.option.orderBy,
|
|
searchTable: self.option.dbTable
|
|
};
|
|
_orgParams[searchKey] = q_word[0];
|
|
if (_paramsFunc && $.isFunction(_paramsFunc)) {
|
|
var result = _paramsFunc();
|
|
if (result && $.isPlainObject(result)) {
|
|
_params = $.extend({},_orgParams, result);
|
|
} else _params = _orgParams;
|
|
} else _params = _orgParams;
|
|
//增加自定义查询参数End
|
|
self.prop.xhr = $.ajax({
|
|
dataType: 'json',
|
|
url: self.option.data,
|
|
type: 'POST',
|
|
data: _params,
|
|
success: function(returnData) {
|
|
if (!returnData || !$.isPlainObject(returnData)) {
|
|
self.hideResults(self);
|
|
self.ajaxErrorNotify(self, errorThrown);
|
|
return;
|
|
}
|
|
var data = self.option.eAjaxSuccess(returnData);
|
|
|
|
//数据结构处理
|
|
var json = {};
|
|
json.originalResult = data.list;
|
|
json.cnt_whole = data.totalRow;
|
|
|
|
json.candidate = [];
|
|
json.keyField = [];
|
|
if (typeof json.originalResult != 'object') {
|
|
self.prop.xhr = null;
|
|
self.notFoundSearch(self);
|
|
return;
|
|
}
|
|
json.cnt_page = json.originalResult.length;
|
|
for (var i = 0; i < json.cnt_page; i++) {
|
|
for (var key in json.originalResult[i]) {
|
|
if (key == self.option.keyField) {
|
|
json.keyField.push(json.originalResult[i][key]);
|
|
}
|
|
if (key == self.option.showField) {
|
|
json.candidate.push(json.originalResult[i][key]);
|
|
}
|
|
}
|
|
}
|
|
self.prepareResults(self, json, q_word, which_page_num);
|
|
},
|
|
error: function(jqXHR, textStatus, errorThrown) {
|
|
if (textStatus != 'abort') {
|
|
self.hideResults(self);
|
|
self.ajaxErrorNotify(self, errorThrown);
|
|
}
|
|
},
|
|
complete: function() {
|
|
self.prop.xhr = null;
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @desc 对JSON源数据进行搜索
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Array} q_word - 搜索关键字
|
|
* @param {number} which_page_num - 目标页数
|
|
*/
|
|
SelectPage.prototype.searchForJson = function(self, q_word, which_page_num) {
|
|
var matched = [];
|
|
var esc_q = [];
|
|
var sorted = [];
|
|
var json = {};
|
|
var i = 0;
|
|
var arr_reg = [];
|
|
|
|
//查询条件过滤
|
|
do {
|
|
//'/\W/g'正则代表全部不是字母,数字,下划线,汉字的字符
|
|
//将非法字符进行转义
|
|
esc_q[i] = q_word[i].replace(/\W/g, '\\$&').toString();
|
|
arr_reg[i] = new RegExp(esc_q[i], 'gi');
|
|
i++;
|
|
} while ( i < q_word.length );
|
|
|
|
// SELECT * FROM data WHERE field LIKE q_word;
|
|
for (i = 0; i < self.option.data.length; i++) {
|
|
var flag = false;
|
|
var row = self.option.data[i];
|
|
for (var j = 0; j < arr_reg.length; j++) {
|
|
var itemText = row[self.option.showField];//默认获取showField字段的文本
|
|
if(self.option.formatItem && $.isFunction(self.option.formatItem))
|
|
itemText = self.option.formatItem(row);
|
|
if (itemText.match(arr_reg[j])) {
|
|
flag = true;
|
|
if (self.option.andOr == 'OR') break;
|
|
} else {
|
|
flag = false;
|
|
if (self.option.andOr == 'AND') break;
|
|
}
|
|
}
|
|
if (flag) matched.push(row);
|
|
}
|
|
|
|
// (CASE WHEN ...) 然后 く order 指定列
|
|
var reg1 = new RegExp('^' + esc_q[0] + '$', 'gi');
|
|
var reg2 = new RegExp('^' + esc_q[0], 'gi');
|
|
var matched1 = [];
|
|
var matched2 = [];
|
|
var matched3 = [];
|
|
for (i = 0; i < matched.length; i++) {
|
|
var orderField = self.option.orderBy[0][0];
|
|
var orderValue = String(matched[i][orderField]);
|
|
if (orderValue.match(reg1)) {
|
|
matched1.push(matched[i]);
|
|
} else if (orderValue.match(reg2)) {
|
|
matched2.push(matched[i]);
|
|
} else {
|
|
matched3.push(matched[i]);
|
|
}
|
|
}
|
|
|
|
if (self.option.orderBy[0][1].match(/^asc$/i)) {
|
|
matched1 = self.sortAsc(self, matched1);
|
|
matched2 = self.sortAsc(self, matched2);
|
|
matched3 = self.sortAsc(self, matched3);
|
|
} else {
|
|
matched1 = self.sortDesc(self, matched1);
|
|
matched2 = self.sortDesc(self, matched2);
|
|
matched3 = self.sortDesc(self, matched3);
|
|
}
|
|
sorted = sorted.concat(matched1).concat(matched2).concat(matched3);
|
|
|
|
//若没有匹配项目,则结束搜索
|
|
/*
|
|
if (sorted.length === undefined || sorted.length === 0 ) {
|
|
self.notFoundSearch(self);
|
|
return;
|
|
}
|
|
*/
|
|
json.cnt_whole = sorted.length;
|
|
//page_move参数用于区别数据加载是在初始化列表还是在进行分页的翻页操作
|
|
if(!self.prop.page_move){
|
|
//仅单选模式进行选中项目定位页功能
|
|
if(!self.option.multiple){
|
|
//若控件当前已有选中值,则获得该项目所在的页数,并跳转到该页进行显示
|
|
var currentValue = $(self.elem.hidden).val();
|
|
if($.type(currentValue) !== 'undefined' && $.trim(currentValue) !== ''){
|
|
var index = 0;
|
|
$.each(sorted,function(i,row){
|
|
if(row[self.option.keyField] == currentValue){
|
|
index = i + 1;
|
|
return false;
|
|
}
|
|
});
|
|
which_page_num = Math.ceil(index / self.option.pageSize);
|
|
if(which_page_num < 1) which_page_num = 1;
|
|
self.prop.current_page = which_page_num;
|
|
}
|
|
}
|
|
}else{
|
|
//过滤后的数据个数不足一页显示的个数时,强制设置页码
|
|
if(sorted.length <= ((which_page_num - 1) * self.option.pageSize)){
|
|
which_page_num = 1;
|
|
self.prop.current_page = 1;
|
|
}
|
|
}
|
|
|
|
// LIMIT xx OFFSET xx
|
|
var start = (which_page_num - 1) * self.option.pageSize;
|
|
var end = start + self.option.pageSize;
|
|
//储存原始行数据,包括所有属性
|
|
json.originalResult = [];
|
|
// 查询后的数据处理
|
|
for (i = start; i < end; i++) {
|
|
if (sorted[i] === undefined) break;
|
|
json.originalResult.push(sorted[i]);
|
|
for (var key in sorted[i]) {
|
|
if (key == self.option.keyField) {
|
|
if (json.keyField === undefined) json.keyField = [];
|
|
json.keyField.push(sorted[i][key]);
|
|
}
|
|
if (key == self.option.showField) {
|
|
if (json.candidate === undefined) json.candidate = [];
|
|
json.candidate.push(sorted[i][key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (json.candidate === undefined) json.candidate = [];
|
|
json.cnt_page = json.candidate.length;
|
|
self.prepareResults(self, json, q_word, which_page_num);
|
|
};
|
|
|
|
/**
|
|
* @desc 升序排序
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Array} arr - 结果集数组
|
|
*/
|
|
SelectPage.prototype.sortAsc = function(self, arr) {
|
|
arr.sort(function(a, b) {
|
|
var valA = a[self.option.orderBy[0][0]];
|
|
var valB = b[self.option.orderBy[0][0]];
|
|
return $.type(valA) === 'number' ? valA - valB : String(valA).localeCompare(String(valB));
|
|
});
|
|
return arr;
|
|
};
|
|
|
|
/**
|
|
* @desc 降序排序
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Array} arr - 结果集数组
|
|
*/
|
|
SelectPage.prototype.sortDesc = function(self, arr) {
|
|
arr.sort(function(a, b) {
|
|
var valA = a[self.option.orderBy[0][0]];
|
|
var valB = b[self.option.orderBy[0][0]];
|
|
return $.type(valA) === 'number' ? valB - valA : String(valB).localeCompare(String(valA));
|
|
});
|
|
return arr;
|
|
};
|
|
|
|
/**
|
|
* @desc 查询无结果的处理
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.notFoundSearch = function(self) {
|
|
$(self.elem.results).empty();
|
|
self.calcResultsSize(self);
|
|
$(self.elem.container).addClass(self.css_class.container_open);
|
|
self.setCssFocusedInput(self);
|
|
};
|
|
|
|
/**
|
|
* @desc 查询结果处理
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} json - 数据结果
|
|
* @param {Array} q_word - 查询关键字
|
|
* @param {number} which_page_num - 目标页
|
|
*/
|
|
SelectPage.prototype.prepareResults = function(self, json, q_word, which_page_num) {
|
|
//处理分页栏
|
|
if(self.option.pagination) self.setNavi(self, json.cnt_whole, json.cnt_page, which_page_num);
|
|
|
|
if (!json.keyField) json.keyField = false;
|
|
|
|
//仅选择模式
|
|
if (self.option.selectOnly && json.candidate.length === 1 && json.candidate[0] == q_word[0]) {
|
|
$(self.elem.hidden).val(json.keyField[0]);
|
|
this.setButtonAttrDefault();
|
|
}
|
|
//是否是输入关键词进行查找
|
|
var is_query = false;
|
|
if (q_word && q_word.length > 0 && q_word[0]) is_query = true;
|
|
//显示结果列表
|
|
self.displayResults(self, json, is_query);
|
|
};
|
|
|
|
/**
|
|
* @desc 生成分页栏
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {number} cnt_whole - 数据总条数
|
|
* @param {number} cnt_page - 页面显示记录数
|
|
* @param {number} page_num - 当前页数
|
|
*/
|
|
SelectPage.prototype.setNavi = function(self, cnt_whole, cnt_page, page_num) {
|
|
/**
|
|
* 生成分页条
|
|
*/
|
|
var buildPageNav = function(self, pagebar, page_num, last_page) {
|
|
if ($('li', $(pagebar)).size() == 0) {
|
|
$(pagebar).hide().empty();
|
|
//处理当当前页码为1时,首页和上一页按钮不允许点击
|
|
var btnclass = '',isNewFontAwesome = true;
|
|
//判断是否使用了font-awesome3.2.1
|
|
$.each(document.styleSheets,function(i,n){
|
|
if(n && n.href && n.href.indexOf('font-awesome-3.2.1') != -1){
|
|
isNewFontAwesome = false;
|
|
return false;
|
|
}
|
|
});
|
|
//为不同版本图标设置样式
|
|
var iconFist='fa fa-angle-double-left',iconPrev='fa fa-angle-left',iconNext='fa fa-angle-right',iconLast='fa fa-angle-double-right';
|
|
if(!isNewFontAwesome){
|
|
iconFist='icon-step-backward';
|
|
iconPrev='icon-backward';
|
|
iconNext='icon-forward';
|
|
iconLast='icon-step-forward';
|
|
}
|
|
|
|
if (page_num == 1) btnclass = ' disabled ';
|
|
//首页
|
|
$(pagebar).append('<li class="csFirstPage' + btnclass + '" title="' + self.message.first_title + '" ><a href="javascript:void(0);"> <i class="'+iconFist+'"></i> </a></li>');
|
|
//上一页
|
|
$(pagebar).append('<li class="csPreviousPage' + btnclass + '" title="' + self.message.prev_title + '" ><a href="javascript:void(0);"><i class="'+iconPrev+'"></i></a></li>');
|
|
var pageInfo = '第 ' + page_num + ' 页(共' + last_page + '页)';
|
|
//设置分页信息
|
|
$(pagebar).append('<li class="pageInfoBox"><a href="javascript:void(0);"> ' + pageInfo + ' </a></li>');
|
|
|
|
if (page_num == last_page) btnclass = ' disabled ';
|
|
else btnclass = '';
|
|
//首页
|
|
$(pagebar).append('<li class="csNextPage' + btnclass + '" title="' + self.message.next_title + '" ><a href="javascript:void(0);"><i class="'+iconNext+'"></i></a></li>');
|
|
//上一页
|
|
$(pagebar).append('<li class="csLastPage' + btnclass + '" title="' + self.message.last_title + '" ><a href="javascript:void(0);"> <i class="'+iconLast+'"></i> </a></li>');
|
|
$(pagebar).show();
|
|
}
|
|
};
|
|
|
|
var pagebar = $('ul', $(self.elem.navi));
|
|
var last_page = Math.ceil(cnt_whole / self.option.pageSize); //计算总页数
|
|
if(last_page == 0) page_num = 0;
|
|
else{
|
|
if(last_page < page_num) page_num = last_page;
|
|
else if(page_num==0) page_num = 1;
|
|
}
|
|
self.prop.current_page = page_num;//更新当前页参数
|
|
self.prop.max_page = last_page;//更新总页数参数
|
|
buildPageNav(self, pagebar, page_num, last_page);
|
|
//刷新分页信息
|
|
var pageInfoBox = $('li.pageInfoBox', $(pagebar));
|
|
|
|
var pageInfo = '第 ' + page_num + ' 页(共' + last_page + '页)';
|
|
$(pageInfoBox).html('<a href="javascript:void(0);"> ' + pageInfo + ' </a>');
|
|
//更新分页样式
|
|
var dClass = 'disabled';
|
|
var first = $('li.csFirstPage', $(pagebar));
|
|
var previous = $('li.csPreviousPage', $(pagebar));
|
|
var next = $('li.csNextPage', $(pagebar));
|
|
var last = $('li.csLastPage', $(pagebar));
|
|
//处理首页,上一页按钮样式
|
|
if (page_num === 1 || page_num === 0) {
|
|
if (!$(first).hasClass(dClass)) $(first).addClass(dClass);
|
|
if (!$(previous).hasClass(dClass)) $(previous).addClass(dClass);
|
|
} else {
|
|
if ($(first).hasClass(dClass)) $(first).removeClass(dClass);
|
|
if ($(previous).hasClass(dClass)) $(previous).removeClass(dClass);
|
|
}
|
|
//处理下一页,最后一页按钮的样式
|
|
if (page_num == last_page || last_page == 0) {
|
|
if (!$(next).hasClass(dClass)) $(next).addClass(dClass);
|
|
if (!$(last).hasClass(dClass)) $(last).addClass(dClass);
|
|
} else {
|
|
if ($(next).hasClass(dClass)) $(next).removeClass(dClass);
|
|
if ($(last).hasClass(dClass)) $(last).removeClass(dClass);
|
|
}
|
|
|
|
if (last_page > 1) self.ehNaviPaging(); //导航按钮的事件设置
|
|
};
|
|
|
|
/**
|
|
* @desc 显示结果集列表
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} json 源数据
|
|
* @param {boolean} is_query - 是否是通过关键字搜索(用于区分是鼠标点击下拉还是输入框输入关键字进行查找)
|
|
*/
|
|
SelectPage.prototype.displayResults = function(self, json, is_query) {
|
|
$(self.elem.results).hide().empty();
|
|
if(self.option.multiple && $.type(self.option.maxSelectLimit) === 'number' && self.option.maxSelectLimit > 0){
|
|
var selectedSize = $('li.selected_tag',self.elem.element_box).size();
|
|
if(selectedSize > 0 && selectedSize >= self.option.maxSelectLimit){
|
|
self.showMessage(self,'最多只能选择 '+self.option.maxSelectLimit+' 个项目');
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(json.candidate.length > 0){
|
|
var arr_candidate = json.candidate;
|
|
var arr_primary_key = json.keyField;
|
|
var keystr = $(self.elem.hidden).val();
|
|
var keyArr = keystr ? keystr.split(',') : new Array();
|
|
for (var i = 0; i < arr_candidate.length; i++) {
|
|
var itemText = '';
|
|
if(self.option.formatItem && $.isFunction(self.option.formatItem)){
|
|
try {
|
|
itemText = self.option.formatItem(json.originalResult[i]);
|
|
} catch (e) {
|
|
console.error('formatItem内容格式化函数内容设置不正确!');
|
|
itemText = arr_candidate[i];
|
|
}
|
|
}else itemText = arr_candidate[i];
|
|
//XSS対策
|
|
var list = $('<li>').html(itemText).attr({
|
|
pkey: arr_primary_key[i],
|
|
title: itemText
|
|
});
|
|
|
|
//选中项目设置高亮样式
|
|
if ($.inArray(arr_primary_key[i].toString(),keyArr) !== -1) {
|
|
$(list).addClass(self.css_class.selected);
|
|
}
|
|
//缓存原始行对象
|
|
$(list).data('dataObj',json.originalResult[i]);
|
|
$(self.elem.results).append(list);
|
|
}
|
|
}else{
|
|
var li = '<li class="sp_message_box"><i class="fa fa-exclamation-triangle"></i> ' + self.message.not_found + '</li>';
|
|
$(self.elem.results).append(li);
|
|
}
|
|
$(self.elem.results).show();
|
|
|
|
if(self.option.multiple && self.option.multipleControlbar) $(self.elem.control).show();
|
|
if(self.option.pagination) $(self.elem.navi).show();
|
|
//显示结果集列表并调整位置
|
|
self.calcResultsSize(self);
|
|
$(self.elem.container).addClass(self.css_class.container_open);
|
|
|
|
//结果集列表事件绑定
|
|
self.eResultList();
|
|
//若是键盘输入关键字进行查询且有内容时,列表自动选中第一行(autoSelectFirst为true时)
|
|
if (is_query && json.candidate.length > 0 && self.option.autoSelectFirst) self.nextLine(self);
|
|
};
|
|
|
|
/**
|
|
* @desc 处理结果列表尺寸及位置
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.calcResultsSize = function(self) {
|
|
var rePosition = function(){
|
|
if ($(self.elem.container).css('position') === 'static') {
|
|
// position: static
|
|
var offset = $(self.elem.combo_input).offset();
|
|
$(self.elem.result_area).css({
|
|
top: offset.top + $(self.elem.combo_input).outerHeight() + 'px',
|
|
left: offset.left + 'px'
|
|
});
|
|
} else {
|
|
if(!self.option.pagination){
|
|
var itemHeight = $('li:first',self.elem.results).outerHeight(true);
|
|
var listHeight = itemHeight * self.option.listSize;
|
|
$(self.elem.results).css({
|
|
'max-height':listHeight,
|
|
'overflow-y':'auto'
|
|
});
|
|
}
|
|
|
|
//在展示下拉列表时,判断默认与输入框左对齐的列表是否会超出屏幕边界,是则右对齐,否则默认左对齐
|
|
var docWidth = $(document).width();
|
|
var docHeight = $(document).height();//文档全部高度
|
|
var viewHeight = $(window).height();//可视区域高度
|
|
var offset = $(self.elem.container).offset();
|
|
var screenScrollTop = $(window).scrollTop();
|
|
var listWidth = $(self.elem.result_area).outerWidth();
|
|
//当前状态,列表并未被显示,数据未被填充,列表并未展现最终高度,所以只能使用默认一页显示10条数据的固定高度进行计算
|
|
var listHeight = $(self.elem.result_area).outerHeight();
|
|
//默认方向的坐标,在多选模式下,因为外框架是DIV,所以需要向左靠一个像素
|
|
var defaultLeft = self.option.multiple ? -1 : 0;
|
|
//输入框高度
|
|
var inputHeight = $(self.elem.container).outerHeight();
|
|
var left = (offset.left + listWidth) > docWidth ? -(listWidth - $(self.elem.container).outerWidth()) : defaultLeft;
|
|
//控件在全文档范围中的实际TOP(非当前可视区域中的相对TOP)
|
|
var screenTop = offset.top;//$(self.elem.container).scrollTop();//offset.top - screenScrollTop;
|
|
var top = 0,dist = 5;//设置偏移量,让列表与输入框有5px的间距
|
|
//列表展开后的坐标高度
|
|
var listBottom = screenTop + inputHeight + listHeight + dist;
|
|
var hasOverflow = docHeight > viewHeight;
|
|
|
|
if((screenTop - screenScrollTop - dist > listHeight) &&
|
|
(hasOverflow && listBottom > (viewHeight + screenScrollTop)) ||
|
|
(!hasOverflow && listBottom > viewHeight)){
|
|
//控件当前位置+控件高度+列表高度超过实际body高度
|
|
//列表则需要向上展示
|
|
top = -(listHeight+1) - dist;
|
|
$(self.elem.result_area).removeClass('shadowUp shadowDown').addClass('shadowUp');
|
|
}else{
|
|
//列表正常向下展示
|
|
top = self.option.multiple ? $(self.elem.container).innerHeight() + 1 : $(self.elem.container).outerHeight();
|
|
$(self.elem.result_area).removeClass('shadowUp shadowDown').addClass('shadowDown');
|
|
top += dist;
|
|
}
|
|
/*
|
|
$(self.elem.result_area).css({
|
|
top : top + 'px',
|
|
left: left + 'px'
|
|
});
|
|
*/
|
|
return {
|
|
top : top + 'px',
|
|
left: left + 'px'
|
|
};
|
|
}
|
|
};
|
|
if($(self.elem.result_area).is(':visible')){
|
|
$(self.elem.result_area).css(rePosition());
|
|
}else{
|
|
$(self.elem.result_area).show(1,function(){
|
|
$(this).css(rePosition());
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 隐藏结果列表
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.hideResults = function(self) {
|
|
if (self.prop.key_paging) {
|
|
self.scrollWindow(self, true);
|
|
self.prop.key_paging = false;
|
|
}
|
|
self.setCssFocusedInput(self);
|
|
|
|
if (self.option.autoFillResult) {
|
|
//self.selectCurrentLine(self, true);
|
|
}
|
|
|
|
$(self.elem.results).empty();
|
|
$(self.elem.result_area).hide();
|
|
$(self.elem.container).removeClass(self.css_class.container_open);
|
|
|
|
self.abortAjax(self);
|
|
self.setButtonAttrDefault(); // 按钮title属性初期化
|
|
};
|
|
|
|
/**
|
|
* @desc 跳转到首页
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.firstPage = function(self) {
|
|
if (self.prop.current_page > 1) {
|
|
self.prop.current_page = 1;
|
|
self.prop.page_move = true;
|
|
self.suggest(self);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 跳转到上一页
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.prevPage = function(self) {
|
|
if (self.prop.current_page > 1) {
|
|
self.prop.current_page--;
|
|
self.prop.page_move = true;
|
|
self.suggest(self);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 跳转到下一页
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.nextPage = function(self) {
|
|
if (self.prop.current_page < self.prop.max_page) {
|
|
self.prop.current_page++;
|
|
self.prop.page_move = true;
|
|
self.suggest(self);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 跳转到尾页
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.lastPage = function(self) {
|
|
console.log(self);
|
|
if (self.prop.current_page < self.prop.max_page) {
|
|
self.prop.current_page = self.prop.max_page;
|
|
self.prop.page_move = true;
|
|
self.suggest(self);
|
|
}
|
|
};
|
|
/**
|
|
* @desc 跳转到指定页
|
|
* @param {Object} self
|
|
* @param {number} page 目标页数
|
|
*/
|
|
SelectPage.prototype.goPage = function(self,page){
|
|
if(typeof(page) === 'undefined') page = 1;
|
|
if (self.prop.current_page < self.prop.max_page) {
|
|
self.prop.current_page = page;
|
|
self.prop.page_move = true;
|
|
self.suggest(self);
|
|
}
|
|
};
|
|
/**
|
|
* @desc 操作结束后的一些收尾工作
|
|
*/
|
|
SelectPage.prototype.afterAction = function(self){
|
|
self.inputResize(self);
|
|
$(self.elem.combo_input).change();
|
|
self.setCssFocusedInput(self);
|
|
if(self.option.multiple){
|
|
if(self.option.selectToCloseList){
|
|
self.hideResults(self);
|
|
$(self.elem.combo_input).blur();
|
|
}else{
|
|
self.suggest(self);
|
|
$(self.elem.combo_input).focus();
|
|
}
|
|
}else{
|
|
self.hideResults(self);
|
|
$(self.elem.combo_input).blur();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 选择当前行
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {boolean} is_enter_key - 是否为回车键
|
|
*/
|
|
SelectPage.prototype.selectCurrentLine = function(self, is_enter_key) {
|
|
self.scrollWindow(self, true);
|
|
|
|
var current = self.getCurrentLine(self);
|
|
if (current) {
|
|
if(!self.option.multiple){
|
|
$(self.elem.combo_input).val($(current).text());
|
|
$(self.elem.hidden).val($(current).attr('pkey'));
|
|
}else{
|
|
//多选模式的项目选择处理
|
|
$(self.elem.combo_input).val('');
|
|
var item = {text:$(current).text(),value:$(current).attr('pkey')};
|
|
if(!self.isAlreadySelected(self,item)){
|
|
self.addNewTag(self,item);
|
|
self.tagValuesSet(self);
|
|
}
|
|
}
|
|
|
|
if (self.option.selectOnly) self.setButtonAttrDefault();
|
|
|
|
//项目选择回调函数触发
|
|
if(self.option.eSelect && $.isFunction(self.option.eSelect))
|
|
self.option.eSelect($(current).data('dataObj'));
|
|
|
|
self.prop.prev_value = $(self.elem.combo_input).val();
|
|
self.prop.selected_text = $(self.elem.combo_input).val();
|
|
|
|
self.putClearButton();
|
|
}
|
|
self.afterAction(self);
|
|
};
|
|
/**
|
|
* 单选模式下选中项目后,显示清空按钮
|
|
*/
|
|
SelectPage.prototype.putClearButton = function(){
|
|
if(!this.option.multiple && !$(this.elem.combo_input).prop('disabled')) $(this.elem.container).append(this.elem.clear_btn);
|
|
};
|
|
/**
|
|
* @desc 全选当前页的行
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.selectAllLine = function(self){
|
|
var jsonarr = new Array();
|
|
$('li',self.elem.results).each(function(i,row){
|
|
var item = {text:$(row).text(),value:$(row).attr('pkey')};
|
|
if(!self.isAlreadySelected(self,item)){
|
|
self.addNewTag(self,item);
|
|
self.tagValuesSet(self);
|
|
}
|
|
jsonarr.push($(row).data('dataObj'));
|
|
//若有最大选择数量限制,则添加最大个数后,不再添加
|
|
if($.type(self.option.maxSelectLimit) === 'number' &&
|
|
self.option.maxSelectLimit > 0 &&
|
|
self.option.maxSelectLimit === $('li.selected_tag',self.elem.element_box).size()){
|
|
return false;
|
|
}
|
|
});
|
|
if(self.option.eSelect && $.isFunction(self.option.eSelect))
|
|
self.option.eSelect(jsonarr);
|
|
self.afterAction(self);
|
|
};
|
|
/**
|
|
* @desc 取消选择本页全部项目
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.unselectAllLine = function(self){
|
|
var size = $('li',self.elem.results).size();
|
|
$('li',self.elem.results).each(function(i,row){
|
|
var key = $(row).attr('pkey');
|
|
var tag = $('li.selected_tag[itemvalue="'+key+'"]',self.elem.element_box);
|
|
self.removeTag(self,tag);
|
|
});
|
|
self.afterAction(self);
|
|
if(self.option.eTagRemove && $.isFunction(self.option.eTagRemove))
|
|
self.option.eTagRemove(size);
|
|
};
|
|
/**
|
|
* @desc 清除所有选中的项目
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.clearAll = function(self){
|
|
var size = 0;
|
|
if(self.option.multiple){
|
|
size = $('li.selected_tag',self.elem.element_box).size();
|
|
$('li.selected_tag',self.elem.element_box).remove();
|
|
}
|
|
$(self.elem.combo_input).val('');
|
|
$(self.elem.hidden).val('');
|
|
self.afterAction(self);
|
|
if(self.option.multiple) {
|
|
if (self.option.eTagRemove && $.isFunction(self.option.eTagRemove))
|
|
self.option.eTagRemove(size);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 获得当前行对象
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.getCurrentLine = function(self) {
|
|
if ($(self.elem.result_area).is(':hidden')) return false;
|
|
var obj = $('li.' + self.css_class.select,self.elem.results);
|
|
if ($(obj).size()) return obj;
|
|
else return false;
|
|
};
|
|
|
|
/**
|
|
* @desc 多选模式下判断当前选中项目是否已经存在已选中列表中
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} item - 选中行对象
|
|
*/
|
|
SelectPage.prototype.isAlreadySelected = function(self,item){
|
|
var isExist = false;
|
|
if(item.value){
|
|
var keys = $(self.elem.hidden).val();
|
|
if(keys){
|
|
var karr = keys.split(',');
|
|
if(karr && karr.length > 0 && $.inArray(item.value,karr) != -1) isExist = true;
|
|
}
|
|
}
|
|
return isExist;
|
|
};
|
|
|
|
/**
|
|
* @desc 多选模式下增加一个标签
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} item - 选中行对象
|
|
*/
|
|
SelectPage.prototype.addNewTag = function(self,item){
|
|
if(!self.option.multiple || !item) return;
|
|
var tmp = self.template.tag.content,tag;
|
|
tmp = tmp.replace(self.template.tag.textKey,item.text);
|
|
tmp = tmp.replace(self.template.tag.valueKey,item.value);
|
|
tag = $(tmp);
|
|
if($(self.elem.combo_input).prop('disabled')) $('span.tag_close',tag).hide();
|
|
$(self.elem.combo_input).closest('li').before(tag);
|
|
};
|
|
/**
|
|
* @desc 多选模式下移除一个标签
|
|
* @param {Object} self - 插件内部对象
|
|
* @param {Object} item - 标签对象
|
|
*/
|
|
SelectPage.prototype.removeTag = function(self,item){
|
|
var key = $(item).attr('itemvalue');
|
|
var keys = $(self.elem.hidden).val();
|
|
//从已保存的key列表中删除该标签对应的项目
|
|
if($.type(key)!='undefined' && keys){
|
|
var keyarr = keys.split(',');
|
|
var index = $.inArray(key.toString(),keyarr);
|
|
if(index != -1){
|
|
keyarr.splice(index,1);
|
|
$(self.elem.hidden).val(keyarr.toString());
|
|
}
|
|
}
|
|
$(item).remove();
|
|
self.inputResize(self);
|
|
};
|
|
|
|
/**
|
|
* @desc 多选模式下标签结果值放入隐藏域
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.tagValuesSet = function(self){
|
|
if(!self.option.multiple) return;
|
|
var tags = $('li.selected_tag',$(self.elem.element_box));
|
|
if(tags && $(tags).size() > 0){
|
|
var result = new Array();
|
|
$.each(tags,function(i,li){
|
|
var v = $(li).attr('itemvalue');
|
|
if($.type(v)!=='undefined') result.push(v);
|
|
});
|
|
if(result.length > 0){
|
|
$(self.elem.hidden).val(result.join(','));
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @desc 多选模式下输入框根据输入内容调整输入框宽度
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.inputResize = function(self){
|
|
if(!self.option.multiple) return;
|
|
var width = '';
|
|
var inputLi = self.elem.combo_input.closest('li');
|
|
//设置默认宽度
|
|
var setDefaultSize = function(self,inputLi){
|
|
inputLi.removeClass('full_width');
|
|
var minimumWidth = self.elem.combo_input.val().length + 1;
|
|
var width = (minimumWidth * 0.75) + 'em';
|
|
self.elem.combo_input.css('width', width);
|
|
self.elem.combo_input.removeAttr('placeholder');
|
|
};
|
|
if($('li.selected_tag',$(self.elem.element_box)).size() === 0){
|
|
if(self.elem.combo_input.attr('placeholder_bak')){
|
|
if(!inputLi.hasClass('full_width')) inputLi.addClass('full_width');
|
|
self.elem.combo_input.attr('placeholder',self.elem.combo_input.attr('placeholder_bak'));
|
|
self.elem.combo_input.removeAttr('style');
|
|
}else setDefaultSize(self,inputLi);
|
|
}else setDefaultSize(self,inputLi);
|
|
};
|
|
|
|
/**
|
|
* @desc 选择下一行
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.nextLine = function(self) {
|
|
var obj = self.getCurrentLine(self);
|
|
var idx;
|
|
if (!obj) idx = -1;
|
|
else {
|
|
idx = $(self.elem.results).children('li').index(obj);
|
|
$(obj).removeClass(self.css_class.select);
|
|
}
|
|
idx++;
|
|
if (idx < $(self.elem.results).children('li').length) {
|
|
var next = $(self.elem.results).children('li').eq(idx);
|
|
$(next).addClass(self.css_class.select);
|
|
self.setCssFocusedResults(self);
|
|
} else self.setCssFocusedInput(self);
|
|
self.scrollWindow(self, false);
|
|
};
|
|
|
|
/**
|
|
* @desc 选择上一行
|
|
* @param {Object} self - 插件内部对象
|
|
*/
|
|
SelectPage.prototype.prevLine = function(self) {
|
|
var obj = self.getCurrentLine(self);
|
|
var idx;
|
|
if (!obj) idx = $(self.elem.results).children('li').length;
|
|
else {
|
|
idx = $(self.elem.results).children('li').index(obj);
|
|
$(obj).removeClass(self.css_class.select);
|
|
}
|
|
idx--;
|
|
if (idx > -1) {
|
|
var prev = $(self.elem.results).children('li').eq(idx);
|
|
$(prev).addClass(self.css_class.select);
|
|
self.setCssFocusedResults(self);
|
|
} else self.setCssFocusedInput(self);
|
|
self.scrollWindow(self, false);
|
|
};
|
|
|
|
|
|
/**
|
|
* @desc 下拉分页查询控件初始化入口
|
|
* @global
|
|
* @memberof jQuery,bootstrap2,bootstrap3
|
|
* @param option {Object} 初始化参数集
|
|
*/
|
|
function Plugin(option) {
|
|
return this.each(function(){
|
|
var $this = $(this),
|
|
data = $this.data(SelectPage.dataKey),
|
|
params = $.extend({}, defaults, $this.data(), data && data.option ,typeof option === 'object' && option);
|
|
if(!data) $this.data(SelectPage.dataKey,(data = new SelectPage(this,params)));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 获得稿件内部对象
|
|
* @param {object} obj
|
|
* @returns
|
|
*/
|
|
function getPlugin(obj){
|
|
var container = $(obj).closest('div.sp_container');
|
|
return $('input.sp_input',container);
|
|
}
|
|
|
|
/**
|
|
* @desc 清除所有模式下选择的项目
|
|
*/
|
|
function ClearSelected(){
|
|
return this.each(function(){
|
|
var $this = getPlugin(this),
|
|
data = $this.data(SelectPage.dataKey);
|
|
if(data) data.clearAll(data);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 刷新选中项目内容
|
|
* 使用场景:使用$().val('xxx')修改插件的选中项目ID,此时需要刷新插件在输入框中的显示文本
|
|
*/
|
|
function SelectedRefresh(){
|
|
return this.each(function(){
|
|
var $this = getPlugin(this),
|
|
data = $this.data(SelectPage.dataKey);
|
|
if(data && data.elem.hidden.val())
|
|
data.setInitRecord(true);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 修改插件数据源
|
|
* 仅在json数据源模式有效
|
|
* @param {array} data
|
|
* @example
|
|
* [{name:'aa',sex:1},{name:'bb',sex:0},{...}]
|
|
*/
|
|
function ModifyDataSource(data){
|
|
return this.each(function(){
|
|
if(data && $.isArray(data) && data.length > 0){
|
|
var $this = getPlugin(this),
|
|
plugin = $this.data(SelectPage.dataKey);
|
|
if(plugin){
|
|
plugin.clearAll(plugin);
|
|
plugin.option.data = data;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @desc 获得选中项目的文本
|
|
* @returns {string}
|
|
*/
|
|
function GetInputText(){
|
|
var str = '';
|
|
this.each(function(){
|
|
var $this = getPlugin(this),data = $this.data(SelectPage.dataKey);
|
|
if(data) str += data.elem.combo_input.val();
|
|
});
|
|
return str;
|
|
}
|
|
|
|
var old = $.fn.selectPage;
|
|
|
|
$.fn.selectPage = Plugin;
|
|
$.fn.selectPage.Constructor = SelectPage;
|
|
$.fn.selectPageClear = ClearSelected;
|
|
$.fn.selectPageRefresh = SelectedRefresh;
|
|
$.fn.selectPageData = ModifyDataSource;
|
|
$.fn.selectPageText = GetInputText;
|
|
|
|
// 处理新旧版本冲突
|
|
// =================
|
|
$.fn.selectPage.noConflict = function () {
|
|
$.fn.selectPage = old;
|
|
return this;
|
|
};
|
|
})(window.jQuery);
|