1
0
mirror of synced 2025-02-03 21:59:24 +03:00

Added basic implementation of tags

Tags no longer takes an array, as pre-existing tags should already
exist as options in the data adapter.  A compatibility module will
later be added to convert tag data that is passed in to array data.

Tags allow for users to enter their own options, which will be
added to the beginning of the results list.
This commit is contained in:
Kevin Brown 2014-10-20 19:15:37 -04:00
parent 9e130956fc
commit 559a93bcb6
11 changed files with 534 additions and 102 deletions

View File

@ -879,6 +879,16 @@ define('select2/data/select',[
SelectAdapter.prototype.select = function (data) {
var self = this;
// Create items marked as tags
if (data._tag === true) {
// Clear the tag flag from it
delete data._tag;
// Create and add the option
var $option = this.option(data);
this.$element.append($option);
}
if (this.$element.prop('multiple')) {
this.current(function (currentData) {
var val = [];
@ -901,6 +911,7 @@ define('select2/data/select',[
var val = data.id;
this.$element.val(val);
this.$element.trigger('change');
}
};
@ -924,6 +935,7 @@ define('select2/data/select',[
}
self.$element.val(val);
self.$element.trigger('change');
});
};
@ -967,6 +979,25 @@ define('select2/data/select',[
callback(data);
};
SelectAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = $option.data('data');
@ -1074,25 +1105,6 @@ define('select2/data/array',[
ArrayAdapter.__super__.select.call(this, data);
};
ArrayAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
ArrayAdapter.prototype.query = function (params, callback) {
var matches = [];
var self = this;
@ -1157,6 +1169,69 @@ define('select2/data/ajax',[
return AjaxAdapter;
});
define('select2/data/tags',[
], function () {
function Tags (decorated, $element, options) {
var tags = options.get('tags');
decorated.call(this, $element, options);
}
Tags.prototype.query = function (decorated, params, callback) {
var self = this;
if (params.term == null || params.term === '' || params.page != null) {
decorated.call(this, params, callback);
return;
}
function wrapper (data, child) {
for (var i = 0; i < data.length; i++) {
var option = data[i];
var checkChildren = (
option.children != null && !wrapper(option.children, true)
);
var checkText = option.text === params.term;
if (checkText || checkChildren) {
if (child) {
return false;
}
callback(data);
return;
}
}
if (child) {
return true;
}
var tag = self.createTag(params);
tag._tag = true;
data.unshift(tag);
callback(data);
}
decorated.call(this, params, wrapper);
};
Tags.prototype.createTag = function (decorated, params) {
return {
id: params.term,
text: params.term
};
};
return Tags;
});
define('select2/dropdown',[
'./utils'
], function (Utils) {
@ -1256,13 +1331,14 @@ define('select2/defaults',[
'./data/select',
'./data/array',
'./data/ajax',
'./data/tags',
'./dropdown',
'./dropdown/search'
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
SelectData, ArrayData, AjaxData, Tags,
Dropdown, Search) {
function Defaults () {
this.reset();
@ -1281,6 +1357,10 @@ define('select2/defaults',[
}
}
if (options.tags != null) {
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
}
if (options.resultsAdapter == null) {
options.resultsAdapter = ResultsList;
}

120
dist/js/select2.amd.js vendored
View File

@ -879,6 +879,16 @@ define('select2/data/select',[
SelectAdapter.prototype.select = function (data) {
var self = this;
// Create items marked as tags
if (data._tag === true) {
// Clear the tag flag from it
delete data._tag;
// Create and add the option
var $option = this.option(data);
this.$element.append($option);
}
if (this.$element.prop('multiple')) {
this.current(function (currentData) {
var val = [];
@ -901,6 +911,7 @@ define('select2/data/select',[
var val = data.id;
this.$element.val(val);
this.$element.trigger('change');
}
};
@ -924,6 +935,7 @@ define('select2/data/select',[
}
self.$element.val(val);
self.$element.trigger('change');
});
};
@ -967,6 +979,25 @@ define('select2/data/select',[
callback(data);
};
SelectAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = $option.data('data');
@ -1074,25 +1105,6 @@ define('select2/data/array',[
ArrayAdapter.__super__.select.call(this, data);
};
ArrayAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
ArrayAdapter.prototype.query = function (params, callback) {
var matches = [];
var self = this;
@ -1157,6 +1169,69 @@ define('select2/data/ajax',[
return AjaxAdapter;
});
define('select2/data/tags',[
], function () {
function Tags (decorated, $element, options) {
var tags = options.get('tags');
decorated.call(this, $element, options);
}
Tags.prototype.query = function (decorated, params, callback) {
var self = this;
if (params.term == null || params.term === '' || params.page != null) {
decorated.call(this, params, callback);
return;
}
function wrapper (data, child) {
for (var i = 0; i < data.length; i++) {
var option = data[i];
var checkChildren = (
option.children != null && !wrapper(option.children, true)
);
var checkText = option.text === params.term;
if (checkText || checkChildren) {
if (child) {
return false;
}
callback(data);
return;
}
}
if (child) {
return true;
}
var tag = self.createTag(params);
tag._tag = true;
data.unshift(tag);
callback(data);
}
decorated.call(this, params, wrapper);
};
Tags.prototype.createTag = function (decorated, params) {
return {
id: params.term,
text: params.term
};
};
return Tags;
});
define('select2/dropdown',[
'./utils'
], function (Utils) {
@ -1256,13 +1331,14 @@ define('select2/defaults',[
'./data/select',
'./data/array',
'./data/ajax',
'./data/tags',
'./dropdown',
'./dropdown/search'
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
SelectData, ArrayData, AjaxData, Tags,
Dropdown, Search) {
function Defaults () {
this.reset();
@ -1281,6 +1357,10 @@ define('select2/defaults',[
}
}
if (options.tags != null) {
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
}
if (options.resultsAdapter == null) {
options.resultsAdapter = ResultsList;
}

View File

@ -10417,6 +10417,16 @@ define('select2/data/select',[
SelectAdapter.prototype.select = function (data) {
var self = this;
// Create items marked as tags
if (data._tag === true) {
// Clear the tag flag from it
delete data._tag;
// Create and add the option
var $option = this.option(data);
this.$element.append($option);
}
if (this.$element.prop('multiple')) {
this.current(function (currentData) {
var val = [];
@ -10439,6 +10449,7 @@ define('select2/data/select',[
var val = data.id;
this.$element.val(val);
this.$element.trigger('change');
}
};
@ -10462,6 +10473,7 @@ define('select2/data/select',[
}
self.$element.val(val);
self.$element.trigger('change');
});
};
@ -10505,6 +10517,25 @@ define('select2/data/select',[
callback(data);
};
SelectAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = $option.data('data');
@ -10612,25 +10643,6 @@ define('select2/data/array',[
ArrayAdapter.__super__.select.call(this, data);
};
ArrayAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
ArrayAdapter.prototype.query = function (params, callback) {
var matches = [];
var self = this;
@ -10695,6 +10707,69 @@ define('select2/data/ajax',[
return AjaxAdapter;
});
define('select2/data/tags',[
], function () {
function Tags (decorated, $element, options) {
var tags = options.get('tags');
decorated.call(this, $element, options);
}
Tags.prototype.query = function (decorated, params, callback) {
var self = this;
if (params.term == null || params.term === '' || params.page != null) {
decorated.call(this, params, callback);
return;
}
function wrapper (data, child) {
for (var i = 0; i < data.length; i++) {
var option = data[i];
var checkChildren = (
option.children != null && !wrapper(option.children, true)
);
var checkText = option.text === params.term;
if (checkText || checkChildren) {
if (child) {
return false;
}
callback(data);
return;
}
}
if (child) {
return true;
}
var tag = self.createTag(params);
tag._tag = true;
data.unshift(tag);
callback(data);
}
decorated.call(this, params, wrapper);
};
Tags.prototype.createTag = function (decorated, params) {
return {
id: params.term,
text: params.term
};
};
return Tags;
});
define('select2/dropdown',[
'./utils'
], function (Utils) {
@ -10794,13 +10869,14 @@ define('select2/defaults',[
'./data/select',
'./data/array',
'./data/ajax',
'./data/tags',
'./dropdown',
'./dropdown/search'
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
SelectData, ArrayData, AjaxData, Tags,
Dropdown, Search) {
function Defaults () {
this.reset();
@ -10819,6 +10895,10 @@ define('select2/defaults',[
}
}
if (options.tags != null) {
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
}
if (options.resultsAdapter == null) {
options.resultsAdapter = ResultsList;
}

File diff suppressed because one or more lines are too long

120
dist/js/select2.js vendored
View File

@ -1308,6 +1308,16 @@ define('select2/data/select',[
SelectAdapter.prototype.select = function (data) {
var self = this;
// Create items marked as tags
if (data._tag === true) {
// Clear the tag flag from it
delete data._tag;
// Create and add the option
var $option = this.option(data);
this.$element.append($option);
}
if (this.$element.prop('multiple')) {
this.current(function (currentData) {
var val = [];
@ -1330,6 +1340,7 @@ define('select2/data/select',[
var val = data.id;
this.$element.val(val);
this.$element.trigger('change');
}
};
@ -1353,6 +1364,7 @@ define('select2/data/select',[
}
self.$element.val(val);
self.$element.trigger('change');
});
};
@ -1396,6 +1408,25 @@ define('select2/data/select',[
callback(data);
};
SelectAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = $option.data('data');
@ -1503,25 +1534,6 @@ define('select2/data/array',[
ArrayAdapter.__super__.select.call(this, data);
};
ArrayAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
ArrayAdapter.prototype.query = function (params, callback) {
var matches = [];
var self = this;
@ -1586,6 +1598,69 @@ define('select2/data/ajax',[
return AjaxAdapter;
});
define('select2/data/tags',[
], function () {
function Tags (decorated, $element, options) {
var tags = options.get('tags');
decorated.call(this, $element, options);
}
Tags.prototype.query = function (decorated, params, callback) {
var self = this;
if (params.term == null || params.term === '' || params.page != null) {
decorated.call(this, params, callback);
return;
}
function wrapper (data, child) {
for (var i = 0; i < data.length; i++) {
var option = data[i];
var checkChildren = (
option.children != null && !wrapper(option.children, true)
);
var checkText = option.text === params.term;
if (checkText || checkChildren) {
if (child) {
return false;
}
callback(data);
return;
}
}
if (child) {
return true;
}
var tag = self.createTag(params);
tag._tag = true;
data.unshift(tag);
callback(data);
}
decorated.call(this, params, wrapper);
};
Tags.prototype.createTag = function (decorated, params) {
return {
id: params.term,
text: params.term
};
};
return Tags;
});
define('select2/dropdown',[
'./utils'
], function (Utils) {
@ -1685,13 +1760,14 @@ define('select2/defaults',[
'./data/select',
'./data/array',
'./data/ajax',
'./data/tags',
'./dropdown',
'./dropdown/search'
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
SelectData, ArrayData, AjaxData, Tags,
Dropdown, Search) {
function Defaults () {
this.reset();
@ -1710,6 +1786,10 @@ define('select2/defaults',[
}
}
if (options.tags != null) {
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
}
if (options.resultsAdapter == null) {
options.resultsAdapter = ResultsList;
}

File diff suppressed because one or more lines are too long

View File

@ -211,6 +211,33 @@ $(".js-example-data-array-selected").select2({
<script type="text/x-example-code" class="js-code-data-disabled">
</script>
</div>
</section>
<section id="tagss" class="row">
<div class="col-md-4">
<h1>Tagging support</h1>
<p>
Select2 can be used to quickly set up fields used for tagging.
</p>
<p>
<select class="js-example-tags form-control">
<option value="one">First</option>
<option value="other">Other</option>
</select>
</p>
</div>
<div class="col-md-8">
<h2>Example code</h2>
<pre data-fill-from=".js-code-disabled-results"></pre>
<script type="text/x-example-code" class="js-code-data-disabled">
</script>
</div>
</section>
@ -309,6 +336,8 @@ require(["select2/core", "select2/utils"], function (Select2, Utils) {
var $disabledResults = $(".js-example-disabled-results");
var $tags = $(".js-example-tags");
$basicSingle.select2();
$basicMultiple.select2()
@ -329,5 +358,9 @@ require(["select2/core", "select2/utils"], function (Select2, Utils) {
});
$disabledResults.select2();
$tags.select2({
tags: true
});
});
</script>

View File

@ -30,25 +30,6 @@ define([
ArrayAdapter.__super__.select.call(this, data);
};
ArrayAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
ArrayAdapter.prototype.query = function (params, callback) {
var matches = [];
var self = this;

View File

@ -29,6 +29,16 @@ define([
SelectAdapter.prototype.select = function (data) {
var self = this;
// Create items marked as tags
if (data._tag === true) {
// Clear the tag flag from it
delete data._tag;
// Create and add the option
var $option = this.option(data);
this.$element.append($option);
}
if (this.$element.prop('multiple')) {
this.current(function (currentData) {
var val = [];
@ -51,6 +61,7 @@ define([
var val = data.id;
this.$element.val(val);
this.$element.trigger('change');
}
};
@ -74,6 +85,7 @@ define([
}
self.$element.val(val);
self.$element.trigger('change');
});
};
@ -117,6 +129,25 @@ define([
callback(data);
};
SelectAdapter.prototype.option = function (data) {
var $option = $('<option></option>');
$option.text(data.text);
$option.val(data.id);
$option.prop('disabled', data.disabled || false);
// Get any automatically generated data values
var detectedData = this.item($option);
// Merge it with the already present data
var combinedData = $.extend({}, data, detectedData);
// Override the option's data with the combined data
$option.data('data', combinedData);
return $option;
};
SelectAdapter.prototype.item = function ($option) {
var data = $option.data('data');

62
src/js/select2/data/tags.js vendored Normal file
View File

@ -0,0 +1,62 @@
define([
], function () {
function Tags (decorated, $element, options) {
var tags = options.get('tags');
decorated.call(this, $element, options);
}
Tags.prototype.query = function (decorated, params, callback) {
var self = this;
if (params.term == null || params.term === '' || params.page != null) {
decorated.call(this, params, callback);
return;
}
function wrapper (data, child) {
for (var i = 0; i < data.length; i++) {
var option = data[i];
var checkChildren = (
option.children != null && !wrapper(option.children, true)
);
var checkText = option.text === params.term;
if (checkText || checkChildren) {
if (child) {
return false;
}
callback(data);
return;
}
}
if (child) {
return true;
}
var tag = self.createTag(params);
tag._tag = true;
data.unshift(tag);
callback(data);
}
decorated.call(this, params, wrapper);
};
Tags.prototype.createTag = function (decorated, params) {
return {
id: params.term,
text: params.term
};
};
return Tags;
});

View File

@ -10,13 +10,14 @@ define([
'./data/select',
'./data/array',
'./data/ajax',
'./data/tags',
'./dropdown',
'./dropdown/search'
], function (ResultsList,
SingleSelection, MultipleSelection, Placeholder,
Utils,
SelectData, ArrayData, AjaxData,
SelectData, ArrayData, AjaxData, Tags,
Dropdown, Search) {
function Defaults () {
this.reset();
@ -35,6 +36,10 @@ define([
}
}
if (options.tags != null) {
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
}
if (options.resultsAdapter == null) {
options.resultsAdapter = ResultsList;
}