1
0
mirror of synced 2024-11-22 21:16:10 +03:00

Set up a public event relay

Now Select2 can fire jQuery events that will match the corresponding
internal events. The `open` and `close` events are now publicly
accessible.

The selection adapter was chosen because it is the least likely to
be moved, but handles the most common events. This `EventRelay`
decorator should theoretically be able to decorate any of the
adapters, as they all have the `bind` method that it needs.
This commit is contained in:
Kevin Brown 2015-01-08 11:41:28 -05:00
parent bba967ba21
commit 64cb528f62
11 changed files with 267 additions and 11 deletions

View File

@ -1226,6 +1226,31 @@ define('select2/selection/search',[
return Search; return Search;
}); });
define('select2/selection/eventRelay',[
'jquery'
], function ($) {
function EventRelay () { }
EventRelay.prototype.bind = function (decorated, container, $container) {
var self = this;
var relayEvents = ['open', 'close'];
decorated.call(this, container, $container);
container.on('*', function (name, params) {
if (relayEvents.indexOf(name) === -1) {
return;
}
var evt = $.Event('select2:' + name, params);
self.$element.trigger(evt);
});
};
return EventRelay;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -3299,6 +3324,7 @@ define('select2/defaults',[
'./selection/placeholder', './selection/placeholder',
'./selection/allowClear', './selection/allowClear',
'./selection/search', './selection/search',
'./selection/eventRelay',
'./utils', './utils',
'./translation', './translation',
@ -3323,7 +3349,7 @@ define('select2/defaults',[
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear, SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch, SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
@ -3444,6 +3470,11 @@ define('select2/defaults',[
SelectionSearch SelectionSearch
); );
} }
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {

View File

@ -1226,6 +1226,31 @@ define('select2/selection/search',[
return Search; return Search;
}); });
define('select2/selection/eventRelay',[
'jquery'
], function ($) {
function EventRelay () { }
EventRelay.prototype.bind = function (decorated, container, $container) {
var self = this;
var relayEvents = ['open', 'close'];
decorated.call(this, container, $container);
container.on('*', function (name, params) {
if (relayEvents.indexOf(name) === -1) {
return;
}
var evt = $.Event('select2:' + name, params);
self.$element.trigger(evt);
});
};
return EventRelay;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -3299,6 +3324,7 @@ define('select2/defaults',[
'./selection/placeholder', './selection/placeholder',
'./selection/allowClear', './selection/allowClear',
'./selection/search', './selection/search',
'./selection/eventRelay',
'./utils', './utils',
'./translation', './translation',
@ -3323,7 +3349,7 @@ define('select2/defaults',[
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear, SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch, SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
@ -3444,6 +3470,11 @@ define('select2/defaults',[
SelectionSearch SelectionSearch
); );
} }
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {

View File

@ -10761,6 +10761,31 @@ define('select2/selection/search',[
return Search; return Search;
}); });
define('select2/selection/eventRelay',[
'jquery'
], function ($) {
function EventRelay () { }
EventRelay.prototype.bind = function (decorated, container, $container) {
var self = this;
var relayEvents = ['open', 'close'];
decorated.call(this, container, $container);
container.on('*', function (name, params) {
if (relayEvents.indexOf(name) === -1) {
return;
}
var evt = $.Event('select2:' + name, params);
self.$element.trigger(evt);
});
};
return EventRelay;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -12834,6 +12859,7 @@ define('select2/defaults',[
'./selection/placeholder', './selection/placeholder',
'./selection/allowClear', './selection/allowClear',
'./selection/search', './selection/search',
'./selection/eventRelay',
'./utils', './utils',
'./translation', './translation',
@ -12858,7 +12884,7 @@ define('select2/defaults',[
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear, SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch, SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
@ -12979,6 +13005,11 @@ define('select2/defaults',[
SelectionSearch SelectionSearch
); );
} }
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {

File diff suppressed because one or more lines are too long

33
dist/js/select2.js vendored
View File

@ -1654,6 +1654,31 @@ define('select2/selection/search',[
return Search; return Search;
}); });
define('select2/selection/eventRelay',[
'jquery'
], function ($) {
function EventRelay () { }
EventRelay.prototype.bind = function (decorated, container, $container) {
var self = this;
var relayEvents = ['open', 'close'];
decorated.call(this, container, $container);
container.on('*', function (name, params) {
if (relayEvents.indexOf(name) === -1) {
return;
}
var evt = $.Event('select2:' + name, params);
self.$element.trigger(evt);
});
};
return EventRelay;
});
define('select2/translation',[ define('select2/translation',[
], function () { ], function () {
@ -3727,6 +3752,7 @@ define('select2/defaults',[
'./selection/placeholder', './selection/placeholder',
'./selection/allowClear', './selection/allowClear',
'./selection/search', './selection/search',
'./selection/eventRelay',
'./utils', './utils',
'./translation', './translation',
@ -3751,7 +3777,7 @@ define('select2/defaults',[
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear, SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch, SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
@ -3872,6 +3898,11 @@ define('select2/defaults',[
SelectionSearch SelectionSearch
); );
} }
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {

File diff suppressed because one or more lines are too long

View File

@ -396,6 +396,67 @@ $(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(nu
</div> </div>
</section> </section>
<section id="events" class="row">
<div class="col-md-4">
<h1>Events</h1>
<p>
Select2 will trigger some events on the original select element,
allowing you to integrate it with other components. You can find more
information on events
<a href="options.html#events">on the options page</a>.
</p>
<p>
<select class="js-states js-example-events form-control"></select>
</p>
<p>
<select class="js-states js-example-events form-control" multiple="multiple"></select>
</p>
<p>
<code>change</code> is fired whenever an option is selected or removed.
</p>
<p>
<code>select2:open</code> is fired whenever the dropdown is opened.
</p>
<p>
<code>select2:close</code> is fired whenever the dropdown is closed.
</p>
</div>
<div class="col-md-8">
<h2>Example code</h2>
<ul class="js-event-log"></ul>
<pre data-fill-from=".js-code-events"></pre>
<script type="text/javascript" class="js-code-events">
var $eventLog = $(".js-event-log");
var $eventSelect = $(".js-example-events");
$eventSelect.on("select2:open", function (e) { log("select2:open"); });
$eventSelect.on("select2:close", function (e) { log("select2:close"); });
$eventSelect.on("change", function (e) { log("change"); });
function log (name, args) {
args = args || {};
var $e = $("<li>" + name + " -> " + JSON.stringify(args) + "</li>");
$eventLog.append($e);
$e.animate({ opacity: 1 }, 10000, 'linear', function () {
$e.animate({ opacity: 0 }, 2000, 'linear', function () {
$e.remove();
});
});
}
</script>
</div>
</section>
<section id="tags" class="row"> <section id="tags" class="row">
<div class="col-md-4"> <div class="col-md-4">
<h1>Tagging support</h1> <h1>Tagging support</h1>
@ -838,6 +899,8 @@ $.fn.select2.amd.require(
$(".js-example-programmatic").select2(); $(".js-example-programmatic").select2();
$(".js-example-programmatic-multi").select2(); $(".js-example-programmatic-multi").select2();
$eventSelect.select2();
$tags.select2({ $tags.select2({
tags: ['red', 'blue', 'green'] tags: ['red', 'blue', 'green']
}); });

View File

@ -15,13 +15,13 @@ slug: home
</div> </div>
<div class="col-md-6 jumbotron-side"> <div class="col-md-6 jumbotron-side">
<p> <p>
<a href="announcements-4.0.html" class="btn btn-success btn-lg"> <a href="https://github.com/select2/select2/releases" class="btn btn-success btn-lg">
<i class="fa fa-download fa-lg"></i> <i class="fa fa-download fa-lg"></i>
Download Download
</a> </a>
</p> </p>
<p> <p>
<strong>Version</strong> 4.0.0 <em>beta</em> <strong>Version</strong> 4.0.0 <em>beta 1</em>
</p> </p>
</div> </div>
</div> </div>

View File

@ -632,6 +632,45 @@ ajax: {
component that state has changed, as well as an adapter that allows some component that state has changed, as well as an adapter that allows some
of these events to be relayed to the outside word. of these events to be relayed to the outside word.
</p> </p>
<dl class="dl-horizontal">
<dt>Adapter</dt>
<dd>
<code title="select2/selection">SelectionAdapter</code>
</dd>
<dt>Decorator</dt>
<dd>
<code title="select2/selection/eventRelay">EventRelay</code>
</dd>
</dl>
<h2>
Public events
</h2>
<p>
All public events are relayed using the jQuery event system, and they are
triggered on the <code>&lt;select&gt;</code> element that Select2 is
attached to. You can attach to them using the
<a href="https://api.jquery.com/on/"><code>.on</code> method</a> provided
by jQuery.
</p>
<h2>
Internal events
</h2>
<p>
Select2 triggers internal events using its own internal event system,
which allows adapters to communicate with each other. These events are not
accessible through the jQuery event system.
</p>
<p>
You can find more information on the public events triggered by individual
adapters in <a href="#adapters">the individual adapter documentation</a>.
</p>
</section> </section>
<section id="adapters"> <section id="adapters">

View File

@ -7,6 +7,7 @@ define([
'./selection/placeholder', './selection/placeholder',
'./selection/allowClear', './selection/allowClear',
'./selection/search', './selection/search',
'./selection/eventRelay',
'./utils', './utils',
'./translation', './translation',
@ -31,7 +32,7 @@ define([
], function ($, ResultsList, ], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear, SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch, SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS, Utils, Translation, DIACRITICS,
@ -152,6 +153,11 @@ define([
SelectionSearch SelectionSearch
); );
} }
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
} }
if (typeof options.language === 'string') { if (typeof options.language === 'string') {

24
src/js/select2/selection/eventRelay.js vendored Normal file
View File

@ -0,0 +1,24 @@
define([
'jquery'
], function ($) {
function EventRelay () { }
EventRelay.prototype.bind = function (decorated, container, $container) {
var self = this;
var relayEvents = ['open', 'close'];
decorated.call(this, container, $container);
container.on('*', function (name, params) {
if (relayEvents.indexOf(name) === -1) {
return;
}
var evt = $.Event('select2:' + name, params);
self.$element.trigger(evt);
});
};
return EventRelay;
});