1
0
mirror of synced 2024-11-22 13:06:08 +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;
});
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',[
], function () {
@ -3299,6 +3324,7 @@ define('select2/defaults',[
'./selection/placeholder',
'./selection/allowClear',
'./selection/search',
'./selection/eventRelay',
'./utils',
'./translation',
@ -3323,7 +3349,7 @@ define('select2/defaults',[
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch,
SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS,
@ -3444,6 +3470,11 @@ define('select2/defaults',[
SelectionSearch
);
}
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
}
if (typeof options.language === 'string') {

View File

@ -1226,6 +1226,31 @@ define('select2/selection/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',[
], function () {
@ -3299,6 +3324,7 @@ define('select2/defaults',[
'./selection/placeholder',
'./selection/allowClear',
'./selection/search',
'./selection/eventRelay',
'./utils',
'./translation',
@ -3323,7 +3349,7 @@ define('select2/defaults',[
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch,
SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS,
@ -3444,6 +3470,11 @@ define('select2/defaults',[
SelectionSearch
);
}
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
}
if (typeof options.language === 'string') {

View File

@ -10761,6 +10761,31 @@ define('select2/selection/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',[
], function () {
@ -12834,6 +12859,7 @@ define('select2/defaults',[
'./selection/placeholder',
'./selection/allowClear',
'./selection/search',
'./selection/eventRelay',
'./utils',
'./translation',
@ -12858,7 +12884,7 @@ define('select2/defaults',[
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch,
SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS,
@ -12979,6 +13005,11 @@ define('select2/defaults',[
SelectionSearch
);
}
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
}
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;
});
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',[
], function () {
@ -3727,6 +3752,7 @@ define('select2/defaults',[
'./selection/placeholder',
'./selection/allowClear',
'./selection/search',
'./selection/eventRelay',
'./utils',
'./translation',
@ -3751,7 +3777,7 @@ define('select2/defaults',[
], function ($, ResultsList,
SingleSelection, MultipleSelection, Placeholder, AllowClear,
SelectionSearch,
SelectionSearch, EventRelay,
Utils, Translation, DIACRITICS,
@ -3872,6 +3898,11 @@ define('select2/defaults',[
SelectionSearch
);
}
options.selectionAdapter = Utils.Decorate(
options.selectionAdapter,
EventRelay
);
}
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>
</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">
<div class="col-md-4">
<h1>Tagging support</h1>
@ -838,6 +899,8 @@ $.fn.select2.amd.require(
$(".js-example-programmatic").select2();
$(".js-example-programmatic-multi").select2();
$eventSelect.select2();
$tags.select2({
tags: ['red', 'blue', 'green']
});

View File

@ -15,13 +15,13 @@ slug: home
</div>
<div class="col-md-6 jumbotron-side">
<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>
Download
</a>
</p>
<p>
<strong>Version</strong> 4.0.0 <em>beta</em>
<strong>Version</strong> 4.0.0 <em>beta 1</em>
</p>
</div>
</div>

View File

@ -632,6 +632,45 @@ ajax: {
component that state has changed, as well as an adapter that allows some
of these events to be relayed to the outside word.
</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 id="adapters">

View File

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