Skip to content

Commit 559a93b

Browse files
committed
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.
1 parent 9e13095 commit 559a93b

11 files changed

Lines changed: 534 additions & 102 deletions

File tree

dist/js/select2.amd.full.js

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,16 @@ define('select2/data/select',[
879879
SelectAdapter.prototype.select = function (data) {
880880
var self = this;
881881

882+
// Create items marked as tags
883+
if (data._tag === true) {
884+
// Clear the tag flag from it
885+
delete data._tag;
886+
887+
// Create and add the option
888+
var $option = this.option(data);
889+
this.$element.append($option);
890+
}
891+
882892
if (this.$element.prop('multiple')) {
883893
this.current(function (currentData) {
884894
var val = [];
@@ -901,6 +911,7 @@ define('select2/data/select',[
901911
var val = data.id;
902912

903913
this.$element.val(val);
914+
904915
this.$element.trigger('change');
905916
}
906917
};
@@ -924,6 +935,7 @@ define('select2/data/select',[
924935
}
925936

926937
self.$element.val(val);
938+
927939
self.$element.trigger('change');
928940
});
929941
};
@@ -967,6 +979,25 @@ define('select2/data/select',[
967979
callback(data);
968980
};
969981

982+
SelectAdapter.prototype.option = function (data) {
983+
var $option = $('<option></option>');
984+
985+
$option.text(data.text);
986+
$option.val(data.id);
987+
$option.prop('disabled', data.disabled || false);
988+
989+
// Get any automatically generated data values
990+
var detectedData = this.item($option);
991+
992+
// Merge it with the already present data
993+
var combinedData = $.extend({}, data, detectedData);
994+
995+
// Override the option's data with the combined data
996+
$option.data('data', combinedData);
997+
998+
return $option;
999+
};
1000+
9701001
SelectAdapter.prototype.item = function ($option) {
9711002
var data = $option.data('data');
9721003

@@ -1074,25 +1105,6 @@ define('select2/data/array',[
10741105
ArrayAdapter.__super__.select.call(this, data);
10751106
};
10761107

1077-
ArrayAdapter.prototype.option = function (data) {
1078-
var $option = $('<option></option>');
1079-
1080-
$option.text(data.text);
1081-
$option.val(data.id);
1082-
$option.prop('disabled', data.disabled || false);
1083-
1084-
// Get any automatically generated data values
1085-
var detectedData = this.item($option);
1086-
1087-
// Merge it with the already present data
1088-
var combinedData = $.extend({}, data, detectedData);
1089-
1090-
// Override the option's data with the combined data
1091-
$option.data('data', combinedData);
1092-
1093-
return $option;
1094-
};
1095-
10961108
ArrayAdapter.prototype.query = function (params, callback) {
10971109
var matches = [];
10981110
var self = this;
@@ -1157,6 +1169,69 @@ define('select2/data/ajax',[
11571169
return AjaxAdapter;
11581170
});
11591171

1172+
define('select2/data/tags',[
1173+
1174+
], function () {
1175+
function Tags (decorated, $element, options) {
1176+
var tags = options.get('tags');
1177+
1178+
decorated.call(this, $element, options);
1179+
}
1180+
1181+
Tags.prototype.query = function (decorated, params, callback) {
1182+
var self = this;
1183+
1184+
if (params.term == null || params.term === '' || params.page != null) {
1185+
decorated.call(this, params, callback);
1186+
return;
1187+
}
1188+
1189+
function wrapper (data, child) {
1190+
for (var i = 0; i < data.length; i++) {
1191+
var option = data[i];
1192+
1193+
var checkChildren = (
1194+
option.children != null && !wrapper(option.children, true)
1195+
);
1196+
1197+
var checkText = option.text === params.term;
1198+
1199+
if (checkText || checkChildren) {
1200+
if (child) {
1201+
return false;
1202+
}
1203+
1204+
callback(data);
1205+
1206+
return;
1207+
}
1208+
}
1209+
1210+
if (child) {
1211+
return true;
1212+
}
1213+
1214+
var tag = self.createTag(params);
1215+
tag._tag = true;
1216+
1217+
data.unshift(tag);
1218+
1219+
callback(data);
1220+
}
1221+
1222+
decorated.call(this, params, wrapper);
1223+
};
1224+
1225+
Tags.prototype.createTag = function (decorated, params) {
1226+
return {
1227+
id: params.term,
1228+
text: params.term
1229+
};
1230+
};
1231+
1232+
return Tags;
1233+
});
1234+
11601235
define('select2/dropdown',[
11611236
'./utils'
11621237
], function (Utils) {
@@ -1256,13 +1331,14 @@ define('select2/defaults',[
12561331
'./data/select',
12571332
'./data/array',
12581333
'./data/ajax',
1334+
'./data/tags',
12591335

12601336
'./dropdown',
12611337
'./dropdown/search'
12621338
], function (ResultsList,
12631339
SingleSelection, MultipleSelection, Placeholder,
12641340
Utils,
1265-
SelectData, ArrayData, AjaxData,
1341+
SelectData, ArrayData, AjaxData, Tags,
12661342
Dropdown, Search) {
12671343
function Defaults () {
12681344
this.reset();
@@ -1281,6 +1357,10 @@ define('select2/defaults',[
12811357
}
12821358
}
12831359

1360+
if (options.tags != null) {
1361+
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
1362+
}
1363+
12841364
if (options.resultsAdapter == null) {
12851365
options.resultsAdapter = ResultsList;
12861366
}

dist/js/select2.amd.js

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,16 @@ define('select2/data/select',[
879879
SelectAdapter.prototype.select = function (data) {
880880
var self = this;
881881

882+
// Create items marked as tags
883+
if (data._tag === true) {
884+
// Clear the tag flag from it
885+
delete data._tag;
886+
887+
// Create and add the option
888+
var $option = this.option(data);
889+
this.$element.append($option);
890+
}
891+
882892
if (this.$element.prop('multiple')) {
883893
this.current(function (currentData) {
884894
var val = [];
@@ -901,6 +911,7 @@ define('select2/data/select',[
901911
var val = data.id;
902912

903913
this.$element.val(val);
914+
904915
this.$element.trigger('change');
905916
}
906917
};
@@ -924,6 +935,7 @@ define('select2/data/select',[
924935
}
925936

926937
self.$element.val(val);
938+
927939
self.$element.trigger('change');
928940
});
929941
};
@@ -967,6 +979,25 @@ define('select2/data/select',[
967979
callback(data);
968980
};
969981

982+
SelectAdapter.prototype.option = function (data) {
983+
var $option = $('<option></option>');
984+
985+
$option.text(data.text);
986+
$option.val(data.id);
987+
$option.prop('disabled', data.disabled || false);
988+
989+
// Get any automatically generated data values
990+
var detectedData = this.item($option);
991+
992+
// Merge it with the already present data
993+
var combinedData = $.extend({}, data, detectedData);
994+
995+
// Override the option's data with the combined data
996+
$option.data('data', combinedData);
997+
998+
return $option;
999+
};
1000+
9701001
SelectAdapter.prototype.item = function ($option) {
9711002
var data = $option.data('data');
9721003

@@ -1074,25 +1105,6 @@ define('select2/data/array',[
10741105
ArrayAdapter.__super__.select.call(this, data);
10751106
};
10761107

1077-
ArrayAdapter.prototype.option = function (data) {
1078-
var $option = $('<option></option>');
1079-
1080-
$option.text(data.text);
1081-
$option.val(data.id);
1082-
$option.prop('disabled', data.disabled || false);
1083-
1084-
// Get any automatically generated data values
1085-
var detectedData = this.item($option);
1086-
1087-
// Merge it with the already present data
1088-
var combinedData = $.extend({}, data, detectedData);
1089-
1090-
// Override the option's data with the combined data
1091-
$option.data('data', combinedData);
1092-
1093-
return $option;
1094-
};
1095-
10961108
ArrayAdapter.prototype.query = function (params, callback) {
10971109
var matches = [];
10981110
var self = this;
@@ -1157,6 +1169,69 @@ define('select2/data/ajax',[
11571169
return AjaxAdapter;
11581170
});
11591171

1172+
define('select2/data/tags',[
1173+
1174+
], function () {
1175+
function Tags (decorated, $element, options) {
1176+
var tags = options.get('tags');
1177+
1178+
decorated.call(this, $element, options);
1179+
}
1180+
1181+
Tags.prototype.query = function (decorated, params, callback) {
1182+
var self = this;
1183+
1184+
if (params.term == null || params.term === '' || params.page != null) {
1185+
decorated.call(this, params, callback);
1186+
return;
1187+
}
1188+
1189+
function wrapper (data, child) {
1190+
for (var i = 0; i < data.length; i++) {
1191+
var option = data[i];
1192+
1193+
var checkChildren = (
1194+
option.children != null && !wrapper(option.children, true)
1195+
);
1196+
1197+
var checkText = option.text === params.term;
1198+
1199+
if (checkText || checkChildren) {
1200+
if (child) {
1201+
return false;
1202+
}
1203+
1204+
callback(data);
1205+
1206+
return;
1207+
}
1208+
}
1209+
1210+
if (child) {
1211+
return true;
1212+
}
1213+
1214+
var tag = self.createTag(params);
1215+
tag._tag = true;
1216+
1217+
data.unshift(tag);
1218+
1219+
callback(data);
1220+
}
1221+
1222+
decorated.call(this, params, wrapper);
1223+
};
1224+
1225+
Tags.prototype.createTag = function (decorated, params) {
1226+
return {
1227+
id: params.term,
1228+
text: params.term
1229+
};
1230+
};
1231+
1232+
return Tags;
1233+
});
1234+
11601235
define('select2/dropdown',[
11611236
'./utils'
11621237
], function (Utils) {
@@ -1256,13 +1331,14 @@ define('select2/defaults',[
12561331
'./data/select',
12571332
'./data/array',
12581333
'./data/ajax',
1334+
'./data/tags',
12591335

12601336
'./dropdown',
12611337
'./dropdown/search'
12621338
], function (ResultsList,
12631339
SingleSelection, MultipleSelection, Placeholder,
12641340
Utils,
1265-
SelectData, ArrayData, AjaxData,
1341+
SelectData, ArrayData, AjaxData, Tags,
12661342
Dropdown, Search) {
12671343
function Defaults () {
12681344
this.reset();
@@ -1281,6 +1357,10 @@ define('select2/defaults',[
12811357
}
12821358
}
12831359

1360+
if (options.tags != null) {
1361+
options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
1362+
}
1363+
12841364
if (options.resultsAdapter == null) {
12851365
options.resultsAdapter = ResultsList;
12861366
}

0 commit comments

Comments
 (0)