文本域 自定义下拉框 支持模糊检索 关键字高亮 上下选择
转载自:文本域 自定义下拉框 支持模糊检索 关键字高亮 上下选择
一、需求
需要创建一个常见问题库,填写存在问题时可以下拉选择,可以模糊搜索,也可以手写。如果选择了问题库中的内容,自动填充内容到存在问题中,并且自动选择严重程度,最终保存的值还是界面显示的内容。
二、可行性研究
1、h5的datalist 可以支持下拉选择,模糊搜索,手写 。经过试验 list属性只能用于input输入框 不可适用于textarea。 无法直接使用datalist方式,pass。
2、使用input的datalist和textarea结合的方式,界面显示textarea。点击变成input使用datalist方式进行检索,填写完成后转成textarea。 经过试验,功能可以达到,但是input不换行,用户体验太差,pass。
3、使用semantic ui的输入框 也不支持textarea,pass。
4、手写下拉框,可行。
三、实现
1、实现思路
a、点击文本框,弹出下拉框。下拉框以td绝对定位,根据页面高度计算位置,下拉框是在td上面还是下面
b、点击空白处关闭下拉框
c、文本域输入内容,检索下拉框匹配内容,高亮显示关键字,隐藏没有匹配项内容
d、监听键盘上下键,动态选择下拉框内容,并自动填充值
2、在页面创建临时div 默认隐藏 用于缓存数据
JavaScript
<div id="tempQuestionDiv" style="display:none"><ul><#list problemList as list><li><span severityLevel="${list.severityLevel}">${list.questionContent}</span><dd>${list.severityLevelName}</dd></li></#list></ul></div>
3、页面结构
td中一个textarea
4、界面样式
CSS
.deductCheckInfo{position: relative;
}#questionDiv{border: 1px solid #96C8DA;width: 321px;height: 300px;z-index: 9999;position: absolute;text-align:left;background: white;border-radius:5px;padding: 5px 6px;overflow-y: scroll;
}
#questionDiv ul li{
padding:3px 6px;
cursor: pointer;}
#questionDiv ul li span{margin-bottom: 5px;color: #333;font-size: 13px;display: block;line-height: 18px;
}#questionDiv ul li dd{color: #333;font-size: 13px;display: block;opacity: 0.7 ;
}#questionDiv ul .active{background: rgba(0, 0, 0, 0.07);/* font-weight: 600; */
}#questionDiv ul li:hover{background: rgba(0, 0, 0, 0.14);
}
5、事件绑定和提取方法
a、文本域点击事件
JavaScript
//输入框点击事件$("body").on("click",".deductCheckInfo textarea",function(event){var that=this;//先删除已有的下拉框$("#questionDiv").remove();//重新获取下拉框内容var tempQuestionDiv=$("#tempQuestionDiv").html();//判断当前td下是否存在下拉框var $QuestionDiv=$(this).parent().find("#questionDiv");//当前td下不存在下拉框if($QuestionDiv && $QuestionDiv.length==0){//添加下拉框$(this).after("<div id=\"questionDiv\">"+tempQuestionDiv+"</div>");//获取下拉框的高度 获取包括padding的高度加上边框线高度var questionDivHeight=$("#questionDiv").innerHeight()+2;//获取td的高度var deductCheckInfoTdHeight=$(this).parent().innerHeight();//获取td的Y坐标var tdY=$(this).parent().offset().top;//获取页面高度(下边距60+form表单高度+form表单距离顶部的高度)var formHeight=60+$("div.form").innerHeight()+$("div.form").offset().top;//高度差 td左下角位置离页面底部的距离(页面高度-td的坐标-td的高度)var tempHeight=formHeight-tdY-deductCheckInfoTdHeight;//TD距离页面底部的距离小于下拉框高度时 且 (td的Y减去tab项的高度)大于下拉框高度时if(tempHeight<questionDivHeight && (tdY-$("#checkImplementTab").height())>questionDivHeight){//将下拉框向上移动 避免遮挡var top=-(questionDivHeight);//移动$("#questionDiv").css("top",top)}//点击事件$("#questionDiv").find("ul li").click(function(){//获取li的jq对象var $li=$(this);//获取textarea的jq对象var $textarea=$(that);//下拉框回写数据selectProblemData($li,$textarea);});}//获取当前文本域内容var textareaVal=$(this).val();//下拉框内容检索和显示selectProblemShow(textareaVal);//取消冒泡event.stopPropagation();});
b、文本框输入内容
JavaScript
//监听文本框输入内容$(".deductCheckInfo textarea").on("input propertychange",function(e){//获取当前输入内容var curText=$(this).val();//下拉框内容检索和显示selectProblemShow(curText);});
c、监听键盘按键
JavaScript
//监听文本框键盘按键$(".deductCheckInfo textarea").on("keydown",function(e){var keyCode=e.keyCode;//判断下拉框显示的时候 并且只有 上下键 才触发if(!$("#questionDiv").is(":hidden") && (keyCode==38 || keyCode==40)){//需要改为显示的全部livar thisliall=$("#questionDiv ul li");//显示的全部livar thisli=new Array();thisliall.each(function(){if(!$(this).is(":hidden")){thisli.push($(this));}});//当前选中的li标签var activeLi=$("#questionDiv ul li[class='active']");//文本域jq对象var $textarea=$(this);//下一个需要选中的livar $nextLi;//下一行是否是第一行var firstFlag=false;//上一行是否是最后一行var lastFlag=false;//如果没有选中的数据if(activeLi && activeLi.length==0){//向上 添加最后一行作为下一个需要选中的liif(keyCode==38){$nextLi=$(thisli[thisli.length-1]);lastFlag=true;//向上滚动srollUpFun($nextLi,lastFlag);//向下 添加第一行作为下一个需要选中的li }else if(keyCode==40){$nextLi=$(thisli[0]);firstFlag=true;//向下滚动srollDownFun($nextLi,firstFlag);}//如果有选中的数据}else{//向上 递归选中上一行if(keyCode==38){$nextLi=getPrevShowLi(activeLi);//如果没有上一行,则设置第一行为下一行if($nextLi && $nextLi.length==0){$nextLi=$(thisli[thisli.length-1]);lastFlag=true;}//向上滚动srollUpFun($nextLi,lastFlag);//向下 递归选中下一行}else if(keyCode==40){$nextLi=getNextShowLi(activeLi);//如果没有下一行,则设置第一行为下一行if($nextLi && $nextLi.length==0){$nextLi=$(thisli[0]);firstFlag=true;}//向下滚动srollDownFun($nextLi,firstFlag);}}//清除当前选中activeLi.removeClass("active");//下一个li添加选中$nextLi.addClass("active");//下拉框回写数据selectProblemData($nextLi,$textarea);}});
d、空白处点击事件
JavaScript
//点击空白处隐藏删除下拉框
$(document).click(function(e){$("#questionDiv").remove();
});
e、提取方法
JavaScript
/**根据输入值 显示问题项目 下拉框显示效果
*/
function selectProblemShow(inputVal){//先显示下拉框$("#questionDiv").show();//获取全部数据var li=$("#questionDiv").find("ul li");//没有数据时,不显示下拉框if(li && li.length==0){$("#questionDiv").hide();}//li的总数var totalli=li.length;//隐藏li的总数var hiddenLiCount=0;//遍历lili.each(function(){//问题内容var questionContent=$(this).find("span").html();//去除高亮标签re1 = new RegExp("<b>","g"); re2 = new RegExp("</b>","g"); //获取原始内容if(questionContent){questionContent=questionContent.replace(re1,'').replace(re2,'')}//重新设置原始内容$(this).find("span").html(questionContent);//该项内容不包含输入的数据,隐藏该项if(questionContent.indexOf(inputVal)==-1){$(this).hide();}else{//该项内容包含输入的数据,显示该项$(this).show();//输入内容不为空时if(inputVal){//高亮显示var values=questionContent.split(inputVal);//填充数据$(this).find("span").html(values.join("<b>"+inputVal+"</b>"));}}//如果元素隐藏,计数if($(this).is(':hidden')){hiddenLiCount++;}});//全部隐藏,隐藏下拉框if(totalli==hiddenLiCount){$("#questionDiv").hide();}
}/**
下拉框回写数据
*/
function selectProblemData($li,$textarea){//获取问题内容var questionContent=$li.find("span").html();re1 = new RegExp("<b>","g"); re2 = new RegExp("</b>","g"); //处理高亮标签if(questionContent){questionContent=questionContent.replace(re1,'').replace(re2,'');}//严重程度var severityLevel=$li.find("span").attr("severityLevel");//设置内容$textarea.val(questionContent);//设置严重程度$textarea.parent().next().find("div.dropdown").dropdown('set selected',severityLevel);$("textArea").autoTextarea({minHeight:28,maxHeight:220,//文本框是否自动撑高,默认:null,不自动撑高;如果自动撑高必须输入数值,该值作为文本框自动撑高的最大高度});
}/**
递归获取下一个显示的li
*/
function getNextShowLi($li){//获取下一个元素var next=$li.next();//判断是隐藏if(next.is(":hidden")){//继续获取下一个元素next=getNextShowLi(next);}return next;
}/**
递归获取上一个显示的li
*/
function getPrevShowLi($li){//获取上一个元素var prev=$li.prev();//判断是隐藏if(prev.is(":hidden")){//继续获取上一个元素prev=getPrevShowLi(prev);}return prev;
}/**下拉框 向下选择 选择li超过可见区域时,滚动到li的位置
*/
function srollDownFun($li,firstFlag){//下拉框容器var container = $('#questionDiv');//下一行不是第一行,计算向下滚动if(!firstFlag){//获取可见区域li的绝对高度var tempTop=$li.offset().top - container.offset().top;//获取下拉框的高度var questionDivHeight=$("#questionDiv").innerHeight()+2;//判断可见区域最后一个li的绝对高度(包括本身的高度,取li的左下角的位置)大于下拉框高度if(tempTop+$li.height()>questionDivHeight){//滚动 -5(padding)container.animate({scrollTop: $li.offset().top - container.offset().top + container.scrollTop()-5},0);}}else{//是第一行,重置滚动条位置container.animate({scrollTop: 0},0);}
}/**
下拉框 向上选择 选择li超过可见区域时,滚动到li的位置
*/
function srollUpFun($li,lastFlag){//下拉框容器var container = $('#questionDiv');//上一行不是最后一行,计算向上滚动if(!lastFlag){//下一个需要显示的li绝对高度 li的Y坐标-容器的Y坐标var tempTop=$li.offset().top - container.offset().top;//获取下拉框的高度var questionDivHeight=$("#questionDiv").innerHeight()+2;//当绝对高度小于0时 说明被遮挡了if(tempTop<0){//滚动 滚动条的高度减去 负的绝对高度 -5(padding)container.animate({scrollTop: container.scrollTop()-(-tempTop)-5},0);}}else{//上一行是最后一行,滚动条滚动到底部var scrollHeight = $('#questionDiv').prop("scrollHeight");//滚动container.animate({scrollTop: scrollHeight},0);}
}
四、效果
1、点击效果
2、模糊检索,高亮效果
3、方向键下 选择第一条效果
4、选择完成效果
5、点击回显效果
文本域 自定义下拉框 支持模糊检索 关键字高亮 上下选择相关推荐
- java学习笔记(22)java输入标签,单选框,复选框,添加文件,文本域,下拉框
通过输入标签来制作如图所示的输入框: <body>账号:<input type="text" /><br />密码:<input type ...
- HTML -- HTML文本框、单选框、多选框、按钮、文本域、文件域、下拉框、搜索框滑动和简单验证
1. HTML文本框.单选框.多选框.按钮.文本域.文件域.下拉框.搜索框滑动和简单验证 1.1 表单元素格式 placeholder 提示文本. 示例: <!DOCTYPE html> ...
- Combo( 自定义下拉框) 组件
本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方法,这个组件依赖于 ValidateBox(验证框)组件 一. 加载方式 自定义下拉框不能通过标签的方式进行创建. <in ...
- 【EasyUI篇】Combo自定义下拉框组件
微信公众号:程序yuan 关注可了解更多的教程.问题或建议,请公众号留言; 查看--> 全套EasyUI示例目录 20.Combo自定义下拉框组件 这组件不可以通过class方式进行定义 JSP ...
- python爬取下拉列表数据_Python+selenium之获取文本值和下拉框选择数据
Python+selenium之获取文本值和下拉框选择数据 一.结合实例进行描述 1. 实例如下所示: #新增标签操作 def func_labels(self): self.driver.find_ ...
- uniapp 自定义下拉框
uniapp 自定义下拉框 根据 https://gitee.com/kcren/uniapp-dropdown-filter/tree/master 自己加了一层封装 可以进行切换选择下拉内容 模板 ...
- autojs自定义下拉框
牙叔教程 简单易懂 使用场景 自定义下拉框spinner 效果展示 git动图较大, 稍等片刻, 马上就好 autojs版本 8.8.12-0 萌新三连问 我要改背景 我要改字体颜色 我改了下拉框数据 ...
- css自定义下拉框样式
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...
- select美化自定义下拉框样式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
最新文章
- linux 检测添加磁盘空间,Linux构造磁盘空间满的测试环境
- python实现kmean算法_K-means聚类算法的Python实现,Kmeans
- tcp测试监听工具_linux 下两款网络性能测试工具介绍
- 存储过程实例(用存储过程获取单张表的总记录数)
- lavas自动创建目录及说明
- The Innovation | 谁是蛋白质和核酸的失踪的“媒人”?
- Git和Code Review流程
- 弘辽科技:淘宝直通车点击量是什么意思?直通车点击量怎么提升?
- 360手机如何修改服务器,360路由器手机怎么设置_手机如何设置360路由器? - 192路由网...
- vue 全屏背景图片 别看其他的了看我这篇就解决了!
- 网页设计之CSS3精要
- 用Python绘制折线图(上)
- MATLAB:预设矩阵的大小与不预设的时间差距
- php7 libevent扩展,php7下安装event扩展方法
- IO IR 个人作业汇总——康熙
- Android关于第三方h5在webview调用摄像头及相机的处理
- mLife | 朱永官院士提出生态系统微生物组学
- iptables实现华为云服务器无公网IP上网
- Delphi 用IdFtp控件实现ftp的全目录下载
- POS单上的商户编号解释
热门文章
- 计算机应用有作业吗,计算机应用基础_作业1
- Android实现关机代码
- 把Vue项目打包为桌面应用(nwjs)
- 关于使用PyQt5时报错This application failed to start because no Qt platform plugin could be initialized及后续问题
- MySQL之——函数
- 手持振弦传感器VH03读数仪测读仪频率仪地质灾害土木工程自动化监测
- contiki学习心路历程
- 计算机组成原理 第三章存储系统 知识点
- python将对象放入列表_将C对象添加到Python List并将C对象列表返回给python
- excel部分内容有问题xml的修复