मैं स्वत: पूर्ण प्लग-इन परिणामों को कस्टम-प्रारूप कैसे कर सकता हूं?


167

मैं jQuery UI स्वत: पूर्ण प्लग-इन का उपयोग कर रहा हूं । क्या ड्रॉप-डाउन परिणामों में खोज वर्ण अनुक्रम को उजागर करने का एक तरीका है?

उदाहरण के लिए, यदि मेरे पास डेटा के रूप में "फू बार" है और मैं ड्रॉप-डाउन में " फू बार" प्राप्त करूंगा , तो इस तरह टाइप करेंगे :

"ब्रेक" के बाद "ब्रे" टाइप किया जाता है "ब्रे" एक बोल्ड टाइप होने के साथ टाइप किया जाता है और एक लाइट होने के लिए "एक्सीटेस्ट"।

जवाबों:


233

लाइव सुझाव के साथ स्वतः पूर्ण

हां, अगर आप बंदर-पेटी को पूरा कर सकते हैं।

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(...)

अब, यह एक हैक है, क्योंकि:

  • सूची में दिए गए प्रत्येक आइटम के लिए एक regexp obj बनाया गया है। उस regexp obj को सभी वस्तुओं के लिए फिर से इस्तेमाल किया जाना चाहिए।

  • पूर्ण भाग के प्रारूपण के लिए कोई css वर्ग का उपयोग नहीं किया गया है। यह एक इनलाइन शैली है।
    इसका मतलब है कि यदि आपके पास एक ही पृष्ठ पर कई ऑटोकॉम्पलेट्स हैं, तो वे सभी एक ही उपचार प्राप्त करेंगे। एक सीएसएस शैली का समाधान होगा।

... लेकिन यह मुख्य तकनीक को दिखाता है, और यह आपकी बुनियादी आवश्यकताओं के लिए काम करता है।

वैकल्पिक शब्द

अद्यतन कार्य उदाहरण: http://output.jsbin.com/qixaxinuhe


टाइप किए गए पात्रों के मामले का उपयोग करने के विपरीत, मैच स्ट्रिंग्स के मामले को संरक्षित करने के लिए, इस लाइन का उपयोग करें:

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

दूसरे शब्दों में, ऊपर दिए गए मूल कोड से शुरू करके, आपको बस इसके this.termसाथ बदलने की आवश्यकता है "$&"


संपादित करें
उपरोक्त पृष्ठ पर प्रत्येक स्वत: पूर्ण विजेट बदलता है । यदि आप केवल एक को बदलना चाहते हैं, तो इस प्रश्न को देखें:
पृष्ठ पर स्वतः पूर्ण का केवल एक * उदाहरण * कैसे पैच करें?


धन्यवाद चीज़ो। क्या आपके पास इसके लिए jsbin लिंक है?
dev.e.loper

1
ध्यान दें कि यदि आप श्रृंखला चीजों को साथ करते हैं, तो संदर्भ को रीसेट करना महत्वपूर्ण है: oldFn.apply (यह, [उल, आइटम]);
एमैनटन 18

आपका बहुत बहुत धन्यवाद! अगर यह jQuery UI का एक हिस्सा बन गया तो बहुत बढ़िया होगा।
डेविड राइडर

4
एक बात मैं कहूंगा कि यदि आप चाहते हैं कि यह मिलान स्ट्रिंग के किसी भी हिस्से में परिणाम को बोल्ड करें (सिर्फ शुरुआत नहीं) तो RegExp लाइन को इस पर संशोधित करें: var re = new RegExp (this.term);
डेविड राइडर

1
JQueryUI स्वत: पूर्ण डिफ़ॉल्ट रूप से असंवेदनशील खोज करने के लिए प्रतीत होता है, इसलिए यह RegExp ऑब्जेक्ट में "i" ध्वज को जोड़ने के लिए समझ में आता है। @DavidRyder के रूप में regex में "^" का उपयोग करने का कोई कारण नहीं है। जैसे: var re = new RegExp(this.term, "i"); बढ़िया पोस्ट!
सैम

65

यह भी काम करता है:

       $.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);
        };

@ जोर्न ज़ेफ़र और @ चीज़ो की प्रतिक्रियाओं का एक संयोजन।


मुझे यह सबसे अच्छा लगा, क्योंकि यह पूरे शब्द से मेल खाता है।
atp

3
यह अच्छा काम करता है। केवल एक चीज देखने के लिए है कि आइटम। लैला को प्रतिस्थापित किया जा रहा है। मेरे लिए, मुझे अपने टेक्स्ट बॉक्स में "<strong ..." मिल रहा था। बस बदले हुए परिणाम को दूसरे चर पर नियत करने से साफ़ हो जाता है। यदि आपके डेटा में एक मान गुण है जो पाठ बॉक्स में डाला जाता है, तो आपको यह समस्या नहीं होगी।
किजाना वुडार्ड

यदि आपके पास एक स्वत: पूर्णता है जो कई मूल्यों का समर्थन करती है तो यह काम नहीं करता है। कोई सुझाव?
leora

अपने स्वत: पूर्ण परिणामों में पाठ हाइलाइटिंग प्राप्त करने का सबसे सरल तरीका। स्पष्ट रूप से कीड़े के लिए बाहर देखो जैसा कि
लियोरा

@RNKushwaha कहीं भी कॉल करने से पहले$().autocomplete()
ब्रायन लीशमैन

8

सुपर सहायक। धन्यवाद। +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();

1
धन्यवाद Orolo, मैं कई स्थानों पर स्वत: पूर्ण का उपयोग कर रहा था और एक केंद्रीय स्थान चाहता था जहां मैं केवल परिणाम दिखाने के लिए परिवर्तन कर सकता हूं जो कि टाइप किए गए पात्रों से शुरू होता है और यह वही है जिसकी मुझे वास्तव में आवश्यकता है!
स्वप्नकुमार

धन्यवाद। यह सभी का सबसे अच्छा समाधान है। यह केस असंवेदनशील के लिए काम करता है।
अनिकेत कुलकर्णी

7

यहाँ यह जाता है, एक कार्यात्मक पूर्ण उदाहरण:

<!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>

उम्मीद है की यह मदद करेगा


6

jQueryUI 1.9.0 बदलता है कि _renderItem कैसे काम करता है।

नीचे दिया गया कोड इस बदलाव को ध्यान में रखता है और यह भी दिखाता है कि मैं कैसे जेरे ज़ेफ़रर के jQuery स्वतः पूर्ण प्लगइन का उपयोग करके हाइलाइटिंग मिलान कर रहा था। यह समग्र खोज शब्द में सभी व्यक्तिगत शब्दों को उजागर करेगा।

नॉकआउट और जकाउट का उपयोग करने के लिए आगे बढ़ने के बाद से मुझे यह परिणाम स्टाइल करने का एक बहुत आसान तरीका मिला।

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();
});

जब मैं की तरह वर्ण के साथ खोज '(' यह एक त्रुटि (कारण बनता है "Uncaught सिंटैक्स त्रुटि: अमान्य रेगुलर एक्सप्रेशन: / (सैम | पर | () /: असमाप्त समूह"?) वैसे भी इस regex के साथ collission रोकने के द्वारा हल करने के लिए
Idan Shechter

बहुत बढ़िया जवाब! प्यार करें कि यह उन शर्तों की परवाह किए बिना जहां वे दिखाई देते हैं। बहुत ही शांत। पोस्ट अपडेट करने के लिए धन्यवाद। एक सवाल जो मैंने किया है, वह आपके द्वारा उपयोग किए जाने वाले .ui-menu-item-highlight-class के बारे में है। क्या यह jquery-ui या उपभोक्ताओं द्वारा परिभाषित होने की उम्मीद है? मैंने अपने खुद के साधनों के अनुरूप वर्ग नाम बदल दिया और बस फ़ॉन्ट-वजन बोल्ड कर दिया। .jqAutocompleteMatch { font-weight: bold; }
सैम '

@IdanShechter शानदार टिप्पणी। this.termरेगेक्स के लिए भागने के कुछ तर्क किसी भी प्रसंस्करण को करने से पहले उपयोग किए जाने चाहिए। यह कैसे करना है के कई उत्तरों में से एक के रूप में जावास्क्रिप्ट रेगेक्स में उपयोग के लिए एस्केप स्ट्रिंग देखें ।
सैम

3

और भी आसान तरीके के लिए, यह आज़माएँ:

$('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)
});
  }

3

यहां टेड डी कोनिंग के समाधान का पुनर्पाठ है। उसमे समाविष्ट हैं :

  • केस असंवेदनशील खोज
  • खोजे गए तार की कई घटनाओं का पता लगाना
$.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);
};

1
मुझे लगता है कि आप पहिया का फिर से आविष्कार कर रहे हैं! आप उन सभी रेग्युलर एक्सप्रेशंस का उपयोग क्यों नहीं करते जो इस कोड की तुलना में अधिक तेज़, आसान और अधिक कॉम्पैक्ट हैं?
जॉर्ज मावरित्सक

2

यहां एक संस्करण है जिसे किसी भी नियमित अभिव्यक्ति की आवश्यकता नहीं है और लेबल में कई परिणामों से मेल खाता है।

$.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);
};

यह शायद सबसे अच्छा समाधान है, लेकिन string.split केवल केस-संवेदी मैचों में सक्षम है, मुझे विश्वास है।
नोएल अब्राहम

क्या आपके पास गैर-मामले-संवेदनशील के आधार पर शब्दों से मेल खाने का कोई तरीका है? क्योंकि अगर मेरे पास एक खोज "अल्फ़ा" है, तो यह "अल्फा"
पैट्रिक

1

कॉम्बोक्स डेमो पर एक नज़र डालें, इसमें परिणाम हाइलाइटिंग शामिल हैं: http://jqueryui.com/demos/autocomplete/#combobox

वहाँ उपयोग में regex भी html परिणामों के साथ संबंधित है।


अब तक दिखाई नहीं देता (जहाँ तक मैं बता सकता हूँ)
सैम

1

यहाँ मेरा संस्करण है:

  • स्ट्रिंग्स / इंजेक्शन स्पैन टैग को तोड़ने के लिए RegEx के बजाय DOM फ़ंक्शंस का उपयोग करता है
  • केवल निर्दिष्ट स्वतः पूर्णता प्रभावित होती है, सभी नहीं
  • UI संस्करण 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);
};

हाइलाइट किए गए टेक्स्ट उदाहरण


1

आप फॉलिंग कोड का उपयोग कर सकते हैं:

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;
    }
});

और तर्क:

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

यह कस्टम विजेट बनाता है जो मूल प्लगइन प्रोटोटाइप की _renderItemओवरराइटिंग _renderItemके बिना ओवरराइड कर सकता है ।

मेरे उदाहरण में कुछ सरल कोड के लिए मूल रेंडर फ़ंक्शन का भी उपयोग किया गया

यदि आप स्वत: पूर्ण के विभिन्न दृश्य के साथ विभिन्न स्थानों में प्लगइन का उपयोग करना चाहते हैं और अपने कोड को तोड़ना नहीं चाहते हैं तो यह महत्वपूर्ण बात है।


आम तौर पर 6 साल पुराने एक प्रश्न का उत्तर देने के बजाय नए प्रश्नों के उत्तर देने में समय बिताना बेहतर होता है, या बिना उत्तर दिए।
zchrykng

0

यदि आप इसके बजाय तीसरे पक्ष के प्लगइन का उपयोग करते हैं, तो इसका एक हाइलाइट विकल्प है: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(विकल्प टैब देखें)


हाँ मैं में इस प्लग के बारे में पता कर रहा हूँ, लेकिन, हम अपने ऐप्लिकेशन में jQueryUI उपयोग कर रहे हैं तो यह के साथ इस काम कर पाने के लिए अच्छा होगा jQueryUI स्वत: पूर्ण प्लग में।
dev.e.loper

1
2010-06-23 के अनुसार, jQuery के ऑटोोकॉमल प्लगइन को jQuery के यूआई ऑटोकोम्प्लीट प्लगइन के पक्ष में चित्रित किया गया है। अधिक जानकारी के लिए बासिस्टेंस.डे / जेक्वेरी -प्लाजिन्स / जेकरी- प्लुगिन- डिपोकोम को देखें
shek

0

कई मूल्यों का समर्थन करने के लिए, बस निम्नलिखित फ़ंक्शन जोड़ें:

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>");
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.