jquery - ejemplo - Cómo renderizar html en select2 opciones
select2 option data (4)
Ok, jugué con esto por un tiempo y encontré una solución que funciona, así que responderé mi propia pregunta aquí.
La clave aquí para mí es construir una matriz de datos con contenido tanto para templateSelection
como templateResult
. La última muestra la búsqueda en el menú desplegable, pero el contenido de varias líneas no se incluirá en el elemento select2, por lo que debe mostrarse en línea (o al menos en una sola línea). La definición de escapeMarkup
como una opción permite anular la función principal que normalmente eliminaría el contenido html.
También es importante definir el atributo del title
ya que de lo contrario terminarás con etiquetas html en la información sobre herramientas.
var data = [{
id: 0,
text: ''<div style="color:green">enhancement</div>'',
html: ''<div style="color:green">enhancement</div><div><b>Select2</b> supports custom themes using the theme option so you can style Select2 to match the rest of your application.</div>'',
title: ''enchancement''
}, {
id: 1,
text: ''<div style="color:red">bug</div>'',
html: ''<div style="color:red">bug</div><div><small>This is some small text on a new line</small></div>'',
title: ''bug''
}];
$("select").select2({
data: data,
escapeMarkup: function(markup) {
return markup;
},
templateResult: function(data) {
return data.html;
},
templateSelection: function(data) {
return data.text;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select></select>
Alternativamente, con un par de pequeños ajustes de CSS, puede permitir que el contenido completo de la opción html se muestre dentro del contenedor de selección sin la necesidad de devoluciones de llamada de la plantilla:
var data = [{
id: 0,
text: ''<div style="font-size: 1.2em; color:green">enhancement</div><div><b>Select2</b> supports custom themes using the theme option so you can style Select2 to match the rest of your application.</div>'',
title: ''enchancement''
}, {
id: 1,
text: ''<div style="color:red">bug</div><div><small>This is some small text on a new line</small></div>'',
title: ''bug''
}];
$("select").select2({
data: data,
escapeMarkup: function(markup) {
return markup;
}
})
.select2-container .select2-selection--single {
height: auto!important;
padding: 5px 0;
}
.select2-container--default .select2-selection--single .select2-selection__rendered {
line-height: normal!important;
}
.select2-container .select2-selection--single .select2-selection__rendered {
white-space: normal!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select style="width: 100%"></select>
En este ejemplo de datos cargados desde una fuente remota, puedo ver imágenes y otros elementos html representados como opciones. Me gustaría lograr lo mismo usando datos en una matriz local. He intentado crear una matriz como se describe en la documentación y agregarla con la opción de data
, pero el html se representa como texto simple:
var data = [
{ id: 0, text: ''<div style="color:green">enhancement</div>'' },
{ id: 1, text: ''<div style="color:red">bug</div><div><small>This is some small text on a new line</small></div>'' }];
$("select").select2({
data: data
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select></select>
¿Cómo puedo agregar contenido html a las opciones select2?
Otro ejemplo se define como tal.
function template(data) {
if ($(data.html).length === 0) {
return data.text;
}
return $(data.html);
}
$("select").select2({
ajax: {
url: ''routeurl'',
dataType: ''json'',
type: ''POST'',
processResults: function(data) {
return {
results: data
};
},
cache: true
},
allowClear: true,
placeholder: ''Select at least one element'',
templateResult: template,
templateSelection: template
});
El resultado Endpoint con formato json como tal.
[{
id: 0,
text: ''enhancement'',
html: ''<div style="color:green">enhancement</div>''
}, {
id: 1,
text: ''bug'',
html: ''<div style="color:red">bug</div><div><small>This is some small text on a new line</small></div>''
}, {
id: 2,
text: ''success'',
html: ''Success''
}]
Si no me equivoco, solo puede representar HTML si configura las opciones templateResult y templateSelection y hace que devuelvan un objeto jQuery.
var data = [
{ id: 0, text: ''<div style="color:green">enhancement</div>'' },
{ id: 1, text: ''<div style="color:red">bug</div><div><small>This is some small text on a new line</small></div>'' }];
$("select").select2({
data: data,
templateResult: function (d) { return $(d.text); },
templateSelection: function (d) { return $(d.text); },
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select></select>
Simplemente puede agregar otro campo con el html a su matriz de datos y hacer su propia plantilla usando la opción templateResult
como tal
JSFiddle Demo
var data = [{
id: 0,
text: ''enhancement'',
html: ''<div style="color:green">enhancement</div>''
}, {
id: 1,
text: ''bug'',
html: ''<div style="color:red">bug</div><div><small>This is some small text on a new line</small></div>''
}];
function template(data) {
return data.html;
}
$("select").select2({
data: data,
templateResult: template,
escapeMarkup: function(m) {
return m;
}
});