2013-11-14 9 views
16

Wie pro Titel spiegelt, ist es eine Möglichkeit, select2 zu zwingen, immer statt einem Drop-up ein Dropdown zu erstellen?Prevent Select2 aus dem Drop-Down nach oben

Es scheint auch einige Javascript zu geben, die entweder die Spiegelung verursachen, wenn Sie über das Dropdown blättern, eine neue CSS-Klasse "select2-drop-over" hinzufügen oder beides.

EDIT: Ich habe sollte festgelegt, dass ich die Bibliothek in über select2-Schienen bin ziehen. Ich hoffe, dass es einen Weg gibt, der nicht die gesamte lib select2 in mich zieht und die Datei select2.js direkt editiert.

Antwort

3

Ändern der Plugin bevorzugt ändern ist nicht, wie Sie erwähnen. Ich hatte ein ähnliches Problem und konnte keine Möglichkeit finden, select2 Optionen zu verwenden, um das Dropdown zu zwingen, darunter zu bleiben. Die Lösung, die ich am Ende mit ist die folgende:

$("#mySelect2").select2({ ...options... }) 
    .on('select2-open', function() { 

     // however much room you determine you need to prevent jumping 
     var requireHeight = 600; 
     var viewportBottom = $(window).scrollTop() + $(window).height(); 

     // figure out if we need to make changes 
     if (viewportBottom < requireHeight) 
     {   
      // determine how much padding we should add (via marginBottom) 
      var marginBottom = requireHeight - viewportBottom; 

      // adding padding so we can scroll down 
      $(".aLwrElmntOrCntntWrppr").css("marginBottom", marginBottom + "px"); 

      // animate to just above the select2, now with plenty of room below 
      $('html, body').animate({ 
       scrollTop: $("#mySelect2").offset().top - 10 
      }, 1000); 
     } 
    }); 

Dieser Code bestimmt, ob es genug Platz ist, um den Drop-Down am Boden zu platzieren und wenn nicht, schafft es durch Zugabe von margin-bottom zu einem Elemente auf der Seite. Es scrollt dann bis knapp über die select2, so dass das Dropdown nicht umdrehen wird.

+0

Das scheint nicht für mich zu funktionieren: http://jsfiddle.net/brunodd/jEADR/2006/ – brunodd

+0

Ich bin mir nicht sicher, was du meinst, es funktioniert ok für mich in Chrome – shanabus

+1

Die Version, die ich benutze ist 4.0 und das ist noch 3. Ich habe es sowieso schon behoben. http://jsfiddle.net/brunodd/jEADR/2009 – brunodd

18

können Sie bearbeiten nur select2.js


Wo es heißt

enoughRoomBelow = dropTop + dropHeight <= viewportBottom, 
enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(), 

es nur

enoughRoomBelow = true, 
enoughRoomAbove = false, 
+10

Aber das bedeutet, dass Sie dies im Hinterkopf behalten, wenn Sie Select2 in der Zukunft aktualisieren möchten. Also sei vorsichtig damit. – MarkoHiel

+1

Sie sollten das Quellskript nie ändern oder Sie werden Probleme auf der ganzen Linie haben. – cmfolio

+0

Leider, das ist der einzige Weg, um es für mich zu beheben (mit Ajax Abfragen und die Notwendigkeit, bei der Auswahl zu schließen). Ein PR wurde erstellt, um dieses Problem zu beheben, ist aber noch nicht zusammengeführt: https://github.com/select2/select2/pull/4560 –

1

von Aktualisiert [shanabus]

jQuery("#line_item").select2({ 
      formatResult: Invoice.formatLineItem 
     }) 
     .on('select2-open', function() { 
      // however much room you determine you need to prevent jumping 
      var requireHeight = $("#select2-drop").height()+10; 
      var viewportBottom = $(window).height() - $("#line_item").offset().top; 

      // figure out if we need to make changes 
      if (viewportBottom < requireHeight) 
      { 
       // determine how much padding we should add (via marginBottom) 
       var marginBottom = requireHeight - viewportBottom; 

       // adding padding so we can scroll down 
       $(".aLwrElmntOrCntntWrppr").css("marginBottom", marginBottom + "px"); 

       // animate to just above the select2, now with plenty of room below 
       $('html, body').animate({ 
        scrollTop: $("#select2-drop").offset().top - 10 
       }, 1000); 
      } 
     }); 
+0

Was ist $ (". aLwrElmntOrCntntWrppr") – Jaskey

3

antwortet ich verwendet, um eine einfache/schnelle Lösung dafür zu finden:

 $("select").select2({ 

      // Options 

     }).on('select2:open',function(){ 

      $('.select2-dropdown--above').attr('id','fix'); 
      $('#fix').removeClass('select2-dropdown--above'); 
      $('#fix').addClass('select2-dropdown--below'); 

     }); 

Es ist ganz einfach, man muss nur die .select2-dropdown-- ändern oben zu .select2-Dropdown - unter im Eröffnungsveranstaltung (select2: offen).

Es wird funktioniert nur unter der Veranstaltung, und es könnte viele andere Möglichkeiten, um es auszuführen nur Klassen zu ändern, wenn die Auswahl geöffnet wird.

ps. Es wird nicht funktionieren, wenn Sie versuchen, Ihre Auswahl mit jquery zu füllen.

+0

funktioniert nicht als select2 fügt einige Inline-CSS mit einem Top-Wert – Ben

+0

Nun, es hat für mich funktioniert. Prost. –

+0

Weiß nicht wie möglich mit einem Inline-Top-Wert auf dem betroffenen Element – Ben

2

Sie können es wie so durch Überschreiben CSS tun:

.select-dropdown { 
    position: static; 
} 
.select-dropdown .select-dropdown--above { 
     margin-top: 336px; 
} 
2

Da der Quellcode zu modifizieren ist keine Option, und das Hinzufügen eines Haken zum select2:open Ereignis ist nicht sehr elegant, vor allem, wenn Sie mehrere select2 Instanzen Auf der gleichen Seite habe ich eine kleine Erweiterung für das Select2 Plugin geschrieben.

Meine Implementierung basiert auf einem PR aus dem Repository des Plugins (https://github.com/select2/select2/pull/4618), das noch nicht zusammengeführt wurde.

Grundsätzlich überschreibt der folgende Code die ursprüngliche Plugin-Funktion, die die Dropdown-Positionierung behandelt, und fügt eine neue Option (dropdownPosition) hinzu, um die Dropdown-Positionierung über/unter zu erzwingen.

Die neue Option dropdownPosition kann folgende Werte annehmen: - below - Das Dropdown wird immer am unteren Rand der Eingabe angezeigt; - above - das Dropdown wird immer am Anfang der Eingabe angezeigt; - auto (Standard) - es verwendet das alte Verhalten.

Legen Sie einfach den folgenden Code nach select2.js Datei:

(function($) { 

    var Defaults = $.fn.select2.amd.require('select2/defaults'); 

    $.extend(Defaults.defaults, { 
    dropdownPosition: 'auto' 
    }); 

    var AttachBody = $.fn.select2.amd.require('select2/dropdown/attachBody'); 

    var _positionDropdown = AttachBody.prototype._positionDropdown; 

    AttachBody.prototype._positionDropdown = function() { 

    var $window = $(window); 

    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); 
    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); 

    var newDirection = null; 

    var offset = this.$container.offset(); 

    offset.bottom = offset.top + this.$container.outerHeight(false); 

    var container = { 
     height: this.$container.outerHeight(false) 
    }; 

    container.top = offset.top; 
    container.bottom = offset.top + container.height; 

    var dropdown = { 
     height: this.$dropdown.outerHeight(false) 
    }; 

    var viewport = { 
     top: $window.scrollTop(), 
     bottom: $window.scrollTop() + $window.height() 
    }; 

    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); 
    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); 

    var css = { 
     left: offset.left, 
     top: container.bottom 
    }; 

    // Determine what the parent element is to use for calciulating the offset 
    var $offsetParent = this.$dropdownParent; 

    // For statically positoned elements, we need to get the element 
    // that is determining the offset 
    if ($offsetParent.css('position') === 'static') { 
     $offsetParent = $offsetParent.offsetParent(); 
    } 

    var parentOffset = $offsetParent.offset(); 

    css.top -= parentOffset.top 
    css.left -= parentOffset.left; 

    var dropdownPositionOption = this.options.get('dropdownPosition'); 

    if (dropdownPositionOption === 'above' || dropdownPositionOption === 'below') { 
     newDirection = dropdownPositionOption; 
    } else { 

     if (!isCurrentlyAbove && !isCurrentlyBelow) { 
     newDirection = 'below'; 
     } 

     if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { 
     newDirection = 'above'; 
     } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { 
     newDirection = 'below'; 
     } 

    } 

    if (newDirection == 'above' || 
    (isCurrentlyAbove && newDirection !== 'below')) { 
     css.top = container.top - parentOffset.top - dropdown.height; 
    } 

    if (newDirection != null) { 
     this.$dropdown 
     .removeClass('select2-dropdown--below select2-dropdown--above') 
     .addClass('select2-dropdown--' + newDirection); 
     this.$container 
     .removeClass('select2-container--below select2-container--above') 
     .addClass('select2-container--' + newDirection); 
    } 

    this.$dropdownContainer.css(css); 

    }; 

})(window.jQuery); 

Das initialisieren das Plugin mit wie folgt:

$(document).ready(function() { 
    $(".select-el").select2({ 
    dropdownPosition: 'below' 
    }); 
}); 

Fiddle hier: https://jsfiddle.net/byxj73ov/

Github-Repository: https://github.com/andreivictor/select2-dropdownPosition