Select2动态添加图片图标到选项

20

这就是select2.github.io为您提供的内容:

function addIcons(opt) {
    if (!opt.id) {
        return opt.text;
    }
    var $opt = $(
            '<span><img src="/images/flags/' + opt.element.value.toLowerCase() + '.png" class="img-flag" /> ' + opt.text + '</span>'
            );
    return $opt;
}

我想要在我的选项中添加一个data-image属性:

<option value="flag" data-image="/images/flags/flag.png">Country 1</option>

并在函数中记录它:

function addIcons(opt) {
    if (!opt.id) {
        return opt.text;
    }

    var optimage = opt.attr('data-image');
    var $opt = $(
            '<span><img src="/images/flags/' + optimage + '" class="img-flag" /> ' + opt.text + '</span>'
            );
    return $opt;
}

遗憾的是,简单的console.log(opt);在函数中没有返回任何内容,因此我无法查看是否可以访问我的data-image属性。上面的代码块会返回错误,所以这显然行不通。对此有什么建议吗?


一个错误?具体的错误信息是什么?你有一个 jsfiddle 演示吗? - PeterKA
要获取数据值,请使用$(opt.element).attr('data-image'); - Rk dev tech
6个回答

23

使用attr解决,并在Select2 4.0.6-rc.0上进行了测试。

$(".class").select2({
    templateResult: formatState,
    templateSelection: formatState
});

function formatState (opt) {
    if (!opt.id) {
        return opt.text.toUpperCase();
    } 

    var optimage = $(opt.element).attr('data-image'); 
    console.log(optimage)
    if(!optimage){
       return opt.text.toUpperCase();
    } else {                    
        var $opt = $(
           '<span><img src="' + optimage + '" width="60px" /> ' + opt.text.toUpperCase() + '</span>'
        );
        return $opt;
    }
};

16
如果Optimage返回“undefined”,请尝试使用我的示例:它可以正常工作。

$("#selectUserForChat").select2({
  templateResult: addUserPic,
  templateSelection: addUserPic
});

function addUserPic(opt) {
  if (!opt.id) {
    return opt.text;
  }
  var optimage = $(opt.element).data('image');
  if (!optimage) {
    return opt.text;
  } else {
    var $opt = $(
      '<span class="userName"><img src="' + optimage + '" class="userPic" /> ' + $(opt.element).text() + '</span>'
    );
    return $opt;
  }
};


9
我用这段代码解决了问题:var optimage = $(opt.element).data('image');
$(".category").select2({
            templateResult: formatState,
            templateSelection: formatState
        });
        function formatState (opt) {
            if (!opt.id) {
                return opt.text;
            }               
            var optimage = $(opt.element).data('image'); 
            if(!optimage){
                return opt.text;
            } else {                    
                var $opt = $(
                    '<span><img src="' + optimage + '" width="23px" /> ' + opt.text + '</span>'
                );
                return $opt;
            }

        };

这与我的示例相同,但并没有起作用:var optimage = opt.attr('data-image'); - Warre Buysse
我尝试完成答案 - user4540007

3

试试这个:

var optimage = $(opt).data('image'); //or $(opt).attr('data-image')
var $opt = $(
    '<span><img src="' + optimage + '" class="img-flag" /> ' + $(opt).text() + '</span>'
);

optimage 返回 "undefined"。我也尝试过这种方式。 - Warre Buysse

0

这里的每一个答案都是错误的,因为当返回一个jQuery对象给select2时,它会暴露你的应用程序于XSS漏洞。让我们阅读文档并找出原因:

内置转义

默认情况下,templateResult返回的字符串被认为只包含文本,并将通过escapeMarkup函数传递,该函数会删除任何HTML标记。

如果您需要在结果模板中呈现HTML,则必须将呈现的结果包装在jQuery对象中。在这种情况下,结果将直接传递给jQuery.fn.append,并将由jQuery直接处理。任何标记,例如HTML,都不会被转义,而且你需要转义用户提供的任何恶意输入

看看其他答案,它们都有一个致命缺陷,在传回文本之前没有对其进行转义。相反,正确的代码应该像这样(假设有一个合适的escape函数,在我的情况下我使用了lodash):

$(".class").select2({
    templateResult: formatState,
    templateSelection: formatState
});

function formatState (opt) {
    if (!opt.id) {
        return opt.text;
    } 

    var optimage = $(opt.element).attr('data-image'); 
    if(!optimage) {
       // This is safe, since you're returning a string
       return opt.text;
    } else {
       // Create an individual image element to properly escape the src url
       var img = $("<img width='60px'>");
       img.attr("src", optimage);

       // And remember to escape the text we're outputing
       var $opt = $(
         '<span>' +
         img.prop('outerHTML'); +
         '" width="60px" /> ' + 
         escape(opt.text) + 
         '</span>'
       );
       return $opt;
    }
};

0

虽然这不一定和问题直接相关,但在我的情况下没有起作用是因为如果您使用的是Select 2 < 4.0,则不存在templateResulttemplateSelection。请改用formatResultformatSelection


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