如何在select2选项中呈现HTML

51
这个例子 中,我可以看到从远程源加载的数据作为选项渲染了图像和其他html元素。 我想使用本地数组中的数据来实现相同的功能。 我已经尝试按照文档中的描述构建数组,并使用 data 选项添加它,但是html被呈现为纯文本。

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>

我如何将HTML内容添加到select2选项中?

8个回答

71

好的,我已经玩了一段时间,找到了一个可行的解决方案,所以我会在这里回答自己的问题。

对我来说关键是使用包含templateSelectiontemplateResult内容的数据数组进行构建。后者在下拉列表中可以正常呈现,但是任何多行内容都不会包含在select2元素中,因此需要内联显示(或至少单行显示)。定义escapeMarkup作为选项允许覆盖通常会剥离html内容的核心函数。

同时定义title属性也很重要,否则您将在工具提示中看到html标签。

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>

此外,通过进行少量的CSS调整,您可以允许完整的html选项内容显示在选择容器内,无需使用模板回调函数:

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>


太棒了,Billy的回答! - TombMedia
该方法非常有效。然而,如果没有将所有内容包裹在$(function(){});中,Select2将填充您的数据但不会显示HTML。这是需要指出的一个好事情。希望这能帮助到某个人。 - Waiyl Karim
@WaiylKarim - 这可能取决于事情的顺序。只要我的JavaScript在标记之后,这对我来说就很好用。 - But those new buttons though..
@billynoah 同意 - Waiyl Karim

35

如果我没记错的话,只有在设置了templateResult和templateSelection选项并且它们返回一个jQuery对象时,您才能渲染HTML。

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>
 


谢谢 - 我也刚刚明白了这一点。这是正确的方向,但正如您所看到的,完整的HTML内容一旦被选择,就无法很好地呈现,因此需要两种不同的格式。尽管如此,这个方案包含了完成工作所必需的关键构建块,所以我会点赞的;-) - But those new buttons though..

17

你可以简单地将另一个字段与HTML一起添加到数据数组中,并使用templateResult选项创建自己的模板,如下所示。

JSFiddle演示

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

8
另一个例子可以这样定义:
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
});

以json格式返回的终端点结果如下:

[{
   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'
}]

1

使用

escapeMarkup: function(m) { return m; }

打开XSS漏洞 (https://codepen.io/nkorovikov/pen/ZEBdMBP)

我没有找到一种方法来使用数组中的数据模板,但对于从ajax和直接添加选择元素到HTML获取数据的情况下,模板可以完美地工作。

<select class="templatingSelect2">
        <option value=""></option>
        <option value="usd">USD</option>
        <option value="euro">Euro</option>
        <option value="gbp">Pound</option>
        </select>

(https://codepen.io/SitePoint/pen/bELxVw)


1

以下是对@EatenByAGrue答案的补充:

如果您需要搜索文本(例如提供的示例中的enhancementbug以及 html 内容(例如This is some small text),则需要扩展匹配逻辑,如官方文档所示。

例如:

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;
  },
  matcher: matcher
});

function matcher(params, data) {
    // If there are no search terms, return all of the data
    if ($.trim(params.term) === '') {
        return data;
    }

    // Do not display the item if there is no 'text' property
    if (typeof data.text === 'undefined') {
        return null;
    }

    // `params.term` should be the term that is used for searching
    // `data.text` is the text that is displayed for the data object
    // `data.html` is the additional / info text, within the option, seen once the dropdown is shown
    // The search is case insensitive
    if (data.text.toLowerCase().indexOf(params.term.toLowerCase()) > -1 || (typeof data.html !== 'undefined' && data.html.toLowerCase().indexOf(params.term.toLowerCase()) > -1)) {
        var modifiedData = $.extend({}, data, true);
        modifiedData.text += ' (matched)';

        // You can return modified objects from here
        // This includes matching the `children` how you want in nested data sets
        return modifiedData;
    }

    // Return `null` if the term should not be displayed
    return null;
}
<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.8/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script>

<select></select>


1
好主意。在某些情况下,搜索选项的所有组件可能非常有用! - But those new buttons though..

-1
将select2控件的text属性更改为HTML:
$(document).ready(function() {

  function select2OptionFormat(option) {
    var originalOption = option.element;
      if ($(originalOption).data('html')) {
        return $(originalOption).data('html');
      }          
      return option.text;
  }


  $('select').select2({
    formatResult: select2OptionFormat,
    formatSelection: select2OptionFormat,
    escapeMarkup: function(m) { return m; }
  });


});

参考:

https://codepen.io/kohnmd/pen/KwYvvM


-2

这里有一个使用jQuery的替代选项

$('.select2').on("select2:open", function(e) {
        setTimeout(function(){
            $('#select2-myselect2name-results li').after('my html code here');
        }, 500);
 });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接