2010-04-06 13 views
38

मैंने हाल ही में bassistance द्वारा jQuery UI autocomplete पर उत्पादित मेरे कुछ स्वत: पूर्ण प्लगइन्स माइग्रेट किए हैं।jQuery UI स्वत: पूर्ण में "mustMatch" और "selectFirst" को कैसे कार्यान्वित करें?

कोर ऑटोकंपलेट कोड को संशोधित किए बिना कॉलबैक और अन्य विकल्पों के साथ "mustMatch" और "selectFirst" को कैसे कार्यान्वित किया जा सकता है?

उत्तर

40

मुझे लगता है कि मैं दोनों सुविधाओं का हल ...

चीजों को आसान बनाने के लिए, मैं एक प्रयोग आम कस्टम चयनकर्ता:

$.expr[':'].textEquals = function (a, i, m) { 
    return $(a).text().match("^" + m[3] + "$"); 
}; 

कोड के बाकी:

$(function() { 
    $("#tags").autocomplete({ 
     source: '/get_my_data/', 
     change: function (event, ui) { 
      //if the value of the textbox does not match a suggestion, clear its value 
      if ($(".ui-autocomplete li:textEquals('" + $(this).val() + "')").size() == 0) { 
       $(this).val(''); 
      } 
     } 
    }).live('keydown', function (e) { 
     var keyCode = e.keyCode || e.which; 
     //if TAB or RETURN is pressed and the text in the textbox does not match a suggestion, set the value of the textbox to the text of the first suggestion 
     if((keyCode == 9 || keyCode == 13) && ($(".ui-autocomplete li:textEquals('" + $(this).val() + "')").size() == 0)) { 
      $(this).val($(".ui-autocomplete li:visible:first").text()); 
     } 
    }); 
}); 

यदि आपका स्वत: पूर्ण सुझाव के किसी भी regexp द्वारा प्रयोग किया जाता है किसी भी 'विशेष' वर्ण, आप मीटर के भीतर उन अक्षरों को पलायन करना होगा [3] कस्टम चयनकर्ता में:

function escape_regexp(text) { 
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 
} 

और कस्टम चयनकर्ता बदलने के लिए:

$.expr[':'].textEquals = function (a, i, m) { 
    return $(a).text().match("^" + escape_regexp(m[3]) + "$"); 
}; 
+0

क्या आप "ऑटोफिल" काम करने में भी सक्षम थे? मुझे यहां एक प्रश्न मिला है http://stackoverflow.com/questions/2933713/add-autofill-capabilities-to-jquery-ui-1-8-1 लेकिन मैं अपने जीवन के लिए काम करने के लिए ऑटोफिल नहीं कर सकता । –

+1

प्लगइन के फोकस, चयन इत्यादि में ईवेंट पैरामीटर के साथ पारित यूई ऑब्जेक्ट का उपयोग करने के लिए मैं इसे कैसे अनुकूलित कर सकता हूं? – Gazillion

+0

मुझे लगभग यह काम करने के लिए मिला (केवल जरूरी चीजें) लेकिन यह मानने के लिए प्रतीत होता है कि यह सुझाव दिया गया था या नहीं। कोई विचार? :/ –

3

मुझे लगता है कि मुझे मिल गया mustMatch इस कोड के साथ काम कर रहे ... पूरी की जरूरत है, हालांकि परीक्षण:

<script type="text/javascript"> 
    $(function() { 
     $("#my_input_id").autocomplete({ 
      source: '/get_my_data/', 
      minChars: 3, 
      change: function(event, ui) { 
       // provide must match checking if what is in the input 
       // is in the list of results. HACK! 
       var source = $(this).val(); 
       var found = $('.ui-autocomplete li').text().search(source); 
       console.debug('found:' + found); 
       if(found < 0) { 
        $(this).val(''); 
       } 
      } 
     }); 
    }); 
</script> 
+0

अच्छा लेकिन मैं वापसी पर एक खाली मूल्य जमा कर सकता हूं। मुझे लगता है कि आपको एक कीडाउन फ़ंक्शन लागू करना होगा। – CyberJunkie

2

मुझे यह प्रश्न उपयोगी साबित हुआ।

मैंने सोचा कि मैं अब जिस कोड का उपयोग कर रहा हूं उसे पोस्ट कर दूंगा (Esteban Feldman's answer से अनुकूलित)।

मैंने टेक्स्टबॉक्स मान को रीसेट करने से पहले इस मुद्दे को हाइलाइट करने के लिए अपना स्वयं का मैच विकल्प और एक सीएसएस क्लास जोड़ा है।

 change: function (event, ui) { 
      if (options.mustMatch) { 
      var found = $('.ui-autocomplete li').text().search($(this).val()); 

      if (found < 0) { 
       $(this).addClass('ui-autocomplete-nomatch').val(''); 
       $(this).delay(1500).removeClass('ui-autocomplete-nomatch', 500); 
      } 
      } 
     } 

सीएसएस

.ui-autocomplete-nomatch { background: white url('../Images/AutocompleteError.gif') right center no-repeat; } 
+0

@ गॉर्डनबी - क्या आपके पास कहीं भी छवियां हैं autocompleteerror.gif – leora

+0

यह सिर्फ 16x16 छवि थी जिसे मैंने खींचा .... पुस्तकालय छवि नहीं। – GordonB

0

मैं कुछ अलग तरीके से यह कर परिणाम कैशिंग और पाठ क्षेत्र समाशोधन अगर एक निश्चित अवधि के लिए परिणाम की संख्या शून्य है कर रहा हूँ:

<script type='text/javascript'> 
function init_autocomplete(args) 
{ 
    var resultCache = {}; 
    var currentRequestTerm = null; 

    var closeCallback = function() 
    { 
     // Clear text field if current request has no results 
     if(resultCache[currentRequestTerm].length == 0) 
      $(args.selector).val(''); 
    }; 

    var sourceCallback = function(request, responseCallback) 
    { 
     // Save request term 
     currentRequestTerm = request.term; 

     // Check for cache hit 
     // ... 
     // If no cache hit, fetch remote data 
     $.post(
      dataSourceUrl, 
      { ... }, // post data 
      function(response) 
      { 
       // Store cache 
       resultCache[request.term] = response; 

       responseCallback(response); 
      } 
    }; 

    $(args.selector).autocomplete({ 
     close: closeCallback, 
     source: sourceCallback 
    }); 
} 
</script> 
1

समाधान जिसे मैंने 'mustMatch' को लागू करने के लिए उपयोग किया है:

<script type="text/javascript"> 
... 

$('#recipient_name').autocomplete({ 
    source: friends, 
    change: function (event, ui) { 
     if ($('#message_recipient_id').attr('rel') != $(this).val()) { 
      $(this).val(''); 
      $('#message_recipient_id').val(''); 
      $('#message_recipient_id').attr('rel', ''); 
     } 
    }, 
    select: function(event, ui) { 
     $('#message_recipient_id').val(ui.item.user_id); 
     $('#message_recipient_id').attr('rel', ui.item.label); 
    } 
}); 

... 
</script> 
1

मुझे एक समस्या मिली। हालांकि सुझाव सूची सक्रिय है, लेकिन यदि आप सुझाव से मेल नहीं खाते हैं तो भी आप अपना फॉर्म सबमिट कर सकते हैं। इसे विसर्जित करने के लिए मैंने जोड़ा:

$('form').submit(function() { 
     if ($(".ui-autocomplete li:textEquals('" + $(this).val() + "')").size() == 0) { 
      $(this).val(''); 
      $("span").text("Select a valid city").show(); 
      return false; 
     } 
}); 

यह फ़ॉर्म सबमिट करने और संदेश प्रदर्शित करने से रोकता है। http://jqueryui.com/demos/autocomplete/#combobox

मैं इसे अपडेट करने के बाद स्वत: भरण, कुछ अन्य बातें जोड़ने के लिए:

+0

नोट: यह डॉक्टर हॉफडे स्वीकृत उत्तर पर एक टिप्पणी प्रतीत होता है। –

1

यह JQuery-यूआई आधिकारिक डेमो mustMatch, अन्य बिंदास सामग्री के बीच है।

जावास्क्रिप्ट:

 


/* stolen from http://jqueryui.com/demos/autocomplete/#combobox 
* 
* and these options added. 
* 
* - autoFill (default: true): select first value rather than clearing if there's a match 
* 
* - clearButton (default: true): add a "clear" button 
* 
* - adjustWidth (default: true): if true, will set the autocomplete width the same as 
* the old select. (requires jQuery 1.4.4 to work on IE8) 
* 
* - uiStyle (default: false): if true, will add classes so that the autocomplete input 
* takes a jQuery-UI style 
*/ 
(function($) { 
    $.widget("ui.combobox", { 
     options: { 
      autoFill: true, 
      clearButton: true, 
      adjustWidth: true, 
      uiStyle: false, 
      selected: null, 
     }, 
    _create: function() { 
     var self = this, 
      select = this.element.hide(), 
      selected = select.children(":selected"), 
      value = selected.val() ? selected.text() : "", 
       found = false; 
     var input = this.input = $("") 
       .attr('title', '' + select.attr("title") + '') 
     .insertAfter(select) 
     .val(value) 
     .autocomplete({ 
      delay: 0, 
      minLength: 0, 
      source: function(request, response) { 
       var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); 
         var resp = 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" 
         ), "$1"), 
         value: text, 
         option: this 
        }; 
       }); 
         found = resp.length > 0; 
       response(resp); 
      }, 
      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 || input.data("autocomplete").term=="") { 
        // set to first suggestion, unless blank or autoFill is turned off 
           var suggestion; 
           if(!self.options.autoFill || input.data("autocomplete").term=="") found=false; 
           if(found) { 
            suggestion = jQuery(input.data("autocomplete").widget()).find("li:first")[0]; 
            var option = select.find("option[text="+suggestion.innerText+"]").attr('selected', true); 
            $(this).val(suggestion.innerText); 
         input.data("autocomplete").term = suggestion.innerText; 
          self._trigger("selected", event, { item: option[0] }); 
           } else { 
            suggestion={innerText: ''}; 
            select.find("option:selected").removeAttr("selected"); 
            $(this).val(''); 
         input.data("autocomplete").term = ''; 
            self._trigger("selected", event, { item: null }); 
           } 
        return found; 
        } 
       } 
      } 
     }); 

      if(self.options.adjustWidth) { input.width(select.width()); } 

      if(self.options.uiStyle) { 
       input.addClass("ui-widget ui-widget-content ui-corner-left"); 
      } 


     input.data("autocomplete")._renderItem = function(ul, item) { 
      return $("
  • ") .data("item.autocomplete", item) .append("" + item.label + "") .appendTo(ul); }; this.button = $(" ") .attr("tabIndex", -1) .attr("title", "Show All Items") .insertAfter(input) .button({ icons: { primary: "ui-icon-triangle-1-s" }, text: false }) .removeClass("ui-corner-all") .addClass("ui-corner-right ui-button-icon") .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(); }); if(self.options.clearButton) { this.clear_button = $(" ") .attr("tabIndex", -1) .attr("title", "Clear Entry") .insertAfter(input) .button({ icons: { primary: "ui-icon-close" }, text: false }) .removeClass("ui-corner-all") .click(function(event, ui) { select.find("option:selected").removeAttr("selected"); input.val(""); input.data("autocomplete").term = ""; self._trigger("selected", event, { item: null }); // work around a bug (likely same cause as #5265) $(this).blur(); }); } }, destroy: function() { this.input.remove(); this.button.remove(); this.element.show(); $.Widget.prototype.destroy.call(this); } }); })(jQuery);

    सीएसएस

     
    .hjq-combobox .ui-button { margin-left: -1px; } 
    .hjq-combobox .ui-button-icon-only .ui-button-text { padding: 0; } 
    .hjq-combobox button.ui-button-icon-only { width: 20px; } 
    .hjq-combobox .ui-autocomplete-input { margin-right: 0; } 
    .hjq-combobox {white-space: nowrap;} 
    

    नोट (.hjq-बता गया एक रैपिंग अवधि है): इस कोड को अद्यतन किया जाता है की जा रही है और बनाए रखा यहाँ: https://github.com/tablatom/hobo/blob/master/hobo_jquery_ui/vendor/assets/javascripts/combobox.js

    32

    मैं कुछ प्रयोग किया जाता है जितना आसान होगा उतना आसान है और यह काम करता है। मुझे उम्मीद है कि यह किसी की मदद करेगा।

     change: function (event, ui) { 
          if (!ui.item) { 
           $(this).val(''); 
          } 
         } 
    
    +0

    बिल्कुल सही, धन्यवाद! क्या आपने ऑटोफिल लागू किया है? इसके लिए भी खोज रहे हैं :) –

    +2

    बस ध्यान दें कि आपको यह सुनिश्चित करना चाहिए कि आपके पास 'ऑटोफोकस: सत्य' – Elliott

    +0

    है जो मैं ढूंढ रहा था –

    1

    हो सकता है कि यह सिर्फ इसलिए है क्योंकि यह एक पुरानी समस्या नहीं है, लेकिन मैंने पाया कि सबसे आसान समाधान पहले से ही वहाँ प्लगइन में है, तो आप सिर्फ उचित कार्यों का उपयोग करने की आवश्यकता है इस तक पहुंचें।

    इस कोड को मामलों को संभाल लेंगे जब स्वत: पूर्ण अमान्य मान वाला ध्यान केंद्रित खो देता है: बहुत bassistance से मूल कार्यक्षमता की तरह,

    change: function(e, ui) { 
        if (!ui.item) { 
         $(this).val(""); 
        } 
    } 
    

    और यह कोड, मामलों को संभाल लेंगे जब यहां कोई मिलान नहीं लिखते समय स्वत: पूर्ण में:

    response: function(e, ui) { 
        if (ui.content.length == 0) { 
         $(this).val(""); 
        } 
    } 
    

    यह या तो एक स्थिर सरणी स्रोत या JSON डेटा स्रोत के साथ अच्छी तरह से काम करता है। autoFocus: true विकल्प के साथ, यह एक कुशल तरीके से आवश्यक सब कुछ करने लगता है।

    अंतिम मामला जिसे आप संभालना चाहते हैं वह यह है कि जब ESCAPE कुंजी को टेक्स्टबॉक्स में अमान्य मान के साथ दबाया जाता है तो क्या करना है। मैं जो करता हूं वह पहले मिलान किए गए परिणाम के मूल्य का उपयोग करता है। और इस तरह मैं यह करता हूं ...

    सबसे पहले, सर्वश्रेष्ठ मिलान रखने के लिए एक चर घोषित करें। अपने स्वत: पूर्ण प्लगइन के बाहर यह करो।

    open: function(e, ui) { 
        bestMatch = ""; 
    
        var acData = $(this).data('uiAutocomplete'); 
        acData.menu.element.find("A").each(function() { 
         var me = $(this); 
    
         if (me.parent().index() == 0) { 
          bestMatch = me.text(); 
         } 
        }); 
    } 
    

    अंत में, अपने स्वत: पूर्ण करने के लिए निम्न इवेंट जोड़ें::

    var bestMatch = ""; 
    

    तो निम्नलिखित विकल्प का उपयोग

    .on("keydown", function(e) { 
        if (e.keyCode == 27)  // ESCAPE key 
        { 
         $(this).val(bestMatch); 
        } 
    }) 
    

    तुम बस के रूप में आसानी रिक्त क्षेत्र मजबूर कर सकते हैं जब भागने की कुंजी दबाया जाता है। आपको केवल bestMatch वैरिएबल की बजाय कुंजी दबाए जाने पर मान को खाली स्ट्रिंग पर सेट करना है (यदि आप फ़ील्ड को खाली करना चुनते हैं तो इसकी आवश्यकता नहीं है)।

    0

    स्वीकार किए जाते हैं जवाब के आधार पर:

    मेरे अतिरिक्त आवश्यकताओं: कई पूर्ण हो, विनीत त्रुटि मान्यता

    change: function() { 
        var target = $(this), 
         widget = target.autocomplete('widget'), 
         cond = widget.find('li:textEquals("' + target.val() + '")').length === 0; 
    
        target.toggleClass('input-validation-error', cond); 
    } 
    
    0

    देर से उत्तर दें लेकिन किसी की मदद कर सकता है!

    स्वत: पूर्ण विजेट

    1) परिवर्तन में दो घटनाओं को ध्यान में रखते - शुरू हो रहा है जब क्षेत्र धुंधला है और मूल्य बदल जाता है।

    2) प्रतिक्रिया - जब खोज पूर्ण हो जाती है और मेनू दिखाया जाता है तो ट्रिगर होता है। इस प्रकार

    परिवर्तन और प्रतिक्रिया घटनाओं संशोधित करें:

    change : function(event,ui) 
    { 
    if(!ui.item){ 
    $("selector").val(""); 
    } 
    }, 
    
    response : function(event,ui){ 
    if(ui.content.length==0){ 
        $("selector").val(""); 
    } 
    } 
    

    आशा इस मदद करता है!

    संबंधित मुद्दे