inputSelect.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. +function ($) {
  2. $.expr[":"].searchSelectContains = $.expr.createPseudo(function(arg) {
  3. return function( elem ) {
  4. if($(elem).children('a').attr('data-simplified') !== undefined) {
  5. return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0 || $(elem).children('a').attr('data-simplified').toUpperCase().indexOf(arg.toUpperCase()) >= 0;
  6. } else {
  7. return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
  8. }
  9. };
  10. });
  11. $.fn.inputSelect = function (options,downBack,selectBack,initBack){
  12. var defaultsettings = {
  13. defaultText : '-请选择-',
  14. isInputEnabled : false,
  15. onInputBlur : null,
  16. jsonData : null,
  17. initialValue : null,
  18. jsonDataId : null,
  19. jsonDataText : null,
  20. jsonSimplifiedKey : null,
  21. ajax:{
  22. url : null,
  23. data : null,
  24. dataType : null,
  25. resultKey : null,
  26. type : null,
  27. beforeSend : null,
  28. error : null,
  29. success : null,
  30. complete : null
  31. },
  32. itemVisible : 5
  33. };
  34. if(this.length == 0) return this;
  35. if(this.length > 1){
  36. this.each(function(){
  37. $(this).inputSelect(options, downBack, selectBack, initBack);
  38. });
  39. return this;
  40. }
  41. var $this = this,
  42. selectedInput = $this.find('.cus-sel-chosed').find('input'),
  43. selectedText = $this.find('.cus-sel-chosed').find('.cus-sel-chosed-txt'),
  44. _data = downBack,
  45. setKey = {},
  46. setVal = {},
  47. getData = {},
  48. opts = $.extend({}, defaultsettings, options),
  49. tempStr = '';
  50. $this.attr({'data-defaulttext':opts.defaultText});
  51. $this.find('.cus-sel-list').height(37*opts.itemVisible);
  52. function setCurr(v){
  53. if($this.find('a[data-value="'+ v.key +'"]').length<=0){
  54. return false;
  55. }
  56. setChosedKeyVal(v.key, v.val);
  57. $this.find('.cus-sel-list').find('a').removeClass('hover');
  58. $this.find('.cus-sel-list').find('a[data-value="'+v.key+'"]').addClass('hover');
  59. }
  60. function isString(value) {
  61. return Object.prototype.toString.call(value) === "[object String]";
  62. }
  63. function isArrayFn(value){
  64. if(typeof Array.isArray === "function") {
  65. return Array.isArray(value);
  66. } else {
  67. return Object.prototype.toString.call(value) === "[object Array]";
  68. }
  69. }
  70. function isFunction(value) {
  71. return Object.prototype.toString.call(value) === '[object Function]';
  72. };
  73. function render(data, jsonDataId, jsonDataText, jsonSimplifiedKey) {
  74. var i,
  75. dataLength,
  76. tempStr = '';
  77. if(isArrayFn(data)) {
  78. for(i=0, dataLength = data.length; i<dataLength; i++) {
  79. // if(isArrayFn(data[i])) {
  80. // tempStr += render(data[i]);
  81. // } else {
  82. if(jsonDataId && jsonDataText) {
  83. if(jsonSimplifiedKey) {
  84. if(data[i][jsonDataId]==='' || data[i][jsonDataId]<=0) {
  85. tempStr = '<li><a href="javascript:;" title="'+ data[i][jsonDataText] +'" data-value="'+ data[i][jsonDataId] +'" data-simplified="'+ data[i][jsonSimplifiedKey] +'">'+ data[i][jsonDataText] +'</a></li>' + tempStr;
  86. } else {
  87. tempStr += '<li><a href="javascript:;" title="'+ data[i][jsonDataText] +'" data-value="'+ data[i][jsonDataId] +'" data-simplified="'+ data[i][jsonSimplifiedKey] +'">'+ data[i][jsonDataText] +'</a></li>';
  88. }
  89. } else {
  90. if(data[i][jsonDataId]==='' || data[i][jsonDataId]<=0) {
  91. tempStr = '<li><a href="javascript:;" title="'+ data[i][jsonDataText] +'" data-value="'+ data[i][jsonDataId] +'">'+ data[i][jsonDataText] +'</a></li>' + tempStr;
  92. } else {
  93. tempStr += '<li><a href="javascript:;" title="'+ data[i][jsonDataText] +'" data-value="'+ data[i][jsonDataId] +'">'+ data[i][jsonDataText] +'</a></li>';
  94. }
  95. }
  96. } else {
  97. for(var key in data[i]){
  98. if(key==='' || key<=0) {
  99. tempStr = '<li><a href="javascript:;" title="'+ data[i][key] +'" data-value="'+ key +'">'+ data[i][key] +'</a></li>' + tempStr;
  100. } else {
  101. tempStr += '<li><a href="javascript:;" title="'+ data[i][key] +'" data-value="'+ key +'">'+ data[i][key] +'</a></li>';
  102. }
  103. }
  104. }
  105. // }
  106. }
  107. }
  108. return tempStr;
  109. }
  110. function setInitialValue(initialValue, jsonDataArr) {
  111. var tempKey,
  112. tempVal;
  113. if(initialValue){
  114. if(initialValue.key == undefined && initialValue.val == undefined) {
  115. for(var key in initialValue){
  116. tempKey = key,
  117. tempVal = initialValue[key];
  118. setChosedKeyVal(tempKey, tempVal);
  119. $this.find('.cus-sel-list').find('a[data-value="'+tempKey+'"]').addClass('hover');
  120. }
  121. } else if(initialValue.key != undefined && initialValue.val != undefined) {
  122. tempKey = initialValue.key,
  123. tempVal = initialValue.val;
  124. setChosedKeyVal(tempKey, tempVal);
  125. $this.find('.cus-sel-list').find('a[data-value="'+tempKey+'"]').addClass('hover');
  126. } else if(initialValue.key != undefined) {
  127. tempKey = initialValue.key;
  128. tempVal = $this.find('.cus-sel-list').find('a[data-value="'+tempKey+'"]').addClass('hover').text();
  129. setChosedKeyVal(tempKey, tempVal);
  130. } else if(initialValue.val != undefined) {
  131. tempVal = initialValue.val;
  132. tempKey = $this.find('.cus-sel-list').find('a[title="'+tempVal+'"]').addClass('hover').attr('data-value');
  133. setChosedKeyVal(tempKey, tempVal);
  134. }
  135. if(selectBack){
  136. selectBack($this, tempVal, tempKey);
  137. }
  138. } else {
  139. setChosedKeyVal('', $this.attr('data-defaulttext'));
  140. }
  141. }
  142. function scrollToSelectedItem(selectedItem, scrollContainer) {
  143. if(selectedItem.outerHeight() + selectedItem.position().top > scrollContainer.height()){
  144. scrollContainer.scrollTop(scrollContainer.scrollTop() + selectedItem.outerHeight() + selectedItem.position().top - scrollContainer.height());
  145. }else if(selectedItem.position().top < 0){
  146. scrollContainer.scrollTop(scrollContainer.scrollTop() + selectedItem.position().top);
  147. }
  148. }
  149. function showList($Obj, downBack) {
  150. if($Obj) {
  151. $Obj.addClass('active').css({zIndex:1000});
  152. var bodyScrollTop = document.documentElement.scrollTop + document.body.scrollTop,
  153. domTop = $Obj.offset().top,
  154. bodyHeight = $(window).height(),
  155. listHeight = $Obj.children('.cus-sel-list').outerHeight(true),
  156. chosedHeight = $Obj.outerHeight(true);
  157. if(-(domTop+chosedHeight-bodyScrollTop-bodyHeight)<listHeight){
  158. $Obj.children('.cus-sel-list').show().css({'top':-(listHeight)+'px'});
  159. }else{
  160. $Obj.children('.cus-sel-list').show().css({'top':chosedHeight+'px'});
  161. }
  162. if(downBack && isFunction(downBack)){
  163. downBack($Obj);
  164. }
  165. }
  166. }
  167. function hideList() {
  168. $this.find('.cus-sel-list').hide();
  169. $this.css({zIndex:1});
  170. }
  171. function selectItem($Obj, selectBack) {
  172. var key,
  173. value;
  174. if($Obj) {
  175. value = $Obj.text(),
  176. key = $Obj.attr('data-value');
  177. $this.attr('value',key).removeClass('active').find('.cus-sel-list').find('a').removeClass('hover');
  178. $Obj.addClass('hover');
  179. setChosedKeyVal(key, value);
  180. if(selectBack){
  181. selectBack($this, value, key);
  182. }
  183. }
  184. }
  185. function filterList(filterText) {
  186. //过滤文本时清除下拉数据的选中状态,清除当前对象value值/选中文本的data-value
  187. $this.children('.cus-sel-list').find('.hover').removeClass('hover');
  188. $this.attr('value','').children('.cus-sel-chosed')
  189. .find('.cus-sel-chosed-txt').text('').attr('data-value', '').end()
  190. .find('input').attr('data-value', '');
  191. var filterText = $.trim(filterText);
  192. if(filterText) {
  193. $this.children('.cus-sel-list').find('li').show().end().find('li:not(:searchSelectContains('+ filterText +'))').hide();
  194. return $this.children('.cus-sel-list').find('li:searchSelectContains('+ filterText +')');
  195. } else {
  196. $this.children('.cus-sel-list').find('li').show();
  197. return $this.children('.cus-sel-list').find('li');
  198. }
  199. }
  200. function setChosedKeyVal(key,value) {
  201. $this.attr('value', key);
  202. selectedInput.val(value).attr('data-value', key);
  203. selectedText.text(value).attr('data-value', key);
  204. }
  205. // isInputEnabled为true,显示文本框
  206. if(opts.isInputEnabled) {
  207. if($this.data('bind')) {
  208. selectedInput.off('.cusSel');
  209. } else {
  210. $this.data('bind',true);
  211. }
  212. selectedText.hide();
  213. setChosedKeyVal('', $this.attr('data-defaulttext'));
  214. selectedInput.addClass('cus-sel-chosed-input').on('keydown.cusSel', function(event){
  215. event.stopPropagation();
  216. var liVisible = $this.children('.cus-sel-list').find('li:visible'),
  217. selectedItem = $this.children('.cus-sel-list').find('.hover').eq(0),
  218. selectedItemIndex = liVisible.index(selectedItem.parent());
  219. if(event.which === 13){ //enter
  220. event.preventDefault();
  221. if(selectedItem) {
  222. selectItem( selectedItem, selectBack);
  223. } else {
  224. setChosedKeyVal('', $this.attr('data-defaulttext'));
  225. }
  226. hideList();
  227. } else if (event.which == 27) { //ese
  228. } else if (event.which == 40) { //down
  229. event.preventDefault();
  230. if(liVisible.length>0) {
  231. if(selectedItem.parent().is(':visible')) {
  232. if(liVisible.length > 1) {
  233. selectedItem.removeClass('hover');
  234. if(selectedItemIndex != liVisible.length-1) {
  235. selectedItem = liVisible.eq(selectedItemIndex+1).find('a').addClass('hover');
  236. } else {
  237. selectedItem = liVisible.first().find('a').addClass('hover');
  238. }
  239. }
  240. } else {
  241. selectedItem.removeClass('hover');
  242. selectedItem = liVisible.eq(0).find('a').addClass('hover');
  243. }
  244. scrollToSelectedItem( selectedItem, $this.children('.cus-sel-list'));
  245. }
  246. } else if (event.which == 38) { //up
  247. event.preventDefault();
  248. if(liVisible.length>0) {
  249. if(selectedItem.parent().is(':visible')) {
  250. if(liVisible.length>1) {
  251. selectedItem.removeClass('hover');
  252. if(selectedItemIndex != 0) {
  253. selectedItem = liVisible.eq(selectedItemIndex-1).find('a').addClass('hover');
  254. } else {
  255. selectedItem = liVisible.last().find('a').addClass('hover');
  256. }
  257. }
  258. } else {
  259. selectedItem.removeClass('hover');
  260. selectedItem = liVisible.eq(0).find('a').addClass('hover');
  261. }
  262. scrollToSelectedItem( selectedItem, $this.children('.cus-sel-list'));
  263. }
  264. }
  265. }).on('keyup.cusSel', function(event){
  266. if(event.which != 13 && event.which != 27 && event.which != 38 && event.which != 40){
  267. var filterResult = filterList($(this).val());
  268. if(filterResult.length) {
  269. showList($this, downBack);
  270. } else {
  271. hideList();
  272. }
  273. $this.find('.cus-sel-chosed-txt').text($(this).val()).attr('data-value', $(this).attr('data-value'));
  274. }
  275. }).on('focus.cusSel', function(){
  276. if($.trim($(this).val())===$this.attr('data-defaulttext')) {
  277. $(this).val('');
  278. }
  279. }).on('blur.cusSel', function(){
  280. setTimeout(function(){
  281. if($.trim(selectedInput.val())==='') {
  282. selectedInput.val($this.attr('data-defaulttext'));
  283. }
  284. if(opts.onInputBlur) {
  285. opts.onInputBlur();
  286. }
  287. }, 100);
  288. });
  289. }
  290. if(isString(options)){
  291. switch(options){
  292. case 'setDatas':
  293. setCurr(_data);
  294. break;
  295. case 'setDataKey':
  296. setKey.key = _data;
  297. setKey.val = $.trim($this.find('.cus-sel-list').find('a[data-value="'+_data+'"]').text());
  298. setCurr(setKey);
  299. break;
  300. case 'setDataVal':
  301. setVal.val = _data;
  302. $this.find('.cus-sel-list').find('a').each(function(){
  303. if($.trim($(this).text())==_data){
  304. setVal.key = $(this).data('value');
  305. }
  306. });
  307. setCurr(setVal);
  308. break;
  309. case 'getDatas':
  310. getData.key = selectedText.attr('data-value');
  311. getData.val = $.trim(selectedText.text()) === $this.attr('data-defaulttext')?'': $.trim(selectedText.text());
  312. return getData;
  313. break;
  314. case 'getDataKey':
  315. return selectedText.attr('data-value');
  316. break;
  317. case 'getDataVal':
  318. return $.trim(selectedText.text()) === $this.attr('data-defaulttext')?'': $.trim(selectedText.text());
  319. break;
  320. case 'resetValue':
  321. setChosedKeyVal('', $this.attr('data-defaulttext'));
  322. $this.find('.cus-sel-list').find('a.hover').removeClass('hover');
  323. break;
  324. case 'clearValue':
  325. setChosedKeyVal('', $this.attr('data-defaulttext'));
  326. $this.find('.cus-sel-list').find('ul').html('');
  327. break;
  328. }
  329. return false;
  330. }
  331. if(opts.ajax.url) {
  332. $.ajax({
  333. url: opts.ajax.url,
  334. data: opts.ajax.data,
  335. dataType: opts.ajax.datatype ? opts.ajax.datatype : 'json',
  336. type: opts.ajax.type ? opts.ajax.type : 'get',
  337. beforeSend: function(XHR){
  338. if(opts.ajax.beforeSend) {
  339. opts.ajax.beforeSend.call($this, {'XHR': XHR});
  340. } else {
  341. return;
  342. }
  343. },
  344. error: function(XHR, status, error) {
  345. if(opts.ajax.error) {
  346. opts.ajax.error.call($this, {'XHR': XHR,'textStatus': status, 'errorThrown': error});
  347. } else {
  348. return;
  349. }
  350. },
  351. complete: function(XHR, status){
  352. if(opts.ajax.complete) {
  353. opts.ajax.complete.call($this, {'XHR': XHR,'textStatus': status});
  354. } else {
  355. return;
  356. }
  357. },
  358. success: function (data, status) {
  359. var response = data,
  360. ajaxResultKey = opts.ajax.resultKey,
  361. tempHtml;
  362. if(opts.ajax.success) {
  363. opts.ajax.success.call($this, {'response': data,'textStatus': status});
  364. } else {
  365. if(ajaxResultKey) {
  366. tempHtml = render(response[ajaxResultKey], opts.jsonDataId, opts.jsonDataText, opts.jsonSimplifiedKey);
  367. $this.children('.cus-sel-list').children('ul').html(tempHtml);
  368. setInitialValue(opts.initialValue, response[ajaxResultKey]);
  369. } else {
  370. alert('使用ajax加载数据需配置resultKey(json数组对应的key)');
  371. }
  372. }
  373. }
  374. });
  375. }
  376. if(opts.jsonData) {
  377. tempStr = render(opts.jsonData, opts.jsonDataId, opts.jsonDataText, opts.jsonSimplifiedKey);
  378. $this.children('.cus-sel-list').children('ul').html(tempStr);
  379. setInitialValue(opts.initialValue, opts.jsonData);
  380. }
  381. if($this.data('bind')) {
  382. $this.off('click.cusSel','.cus-sel-chosed').children('.cus-sel-list').off('click.cusSel','a');
  383. } else {
  384. $this.data('bind',true);
  385. }
  386. $this.on('click.cusSel','.cus-sel-chosed',function(e){
  387. if($this.is('.disabled') || $this.is('.active')){
  388. return false;
  389. }
  390. $('.cus-sel').removeClass('active').css({zIndex:1});
  391. $('.cus-sel-list').hide();
  392. var _this = $(this);
  393. if(opts.isInputEnabled) {
  394. if($(e.target).is('.cus-sel-chosed-input')) {
  395. return false;
  396. } else if($(e.target).is('.jselect-icon')) {
  397. showList($this, downBack);
  398. selectedInput.focus();
  399. }
  400. } else {
  401. showList($this, downBack);
  402. }
  403. });
  404. $this.children('.cus-sel-list').on('click.cusSel', 'a', function () {
  405. var _this = $(this);
  406. selectItem(_this, selectBack);
  407. hideList();
  408. return false;
  409. });
  410. if(initBack){
  411. setTimeout(function(){initBack();},300);
  412. }
  413. $this.optionsData = function(data,funback){
  414. if(data){
  415. tempStr = render(data, opts.jsonDataId, opts.jsonDataText, opts.jsonSimplifiedKey);
  416. $this.children('.cus-sel-list').children('ul').html(tempStr);
  417. setChosedKeyVal('', $this.attr('data-defaulttext'));
  418. }
  419. if(funback){
  420. funback($this);
  421. }
  422. };
  423. return this;
  424. };
  425. $("html,body").click(function (e) {
  426. var target = e.target;
  427. if ($(target).parents(".cus-sel").length == 0) {
  428. $(".cus-sel").removeClass("active").css({zIndex:1});
  429. $(".cus-sel-list").hide();
  430. }
  431. });
  432. $(document).on('mouseenter', '[data-toggle="inputSelect"]', function (e) {
  433. if($(this).data('mouseenter')) return false;
  434. $(this).data('mouseenter',true);
  435. $(this).inputSelect({isInputEnabled: true});
  436. });
  437. }(jQuery);