2012-10-29 8 views
5

Ho impostato un jsFiddle rapido per dimostrare il problema.Popoli Bootstrap di Twitter e descrizioni comandi sugli elementi dell'opzione Elenco che mostrano nel posto sbagliato

Quando si utilizza una descrizione comando o un popover da Bootstrap su un elemento opzione di un elenco di selezione, il popover o la descrizione comando non viene visualizzata accanto all'elemento, ma piuttosto nell'estrema sinistra superiore della pagina.

Il codice HTML che sto usando è:

<select size="5" id="testList"> 
    <option value="1" rel="popover" data-original-title="This is item 1." data-content="Lots of stuff to say" style="color: red; ">Item 1</option> 
    <option value="2" rel="popover" data-original-title="This is item 2." data-content="Lots of stuff to say" style="color: green; ">Item 2</option> 
    <option value="3" rel="popover" data-original-title="This is item 3." data-content="Lots of stuff to say" style="">Item 3</option> 
    <option value="4" rel="popover" data-original-title="Blah" data-content="Lots of stuff to say" style="color: orange; ">Item 4</option> 
</select>​ 

La chiamata javascript è semplice:

$(function() { 
    $('#testList option[rel=popover]').popover({ 
     placement: 'right', 
     trigger: 'hover' 
    }); 
}); ​ 

Cosa posso fare per farlo presentarsi nel posto giusto?

+0

È interessante notare che il collegamento jsFiddle sembra funzionare ora. Forse una versione più recente ha risolto questo? – SteveShaffer

risposta

15

È previsto. TB tooltip/popover calcola la loro posizione in base agli elementi associati offsetWidth e offsetHeight. L'opzione non ha tali proprietà, mai, quindi un popover finirà sempre in qualcosa relativo al farmost body a sinistra/in alto.

Tuttavia, è possibile inserire un popover per il select sé. Bind mouseover per la selezione, da quello mostra un popover sulla destra popolato con gli attributi dei dati per lo option al passaggio del mouse.

HTML, pulito per rel="popover" e "data-original-title"

<select size="4" id="testList"> 
<option value="1" data-title="This is item 1." data-content="Lots of stuff to say 1" style="color:red;">Item 1</option> 
<option value="2" data-title="This is item 2." data-content="Lots of stuff to say 2" style="color:green;">Item 2</option> 
<option value="3" data-title="This is item 3." data-content="Lots of stuff to say 3" style="">Item 3</option> 
<option value="4" data-title="Blah" data-content="Lots of stuff to say 4" style="color:orange;">Item 4</option> 
</select>​​ 

legano passaggio del mouse, raccolgono opzione data-attribues, spettacolo popover

$("#testList").on('mouseover', function(e) { 
    var $e = $(e.target); 
    if ($e.is('option')) { 
     $('#testList').popover('destroy'); 
     $("#testList").popover({ 
      trigger: 'manual', 
      placement: 'right', 
      title: $e.attr("data-title"), 
      content: $e.attr("data-content") 
     }).popover('show'); 
    } 
}); 

po 'di pulizia in modo che il popover scompare quando si lascia la select

$("#testList").on('mouseleave', function(e) { 
    $('#testList').popover('destroy'); 
}); 

non pensa che si possa fare molto scommessa ter per un elenco di opzioni :) è in conflitto con template, costringendo il popover a seguire più o meno la posizione verticale di ciascuna opzione in base all'indice.

biforcuta codice http://jsfiddle.net/mM8sx/


Aggiornamento - problemi con IE e Chrome su Windows.
Ho visto alcuni riferimenti a questa risposta, sottolineando che non funzionava in IE e Chrome su Windows. È dovuto al fatto che su Windows, gli elementi <option> non ricevono affatto eventi del mouse. Ecco un "trucco" della risposta di cui sopra, che lo rende "crossbrowser".

Testato con successo con Chrome, FF, IE e Safari su Windows. Chrome, FF e Opera su Ubuntu. L'idea è di indirizzare il corretto <option> su mousemove (non il mouseover) calcolando l'indice in base agli effetti del mouse clientY/height di un'opzione.

$("#testList").on('mousemove', function(e) { 
    if (!isWindows) { 
     var $e = $(e.target); 
    } else { 
     var newIndex = Math.floor(e.clientY/optionHeight); 
     if (newIndex === index) return; 
     index = newIndex; 
     $e = $(this).find('option:eq('+index+')'); 
    }  
    if ($e.is('option')) { 
     $('#testList').popover('destroy'); 
     $("#testList").popover({ 
      trigger: 'manual', 
      placement: 'right', 
      title: $e.attr("data-title"), 
      content: $e.attr("data-content") 
     }).popover('show'); 
    } 
}); 

vedere violino per i dettagli ->http://jsfiddle.net/LfrPs/

+0

Il tuo violino funziona come previsto, ma ho avuto una domanda successiva. Cosa succede se non volessi impostare in modo esplicito la dimensione della selezione? Come posso quindi ottenere il popover con un elemento di selezione a discesa? – Sam

+1

@Sam, mi piacerebbe risolverlo - sfortunatamente l'evento 'mouseover' per' option' non viene attivato quando 'size' non è impostato. Funziona in FireFox, ma non in Chrome o Opera (havent testato IE), quindi non puoi determinare quale popover deve essere visualizzato. – davidkonrad

+0

Grandi idee, ma la versione 'mousemove' non funziona in modo affidabile ora in Firefox, e le altre non funzionano affatto con la versione 3.x di Bootstrap, nei miei test. :( –

2

cercato molto duramente per applicare la stessa scatola popover a una casella a discesa senza fortuna:

  1. Sembra che non c'è nessun caso si attiva affatto per gli elementi di opzione all'interno di una selezione a discesa.
  2. L'e.target dell'evento hover su un elemento 'select' sarà sempre l'elemento select stesso! Non c'è modo di ottenere un riferimento al tag 'option' che sta aleggiando.
  3. Ho anche provato a racchiudere il testo in un elemento 'opzione' in un elemento 'span' e provare ad aggiungere un listener di eventi 'hover' o 'mouseover' a quell'elemento 'span'. Questo non funziona neanche.

Quando si modifica il menu a discesa in un elenco (ad esempio, l'aggiunta di dimensioni = attributo "xx"), gli elementi di opzione possono quindi funzionare come elementi normali. Ho il sospetto che in un menu a tendina, tutte le opzioni siano avvolte dal browser in un livello separato. Nessuna interazione con gli elementi interni di un elemento selezionato è consentita. Per favore dimmi se ho torto.