Select2 with Primary selected option
Set a Select2 option as Primary, with visual feedback and a hidden form field to relay the Primary selected item with the form data.
by HugeHugh
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.css">
<label for="Troops">Troops</label>
<select name="Troops" id="Troops" multiple="" class="primary-selectable">
<option value="1">Barbarian</option>
<option value="2">Archer</option>
<option value="3">Goblin</option>
<option value="4">Giant</option>
<option value="5" selected="selected">Wall Breaker</option>
<option value="6">Balloon</option>
<option value="7" selected="selected">Wizard</option>
<option value="8">Healer</option>
<option value="9">Dragon</option>
<option value="10" selected="selected">P.E.K.K.A.</option>
<option value="11">Minion</option>
<option value="12">Hogrider</option>
<option value="13">Valkyrie</option>
<option value="14" selected="selected">Golem</option>
<option value="15" selected="selected">Witch</option>
<option value="16">Lava Hound</option>
<option value="17" selected="selected">Barbarian King</option>
<option value="18" selected="selected">Archer Queen</option>
</select>
<div style="height: 20px"></div>
<label>Primary Troop</label>
<input type="hidden" id="TroopsPrimary" name="TroopsPrimary" value="17">
<span id="TroopsPrimaryDisplay"></span>
<span id="TroopsPrimaryDisplayNone">No Primary Troop selected</span>
<div class="who">Written by <a target="_top" href="http://www.hughanderson.com">Hugh Anderson</a>
<br>View the <a target="_top" href="http://www.programico.com/smartjs-blog/click-on-a-select2-item-to-set-it-as-primary">Blog Post</a></div>
CSS
/* http://www.cssportal.com/css-gradient-generator/ */
.select2-container-multi .select2-choices .select2-search-choice.select2-primary {
background-color: green;
border-color: green;
background-image: -ms-linear-gradient(top, #5CBD73 0%, #79EF70 50%, #24E23D 51%, #1F9C49 100%);
background-image: -moz-linear-gradient(top, #5CBD73 0%, #79EF70 50%, #24E23D 51%, #1F9C49 100%);
background-image: -o-linear-gradient(top, #5CBD73 0%, #79EF70 50%, #24E23D 51%, #1F9C49 100%);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #5CBD73), color-stop(50, #79EF70), color-stop(51, #24E23D), color-stop(100, #1F9C49));
background-image: -webkit-linear-gradient(top, #5CBD73 0%, #79EF70 50%, #24E23D 51%, #1F9C49 100%);
background-image: linear-gradient(to bottom, #5CBD73 0%, #79EF70 50%, #24E23D 51%, #1F9C49 100%);
}
/* visibility is handled by JavaScript */
#TroopsPrimaryDisplay, #TroopsPrimaryDisplayNone {
display: none;
}
#TroopsPrimaryDisplayNone {
font-style: italic;
color: #888;
}
#Troops {
width: 100%;
}
body {
font-family: sans-serif;
}
label {
font-weight: bold;
}
/* if using Bootstrap this will happen automatically, i'm just setting it to full width here */
.select2-container {
display: block;
}
.who {
margin-top:3em;
font-style:italic;
font-size:smaller;
text-align: right;
}
JavaScript
Select2.class.multi.prototype.findHighlightableChoices = function () {
return this.results.find(".select2-result-selectable:not(.select2-disabled)");
};
var Select2TriggerSelect = Select2.class.multi.prototype.triggerSelect;
Select2.class.multi.prototype.triggerSelect = function (data) {
if (this.val().indexOf(this.id(data)) !== -1) {
var val = this.id(data);
var evt = $.Event("select2-removing");
evt.val = val;
evt.choice = data;
this.opts.element.trigger(evt);
if (evt.isDefaultPrevented()) {
return false;
}
var existingVals = this.val();
var self = this;
if (!existingVals || existingVals.length == 0) return true;
for (a = 0; a < existingVals.length; a++) {
if (existingVals[a] === val) {
existingVals[a] = '';
this.val(existingVals);
this.results.find('.select2-result').each(function () {
var $this = $(this);
if (self.id($this.data('select2-data')) === val) {
$this.removeClass('select2-selected');
}
});
}
}
this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
this.triggerChange({ removed: data });
} else {
return Select2TriggerSelect.apply(this, arguments);
}
}