选择2:预选项目并通过templateSelection

时间:2017-07-13 12:15:42

标签: jquery jquery-select2

使用Select2 v4时,建议的(实际上是正确的)方式以编程方式设置选定的值,是操纵底层的select元素,添加所需的<option>元素你想要的,用$selectElement.val(<value>)设置值并触发.trigger('change')事件,以便select2插件将从底层的select元素更新自己。您可以看到此here

这个问题是你定义了一个templateSelection,它不仅返回所选值的文本,还返回一个完整的HTML DOM(例如,你可以应用样式,添加图像,图标等等)将其作为渲染选择返回。)

templateSelection接受输入,因为它来自数组数据源或ajax数据源等。每个项目代表一个选项,但它可能不仅仅是idtexttemplateSelection可以考虑许多项目的属性来生成渲染输出。

您只能在<option>元素中定义值和文本。您无法定义要设置为选中的实际对象(项目),以便templateSelection可以生成正确的输出。

有没有办法只使用select2的API来实现这一目标?

如果没有,是否还有其他解决方法可以通过templateSelection正确呈现代码中的值?

3 个答案:

答案 0 :(得分:1)

templateSelection是基于选项的文本内容构建对象的回调。返回和显示的对象与选项的内容不同。选项仍然是简单的id和文本内容。造型分开处理。

定义templateSelection时,您定义了一个将选项作为参数的函数,因此您可以将文本和选项的ID作为可用变量进行访问。此函数将返回根据您的模板构建的对象。

见这个例子:

$(document).ready(function() {
  $('.js-example-basic-single').select2({
    width: 'width: 100%',
    templateSelection: formatState
  });
});

$('.js-example-basic-single').val('WY');
$('.js-example-basic-single').trigger('change');

function formatState(state) {
  console.log(state);
  var $state = $(
    '<span>Content from the template: ' + state.element.text + ' ' + state.element.value + '</span>'
  );

  return $state;
}
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<select class="js-example-basic-single" name="state">
  <option value="AL">Alabama</option>
  <option value="WY">Wyoming</option>
</select>

编辑:

由于您可以访问该状态,因此您可以访问使用动态数据定义的任何属性。并且您可以访问该元素,因此您也可以拥有数据属性。这使您可以做更精细的事情:

$(document).ready(function() {
  $('.js-example-basic-single').select2({
    width: 'width: 100%',
    templateSelection: formatState,
    data: [{
      id: 0,
      text: "Wyoming"
    }, {
      id: 1,
      text: "Alabama",
      selected: true,
      disabled: true,
    }, {
      id: 2,
      text: "Washington",
      selected: true,
      customProp: 'something'
    }]
  });
});



function formatState(state) {
  console.log(state);
  var $state 
  if (state.customProp) {
    $state = $(
      '<span>Content from the template: ' + state.element.text + ' ' + state.element.value + ' and my custom property is <strong>' + state.customProp + '</strong></span>'
    );
  } else {
  $state = $(
      '<span>Content from the template: ' + state.element.text + ' ' + state.element.value + '</span>'
       );
  }

  return $state;
}
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<select class="js-example-basic-single" name="state">
</select>

答案 1 :(得分:0)

我在Select2 v4.0.3中遇到了同样的问题。通过向当前选择项数组中的目标项添加必要的属性来解决该问题:

var $widget = jQuery('#mySelect2Widget');

// add new option to widget
var newOption = new Option('New option text', 'New option id', false, true);
$widget.append(newOption);

// get current selection items
var items = $widget.select2('data');
var targetItem = null;

// find newly added item in the array by id or smth else
// and set it to the "targetItem" variable

targetItem.prop1 = 'abc';
targetItem.prop2 = 1;

// trigger "change" event
$widget.trigger('change');

答案 2 :(得分:0)

只要有像我这样的人遇到这个问题,Select2 v4手册就可以为您提供答案:https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2

以下代码片段来自文档。本质上,您可以通过ajax调用获取初始值,并通过url <- 'https://wordpress.org/support/plugin/demo-data-creator/reviews/' page <- read_html(url) links <- html_nodes(page, css='a.bbp-topic-permalink') reviewurls <- html_attr(links, 'href') # Two empty lists, to be populated inside the loop titles = c() contents = c() for (u in reviewurls) { page = read_html(u) reviewT = html_text(html_node(page, css='h1.page-title')) reviewC = html_text(html_node(page, css='div.bbp-topic-content')) titles = c(titles, reviewT) contents = c(contents, reviewC) } 事件以编程方式设置初始值。

> length(titles)
[1] 21

> head(titles)
[1] "Good for development"                                          
[2] "Used it for creating test users"                               
[3] "Excelent! negative comments come from people who doesn't read!"
...

> head(contents)
[1] "\n\n\t\t\t\t\n\t\t\t\tGood and handy tool for development.\n\n\n\n\t\tThis topic was modified 2 years, 10 months ago by Subrata Sarkar.\n\t\n\n"                                                                                                                                                                                                                                                                                                                                
[2] "\n\n\t\t\t\t\n\t\t\t\tThis plugin came in very handy during development of my own plugin. I used it to create a lot of users and it did exactly what it should.\nNot sure where all the negativity about wiping the database comes from. Are they users that didn’t read all the warnings? Or did older versions of the plugin not warn about wiping all data? Anyway, now it does \U0001f642\n\n\t\t\t\t\n\t\t\t"                                                            
[3] "\n\n\t\t\t\t\n\t\t\t\tDoes exactly what it offers! Nothing less.\nPeople complaining is too lazy to read the SEVERAL warnings about the usage of this plugin.\n\n\t\t\t\t\n\t\t\t" 
...

但是,如果您正在使用templateSelection选项,并且正在返回jQuery对象以提供精美的单行格式选择结果,则此解决方案将不起作用。实际上,触发select2:select似乎无济于事。

使用jQuery,我发现我可以将数据附加到该选项,然后从templateSelection函数中,使用此数据作为后备。

select2:select

在templateSelection函数中:

// Set up the Select2 control
$('#mySelect2').select2({
    ajax: {
        url: '/api/students'
    }
});

// Fetch the preselected item, and add to the control
var studentSelect = $('#mySelect2');
$.ajax({
    type: 'GET',
    url: '/api/students/s/' + studentId
}).then(function (data) {
    // create the option and append to Select2
    var option = new Option(data.full_name, data.id, true, true);
    studentSelect.append(option).trigger('change');

    // manually trigger the `select2:select` event
    studentSelect.trigger({
        type: 'select2:select',
        params: {
            data: data
        }
    });
});

此示例使用多个后备。我们总是尝试使用正常ajax调用中提供的结果,但是我们会从初始选项退回到原始数据,如果缺少原始数据,则退回到文本字段。