Skip to content

Commit 010c786

Browse files
committed
maximize height
1 parent 77b9f8c commit 010c786

File tree

8 files changed

+221
-16
lines changed

8 files changed

+221
-16
lines changed

Select2Action.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Select2Action extends \yii\base\Action
2727
* @example function ($q) { return ['results' => [['id'=>1,'text'=>'First Element'], ['id'=>2,'text'=>'Second Element']]]; }
2828
*/
2929
public $dataCallback;
30-
30+
3131
/**
3232
* @inheritdoc
3333
*/
@@ -36,21 +36,21 @@ public function init()
3636
if (!is_callable($this->dataCallback)) {
3737
throw new InvalidConfigException('"' . get_class($this) . '::dataCallback" should be a valid callback.');
3838
}
39-
39+
4040
\Yii::$app->response->format = Response::FORMAT_JSON;
4141
$this->controller->enableCsrfValidation = false;
4242
}
4343

4444
public function run()
4545
{
4646
$q = \Yii::$app->request->get($this->paramName);
47-
48-
$data = call_user_func($this->dataCallback, $q);
49-
47+
48+
$data = call_user_func($this->dataCallback, $q);
49+
5050
if (is_array($data) && (!isset($data['results']))) {
5151
$data = ['results' => $data];
5252
}
53-
53+
5454
return $data;
5555
}
5656
}

Select2Asset.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ class Select2Asset extends \yii\web\AssetBundle
1616
// The files are not web directory accessible, therefore we need
1717
// to specify the sourcePath property. Notice the @bower alias used.
1818
public $sourcePath = '@bower/select2/dist';
19-
19+
2020
public $css = [
2121
'css/select2.min.css',
2222
];
23-
23+
2424
public $js = [
2525
'js/select2.full.min.js',
2626
];
27-
27+
2828
public $depends = [
2929
'yii\web\JqueryAsset',
3030
];

Select2BootstrapAsset.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@
88
namespace conquer\select2;
99

1010
/**
11-
* @author Andrey Borodulin
1211
* @link http://select2.github.io/select2-bootstrap-theme/
1312
*/
1413
class Select2BootstrapAsset extends \yii\web\AssetBundle
1514
{
1615
// The files are not web directory accessible, therefore we need
1716
// to specify the sourcePath property. Notice the @bower alias used.
1817
public $sourcePath = '@bower/select2-bootstrap-theme/dist';
19-
18+
2019
public $css = [
2120
'select2-bootstrap.min.css',
2221
];
23-
22+
2423
public $depends = [
2524
'yii\bootstrap\BootstrapAsset',
2625
'conquer\select2\Select2Asset',

Select2MaximizeAsset.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* @link https://github.com/borodulin/yii2-select2
4+
* @copyright Copyright (c) 2015 Andrey Borodulin
5+
* @license https://github.com/borodulin/yii2-select2/blob/master/LICENSE
6+
*/
7+
8+
namespace conquer\select2;
9+
10+
/**
11+
* https://github.com/panorama-ed/maximize-select2-height
12+
*/
13+
class Select2MaximizeAsset extends \yii\web\AssetBundle
14+
{
15+
// The files are not web directory accessible, therefore we need
16+
// to specify the sourcePath property. Notice the @conquer alias used.
17+
public $sourcePath = '@conquer/select2/assets';
18+
19+
public $js=[
20+
'maximize-select2-height.min.js',
21+
];
22+
23+
public $depends= [
24+
'conquer\select2\Select2Asset',
25+
];
26+
}

Select2Widget.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ class Select2Widget extends \yii\widgets\InputWidget
6767
*/
6868
public $settings = [];
6969

70+
/**
71+
* If value is integer, then it passed as "cushion" parameter
72+
* @link https://github.com/panorama-ed/maximize-select2-height
73+
* @var mixed
74+
*/
75+
public $maximize = false;
76+
7077
/**
7178
* @inheritdoc
7279
*/
@@ -132,6 +139,7 @@ public function run()
132139
public function registerAssets()
133140
{
134141
$view = $this->getView();
142+
/* @var $bandle yii\web\AssetBundle */
135143
$bandle = Select2Asset::register($view);
136144
if ($this->language !== false) {
137145
$langs[0] = $this->language ? $this->language : \Yii::$app->language;
@@ -151,6 +159,18 @@ public function registerAssets()
151159
Select2BootstrapAsset::register($view);
152160
}
153161
$settings = Json::encode($this->settings);
154-
$view->registerJs("jQuery('#{$this->options['id']}').select2($settings);");
162+
$js = "jQuery('#{$this->options['id']}').select2($settings)";
163+
if ($this->maximize) {
164+
Select2MaximizeAsset::register($view);
165+
if (is_integer($this->maximize)) {
166+
$this->maximize = "{cushion: $this->maximize}";
167+
} elseif (is_array($this->maximize)) {
168+
$this->maximize = Json::encode($this->maximize);
169+
} else {
170+
$this->maximize = '{}';
171+
}
172+
$js .= ".maximizeSelect2Height($this->maximize)";
173+
}
174+
$view->registerJs("$js;");
155175
}
156176
}

assets/maximize-select2-height.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// maximize-select2-height v1.0.2
2+
// (c) Panorama Education 2015
3+
// MIT License
4+
5+
// This jQuery/Select2 plugin expands a Select2 dropdown to take up as much
6+
// height as possible given its position on the page and the current viewport
7+
// size. The plugin correctly handles:
8+
// - Dynamic window resizing.
9+
// - The effects of scroll bars on the viewport.
10+
// - Select2 rendering dropdowns both upwards and downwards.
11+
12+
// NOTE: The original <select> element that is $().select2()'d *must* have a
13+
// unique ID for this code to work. (Ex: <select id="my-unique-id"></select>)
14+
15+
(function ($) {
16+
"use strict";
17+
18+
// We can find these elements now, since the properties we check on them are
19+
// all via methods that are recalculated each time.
20+
var $window = $(window);
21+
var $document = $(document);
22+
23+
// @param {Object} options The options object passed in when this plugin is
24+
// initialized
25+
// @param {Boolean} dropdownDownwards True iff the dropdown is rendered
26+
// downwards (Select2 sometimes renders the options upwards to better fit on
27+
// a page)
28+
// @return {Object} The options passed in, combined with defaults. Keys are:
29+
// - cushion: The number of pixels between the edge of the dropdown and the
30+
// edge of the viewable window. [Default: 10, except when a
31+
// horizontal scroll bar would interfere, in which case it's 30.]
32+
// NOTE: If a value is passed in, no adjustments for possible
33+
// scroll bars are made.
34+
var settings = function (options, dropdownDownwards) {
35+
return $.extend({
36+
cushion: (
37+
dropdownDownwards && $document.width() > $window.width()
38+
) ? 30 : 10
39+
}, options);
40+
};
41+
42+
// @param {String} id The DOM element ID for the original <select> node
43+
// @param {jQuery object} $select2Results The DOM element with class
44+
// "select2-results"
45+
// @param {jQuery object} $grandparent The grandparent object of the
46+
// $select2Results object
47+
// @param {Object} options The options object passed in when this plugin is
48+
// initialized
49+
// @param {Boolean} dropdownDownwards True iff the dropdown is rendered
50+
// downwards (Select2 sometimes renders the options upwards to better fit on
51+
// a page)
52+
// @return {Number} the maximum height of the Select2 results box to display
53+
var computeMaxHeight = function (
54+
id, $select2Results, $grandparent, options, dropdownDownwards
55+
) {
56+
var height;
57+
var resultsBoxMiscellaniaHeight;
58+
var widgetBoxOffset;
59+
60+
if (dropdownDownwards) {
61+
// When the dropdown appears downwards, the formula is:
62+
// visible window size
63+
// + out-of-window pixels we've scrolled past
64+
// - size of content (including offscreen content) above results box
65+
// ------------------------------------------
66+
// total height available to us
67+
68+
// innerHeight is more accurate across browsers than $(window).height().
69+
height = window.innerHeight +
70+
$window.scrollTop() -
71+
$select2Results.offset().top;
72+
} else {
73+
// When the dropdown appears upwards, the formula is:
74+
// vertical position of the widget (clickable) dropdown box
75+
// - out-of-window pixels we've scrolled past
76+
// - height of the search box and other content above the actual results
77+
// but in the results box
78+
// ------------------------------------------
79+
// total height available to us
80+
81+
// Compute the global vertical offset of the widget box (the one with the
82+
// downward arrow that the user clicks on to expose options).
83+
widgetBoxOffset = $("#select2-" + id + "-container").
84+
parent().parent().parent().offset().top;
85+
86+
// Compute the height, if any, of search box and other content in the
87+
// results box but not part of the results.
88+
resultsBoxMiscellaniaHeight = $grandparent.height() -
89+
$select2Results.height();
90+
height = widgetBoxOffset -
91+
$window.scrollTop() -
92+
resultsBoxMiscellaniaHeight;
93+
}
94+
95+
// Leave a little cushion to prevent the dropdown from
96+
// rendering off the edge of the viewport.
97+
return height - settings(options, dropdownDownwards).cushion;
98+
};
99+
100+
// Call on a jQuery Select2 element to maximize the height of the dropdown
101+
// every time it is opened.
102+
// @param {Object} options The options object passed in when this plugin is
103+
// initialized
104+
$.fn.maximizeSelect2Height = function (options) {
105+
return this.each(function (_, el) {
106+
// Each time the Select2 is opened, resize it to take up as much vertical
107+
// space as possible given its position and the current viewport size.
108+
$(el).on("select2:open", function () {
109+
// We have to put this code block inside a timeout because we determine
110+
// whether the dropdown is rendered upwards or downwards via a hack that
111+
// looks at the CSS classes, and these aren't set until Select2 has a
112+
// chance to render the box, which occurs after this event fires.
113+
114+
// The alternative solution that avoids using a timeout would be to
115+
// directly modify the document's stylesheets (instead of the styles for
116+
// individual elements), but that is both ugly/dangerous and actually
117+
// impossible for us because we need to modify the styles of a parent
118+
// node of a given DOM node when the parent has no unique ID, which CSS
119+
// doesn't have the ability to do.
120+
setTimeout(function () {
121+
var $select2Results = $("#select2-" + el.id + "-results");
122+
var $parent = $select2Results.parent();
123+
var $grandparent = $parent.parent();
124+
var dropdownDownwards = $grandparent
125+
.hasClass("select2-dropdown--below");
126+
127+
var maxHeight = computeMaxHeight(
128+
el.id,
129+
$select2Results,
130+
$grandparent,
131+
options,
132+
dropdownDownwards
133+
);
134+
135+
// Set the max height of the relevant DOM elements. We use max-height
136+
// instead of height directly to correctly handle cases in which there
137+
// are only a few elements (we don't want a giant empty dropdown box).
138+
$parent.css("max-height", maxHeight);
139+
$select2Results.css("max-height", maxHeight);
140+
141+
// Select2 corrects the positioning of the results box on scroll, so
142+
// we trigger that event here to let it auto-correct. This is done for
143+
// the case where the dropdown appears upwards; we adjust its max
144+
// height but we also want to move it up further, lest it cover up the
145+
// initial dropdown box.
146+
$(document).trigger("scroll");
147+
});
148+
});
149+
});
150+
};
151+
})(jQuery);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// maximize-select2-height v1.0.2
2+
// (c) Panorama Education 2015
3+
// MIT License
4+
!function(t){"use strict"
5+
var e=t(window),n=t(document),i=function(i,o){return t.extend({cushion:o&&n.width()>e.width()?30:10},i)},o=function(n,o,r,c,s){var u,h,a
6+
return s?u=window.innerHeight+e.scrollTop()-o.offset().top:(a=t("#select2-"+n+"-container").parent().parent().parent().offset().top,h=r.height()-o.height(),u=a-e.scrollTop()-h),u-i(c,s).cushion}
7+
t.fn.maximizeSelect2Height=function(e){return this.each(function(n,i){t(i).on("select2:open",function(){setTimeout(function(){var n=t("#select2-"+i.id+"-results"),r=n.parent(),c=r.parent(),s=c.hasClass("select2-dropdown--below"),u=o(i.id,n,c,e,s)
8+
r.css("max-height",u),n.css("max-height",u),t(document).trigger("scroll")})})})}}(jQuery)

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@
1717
],
1818
"extra": {
1919
"branch-alias": {
20-
"dev-master": "1.3.2.x-dev"
20+
"dev-master": "1.5.2.x-dev",
21+
"dev-release": "1.4.3.x-dev"
2122
}
2223
},
2324
"require": {
2425
"php": ">=5.4.0",
2526
"yiisoft/yii2": "*",
26-
"conquer/helpers": "~2.0.7",
27-
"bower-asset/select2": "~4.0.0",
27+
"conquer/helpers": ">=2.0.7",
28+
"bower-asset/select2": ">=4.0.0",
2829
"bower-asset/select2-bootstrap-theme": "*"
2930
},
3031
"autoload": {

0 commit comments

Comments
 (0)