autocomplete.js 6.7 KB

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