转载自:文本域 自定义下拉框 支持模糊检索 关键字高亮 上下选择

一、需求

需要创建一个常见问题库,填写存在问题时可以下拉选择,可以模糊搜索,也可以手写。如果选择了问题库中的内容,自动填充内容到存在问题中,并且自动选择严重程度,最终保存的值还是界面显示的内容。

二、可行性研究

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、点击回显效果

文本域 自定义下拉框 支持模糊检索 关键字高亮 上下选择相关推荐

  1. java学习笔记(22)java输入标签,单选框,复选框,添加文件,文本域,下拉框

    通过输入标签来制作如图所示的输入框: <body>账号:<input type="text" /><br />密码:<input type ...

  2. HTML -- HTML文本框、单选框、多选框、按钮、文本域、文件域、下拉框、搜索框滑动和简单验证

    1. HTML文本框.单选框.多选框.按钮.文本域.文件域.下拉框.搜索框滑动和简单验证 1.1 表单元素格式 placeholder 提示文本. 示例: <!DOCTYPE html> ...

  3. Combo( 自定义下拉框) 组件

    本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方法,这个组件依赖于 ValidateBox(验证框)组件 一. 加载方式 自定义下拉框不能通过标签的方式进行创建. <in ...

  4. 【EasyUI篇】Combo自定义下拉框组件

    微信公众号:程序yuan 关注可了解更多的教程.问题或建议,请公众号留言; 查看--> 全套EasyUI示例目录 20.Combo自定义下拉框组件 这组件不可以通过class方式进行定义 JSP ...

  5. python爬取下拉列表数据_Python+selenium之获取文本值和下拉框选择数据

    Python+selenium之获取文本值和下拉框选择数据 一.结合实例进行描述 1. 实例如下所示: #新增标签操作 def func_labels(self): self.driver.find_ ...

  6. uniapp 自定义下拉框

    uniapp 自定义下拉框 根据 https://gitee.com/kcren/uniapp-dropdown-filter/tree/master 自己加了一层封装 可以进行切换选择下拉内容 模板 ...

  7. autojs自定义下拉框

    牙叔教程 简单易懂 使用场景 自定义下拉框spinner 效果展示 git动图较大, 稍等片刻, 马上就好 autojs版本 8.8.12-0 萌新三连问 我要改背景 我要改字体颜色 我改了下拉框数据 ...

  8. css自定义下拉框样式

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

  9. select美化自定义下拉框样式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

最新文章

  1. linux 检测添加磁盘空间,Linux构造磁盘空间满的测试环境
  2. python实现kmean算法_K-means聚类算法的Python实现,Kmeans
  3. tcp测试监听工具_linux 下两款网络性能测试工具介绍
  4. 存储过程实例(用存储过程获取单张表的总记录数)
  5. lavas自动创建目录及说明
  6. The Innovation | 谁是蛋白质和核酸的失踪的“媒人”?
  7. Git和Code Review流程
  8. 弘辽科技:淘宝直通车点击量是什么意思?直通车点击量怎么提升?
  9. 360手机如何修改服务器,360路由器手机怎么设置_手机如何设置360路由器? - 192路由网...
  10. vue 全屏背景图片 别看其他的了看我这篇就解决了!
  11. 网页设计之CSS3精要
  12. 用Python绘制折线图(上)
  13. MATLAB:预设矩阵的大小与不预设的时间差距
  14. php7 libevent扩展,php7下安装event扩展方法
  15. IO IR 个人作业汇总——康熙
  16. Android关于第三方h5在webview调用摄像头及相机的处理
  17. mLife | 朱永官院士提出生态系统微生物组学
  18. iptables实现华为云服务器无公网IP上网
  19. Delphi 用IdFtp控件实现ftp的全目录下载
  20. POS单上的商户编号解释

热门文章

  1. 计算机应用有作业吗,计算机应用基础_作业1
  2. Android实现关机代码
  3. 把Vue项目打包为桌面应用(nwjs)
  4. 关于使用PyQt5时报错This application failed to start because no Qt platform plugin could be initialized及后续问题
  5. MySQL之——函数
  6. 手持振弦传感器VH03读数仪测读仪频率仪地质灾害土木工程自动化监测
  7. contiki学习心路历程
  8. 计算机组成原理 第三章存储系统 知识点
  9. python将对象放入列表_将C对象添加到Python List并将C对象列表返回给python
  10. excel部分内容有问题xml的修复