• jQuery UI Autocomplete Combobox 配 ASP.NET DropDownList


    0.引言

     

    1.起因

            
            一开始使用Autocomplete做了一个自动补全的文本框,如上图。后来因业务需要希望能在这个文本框的边上做个下拉列表按钮,一按就展开所有支持自动补全的选项。于是在网上搜索了好久,需找类似的插件,最后却回到了原点。原来jQuery UI 官网Autocomplete介绍里面就有个叫做Combobox的东西(见下图)。
            (Combobox)
     
            因为官网上的Combobox用的是Select+Option,我一开始还犯愁,真正用的时候发现它其实可以完美匹配DropDownList。
            

    2.最终效果


     

    1.代码&分析

     

    1.代码

    官网Combobox示例代码
    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>jQuery UI Autocomplete - Combobox</title>
      <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
      <script src="//code.jquery.com/jquery-1.10.2.js"></script>
      <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
      <link rel="stylesheet" href="/resources/demos/style.css">
      <style>
      .custom-combobox {
        position: relative;
        display: inline-block;
      }
      .custom-combobox-toggle {
        position: absolute;
        top: 0;
        bottom: 0;
        margin-left: -1px;
        padding: 0;
      }
      .custom-combobox-input {
        margin: 0;
        padding: 5px 10px;
      }
      </style>
      <script>
      (function( $ ) {
        $.widget( "custom.combobox", {
          _create: function() {
            this.wrapper = $( "<span>" )
              .addClass( "custom-combobox" )// 此处设置整体span的class
              .insertAfter( this.element );
     
            this.element.hide();
            this._createAutocomplete();
            this._createShowAllButton();
          },
     
          _createAutocomplete: function() {
            var selected = this.element.children( ":selected" ),
              value = selected.val() ? selected.text() : "";
     
            this.input = $( "<input>" )
              .appendTo( this.wrapper )
              .val( value )
              .attr( "title", "" )
              .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )//此处设置input的class
              .autocomplete({
                delay: 0,
                minLength: 0,
                source: $.proxy( this, "_source" )
              })
              .tooltip({
                tooltipClass: "ui-state-highlight"
              });
     
            this._on( this.input, {
              autocompleteselect: function( event, ui ) {
                ui.item.option.selected = true;
                this._trigger( "select", event, {
                  item: ui.item.option
                });
              },
     
              autocompletechange: "_removeIfInvalid"
            });
          },
     
          _createShowAllButton: function() {
            var input = this.input,
              wasOpen = false;
     
            $( "<a>" )
              .attr( "tabIndex", -1 )
              .attr( "title", "Show All Items" )
              .tooltip()
              .appendTo( this.wrapper )
              .button({
                icons: {
                  primary: "ui-icon-triangle-1-s"
                },
                text: false
              })
              .removeClass( "ui-corner-all" )
              .addClass( "custom-combobox-toggle ui-corner-right" )// 此处设置下拉列表按钮的class
              .mousedown(function() {
                wasOpen = input.autocomplete( "widget" ).is( ":visible" );
              })
              .click(function() {
                input.focus();
     
                // Close if already visible
                if ( wasOpen ) {
                  return;
                }
     
                // Pass empty string as value to search for, displaying all results
                input.autocomplete( "search", "" );
              });
          },
     
          _source: function( request, response ) {
            var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
            response( this.element.children( "option" ).map(function() {
              var text = $( this ).text();
              if ( this.value && ( !request.term || matcher.test(text) ) )
                return {
                  label: text,
                  value: text,
                  option: this
                };
            }) );
          },
             // 移除input中补全失败的内容
          _removeIfInvalid: function( event, ui ) {
     
            // Selected an item, nothing to do
            if ( ui.item ) {
              return;
            }
     
            // Search for a match (case-insensitive)
            var value = this.input.val(),
              valueLowerCase = value.toLowerCase(),
              valid = false;
            this.element.children( "option" ).each(function() {
              if ( $( this ).text().toLowerCase() === valueLowerCase ) {
                this.selected = valid = true;
                return false;
              }
            });
     
            // Found a match, nothing to do
            if ( valid ) {
              return;
            }
     
            // Remove invalid value
            this.input
              .val( "" )
              .attr( "title", value + " didn't match any item" )
              .tooltip( "open" );
            this.element.val( "" );
            this._delay(function() {
              this.input.tooltip( "close" ).attr( "title", "" );
            }, 2500 );
            this.input.autocomplete( "instance" ).term = "";
          },
     
          _destroy: function() {
            this.wrapper.remove();
            this.element.show();
          }
        });
      })( jQuery );
     
      $(function() {
        $( "#combobox" ).combobox();
        $( "#toggle" ).click(function() {
          $( "#combobox" ).toggle();
        });
      });
      </script>
    </head>
    <body>
     
    <div class="ui-widget">
      <label>Your preferred programming language: </label>
      <select id="combobox">
        <option value="">Select one...</option>
        <option value="ActionScript">ActionScript</option>
        <option value="AppleScript">AppleScript</option>
        <option value="Asp">Asp</option>
        <option value="BASIC">BASIC</option>
        <option value="C">C</option>
        <option value="C++">C++</option>
        <option value="Clojure">Clojure</option>
        <option value="COBOL">COBOL</option>
        <option value="ColdFusion">ColdFusion</option>
        <option value="Erlang">Erlang</option>
        <option value="Fortran">Fortran</option>
        <option value="Groovy">Groovy</option>
        <option value="Haskell">Haskell</option>
        <option value="Java">Java</option>
        <option value="JavaScript">JavaScript</option>
        <option value="Lisp">Lisp</option>
        <option value="Perl">Perl</option>
        <option value="PHP">PHP</option>
        <option value="Python">Python</option>
        <option value="Ruby">Ruby</option>
        <option value="Scala">Scala</option>
        <option value="Scheme">Scheme</option>
      </select>
    </div>
    <button id="toggle">Show underlying select</button>
     
     
    </body>
    </html>
    View Code
     
    配合效果图和前台页面生成的 DOM 节点来分析

     
    1.原来的select被隐藏了
     
    2.外面是个span标签,内部是一个input标签(输入框)和一个a标签(下拉按钮)
    它们三的class分别对应为
    span .custom-combobox
    input .custom-combobox-input
    a .custom-combobox-toggle 
    可以通过它们的类名对它们进行操作和样式修改
     
    3.http://api.jqueryui.com/autocomplete/  有关Autocomplete插件更多的资料
     

    2.配合DropDownList

    只需将select标签换成一个DropDownList即可
    <asp:DropDownListID="combobox"runat="server"></asp:DropDownList>
    然后在C#中绑定想要自动填充的内容
    combobox.AutoPostBack = true;
    string sqlstr = "SELECT DISTINCT Config_Type FROM [EMS].[dbo].[EMS_Config]";
    using(var dt=SQLLocalEMS.ExecuteQuery(sqlstr, CommandType.Text))
    {
        if(dt!=null)
        {
            combobox.DataSource = dt;   
            combobox.DataTextField = "Config_Type";
            combobox.DataValueField = "Config_Type";
            combobox.DataBind();
        }
    }
     
     

    2.重复插入 combobox 的bug

     

    1.bug描述

    实际使用时发现每一次PostBack都会导致组成 combobox 的各DOM 节点被重复插入到页面底部
    如下图
    1:初始绑定 combobox时生成的
    2、3、4:PostBack页面时重复插入的
    4:当前真实使用的

    2.临时修复方法

    通过在每次插入新的 combobox 前,将之前插入的相关 DOM remove()
     
    _create: function() {
        //修复重复Insert的bug
        $(".ui-helper-hidden-accessible").remove();
        $(".ui-autocomplete").remove();
        this.wrapper = $( "<span>" )
          .addClass( "custom-combobox col-lg-11 padding0" )// 此处设置整体span的class
          .insertAfter( this.element );
        this.element.hide();
        this._createAutocomplete();
        this._createShowAllButton();
      },
     
     
     
     
     





  • 相关阅读:
    sklearn linear_model,svm,tree,naive bayes,ensemble
    便利过滤
    js下载
    小程序修改radio的大小
    el-tree 问题与需求
    jsp页面用html引入vue.js注意问题
    WebPack
    yarn
    vue-cli 4以上 vue.config.js
    Cannot find module 'core-js/modules/es6.regexp.constructor'
  • 原文地址:https://www.cnblogs.com/moonache/p/5422556.html
Copyright © 2020-2023  润新知