自制可输入式下拉框

5 篇文章 0 订阅
4 篇文章 0 订阅

在实际应用场景中经常会碰到系统自带的select下拉框会不满足客户需求的情况,比如下拉内容太多,用户找不过来,即使按照首字母规则排序后也很难满足客户要求,这时候能有一个输入框输入关键字之后,然后下拉选项出现一些想要的内容就是很不错的选择了

应用技术:html,css,javascript,jquery,ajax,c#,asp.net,sqlserver数据库

1.思路整理
使用input和div代替select控件,通过对input注册聚焦失焦事件控制div的显示隐藏来完成select下拉的模拟,div的内容根据input输入的关键字实时获取数据库相关的信息,点击div的内容将完整的信息填入input中,即完成select的模拟

2.前端效果实现
(1)创建一个input,样式position属性设置为relative,紧跟后面创建一个div,样式position属性设置为absolute,设置1px的边框方便观看,并调整top的值,使其顶端正好处于input底端(默认应该就是这样,不用调整top值),在div内部再创建多个div,填充相关内容,然后对其内部的div都注册上鼠标移入移出事件,用于改变内部div的背景色,再注册一个鼠标按下事件用于把点击的那个内容显示到input中

(2)首先隐藏这个div,然后对input标签注册聚焦失焦事件,聚焦后显示这个div,其次需要注意的是失焦的这个情况,在点击input框触发聚焦后,显示div,接下来有1种情况需要考虑:
用户点击了div中的内容,这时候实际上是先触发input的失焦事件的,但input的失焦是让div隐藏的,所以用户点不到div,也就触发不了div的点击事件,这里我的处理方式是在input的失焦事件中的处理逻辑延时执行,可以使用计时器处理

(3)代码展示
html

	<form id="form1" runat="server">
        <div>
            <input id="select-input" name="select-input" style="position:relative" />
            <div id="searchDiv" style="display:none;">
                <div name="searchDiv1">111111111111</div>
                <div name="searchDiv1">222222222222</div>
                <div name="searchDiv1">333333333333</div>
                <div name="searchDiv1">444444444444</div>
            </div>
        </div>
    </form>

css

#searchDiv { 
        border:black 1px solid;
        position:absolute;
        width:300px;
   	}

javascript

	$(document).on("mouseover","div[name=searchDiv1]",function(){
        this.style.backgroundColor='blue';
    });
    $(document).on("mouseout","div[name=searchDiv1]",function(){
        this.style.backgroundColor='white';
    });

    //这里的作用是当点击下拉内容时,把对应的值赋给文本框,达到select的效果(这里不用做下拉的隐藏,因为当用户点击下拉内容的同时会触发input的失焦blur)
    //注意:为什么这里用的是鼠标按下事件onmousedown而不是点击事件onclick,
    //点击的触发条件鼠标按下再抬起才会触发, 当鼠标按下时会触发input失焦,会隐藏下拉内容,所以如果注册的是onclick事件,那么很容易点不到下拉内容,所以注册的是鼠标按下时就触发
    $(document).on("mousedown","div[name=searchDiv1]",function(){
        $("#select-input").val(this.innerText);
    });
    $("#select-input").on("focus", function () {
        $("#searchDiv").show();
    })

    //失焦后延时10ms执行,避免失焦后searchDiv立即隐藏点不到里面的元素的问题
    $("#select-input").on("blur", function () {
        setTimeout(function(){
            $("#searchDiv").hide();
        },"10")
    })

(4)效果展示
在这里插入图片描述
以上就完成了最简单的自制下拉框的功能,接下来就需要将数据库的内容填充给下拉框,自制下拉框的一个难点就在于避免各个事件的相互影响,如input聚焦后,下拉内容展示,点击下拉内容会先触发input失焦

3.后台数据制作(sqlserver数据库)

CREATE TABLE table1(
	tab_id INT IDENTITY(1,1) PRIMARY KEY,
	tab_name VARCHAR(100)
)
INSERT INTO table1(tab_name) values('上海浦东新区公司')
INSERT INTO table1(tab_name) values('上海徐汇区公司')
INSERT INTO table1(tab_name) values('上海公司')
INSERT INTO table1(tab_name) values('上海徐汇区公司')
INSERT INTO table1(tab_name) values('南京分公司1')
INSERT INTO table1(tab_name) values('南京分公司2')
INSERT INTO table1(tab_name) values('南京分公司3')
INSERT INTO table1(tab_name) values('南京分公司4')
INSERT INTO table1(tab_name) values('北京分公司1')
INSERT INTO table1(tab_name) values('北京分公司2')
INSERT INTO table1(tab_name) values('北京分公司3')

4.ashx程序编写

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Web;

namespace WebAppTest
{
    /// <summary>
    /// testHandler 的摘要说明
    /// </summary>
    public class testHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            //获取数据库操作对象
            string constr = "Server=.;integrated security=SSPI;Initial Catalog=testDB";
            SqlConnection sqlConnection = new SqlConnection(constr);
            sqlConnection.Open();
            SqlCommand sqlCommand;
            if (context.Request["param"] == "getContentAll")
            {
                sqlCommand = new SqlCommand("SELECT * FROM table1", sqlConnection);
            }
            else
            {
                sqlCommand = new SqlCommand("SELECT * FROM table1 WHERE tab_name LIKE '%"+ context.Request["KeyID"] + "%'", sqlConnection);
            }
            
            SqlDataAdapter sda = new SqlDataAdapter(sqlCommand);
            DataTable dt = new DataTable();
            sda.Fill(dt);
            sqlConnection.Close();
            context.Response.Write(table2json(dt));
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public static string table2json(DataTable dt)
        {
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                sb.Append("{");
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    if (j == dt.Columns.Count - 1)
                    {
                        sb.Append("\"" + dt.Columns[j].Caption + "\":\"" + dt.Rows[i][j].ToString() + "\"");
                    }
                    else
                    {
                        sb.Append("\"" + dt.Columns[j].Caption + "\":\"" + dt.Rows[i][j].ToString() + "\",");
                    }

                }
                if (i == dt.Rows.Count - 1)
                {
                    sb.Append("}");
                }
                else
                {
                    sb.Append("},");
                }
            }
            sb.Append("]");
            return sb.ToString();
        }
    }
}

5.前端代码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebFormTest.aspx.cs" Inherits="WebAppTest.WebFormTest" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <style type="text/css">
        #searchDiv { 
            border:black 1px solid;
            position:absolute;
            width:300px;
        }

    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <input id="select-input" name="select-input" style="position:relative" />
            <div id="searchDiv" style="display:none;">
                <div name="searchDiv1">111111111111</div>
                <div name="searchDiv1">222222222222</div>
                <div name="searchDiv1">333333333333</div>
                <div name="searchDiv1">444444444444</div>
            </div>
        </div>
    </form>
</body>
<script src="jquery-3.3.1.min.js" charset="utf-8"></script>
    
<script type="text/javascript">
	//鼠标移入移出的背景色设置
    $(document).on("mouseover","div[name=searchDiv1]",function(){
        this.style.backgroundColor='blue';
    });
    $(document).on("mouseout","div[name=searchDiv1]",function(){
        this.style.backgroundColor='white';
    });

    //这里的作用是当点击下拉内容时,把对应的值赋给文本框,达到select的效果(这里不用做下拉的隐藏,因为当用户点击下拉内容的同时会触发input的失焦blur)
    //注意:为什么这里用的是鼠标按下事件onmousedown而不是点击事件onclick,
    //点击的触发条件鼠标按下再抬起才会触发, 当鼠标按下时会触发input失焦,会隐藏下拉内容,所以如果注册的是onclick事件,那么很容易点不到下拉内容,所以注册的是鼠标按下时就触发
    $(document).on("mousedown","div[name=searchDiv1]",function(){
        $("#select-input").val(this.innerText);
    });
    $("#select-input").on("focus", function () {
        $("#searchDiv").show();
    })

    //失焦后延时10ms执行,避免失焦后searchDiv立即隐藏点不到里面的元素的问题
    $("#select-input").on("blur", function () {
        setTimeout(function(){
            $("#searchDiv").hide();
        },"10")
    })

    //对input注册keyup事件,用于实现模糊查询的效果
    $("#select-input").on("keyup", function () {
        $.ajax({
            url: 'testHandler.ashx',
            type: 'POST',
            data: {'param':'getContentByName','keyID':$('#select-input').val() },
            async:true,
            beforeSend: function () {

            },
            success: function (data) {
                var res = eval('(' + data + ')');
                var searchDiv = $("#searchDiv");
                $(searchDiv).empty();

                var content = "";
                for (var i = 0; i < res.length; i++) {
                    content += "<div name='searchDiv1' value='"+res[i].tab_id+"'>"+res[i].tab_name+"</div>";
                }
                $(searchDiv).html(content);
                
            }
        });
    })

    //下拉内容初始化
    $(document).ready(function () {
        $.ajax({
            url: 'testHandler.ashx',
            type: 'POST',
            data: {'param':'getContentAll' },
            async:true,
            beforeSend: function () {

            },
            success: function (data) {
                var res = eval('(' + data + ')');
                var searchDiv = $("#searchDiv");
                $(searchDiv).empty();

                var content = "";
                for (var i = 0; i < res.length; i++) {
                    content += "<div name='searchDiv1' value='"+res[i].tab_id+"'>"+res[i].tab_name+"</div>";
                }
                $(searchDiv).html(content);
                
            }
        });
    })
</script>

</html>

6.效果展示
在这里插入图片描述
基本的实时对接后台的可搜索式下拉框已完成,当然在真实项目上肯定会对美观上有要求的,且数据量也不会这么少,选中相关的选项之后可能也会有后续的处理等等,当然,万变不离其中,只要知道了原理,这些的改变都是锦上添花,下面给出实际项目的展示图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值