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);
    }
}