Как сделать так, чтобы jQuery Autocomplete заменял только определенное слово, а не полную строку? - PullRequest
2 голосов
/ 25 декабря 2010

Я использую bassistance.de jQuery Автозаполнение .

Имей текст типа "привет тебе, @john" Я сделал, автозаполнение запускается только тогда, когда символ @ в слове. Но когда я нажимаю на нужный элемент, он заменяет мне полный текст. Как я могу это сделать - заменить только "@john"? Или, может быть, есть другой плагин автозаполнения для jQuery, который имеет такую ​​возможность?

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

Ответы [ 2 ]

1 голос
/ 26 декабря 2010

Я работал над чем-то очень похожим на теги автозаполнения. У меня работает какой-то базовый код, но мне немного стыдно публиковать здесь, потому что это пограничная чушь. Это требует много очистки и рефакторинга, к которому я доберусь в течение следующих нескольких дней. Тем не менее, он делает то, что вам нужно, способом, аналогичным тому, что предлагает @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>

Буду очень признателен за любые отзывы по этому поводу.

1 голос
/ 26 декабря 2010

Как указано в ссылке, которую вы разместили для плагина автозаполнения

Этот плагин устарел и больше не разрабатывается.Его преемник является частью jQuery UI.

Я бы порекомендовал проверить jQueryUI autocomplete .С помощью этого плагина вы можете привязать пользовательский обработчик события к событию select (срабатывает при выборе элемента в списке):

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

Отменить событие по умолчанию (которое заменяетполное значение поля) и используйте собственную логику для соответствующего обновления поля (в данном случае это может быть просто вставка значения в текстовое поле, где находится курсор пользователя в этот момент времени).

Кажется выполнимым, особенно если вы выяснили, как отображать меню автозаполнения только тогда, когда вы этого хотите.

...