2012-07-08 17 views
0

我正面临着最新的jQuery组合框的问题。用例如下所述。如果文本被用户删除,将jQuery组合框的文本恢复为选定选项的文本?

  1. 我在组合框中输入了一些东西,它提供了所有匹配选项,并选择了其中一个匹配选项。这将组合框文本设置为所选项目的文本。
  2. 现在,我关注组合框,然后回到组合框并删除所有文本,但不选择其他项目。 即使所选值存在,组合框也会显示空白文本。这对我来说不是很直观,因为空白文本应该表示没有选项被选中。

说明这个问题的视频可以在这里找到:http://screencast.com/t/QLUtZYsL2

这是我的目标在上面的用例: 我想确保的情况下,用户以某种方式删除组合框文本,然后在离开组合框时,文本会恢复到所选项目的文本。

使用jQuery组合框示例html页面如下所示。

<!doctype html> 
<html> 
<head> 
<meta charset="utf-8"> 
<title>jQuery UI Example Page</title> 
<link type="text/css" href="css/cupertino/jquery-ui-1.8.21.custom.css" rel="stylesheet" /> 
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.21.custom.min.js"></script> 
<script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script> 
<style> 
.ui-combobox { 
    position: relative; 
    display: inline-block; 
} 
.ui-combobox-toggle { 
    position: absolute; 
    top: 0; 
    bottom: 0; 
    margin-left: -1px; 
    padding: 0; 
    /* adjust styles for IE 6/7 */ 
    *height: 1.7em; 
    *top: 0.1em; 
} 
.ui-combobox-input { 
    margin: 0; 
    padding: 0.3em; 
} 
</style> 
<script type="text/javascript"> 
    (function ($) { 
     $.widget("ui.combobox", { 
      _create: function() { 
       var input, 
       self = this, 
       select = this.element.hide(), 
       selected = select.children(":selected"), 
       value = selected.val() ? selected.text() : "", 
       wrapper = this.wrapper = $("<span>") 
        .addClass("ui-combobox") 
        .insertAfter(select); 

       input = $("<input>") 
       .appendTo(wrapper) 
       .val(value) 
       .addClass("ui-state-default ui-combobox-input") 
       .autocomplete({ 
        delay: 0, 
        minLength: 0, 
        source: function (request, response) { 
         var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); 
         response(select.children("option").map(function() { 
          var text = $(this).text(); 
          if (this.value && (!request.term || matcher.test(text))) 
           return { 
            label: text.replace(
             new RegExp(
              "(?![^&;]+;)(?!<[^<>]*)(" + 
              $.ui.autocomplete.escapeRegex(request.term) + 
              ")(?![^<>]*>)(?![^&;]+;)", "gi" 
             ), "<strong>$1</strong>"), 
            value: text, 
            option: this 
           }; 
         })); 
        }, 
        select: function (event, ui) { 
         ui.item.option.selected = true; 
         self._trigger("selected", event, { 
          item: ui.item.option 
         }); 
        }, 
        change: function (event, ui) { 
         if (!ui.item) { 
          var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"), 
           valid = false; 
          select.children("option").each(function() { 
           if ($(this).text().match(matcher)) { 
            this.selected = valid = true; 
            return false; 
           } 
          }); 
          if (!valid) { 
           // remove invalid value, as it didn't match anything 
           $(this).val(""); 
           select.val(""); 
           input.data("autocomplete").term = ""; 
           return false; 
          } 
         } 
        } 
       }) 
       .addClass("ui-widget ui-widget-content ui-corner-left"); 

       input.data("autocomplete")._renderItem = function (ul, item) { 
        return $("<li></li>") 
        .data("item.autocomplete", item) 
        .append("<a>" + item.label + "</a>") 
        .appendTo(ul); 
       }; 

       $("<a>") 
       .attr("tabIndex", -1) 
       .attr("title", "Show All Items") 
       .appendTo(wrapper) 
       .button({ 
        icons: { 
         primary: "ui-icon-triangle-1-s" 
        }, 
        text: false 
       }) 
       .removeClass("ui-corner-all") 
       .addClass("ui-corner-right ui-combobox-toggle") 
       .click(function() { 
        // close if already visible 
        if (input.autocomplete("widget").is(":visible")) { 
         input.autocomplete("close"); 
         return; 
        } 

        // work around a bug (likely same cause as #5265) 
        $(this).blur(); 

        // pass empty string as value to search for, displaying all results 
        input.autocomplete("search", ""); 
        input.focus(); 
       }); 
      }, 

      destroy: function() { 
       this.wrapper.remove(); 
       this.element.show(); 
       $.Widget.prototype.destroy.call(this); 
      } 
     }); 
    })(jQuery); 

    $(function() { 
     $("#combobox").combobox(); 
     $("#toggle").click(function() { 
      $("#combobox").toggle(); 
     }); 
    }); 
</script> 
</head> 
<body> 
<div class="demo"> 
    <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> 
</div> 
<!-- End demo --> 
</body> 
</html> 

回答

0

我终于找到了一条出路,但让我从一些建设性的批评开始。 jQuery就像ROCKET SCIENCE一样。大声笑。 jQuery没有一个直观的事件模型,并在这个领域的JavaScript挫败jQuery。我花了好几个小时试图解决jQuery组合框中的变化或模糊或聚焦事件,但没有取得任何成功。因此,解决我在第一篇文章中提到的问题的最佳解决方案是遵循下面给出的两种方法之一。

  1. 无论是模糊或focusOut事件附加到jQuery的组合框的父。例如,div可以是父级,因为它内部具有jQuery组合框。看下面的代码。

    $(document).ready(function() { 
        $("#dropdown_sel").combobox(); 
        $($('.ui-combobox-input')[0]).css('width', '500px'); 
        $("#toggle").click(function() { 
         $("#dropdown_sel").toggle(); 
        }); 
        //line below attaches the focusout event 
        $('#dropdown_sel').parent().bind('focusout', function() { if ($.trim($('#dropdown_sel option:selected').val()) != '') { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:selected').text()); } }); 
    }); 
    
  2. 或将blur或focusout事件附加到jQuery组合框的输入元素。看下面的代码。

    $(document).ready(function() { 
        $("#dropdown_sel").combobox(); 
        $($('.ui-combobox-input')[0]).css('width', '500px'); 
        $("#toggle").click(function() { 
         $("#dropdown_sel").toggle(); 
        }); 
        //line below attaches the focusout event 
        $('#dropdown_sel').next().find('input').bind('focusout', function() { if ($.trim($('#dropdown_sel option:selected').val()) != '') { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:selected').text()); } }); 
    }); 
    

如果要选择默认的第一个选项,以提示用户,则代码用于附接focusOut事件将被改变为如下。一个else部分被添加到事件的逻辑中,其中input元素的文本被设置为第一个选项的文本。

$('#dropdown_sel').next().find('input').bind('focusout', function() { if ($.trim($('#dropdown_sel option:selected').val()) != '') { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:selected').text()); } else { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:first').text()); } }); 
0

你可以利用的变化情况来缓存当前选定的文本和值,然后使用事件的内容或模糊事件,以确保当你离开文本不保持空白。如果您可以发布代码示例,我可以修改它以向您显示我在说什么。

+0

我已在我的文章中粘贴了带有组合框的html页面的完整工作版本。只需替换jquery网址并准备好即可。 – Sunil 2012-07-08 22:39:23

+0

Sunil,我试着把你的代码示例放入jsfiddle中,但它似乎有一些问题。你可以看一下吗? http://jsfiddle.net/csharpster/UDdkT/ – 2012-07-23 15:20:13

相关问题