<option>An option1 (this text needs to be styled differently)</option>
I need to find a way to style the text in brackets differently from the main text after the select2 plugin converts it to its own dropdown version.
The select is transformed to this:
<div class="container">
<div class="control-group select-crop">
<label for="s2id_autogen1" class="control-label">Select Your option</label>
<div style="width: 100%;" id="s2id_testSelect" class="select2-container select2-container-multi select2 select2-container-active select2-dropdown-open">
<ul class="select2-choices">
<li class="select2-search-choice">
<div title="An option3 (this text needs to be styled differently)">An option3 (this text needs to be styled differently)</div>
<a tabindex="-1" class="select2-search-choice-close" onclick="return false;" href="#"></a></li>
<li class="select2-search-field">
<input style="width: 832.283px;" id="s2id_autogen1" autocomplete="off" autocorrect="off" autocapitilize="off" spellcheck="false" class="select2-input select2-focused" type="text">
</li>
</ul>
</div>
<select data-placeholder="Select option" class="select2 select2-offscreen" style="width:100%" id="testSelect" multiple="" tabindex="-1">
<option>An option1 (this text needs to be styled differently)</option>
<option>An option2 (this text needs to be styled differently)</option>
<option>An option3 (this text needs to be styled differently)</option>
<option>An option4 (this text needs to be styled differently)</option>
<option>An option5 (this text needs to be styled differently)</option>
</select>
</div>
</div>
<!-- end container -->
<div class="select2-sizer" style="position: absolute; left: -10000px; top: -10000px; display: none; font-size: 16px; font-family: sans-serif; font-style: normal; font-weight: 400; letter-spacing: normal; text-transform: none; white-space: nowrap;"></div>
<div style="width: 1219px; height: 463px; display: block;" class="select2-drop-mask" id="select2-drop-mask"></div>
<div id="select2-drop" style="display: block; top: 62px; left: 8px; width: 1203px;" class="select2-drop select2-drop-multi select2-display-none select2-drop-active">
<ul class="select2-results">
<li class="select2-results-dept-0 select2-result select2-result-selectable select2-highlighted">
<div class="select2-result-label"><span class="select2-match"></span>An option1 (this text needs to be styled differently)</div>
</li>
<li class="select2-results-dept-0 select2-result select2-result-selectable">
<div class="select2-result-label"><span class="select2-match"></span>An option2 (this text needs to be styled differently)</div>
</li>
<li class="select2-results-dept-0 select2-result select2-result-selectable select2-selected">
<div class="select2-result-label"><span class="select2-match"></span>An option3 (this text needs to be styled differently)</div>
</li>
<li class="select2-results-dept-0 select2-result select2-result-selectable">
<div class="select2-result-label"><span class="select2-match"></span>An option4 (this text needs to be styled differently)</div>
</li>
<li class="select2-results-dept-0 select2-result select2-result-selectable">
<div class="select2-result-label"><span class="select2-match"></span>An option5 (this text needs to be styled differently)</div>
</li>
</ul>
</div>
There is an option for templating and using data attributes mentioned in the documentation but I am unable to work out how to tie this into a workable solution.
I assumed I could add the extra text via a data attribute on the option element.
e.g.
<option data-txt="this text needs to be styled differently">An option1 </option>
Then the data-txt attribute content could be appended to the original option content but enclosed inside a span with a class and placed in the revised dropdown selection list and selected item.
e.g.
An option1 <span class="newtext">this text needs to be styled differently</span>
The documentation suggest that it is easy and offers the following example code:
You can attach an anonymous function to the formatSelection setting, E.g.
$('select').select2({
formatSelection: function(item) {
// Debugging -- open the developer console to see what you can access from the item object
console.dir(item);
return '<strong>' + item.id + '</strong>';
}
});
I had to use the escapeMarkup function as it was outputting the tags as text.
i.e.
function format(item) {
var originalOption = item.element;
var originalText = item.text;
return originalText + ' ' + '<span class="newTxt">' + $(originalOption).data('mytxt') + '</span>';
}
$('#testSelect').select2({
allowClear: true,
formatResult: format,
formatSelection: format,
escapeMarkup: function(m) { return m; }
});
It seems to be working. Can you see any problems with it? (apart from the extra text not being available should JS be off but that’s how it is now anyway so there is no loss if js is off but enhancement if on.)
<option data-mytxt="this text needs to be styled differently">[B]Paul's option3[/B]</option>
I need to exclude the apostrophe from messing up the routine. It’s fine without it.
There is one other small problem in that the plugin is adding the text as a title attribute but is including the whole span text html inside the title attribute. There must be an option somewhere to remove the title but I can’t see it yet.
<select multiple id="testSelect" style="width:100%" class="select2" data-placeholder="Select option" >
<option data-mytxt="this text needs to be styled differently">Fred's option1 </option>
<option data-mytxt="styled differently">Jim's option 2</option>
<option data-mytxt="this text needs to be styled differently">Paul's option3</option>
<option data-mytxt="this text needs to be styled">Chris's option4 </option>
<option data-mytxt="this text styled differently">Stuart's option5 </option>
</select>
Great:) Thanks Pullo that fixes the apostrophe nicely.
I just have to work out how to amend the title attribute that the plugin is adding.
<li class="select2-search-choice">
<div [B]title="Paul’s option3 <b class="newTxt">this text needs to be styled differently</b>"[/B]>Paul’s option3 <b class="newTxt">this text needs to be styled differently</b></div>
I’m sure there must be an option as the examples on the documentation page don’t have these titles as fas as I can see.
I suppose the title attribute should stay in place but without the extraneous html mixed in. If that’s not easily possible then just removing it would do.:
Well, I had a look at the plugin’s source code (that you are using on your homepage) and saw:
formatted=this.opts.formatSelection(data, choice.find("div"));
if (formatted != undefined) {
choice.find("div").replaceWith("<div title='"+this.opts.escapeMarkup(formatted)+"'>"+this.opts.escapeMarkup(formatted)+"</div>");
}
which means that as we are using the formatSelection option to add a <span> to the results text, formatted will never be undefined, so the return value of the escapeMarkup function will always be inserted into the <div>'s title attribute and we don’t have a chance to change this.
Which means that what you are seeing is a bug and if you upgrade to v3.4.2 then the problem will go away
As an aside, this means that no title attribute will be present on the <div> (which seems to be the desired behaviour).
If it is important for you to have one, it shouldn’t be too hard to add this via an onchange event listener. Just let me know.
I’ve copied your page locally for future reference but I may leave it without the tooltip for the time being as it is only duplicating what is already displayed so is not really any extra help. However if we need to truncate the text in the option at some point then it may need the tooltip added back in but at present we are letting the text wrap if needed but of course things may change