html给下拉框添加搜索、分页功能(通过ajax从服务器获取搜索数据)

文章目录

  • 下拉框搜索分页功能开发
    • 功能
    • 使用
    • 源码和Demo(点个赞再走咯)
      • test.html
      • searchable-select.css
      • searchserver-select.js

下拉框搜索分页功能开发

最近需要开发一个下拉框从服务器通过Ajax请求搜索数据库并且分页的组件,源码和demo放在下面可以直接使用
功能由searchable-select改造而成

在这里插入图片描述

功能

  • 点击下拉框,自动聚焦输入框
  • 上下键可以选中数据,选中数据后回车填值,关闭下拉框
  • 输入框输入值后按下回车、点击查询按钮,触发搜索事件
  • 分页,由于组件空间有限仅显示5页

使用

源码和demo都已经在下面给出了,自取,demo包括ajax获取数据

1.引入组件

<script src="searchserver-select.js"></script>
<link href="searchable-select.css" rel="stylesheet">

2.添加input输入框

<input id="b">

3.创建组件

自定义数据获取规则,以下为获取测试数据,真实开发Ajax demo下面有给出

//传入一个function,keyWord表示搜索框的值,另外两个不必多说
$('#b1').searchServerSelect({}, function (keyWord, pageIndex = 1, pageSize = 10) {let res = {}//以下为测试数据let dataList = []for (let i = 0; i < 10; i++) {dataList.push({value: keyWord + i, label: keyWord + i})}res.pageIndex = pageIndexres.pageSize = pageSizeres.itemCount = 105res.data = dataList//返回一个Promisereturn new Promise(function(resolve, reject){//当异步代码执行成功时,我们会调用resolve, 当异步代码失败时就会调用rejectsetTimeout(function () {resolve(res); //100ms后,代码正常返回数据!},100)});
});

源码和Demo(点个赞再走咯)

以下效果为demo,需要自行引入jquery

在这里插入图片描述

test.html

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>下拉框搜索</title><script src="../jquery.min.js"></script><script src="searchserver-select.js"></script><link href="searchable-select.css" rel="stylesheet"><script type="text/javascript">//下拉搜索分页框$(function () {$('#b').searchServerSelect({}, function (keyWord, pageIndex = 1, pageSize = 10) {//服务器获取数据return getData(keyWord,pageIndex,pageSize)});$('#b1').searchServerSelect({}, function (keyWord, pageIndex = 1, pageSize = 10) {let res = {}//测试数据let dataList = []for (let i = 0; i < 10; i++) {dataList.push({value: keyWord + i, label: keyWord + i})}res.pageIndex = pageIndexres.pageSize = pageSizeres.itemCount = 105res.data = dataListreturn new Promise(function(resolve, reject){//当异步代码执行成功时,我们会调用resolve, 当异步代码失败时就会调用rejectsetTimeout(function () {resolve(res); //代码正常执行!},100)});});});//TODO 自定义下拉框数据function getData(keyWord,pageIndex = 1,pageSize = 10) {console.log("以下为测试数据获取方式,请自定义数据")let promise1 = $.ajax({url: "/dict/baseShipPort",data: {name:keyWord,current:pageIndex,pageSize:pageSize},type: "post",timeout:5000, //设置超时的时间})return new Promise(function (resolve, reject) {promise1.then(function (data) {if (data.success) {let res = {}let dataList = []let pager = data.datalet records = pager.datafor (let i = 0; i < records.length; i++) {dataList.push({value:records[i].portCode,label:records[i].displayName})}res.pageIndex = pager.pageIndexres.pageSize = pager.pageSizeres.itemCount = pager.itemCountres.data = dataListresolve(res)}else{reject(data)}},function (data) {console.log("以上为测试数据获取方式,请自定义数据")reject(data)})})}</script>
</head>
<body>
<div style="display: flex"><div style="width: 240px;margin-left: 20px">下拉搜索分页 自定义服务器数据<input id="b"></div><div style="width: 240px;margin-left: 20px">下拉搜索分页<input id="b1"><button type="button" onclick="console.log('值为:'+$('#b1').val())" >获取值</button></div>
</div></body>
</html>

searchable-select.css

/* select */
.fr{float: right;
}
.fl{float: left;
}
.searchable-select-hide {display: none;
}.searchable-select {display: inline-block;min-width: 100%;font-size: 14px;line-height: 1.428571429;color: #555;vertical-align: middle;position: relative;outline: none;z-index: 9
}.searchable-select-holder{padding: 0 10px;background-color: #fff;background-image: none;border: 1px solid #d9d9d9;min-height: 32px;line-height: 31px;box-sizing: border-box;-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
}.searchable-select-caret {position: absolute;width: 0;height: 0;box-sizing: border-box;border-color: #a0a0a0 transparent transparent transparent;top: 5px;bottom: 0;border-style: solid;border-width: 5px;margin: auto;right: 5px;
}
.searchable-select-clear {position: absolute;box-sizing: border-box;top: 5px;bottom: 0;margin: auto;right: 18px;cursor: pointer;font-size: 15px;
}.searchable-select-dropdown {position: absolute;background-color: #fff;border: 1px solid #ccc;border-bottom-left-radius: 4px;border-bottom-right-radius: 4px;padding: 4px;border-top: none;top: 28px;left: 0;right: 0;
}.searchable-select-input {margin-top: 5px;border: 1px solid #ccc;outline: none;padding: 4px;width: 100%;box-sizing: border-box;
}
.queryBtn{border: none;width: 19%;margin-left: 1%;background-color: #3f86d8;color: white;cursor: pointer;padding: 4px 0;
}.searchable-scroll {margin-top: 4px;position: relative;
}.searchable-scroll.has-privious {padding-top: 16px;
}.searchable-scroll.has-next {padding-bottom: 16px;
}.searchable-has-privious {top: 0;
}.searchable-has-next {bottom: 0;
}.searchable-has-privious, .searchable-has-next {height: 16px;left: 0;right: 0;position: absolute;text-align: center;z-index: 10;background-color: white;line-height: 8px;cursor: pointer;
}.searchable-select-items {max-height: 400px;overflow-y: scroll;position: relative;
}.searchable-select-items::-webkit-scrollbar {display: none;
}.searchable-select-item {padding: 5px 5px;cursor: pointer;min-height: 30px;box-sizing: border-box;transition: all 1s ease 0s;
}.searchable-select-item.selected{background: #3f86d8!important;color: white;
}
.searchable-select-item.hover {background: #9abde5;color: white;
}
/* select *//*2023 0912*/
/*新增分页功能*/
.searchable-pager{position: relative;width: 100%;height: 20px;
}
.searchable-pager-item{background-color: rgba(248, 248, 248, 0.9);border-radius: 2px;color: black;padding: 3px 4px;line-height: 20px;border: none;outline: none;cursor: pointer;margin-right: 3px;display: inline-block;
}
.searchable-pager-item:hover{background-color: #d2cfcf
}
.searchable-pager-item-active{background-color: rgb(0,115,220);color: white;
}
.searchable-loading{position: absolute;top: -24px;right: 0;z-index: 999;background-color: #3f86d8;color: white;
}

searchserver-select.js

/*** 下拉搜索框+分页功能,从服务器获取数据* @Date 2023-09-12* @author www*/
(function($){$.expr[":"].searchableSelectContains = $.expr.createPseudo(function(arg) {return function( elem ) {return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;};});$.searchServerSelect = function(element, options) {this.element = element;this.options = options || {};this.init();var _this = this;this.searchableElement.click(function(event){// event.stopPropagation();_this.show();}).on('keydown', function(event){if (event.which === 13 || event.which === 40 || event.which == 38){event.preventDefault();_this.show();}});$(document).on('click', null, function(event){if(_this.searchableElement.has($(event.target)).length === 0)_this.hide();});//TODO 输入框变化事件this.input.on('keydown', function(event){event.stopPropagation();if(event.which === 13){         //enter//按下回车,如果没有选中的项,则查询,否则选中然后关闭if(!_this.hasCurrentHoverItem()){//查询_this.filter();} else {//选中_this.selectCurrentHoverItem();_this.hide();}} else if (event.which == 27) { //ese_this.hide();} else if (event.which == 40) { //down_this.hoverNextItem();} else if (event.which == 38) { //up_this.hoverPreviousItem();}}).on('keyup', function(event){if(_this.inputOldValue === _this.input.val()){ //防止按下其他键带来的影响return;}//输入内容变化,那么再次回车应该触发搜索而不是选中if(event.which != 13 && event.which != 27 && event.which != 38 && event.which != 40){_this.cancelHover()}})}var $sS = $.searchServerSelect;$sS.fn = $sS.prototype = {version: '0.0.1'};$sS.fn.extend = $sS.extend = $.extend;$sS.fn.extend({//初始化init: function(){var _this = this;this.element.hide();this.searchableElement = $('<div tabindex="0" class="searchable-select"></div>');this.holder = $('<div class="searchable-select-holder"></div>');this.dropdown = $('<div class="searchable-select-dropdown searchable-select-hide"></div>');this.input = $('<input type="text" class="searchable-select-input" style="width: 80%" />');this.queryBtn = $('<input type="button" class="queryBtn" value="查询" />');this.inputOldValue = '';//控制查询频率this.items = $('<div class="searchable-select-items"></div>');this.caret = $('<span class="searchable-select-caret"></span>');this.clear = $('<span class="searchable-select-clear">×</span>');this.scrollPart = $('<div class="searchable-scroll"></div>');this.pager = $('<div class="searchable-pager"></div>');//当前高亮this.currentHoverItem = false;//当前选中this.currentSelectedItem = false;this.queryBtn.click(function () {_this.filter(true)})this.clear.click(function (event) {event.stopPropagation();_this.cancelSelected()})this.dropdown.append(this.input);this.dropdown.append(this.queryBtn);//查询按钮this.dropdown.append(this.scrollPart);this.scrollPart.append(this.items);this.scrollPart.append(this.pager);this.searchableElement.append(this.caret);this.searchableElement.append(this.clear);this.searchableElement.append(this.holder);this.searchableElement.append(this.dropdown);this.element.after(this.searchableElement);this.buildItems();},//TODO 触发搜索filter: function(btnClick=false){let _this = this;if(!btnClick && _this.inputOldValue === _this.input.val()){ //防止按下其他键带来的影响return;}_this.inputOldValue = _this.input.val()_this.buildItems();},//TODO 初始化添加项buildItems: function(pageIndex = 1,pageSize = 10){var _this = this;let keyword = _this.input.val();let promise = _this.getSelectData(keyword,pageIndex,pageSize)let loading = $('<span class="searchable-loading">loading...</span>')_this.pager.append(loading);promise.then(function (data) {//回调成功//清空原有内容$(_this.items).html('');_this.buildPager(data)let dataList = data.data_this.currentHoverItem = false;if(dataList && dataList.length>0){for (let i = 0; i < dataList.length; i++) {var item = $('<div class="searchable-select-item" data-value="'+dataList[i].value+'">'+dataList[i].label+'</div>');//如果选中的和当前的相等,则高亮if(_this.currentSelectedItem && $(_this.currentSelectedItem).html() === dataList[i].label){_this.selectItem(item);_this.hoverItem(item);}item.on('mouseenter', function(){$(this).addClass('hover');}).on('mouseleave', function(){$(this).removeClass('hover');}).click(function(event){event.stopPropagation();_this.selectItem($(this));_this.hide();});_this.items.append(item);}}},function (err) {console.log("服务器获取数据失败! ",err)$(loading).remove()//失败提示loading = $('<span class="searchable-loading" style="background-color: #e28a8a">加载失败,请稍后</span>')_this.pager.append(loading);setTimeout(function () {$(loading).remove()},3000)})},//渲染分页内容buildPager:function(pager){let _this = this;let thisPager = _this.pager;//清空内容$(thisPager).html('')$(thisPager).append(`<span class="searchable-pager-item fl">共${pager.itemCount}条</span>`)if(pager.itemCount>0){let pageCount = Math.ceil(pager.itemCount / pager.pageSize)//渲染5个页码,最好是单数let showPageBtnCount = 5;let min = pager.pageIndexlet max = pager.pageIndexwhile (max - min + 1 < showPageBtnCount){if(min>1){min -- ;}if(max<pageCount){max++;}if(min===1 && max===pageCount){break;}}let items = $('<div class="fr"></div>')for (let i = min; i <= max; i++) {let itemif(pager.pageIndex===i){item = $(`<a class="searchable-pager-item searchable-pager-item-active">${i}</a>`);}else{item = $(`<a class="searchable-pager-item">${i}</a>`);item.click(function(event){//取消原来的点击事件,防止弹框消失event.stopPropagation();_this.buildItems(i,pager.pageSize)});}$(items).append(item)}$(thisPager).append(items)}},//TODO 获取数据,服务器getSelectData:function(keywords,pageIndex = 1,pageSize = 10){console.log(`getSelectData(${keywords},${pageIndex},${pageSize}) `)if(!this.options.getDataFunction){alert("未设置数据获取逻辑:getDataFunction")}return this.options.getDataFunction(keywords,pageIndex,pageSize);},show: function(){this.dropdown.removeClass('searchable-select-hide');this.input.focus();this.status = 'show';this.dropdown.css('z-index', 100); //打开下拉列表时调高z-index层级},hide: function(){if(!(this.status === 'show'))return;if(this.items.find(':not(.searchable-select-hide)').length === 0)this.input.val('');this.dropdown.addClass('searchable-select-hide');this.searchableElement.trigger('focus');this.status = 'hide';this.dropdown.css('z-index', 1); //关闭下拉列表时恢复z-index层级},//高亮第一个hoverFirstNotHideItem: function(){this.hoverItem(this.items.find('.searchable-select-item:not(.searchable-select-hide)').first());},//选中高亮selectCurrentHoverItem: function(){if(!this.currentHoverItem.hasClass('searchable-select-hide'))this.selectItem(this.currentHoverItem);},//高亮覆盖,向前加载hoverPreviousItem: function(){if(!this.hasCurrentHoverItem())this.hoverFirstNotHideItem();else{var prevItem = this.currentHoverItem.prevAll('.searchable-select-item:not(.searchable-select-hide):first')if(prevItem.length > 0)this.hoverItem(prevItem);}},//高亮覆盖,向后加载hoverNextItem: function(){if(!this.hasCurrentHoverItem())this.hoverFirstNotHideItem();else{var nextItem = this.currentHoverItem.nextAll('.searchable-select-item:not(.searchable-select-hide):first')if(nextItem.length > 0)this.hoverItem(nextItem);}},hasCurrentSelectedItem: function(){return this.currentSelectedItem && this.currentSelectedItem.length > 0;},selectItem: function(item){console.log("selectItem:",$(item)[0].innerHTML)if(this.hasCurrentSelectedItem())this.currentSelectedItem.removeClass('selected');this.currentSelectedItem = item;item.addClass('selected');this.hoverItem(item);this.holder.text(item.text());var value = item.data('value');this.holder.data('value', value);this.element.val(value);if(this.options.afterSelectItem){this.options.afterSelectItem.apply(this);}},hasCurrentHoverItem: function(){return this.currentHoverItem && this.currentHoverItem.length > 0;},hoverItem: function(item){if(this.hasCurrentHoverItem())this.currentHoverItem.removeClass('hover');if(item.outerHeight() + item.position().top > this.items.height())this.items.scrollTop(this.items.scrollTop() + item.outerHeight() + item.position().top - this.items.height());else if(item.position().top < 0)this.items.scrollTop(this.items.scrollTop() + item.position().top);this.currentHoverItem = item;item.addClass('hover');},//取消hovercancelHover:function(){if(this.hasCurrentHoverItem()){this.currentHoverItem.removeClass('hover');this.currentHoverItem = false;}},//取消选中cancelSelected:function () {if(this.hasCurrentSelectedItem()){this.currentSelectedItem.removeClass('selected');this.element.val('')this.currentSelectedItem = falsethis.holder.text('')this.holder.data('value', '');}}});$.fn.searchServerSelect = function(options,getDataFunction){options.getDataFunction = getDataFunction;this.each(function(){var sS = new $sS($(this), options);});return this;};})(jQuery);

点个赞再走咯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/108201.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——二叉树

堆的简易建立 前言堆的顺序表实现一、Heap.h头文件向下调整算法复杂度向上调整算法复杂度 二、Heap.c功能函数文件三、Test.c测试函数文件四、运行结果展示五、完整代码展示 二叉树的链表实现回顾二叉树的概念链式二叉树代码模拟二叉树的遍历 总结 前言 现在我们开始学习堆的建…

C语言入门Day_19 初识函数

目录 1.函数的定义 2.函数的调用 3.易错点 4.思维导图 前言&#xff1a; printf()我们已经很熟悉了&#xff0c;它有一个特定的功能&#xff0c;就是在屏幕上输出一行文字。之前的课程我们都称呼printf()为一个功能&#xff0c;实际上ta在编程中有个特定的名字——函数。 …

获取Windows 10中的照片(旧版)下载

Windows 10中的新版照片应用&#xff0c;目前发现无法直接打开部分iOS设备上存储的照片。需要使用照片&#xff08;旧版&#xff09;才行。 但目前应用商店中无法直接搜索到照片&#xff08;旧版&#xff09;&#xff0c;因此笔者提供如下链接&#xff0c;可以直接访问并呼出W…

C++零碎记录(十三)

23. 多态 23.1 多态简介 ① 多态是C面向对象三大特性之一。 ② 多态分为两类&#xff1a; 1. 静态多态&#xff1a;函数重载和运算符重载属于静态多态&#xff0c;复用函数名。 2. 动态多态&#xff1a;派生类和 虚函数实现运行时多态。 ③ 静态多态和动态多态区别&#xff…

通过 chatgpt 协助完成网站数据破解

Chatgpt 的出现极大地提升了程序员的工作效率&#xff0c;常见的使用场景包括代码自动生成、代码静态检查等&#xff0c;那么 chatgpt 能否用于某些网站的数据破解工作呢&#xff1f; 问题 某天线上服务开始报警&#xff0c;原来是某个视频网站无法获取到其 cdn 地址导致的下…

K8s上安装gitlab-ce

文章目录 K8s上安装gitlab-ce操作如下gitlab-deployment.yml K8s上安装gitlab-ce 前言   使用pv-pvc来持久化gitlab的数据&#xff0c;配置&#xff0c;日志文件。   pod启动后需要需要修改external_url然后重启pod。 操作如下 mkdir -p /mnt/data01/gitlab ctr -n k8s.…

内外统一的边缘原生云基础设施架构——火山引擎边缘云

近日&#xff0c;火山引擎边缘云边缘计算架构师郭少巍在LiveVideoStack Con 2023上海站围绕火山引擎边缘云海量分布式节点和上百T带宽&#xff0c;结合边缘计算在云基础设施架构方面带来的挑战&#xff0c;分享了面对海量数据新的应用形态对低时延和分布式架构的需求&#xff0…

数据通信网络之IPv6以太网二层交换

文章及资源归档至【AIShareLab】&#xff0c;回复 通信系统与网络 可获取。 文章目录 一、目的二、环境及网络拓扑三、需求四、步骤 一、目的 掌握 VLAN、Trunk 的基础配置。掌握以太网链路聚合的基础配置。掌握路由器子接口的配置&#xff0c;以及通过子接口实现 VLAN 之间互…

4.1.8- Web 应用程序使用的组件进行指纹识别

Web 应用程序使用的组件进行指纹识别 IDWSTG-INFO-08 总结 毫不夸张地说&#xff0c;几乎所有可以想象的Web应用程序的想法都已经投入开发。随着全球大量自由和开源软件项目的积极开发和部署&#xff0c;应用程序安全测试很可能会遇到完全或部分依赖于这些知名应用程序或框架…

[uniapp]踩坑日记 unexpected character > 1或‘=’>1 报错

在红色报错文档里下滑&#xff0c;找到Show more 根据提示看是缺少标签&#xff0c;如果不是缺少标签&#xff0c;看看view标签内容是否含有<、>、>、<号,把以上符合都进行以<号为例做{{“<”}}处理

Java多线程并发面试题

文章目录 Java并发基础并行和并发有什么区别&#xff1f;说说什么是进程和线程&#xff1f;Java线程创建方式&#xff1f;Runnable和Callable接口的区别&#xff1f;为什么调用start()方法时会执行run()方法&#xff0c;不直接调用run()方法&#xff1f;sleep()和wait()的区别&…

5.11.Webrtc接口的设计原理

在上节课中呢&#xff0c;我向你介绍了web rtc的接口宏&#xff0c;那有很多同学会产生疑问啊&#xff0c;那觉得web rtc为什么要把接口设计的这么复杂&#xff1f;还非要通过宏来实现一个代理类&#xff0c;再通过代理类来调用到web rtc内部。 那为什么要这么设计呢&#xf…