如何让jQuery Autocomplete只替换某些单词 - 而不是完整的字符串?

时间:2010-12-25 01:48:30

标签: jquery jquery-autocomplete

我正在使用bassistance.de jQuery Autocomplete功能。

像“你好@john”这样的文字 我做了,自动完成仅在字符@在单词时运行。 但是当我点击所需的项目时,它会取代我的全文。 我怎么能这样做 - 只更换“@john”? 或者也许还有另一个jQuery的Autocomplete插件,它有这样的能力吗?

$('#input_line').autocomplete('data.php', {
   extraParams: {input: function() {
           return GetTextareaWord("input_line");
       }
   }
});

2 个答案:

答案 0 :(得分:1)

正如您为自动填充插件发布的链接所述

  

此插件已弃用,不是   发展了。它的继任者是   jQuery UI的一部分。

我建议您查看jQueryUI autocomplete。使用该插件,您可以bind a custom event handler to the select event(在选择列表中的项目时触发):

$( ".selector" ).autocomplete({
   select: function(event, ui) { ... }
});

取消默认事件(替换字段的整个值),并使用您自己的逻辑来适当地更新字段(在这种情况下,它可能只是将值插入用户光标所在的文本字段中)在那个时间点。)

似乎可行,特别是如果您已经想出如何只在需要时显示自动完成菜单。

答案 1 :(得分:1)

我一直在研究与自动完成标签非常相似的东西。我有一些基本的代码工作,但我有点惭愧在这里发布,因为它是边缘垃圾。它需要大量的清洁和重构,我将在接下来的几天内完成。然而,它以类似于@Andrew建议的方式完成了你所需要的工作。

<!DOCTYPE html>
<html>
  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>jQuery UI Example Page</title>
    <link type="text/css" href="../css/smoothness/jquery-ui-1.8.7.custom.css" rel="stylesheet" /> 
    <script type="text/javascript" src="../js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="../js/jquery-ui-1.8.7.custom.min.js"></script>

    <script type="text/javascript">
      $(function() {

        var availableTags = [
          "ActionScript", "AppleScript", "Asp", "BASIC", "C",
          "C++", "Clojure", "COBOL", "ColdFusion", "Erlang",
          "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp",
          "Perl", "PHP", "Python", "Ruby", "Scala", "Scheme"
        ];       


        function getCaretPosition(e) {

          var p = -1;

          if (document.selection) {
            e.focus();
            var s = document.selection.createRange();
            s.moveStart('character', -e.value.length);
            p = s.text.length;
          } else if (e.selectionStart || e.selectionStart == '0') {
            p = e.selectionStart;
          }                      

          return p;

        }

        function getPreviousCaretPosition(e) {

          var s = e.value;
          var i = getCaretPosition(e) - 1;

          while (i >= 0 && s[i] != ' ') { i = i - 1; }                         
          return i;

        }

        function getTerm(s, p) {                             
          var i = p - 1;          
          while (i >= 0 && s[i] != ' ') { i = i - 1; }                         
          return s.substring(i + 1, p);          
        }


        $( "#tags" )
          .bind( "keydown", function( event ) {
            if ( event.keyCode === $.ui.keyCode.TAB &&
                $( this ).data( "autocomplete" ).menu.active ) {
              event.preventDefault();
            }
          })
          .autocomplete({
            minLength: 2,
            source: function(request, response) {    
              var t = getTerm(this.element[0].value, getCaretPosition(this.element[0])); 
              if (t[0] != '#') {
                return false;
              }

              // delegate back to autocomplete, but extract the last term
              response( $.ui.autocomplete.filter(
                availableTags, t.substring(1, t.length) ) );

              return true;

            },
            focus: function() {
              return false;
            },           
            search: function(event, ui) {
              return true;
            },
            select: function(event, ui) {             
              var current = getCaretPosition(this);
              var previous = getPreviousCaretPosition(this);                             
              this.value = this.value.substring(0, previous) + 
                ' #' + ui.item.value + ' ' + this.value.substring(current);              
              return false;     

            }
          });

      });
    </script>

  </head>
<body>
  <div id="container">

    <div id="content">
      <div id="main"> 

        <div class="item">
          <div class="title">
            <h2>hash-tag-autocomplete</h2>
          </div>
        </div>

        <div class="item">
          <form class="simpleform">
            <p><textarea id="tags" rows="5" style="width:100%"></textarea><p>
            <p><input type="submit"/><p>
          </form>
        </div>

      </div>
    </div>

  </div>
</body>
</html>

我将在接下来的几天内使用此功能,并将其打包为jQuery插件。我将尝试将此代码的新版本发布为新答案。

更新

试图让事情更清洁。您可以使用您首选的获取和设置插入符号的方式而不是我获得的功能。

<!DOCTYPE html>
<html>
  <head>

    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>jQuery UI Example Page</title>
    <link type="text/css" href="../css/smoothness/jquery-ui-1.8.7.custom.css" rel="stylesheet" /> 
    <script type="text/javascript" src="../js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="../js/jquery-ui-1.8.7.custom.min.js"></script>

    <script type="text/javascript">
      $(function() {

        var availableTags = [
          "ActionScript",  "AppleScript", "Asp", "BASIC", "C", "C++",
          "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy",
          "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python",
          "Ruby", "Scala", "Scheme"
        ];       

        function getCaretPosition(e) {    
            if (typeof e.selectionStart == 'number') {
                return e.selectionStart;
            } else if (document.selection) {
                var range = document.selection.createRange();
                var rangeLength = range.text.length;
                range.moveStart('character', -e.value.length);
                return range.text.length - rangeLength;
            }
        };   

        function setCaretPosition(e, start, end) {
            if (e.createTextRange) {
                var r = e.createTextRange();
                r.moveStart('character', start);
                r.moveEnd('character', (end || start));
                r.select();
            } else if (e.selectionStart) {
                e.focus();
                e.setSelectionRange(start, (end || start));
            }
        };

        function getWordBeforeCaretPosition(e) {    
            var s = e.value;
            var i = getCaretPosition(e) - 1;
            while (i >= 0 && s[i] != ' ') {
                i = i - 1;
            }             
            return i + 1;    
        };

        function getWordBeforeCaret(e) {  
          var p = getWordBeforeCaretPosition(e);
          var c = getCaretPosition(e);  
          return e.value.substring(p, c);    
        };

        function replaceWordBeforeCaret(e, word) {
            var p = getWordBeforeCaretPosition(e);
            var c = getCaretPosition(e);        
            e.value = e.value.substring(0, p) + word + e.value.substring(c);
            setCaretPosition(e, p + word.length);                     
        };


        $( "#tags" )
          .bind("keydown", function(event) {
            if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active ) {
              event.preventDefault();
            }
          })
          .autocomplete({
            minLength: 0,
            source: function(request, response) {                 
              var w = getWordBeforeCaret(this.element[0]);  
              if (w[0] != '#') {
                this.close();
                return false;
              }             
              response($.ui.autocomplete.filter(availableTags, w.substring(1, w.length)));                
              return true;             
            },
            focus: function() {
              return false;
            },           
            search: function(event, ui) {
              return true;
            },
            select: function(event, ui) {             
              replaceWordBeforeCaret(this, '#' + ui.item.value + ' ');              
              return false;                   
            }
          }); 
      });
    </script>

  </head>
<body>
  <h2>hash-tag-autocomplete</h2>
  <form>
    <p><textarea id="tags" rows="5" style="width:100%"></textarea><p/
    <p><input type="submit"/><p>
  </form>
</body>
</html>

我真的很感激有关此的任何反馈。