2012-04-19 26 views
15

Występuje dziwne zachowanie z jquery ui autocomplete when using it to create a combobox. Ilekroć klikam na pasek przewijania, aby przewijać listę wyników, A następnie kliknij przycisk combobox, aby zamknąć wyniki, lista wyników zostanie zamknięta, a następnie ponownie otwarta. Spodziewam się, że zamknie menu.Jquery UI autouzupełnianie combobox przycisk kliknij wydarzenie

Kroki do Repro

  1. open jsfiddle demo
  2. typu 'ja' w autouzupełniania lub naciśnij przycisk menu.
  3. Kliknij pionowego przewijania do przewijania wyników
  4. Kliknij na przycisk rozwijanej

Script utworzyć przycisk

this.button = $("<button type='button'>&nbsp;</button>") 
    .attr({ "tabIndex": -1, "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() { 

     // when i put breakpoint here, and my focus is not on input, 
     // then this if steatment is false???? 

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

CSS (wymuszenie zbyt długich menu do przewijania)

.ui-autocomplete { 
    max-height: 100px; 
    overflow-y: auto; 
    /* prevent horizontal scrollbar */ 
    overflow-x: hidden; 
    /* add padding to account for vertical scrollbar */ 
    padding-right: 20px; 
} 
/* IE 6 doesn't support max-height 
* we use height instead, but this forces the menu to always be this tall 
*/ 
* html .ui-autocomplete { 
    height: 100px; 
} 

Moje rozwiązanie może zamknąć widżet, nawet jeśli fokus zostanie przeniesiony do samego widgetu, a nie elementu wejściowego?

Jakieś pomysły, jak zmodyfikować ten kod, aby działał w ten sposób?

+0

można podać kod HTML, może JSFiddle? Byłoby wtedy o wiele łatwiej je zdobyć. –

+0

Nie rozumiem, co próbujesz osiągnąć tutaj. [Jsfiddle] (http://jsfiddle.net/vR9s2/2/) –

+0

Jaki problem próbujesz rozwiązać? –

Odpowiedz

5

Na podstawie zagadnień z różnych kliknięcie myszką i imprez dla widgetu automplete, wpadłem na to: jsFiddle example.

jQuery:

var input = $('#txtComplete'); 

var data = []; 
var isOpen = false; 

function _init() { 
    for (var idx = 0; idx <= 100; idx++) { 
     data.push('item: ' + idx); 
    }; 
    input.autocomplete({ 
     source: data, 
     minLength: 0, 
     open: function(event, ui) { 
      isOpen = true; 
     }, 
     select: function(event, ui) { 
      isOpen = false; 
     } 
    }); 
} 

function afterInit() { 
    var button = $("<button type='button'>&nbsp;</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(event) { 
     input.focus(); 
     if (isOpen) { 
      input.autocomplete("close"); 
      isOpen = false; 
     } else { 
      input.autocomplete("search", ""); 
      event.stopImmediatePropagation(); 
     } 
    }); 
} 
$(window).click(function() { 
    input.autocomplete("close"); 
    isOpen = false; 
}); 
$(function() { 
    _init(); 
    afterInit(); 
});​ 
+0

Ale w twoim kodzie ... pole kombi nie jest w stanie kliknąć po raz drugi .. –

+0

@lakshmipriya - Tak, jest. Działa w porządku. – j08691

+0

Przepraszam .. działa dobrze ... –

3

Problem polega na pracy w jquery ui autouzupełniania. Istnieje ustawienie zdarzenia, aby zamknąć menu w określonych warunkach. W jednym z warunków sprawdza, czy element podnoszący mousedown jest częścią widgetu autouzupełniania. Jeśli nie, zamyka menu. Ponieważ używasz funkcji combobox, a przycisk nie jest częścią widgetu autouzupełniania, kliknięcie przycisku powoduje zamknięcie menu z powodu tego zdarzenia.

Możesz zobaczyć szkodliwy warunek z powodu, dlaczego jest tam zaczynając od linii 205 w autocomplete source on github. Prawdopodobnie warto podnieść kwestię na forach jquery ui, ponieważ ich demo combobox również ma ten błąd.

UPDATE

To wydarzenie wymiana jest oparty off jQuery UI 1.8.18. To wydarzenie się zmieniło i najprawdopodobniej zmieni się ponownie. W przypadku tej trasy może być konieczne ręczne zaktualizowanie tego kodu w każdym wydaniu.

można załatać zdarzenie mousedown aby nie zamknąć menu gdyby to był twój przycisk combo, który został kliknięty uruchamiając po utworzeniu autouzupełniania (jsfiddle demo) Poniższy.

var input = $('#combotextbox').autocomplete(/*options*/); 
input.data('autocomplete').menu.element.unbind('mousedown').mousedown(function(event) { 
     var self = input.data('autocomplete'); 
     event.preventDefault(); 
     // clicking on the scrollbar causes focus to shift to the body 
     // but we can't detect a mouseup or a click immediately afterward 
     // so we have to track the next mousedown and close the menu if 
     // the user clicks somewhere outside of the autocomplete 
     var menuElement = self.menu.element[0]; 
     if (!$(event.target).closest(".ui-menu-item").length) { 
      setTimeout(function() { 
       $(document).one('mousedown', function(event) { 
        var t = $(event.target); 
        if (event.target !== self.element[0] && event.target !== menuElement && !$.ui.contains(menuElement, event.target) && !t.hasClass('ui-combo-trigger') && !t.parent().hasClass('ui-combo-trigger')) { 
         self.close(); 
        } 
       }); 
      }, 1); 
     } 

     // use another timeout to make sure the blur-event-handler on the input was already triggered 
     setTimeout(function() { 
      clearTimeout(self.closing); 
     }, 13); 
    }); 

Usuwa bieżące zdarzenia mouseDown, a następnie dodaje go ponownie z dodatkiem sprawdzić, czy element, który wywołał zdarzenie lub jego rodzica (przycisk kliknął lub ui-ikona wewnątrz kliknięciu przycisku) ma klasa ui-combo-trigger.

Kod do utworzenia przycisku jest względnie niezmieniony. Musimy tylko dodać nową klasę ui-combo-trigger.

var button = $("<button type='button'>&nbsp;</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 ui-combo-trigger").click(function(event) { 

     // when i put breakpoint here, and my focus is not on input, 
     // then this if steatment is false???? 
     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(); 
     event.stopImmediatePropagation(); 
    }); 
1

Spróbuj jsfiddle. Myślę, że ci pomogę.

var input = $('#txtComplete'); 

var data = []; 
var openCheck = false; 

function _init() { 
    for (var idx = 0; idx <= 100; idx++) { 
     data.push('item: ' + idx); 
    }; 
    input.autocomplete({ 
     source: data, 
     minLength: 0, 
     open: function(event, ui) { 
      openCheck = true; 
     }, 
     select: function(event, ui) { 
      openCheck = false; 
     } 
    }); 
} 

function afterInit() { 
    var button = $("<button type='button'>&nbsp;</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(event) { 
     if (openCheck) { 
      input.autocomplete("close"); 
      openCheck = false; 
     } else { 
      input.autocomplete("search", ""); 
     } 
    }); 
} 

$(function() { 
    _init(); 
    afterInit(); 
}); 
+0

Nie można używać klawiszy strzałek do nawigacji po liście. –

+0

Przepraszamy za to ... po prostu dodaj input.focus(); kliknij wydarzenie ... to zadziała ... –

0

Brian wyjaśnił problem bardzo dobrze. Z jQuery UI 11 można zrobić coś takiego:

wasOpen = false; 
$button 
    .mousedown(function() { 
    wasOpen = input.autocomplete("widget").is(":visible"); 
    }) 
    .click(function() { 
     input.focus(); 

     // Close if already visible 
     if (wasOpen) { 
      return; 
     } 

patrz przykład na http://jqueryui.com/autocomplete/#combobox

Powiązane problemy