Programing

자동 완성 플러그인 결과를 사용자 정의 형식으로 지정할 수 있습니까?

crosscheck 2020. 5. 27. 21:41
반응형

자동 완성 플러그인 결과를 사용자 정의 형식으로 지정할 수 있습니까?


내가 사용하고 jQuery를 UI 자동 완성 플러그인을 . 드롭 다운 결과에서 검색 문자 순서를 강조 표시하는 방법이 있습니까?

예를 들어, 데이터로 "foo bar"가 있고 "foo"를 입력 하면 다음과 같이 드롭 다운에 " foo bar"가 표시됩니다.

"Bre"는 굵은 체로 "Bre"로 입력하고 "akfast"는 라이트로 "Breakfast"를 입력하면 "Breakfast"가 나타납니다.


실시간 제안으로 자동 완성

예, 원숭이 패치 자동 완성 기능을 사용할 수 있습니다.

jQuery UI v1.8rc3에 포함 된 자동 완성 위젯에서 제안 팝업은 자동 완성 위젯의 _renderMenu 함수에 생성됩니다. 이 기능은 다음과 같이 정의됩니다.

_renderMenu: function( ul, items ) {
    var self = this;
    $.each( items, function( index, item ) {
        self._renderItem( ul, item );
    });
},

_renderItem 함수는 다음과 같이 정의됩니다.

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

따라서 _renderItem fn을 원하는 효과를 생성하는 자신 만의 창작물로 바꾸어야합니다. 라이브러리에서 내부 함수를 재정의하는이 기술은 원숭이 패치 라고 합니다. 내가 한 방법은 다음과 같습니다.

  function monkeyPatchAutocomplete() {

      // don't really need this, but in case I did, I could store it and chain
      var oldFn = $.ui.autocomplete.prototype._renderItem;

      $.ui.autocomplete.prototype._renderItem = function( ul, item) {
          var re = new RegExp("^" + this.term) ;
          var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" + 
                  this.term + 
                  "</span>");
          return $( "<li></li>" )
              .data( "item.autocomplete", item )
              .append( "<a>" + t + "</a>" )
              .appendTo( ul );
      };
  }

에서 해당 함수를 한 번 호출하십시오 $(document).ready(...).

이제 이것은 해킹입니다.

  • 목록에 렌더링되는 모든 항목에 대해 정규 표현식 obj가 생성됩니다. 해당 정규 표현식 obj는 모든 항목에 재사용되어야합니다.

  • 완성 된 부분의 형식에 사용되는 CSS 클래스는 없습니다. 인라인 스타일입니다.
    이는 동일한 페이지에 여러 개의 자동 완성 기능이있는 경우 모두 동일한 처리 방법을 갖음을 의미합니다. CSS 스타일로 해결할 수 있습니다.

...하지만 주요 기술을 설명하며 기본 요구 사항에 적합합니다.

대체 텍스트

업데이트 된 작업 예 : http://output.jsbin.com/qixaxinuhe


일치하는 문자열의 대소 문자를 유지하려면 입력 된 문자의 대소 문자를 사용하는 대신이 행을 사용하십시오.

var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" + 
          "$&" + 
          "</span>");

즉, 위의 원래 코드부터 시작하여로 교체 this.term하면 "$&"됩니다.


편집
는 페이지의 모든 자동 완성 위젯을 변경 합니다. 하나만 변경하려면 다음 질문을 참조하십시오
. 페이지에서 자동 완성 인스턴스를 하나만 패치하는 방법은 무엇입니까?


이것은 또한 작동합니다 :

       $.ui.autocomplete.prototype._renderItem = function (ul, item) {
            item.label = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
            return $("<li></li>")
                    .data("item.autocomplete", item)
                    .append("<a>" + item.label + "</a>")
                    .appendTo(ul);
        };

@ Jörn Zaefferer와 @Cheeso의 답변 조합.


매우 도움이되었습니다. 감사합니다. +1.

"문자열은 용어로 시작해야합니다"를 기준으로 한 가벼운 버전입니다.

function hackAutocomplete(){

    $.extend($.ui.autocomplete, {
        filter: function(array, term){
            var matcher = new RegExp("^" + term, "i");

            return $.grep(array, function(value){
                return matcher.test(value.label || value.value || value);
            });
        }
    });
}

hackAutocomplete();

jQueryUI 1.9.0은 _renderItem의 작동 방식을 변경합니다.

아래 코드는 이러한 변경 사항을 고려하고 Jörn Zaefferer의 jQuery Autocomplete 플러그인을 사용하여 하이라이트 일치를 수행 한 방법을 보여줍니다. 전체 검색어에서 모든 개별 용어를 강조 표시합니다.

Knockout 및 jqAuto 사용으로 이동 한 후 결과를 스타일링하는 훨씬 쉬운 방법을 찾았습니다.

function monkeyPatchAutocomplete() {
   $.ui.autocomplete.prototype._renderItem = function (ul, item) {

      // Escape any regex syntax inside this.term
      var cleanTerm = this.term.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

      // Build pipe separated string of terms to highlight
      var keywords = $.trim(cleanTerm).replace('  ', ' ').split(' ').join('|');

      // Get the new label text to use with matched terms wrapped
      // in a span tag with a class to do the highlighting
      var re = new RegExp("(" + keywords + ")", "gi");
      var output = item.label.replace(re,  
         '<span class="ui-menu-item-highlight">$1</span>');

      return $("<li>")
         .append($("<a>").html(output))
         .appendTo(ul);
   };
};

$(function () {
   monkeyPatchAutocomplete();
});

다음은 기능적인 전체 예입니다.

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Autocomplete - jQuery</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css">
</head>
<body>
<form id="form1" name="form1" method="post" action="">
  <label for="search"></label>
  <input type="text" name="search" id="search" />
</form>

<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script>
$(function(){

$.ui.autocomplete.prototype._renderItem = function (ul, item) {
    item.label = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
    return $("<li></li>")
            .data("item.autocomplete", item)
            .append("<a>" + item.label + "</a>")
            .appendTo(ul);
};


var availableTags = [
    "JavaScript",
    "ActionScript",
    "C++",
    "Delphi",
    "Cobol",
    "Java",
    "Ruby",
    "Python",
    "Perl",
    "Groove",
    "Lisp",
    "Pascal",
    "Assembly",
    "Cliper",
];

$('#search').autocomplete({
    source: availableTags,
    minLength: 3
});


});
</script>
</body>
</html>

도움이 되었기를 바랍니다


더 쉬운 방법으로 다음을 시도하십시오.

$('ul: li: a[class=ui-corner-all]').each (function (){      
 //grab each text value 
 var text1 = $(this).text();     
 //grab user input from the search box
 var val = $('#s').val()
     //convert 
 re = new RegExp(val, "ig") 
 //match with the converted value
 matchNew = text1.match(re);
 //Find the reg expression, replace it with blue coloring/
 text = text1.replace(matchNew, ("<span style='font-weight:bold;color:green;'>")  + matchNew +    ("</span>"));

    $(this).html(text)
});
  }

다음은 Ted de Koning 솔루션의 해시입니다. 다음을 포함합니다 :

  • 대소 문자를 구분하지 않는 검색
  • 검색된 문자열의 많은 항목 찾기
$.ui.autocomplete.prototype._renderItem = function (ul, item) {

    var sNeedle     = item.label;
    var iTermLength = this.term.length; 
    var tStrPos     = new Array();      //Positions of this.term in string
    var iPointer    = 0;
    var sOutput     = '';

    //Change style here
    var sPrefix     = '<strong style="color:#3399FF">';
    var sSuffix     = '</strong>';

    //Find all occurences positions
    tTemp = item.label.toLowerCase().split(this.term.toLowerCase());
    var CharCount = 0;
    tTemp[-1] = '';
    for(i=0;i<tTemp.length;i++){
        CharCount += tTemp[i-1].length;
        tStrPos[i] = CharCount + (i * iTermLength) + tTemp[i].length
    }

    //Apply style
    i=0;
    if(tStrPos.length > 0){
        while(iPointer < sNeedle.length){
            if(i<=tStrPos.length){
                //Needle
                if(iPointer == tStrPos[i]){
                    sOutput += sPrefix + sNeedle.substring(iPointer, iPointer + iTermLength) + sSuffix;
                    iPointer += iTermLength;
                    i++;
                }
                else{
                    sOutput += sNeedle.substring(iPointer, tStrPos[i]);
                    iPointer = tStrPos[i];
                }
            }
        }
    }


    return $("<li></li>")
        .data("item.autocomplete", item)
        .append("<a>" + sOutput + "</a>")
        .appendTo(ul);
};

다음은 정규 표현식이 필요하지 않고 레이블의 여러 결과와 일치하는 버전입니다.

$.ui.autocomplete.prototype._renderItem = function (ul, item) {
            var highlighted = item.label.split(this.term).join('<strong>' + this.term +  '</strong>');
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a>" + highlighted + "</a>")
                .appendTo(ul);
};

콤보 박스 데모를 살펴보면 결과 강조 표시가 포함되어 있습니다. http://jqueryui.com/demos/autocomplete/#combobox

거기에 사용되는 정규식은 html 결과도 처리합니다.


내 버전은 다음과 같습니다.

  • Uses DOM functions instead of RegEx to break strings/inject span tags
  • Only the specified autocomplete is affected, not all
  • Works with UI version 1.9.x
function highlightText(text, $node) {
    var searchText = $.trim(text).toLowerCase(),
        currentNode = $node.get(0).firstChild,
        matchIndex,
        newTextNode,
        newSpanNode;
    while ((matchIndex = currentNode.data.toLowerCase().indexOf(searchText)) >= 0) {
        newTextNode = currentNode.splitText(matchIndex);
        currentNode = newTextNode.splitText(searchText.length);
        newSpanNode = document.createElement("span");
        newSpanNode.className = "highlight";
        currentNode.parentNode.insertBefore(newSpanNode, currentNode);
        newSpanNode.appendChild(newTextNode);
    }
}
$("#autocomplete").autocomplete({
    source: data
}).data("ui-autocomplete")._renderItem = function (ul, item) {
    var $a = $("<a></a>").text(item.label);
    highlightText(this.term, $a);
    return $("<li></li>").append($a).appendTo(ul);
};

Highlight matched text example


you can use folowing code:

lib:

$.widget("custom.highlightedautocomplete", $.ui.autocomplete, {
    _renderItem: function (ul, item) {
        var $li = $.ui.autocomplete.prototype._renderItem.call(this,ul,item);
        //any manipulation with li
        return $li;
    }
});

and logic:

$('selector').highlightedautocomplete({...});

it creates custom widget that can override _renderItem without overwriting _renderItem of original plugin prototype.

in my example also used original render function to some simplify code

it's important thing if you want to use plugin in different places with different view of autocomplete and don't want to break your code.


If you instead use the 3rd party plugin, it has a highlight option: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(see the Options tab)


To support multiple values, just simply add following function:

function getLastTerm( term ) {
  return split( term ).pop();
}

var t = String(item.value).replace(new RegExp(getLastTerm(this.term), "gi"), "<span class='ui-state-highlight'>$&</span>");

참고 URL : https://stackoverflow.com/questions/2435964/how-can-i-custom-format-the-autocomplete-plug-in-results

반응형