autocomplete.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. layui.define(['jquery', 'laytpl', 'layer'], function (e) {
  2. "use strict";
  3. // layui.link('/resource/css/autocomplete.css');
  4. var hint = layui.hint(),
  5. $ = layui.jquery,
  6. laytpl = layui.laytpl,
  7. layer = layui.layer,
  8. module = 'autocomplete',
  9. filter = 'layui-autocomplete',
  10. container = 'layui-form-autocomplete',
  11. container_focus = 'layui-form-autocomplete-focus',
  12. system = {
  13. config: {
  14. template: ['<div class="layui-form-autocomplete">', '<dl class="layui-anim layui-anim-upbit">', '</dl>', '</div>'].join(''),
  15. layout: ['<dd data-index="{{d.index}}">{{d.text}}</dd>'].join(''),
  16. template_txt: '{{d.text}}',
  17. template_val: '{{d.value}}',
  18. cache: false
  19. },
  20. index: layui.autocomplete ? layui.autocomplete.index + 1e4: 0,
  21. data: {},
  22. },
  23. callback = function() {
  24. var _self = this,
  25. _config = _self.config,
  26. _id = _config.id;
  27. return _id && (callback.config[_id] = _config), {
  28. config: _self.config
  29. }
  30. },
  31. job = function(e) {
  32. var _self = this;
  33. _self.index = ++system.index,
  34. _self.config = $.extend({}, _self.config, system.config, e),
  35. _self.render()
  36. };
  37. job.prototype.config = {
  38. text: {
  39. none: "无数据",
  40. loading: "加载中"
  41. },
  42. response: {
  43. code: 'code',
  44. data: 'data'
  45. },
  46. time_limit: 500,
  47. ajax: [],
  48. _ajax: null,
  49. data: [],
  50. filter: ''
  51. },
  52. job.prototype.render = function() {
  53. var _self = this, _config = _self.config;
  54. if (_config.elem = $(_config.elem), _config.where = _config.where || {}, !_config.elem[0]) return _self;
  55. var _elem = _config.elem,
  56. _container = _elem.next('.' + container),
  57. _html = _self.elem = $(laytpl(_config.template).render({}));
  58. _config.id = _self.id, _container[0] && _container.remove(), _elem.attr('autocomplete', 'off'), _elem.after(_html);
  59. _self.events()
  60. },
  61. job.prototype.pullData = function () {
  62. var _self = this,
  63. _config = _self.config,
  64. _elem = _config.elem,
  65. _container = _elem.next('.' + container),
  66. _dom = _container.find('dl');
  67. if (!_config.filter) return _self.renderData([]);
  68. if (_config.cache && _config.data[_self.index]) {
  69. var arr = [];
  70. layui.each(_config.data[_self.index], function (i, e) {
  71. if (typeof e === "string") e = new Array(e);
  72. layui.each(e, function (_i, _e) {
  73. if(_e && _e.toString().toLowerCase().indexOf(_config.filter.toLowerCase()) > -1) {
  74. arr.push(e);
  75. return false;
  76. }
  77. });
  78. });
  79. return _self.renderData(arr);
  80. }
  81. if (_config.cache && _config.ajax[_self.index] != undefined) return;
  82. (!_config.cache && _config.ajax[_self.index] != undefined) && _config.ajax[_self.index].abort(), _config.ajax[_self.index] = $.ajax({
  83. type: _config.method || "get",
  84. url: _config.url,
  85. data: {search_text: _config.filter},
  86. dataType: "json",
  87. beforeSend: function () {
  88. _container.addClass(container_focus), _dom.html(['<dd style="text-align: center" autocomplete-load>', _config.text.loading, '</dd>'].join(''))
  89. },
  90. success: function (resp) {
  91. return 0 != eval('resp.' + _config.response.code) ? layer.msg(eval('resp.' + _config.response.data)) : _config.data[_self.index] = eval('resp.' + _config.response.data), _self.renderData(_config.data[_self.index])
  92. },
  93. error: function () {
  94. hint.error("请求失败")
  95. },
  96. complete: function () {
  97. delete _config.ajax[_self.index]
  98. }
  99. })
  100. },
  101. job.prototype.renderData = function (resp) {
  102. var _self = this,
  103. _config = _self.config,
  104. _elem = _config.elem,
  105. _container = _elem.next('.' + container),
  106. _dom = _container.find('dl'),
  107. _list = [];
  108. layui.each(resp, function (i, e) {
  109. _list.push(laytpl(_config.layout).render({index: i, text: laytpl(_config.template_txt).render(e)}));
  110. });
  111. _dom.html(_list.join('')), _list.length > 0 ? _container.addClass(container_focus) : _container.removeClass(container_focus)
  112. },
  113. job.prototype.events = function () {
  114. var _self = this,
  115. _config = _self.config,
  116. _elem = _config.elem,
  117. _container = _elem.next('.' + container),
  118. _dom = _container.find('dl');
  119. _elem.on('focus', function () {
  120. _config.filter = this.value, _config.cache ? _self.pullData() : _self.renderData(_config.data[_self.index])
  121. }).on('input propertychange', function (e) {
  122. var _value = this.value;
  123. clearTimeout(_config._ajax), _config._ajax = setTimeout(function () {
  124. _config.filter = _value, _self.pullData()
  125. }, _config.time_limit)
  126. }),
  127. $(document).on('click', function (e) {
  128. var _target = e.target, _item = _dom.find(_target), _e = _item.length > 0 ? _item.closest('dd') : undefined;
  129. if (_target === _elem[0]) return false;
  130. if (_e !== undefined) {
  131. if (_e.attr('autocomplete-load') !== undefined) return false;
  132. _elem.val(laytpl(_config.template_val).render(_config.data[_self.index][_e.index()])), _config.onselect == undefined || _config.onselect(_config.data[_self.index][_e.index()])
  133. }
  134. _container.removeClass(container_focus);
  135. })
  136. };
  137. callback.config = {},
  138. callback.job = {},
  139. system.init = function (e, c) {
  140. var c = c || {}, _self = this, _elems = $(e ? 'input[lay-filter="' + e + '"]': 'input[' + filter + ']');
  141. _elems.each(function (_i, _e) {
  142. var _elem = $(_e),
  143. _lay_data = _elem.attr('lay-data');
  144. try {
  145. _lay_data = new Function("return " + _lay_data)()
  146. } catch (ex) {
  147. return hint.error("autocomplete元素属性lay-data配置项存在语法错误:" + _lay_data)
  148. }
  149. var _config = $.extend({elem: this}, system.config, c, _lay_data);
  150. _config.url == undefined && (_config.data == undefined || _config.length === 0) && hint.error("autocomplete配置有误,缺少获取数据方式");
  151. system.render(_config);
  152. })
  153. },
  154. system.render = function (e) {
  155. var j = new job(e);
  156. return callback.call(j)
  157. }
  158. system.init(), e(module, system);
  159. })