I'm using fontawesome, and I want to add or remove an icon to the selected item. So I did this: http://jsbin.com/nasixuro/7/edit (Thanks to @Fares M.)
JS
$(document).ready(function () {
function format_select2_icon(opti) {
if (!opti.id) return opti.text; // optgroup
if ($(opti.element).data('icon') == "1") {
return opti.text + " <i class='fa fa-check'></i>";
} else {
return opti.text;
}
}
$("#sel").select2({
escapeMarkup: function(m) { return m; },
formatResult: format_select2_icon,
formatSelection: format_select2_icon
});
$("#addok").click(function() {
actual_value = $("#sel").find(':selected').text();
if (actual_value.indexOf(" <i class='fa fa-check'></i>") > -1){
alert("asd");
return;
}
newtext = actual_value + " <i class='fa fa-check'></i>";
$("#sel").find(':selected').text(newtext).change();
});
$("#removeok").click(function() {
actual_value= $("#sel").find(':selected').text();
indexOk=actual_value.indexOf(" <i class='fa fa-check'></i>");
if (indexOk > -1){
newtext =actual_value.substring(0, indexOk);
$("#sel").find(':selected').text(newtext).change();
return;
}
});
});
HTML
<select id="sel" style="width: 100%">
<option value="1">Hello</option>
<option value="2" data-icon="1">Friends</option>
<option value="3">Stackoverflow</option>
</select>
<br><br>
<button id="addok">Add <i class='fa fa-check'></i></button>
<button id="removeok">Remove <i class='fa fa-check'></i></button>
As you see, you can add or remove the icon in Hello
and Stackoverflow
items, but in Friends
(that is the option formated with formatSelection
and formatResult
), does not remove the icon, and if you try to add the icon, the appends another one to the existing.
Do you have any idea to solve this?
I think there's two ways to achieve that:
The first solution is the better one,
you can make it work just by defining an escapeMarkup function in select2 options, and this function must return the same data received as input parameter without any changes.
all what you need is:
$("#sel").select2({
escapeMarkup: function(m) {
return m;
}
});
here's a working example: http://jsbin.com/nasixuro/3/edit
The second one, make a small changes in select2.js file.
after inspecting the select2.js, i found the function which updates the text, and there was a little problem, select2.js plugin escapes html to prevent js injection, so to get it work as you expect you have to avoid escaping html and use .html() function from jquery api to insert your html instead of .append() function used in updateSelection function of select2.js.
here's the function i'm talking about:
// single
updateSelection: function (data) {
var container=this.selection.find(".select2-chosen"), formatted, cssClass;
this.selection.data("select2-data", data);
container.empty();
if (data !== null) {
formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
}
if (formatted !== undefined) {
container.append(formatted);
}
cssClass=this.opts.formatSelectionCssClass(data, container);
if (cssClass !== undefined) {
container.addClass(cssClass);
}
this.selection.removeClass("select2-default");
if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
this.container.addClass("select2-allowclear");
}
},
delete this:
if (data !== null) {
formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
}
and change:
if (formatted !== undefined) {
container.append(formatted);
}
to:
if (data !== undefined) {
container.html(data.text);
}
this is a dirty solution in my opinion.
For the Remove action use this js code:
$("#removeok").click(function() {
actual_value= $("#sel").find(':selected').text(),
indexOk =actual_value.indexOf(" <i class='fa fa-check'></i>");
if (indexOk > -1){
newtext =actual_value.substring(0, indexOk);
$("#sel").find(':selected').text(newtext).change();
return;
}
});
Simply replacing <
by <
in the option and removing format functions:
<select id="sel" style="width: 100%">
<option value="1">Hello</option>
<option value="2">Friends <i class='fa fa-check'></i></option>
<option value="3">Stackoverflow</option>
</select>
You can test it here: http://jsbin.com/nasixuro/11/edit
Manbe you can use the select2 parameter : formatResult or formatSelection like below
$(document).ready(function () {
$("#sel").select2();
$("#addok").click(function() {
$("#sel").select2({
//formatResult: format
formatSelection: format
//escapeMarkup: function(m) { return m; }
});
});
});
function format(state) {
if (!state.id) return state.text;
return "<i class='fa fa-check'></i>" + state.text;
}
JSBIN
You need not do the DOM manipulation manually
var icon_checked = "<i class='fa fa-check'></i>";
function format(opt) {
var selection = this.element.select2("val");
if (opt.id === selection) {
return opt.text + icon_checked;
}
return opt.text;
}
$("#sel").select2({
formatResult: format
});
Basically this.element
returns you the select
element instance, on which you can run .select2("val")
to get the selected value.
Compare that with the id of the object, if it is true
then give the HTML with checkbox else return plain text. I think this is what you were trying to achieve.
Here is a Working fiddle, I think this is what you were trying to acheive
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With