【问题标题】:Programmatically set the value of a Select2 ajax以编程方式设置 Select2 ajax 的值
【发布时间】:2014-10-13 06:18:06
【问题描述】:

我有一个 Select2 自动完成输入(通过 SonataAdmin 构建),但我终其一生都无法弄清楚如何以编程方式将其设置为已知的键/值对。

a JS Fiddle here 大致显示了我所拥有的。我想知道的是我可以将什么功能附加到按钮上,以便

  • Select2 字段向用户显示文本“NEW VALUE”,并且
  • 当表单发送到服务器时,Select2 字段将提交值“1”

我已经尝试了 jQuery 和 Select2 dataval 方法的各种组合,针对页面上的各种输入调用,但似乎没有任何效果......肯定有什么方法可以做到这一点?

-- 编辑--

下面接受的答案非常有用,有助于阐明初始化选择的正确方法并解释 initSelection 的用途。

话虽如此,看来我最大的错误是我试图触发更改的方式。

我正在使用:

$(element).select2('data', newObject).trigger('change');

但这会导致 select2 的更改事件中出现一个空的 add 对象。

如果您改为使用:

$(element).select2('data', newObject, true);

然后代码可以正常工作,newObject 在 select2 的更改事件中可用,并且值设置正确。

我希望这些额外的信息对其他人有所帮助!

【问题讨论】:

    标签: javascript jquery jquery-select2 sonata-admin


    【解决方案1】:

    请注意,这是使用版本 4+ 测试的

    找到这个讨论后我终于能够取得进展:https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4

    最后一条评论指出了一种我能够成功使用的方法。

    例子:

    $("#selectelement").select2("trigger", "select", {
        data: { id: "5" }
    });
    

    这似乎是足够的信息来匹配 ajax 数据,并正确设置值。这对自定义数据适配器有很大帮助。

    【讨论】:

    • 作为注释,这将设置
    • 适用于 v4。在谷歌搜索、搜索文档等 2 天后发现了这个。
    • 谢谢!他们的文档说要使用 new Option 但这不适用于带有自定义模板的 AJAX 调用
    • 它可以工作,但是当我尝试使用这种方法选择大约 30 个 select2 元素时,它需要 5 或 6 秒。我有一个表单,其中有一系列项目,因此在编辑该表单时使用此方法选择其他属性需要时间,所以对我不起作用。
    【解决方案2】:

    注意:问题和本答案适用于 Select2 v3。 Select2 v4 的 API 与 v3 截然不同。

    我认为问题出在initSelection 函数上。您是否使用该功能来设置初始值?我知道 Select2 文档听起来像是它的目的,但它也说“本质上这是一个 id-> 对象映射函数”,这不是您实现它的方式。

    由于某种原因,对.trigger('change') 的调用会导致调用initSelection 函数,这会将所选值更改回“ENABLED_FROM_JS”。

    尝试摆脱 initSelection 函数,而是使用以下方法设置初始值:

    autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});
    

    jsfiddle

    注意:OP 提供了formatResultformatSelection 选项。如所提供的,这些回调函数期望项目具有“标签”属性,而不是“文本”属性。 对于大多数用户来说,应该是:

    autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});
    

    更多关于initSelection函数的信息:

    如果您在Select2 documentation 中搜索“initSelection”,您会看到它在元素具有初始值以及调用元素的.val() 函数时使用。那是因为这些值只包含一个 id 而 Select2 需要整个数据对象(部分是为了显示正确的标签)。

    如果 Select2 控件显示静态列表,initSelection 函数将很容易编写(看起来 Select2 可以为您提供它)。在这种情况下,initSelection 函数只需在数据列表中查找id 并返回相应的数据对象。 (我在这里说“返回”,但它并没有真正返回数据对象;它会将它传递给回调函数。)

    在您的情况下,您可能不需要提供 initSelection 函数,因为您的元素没有初始值(在 html 中)并且您不会调用它的 .val() 方法。只需继续使用.select2('data', ...) 方法以编程方式设置值即可。

    如果您要为自动完成(使用 ajax)提供 initSelection 函数,它可能需要进行 ajax 调用来构建数据对象。

    【讨论】:

    • 顺便说一句,是否有任何文档说明“本质上这是一个 id-> 对象映射函数”的含义(以及如何在该上下文中将其用于自动完成字段)?跨度>
    • initSelection 在 Select2 4.0 中已弃用。这已被 数据适配器 上的 current 方法取代,并且仅在完整版本中可用
    • 请更新小提琴 - 资源加载失败并显示 404
    • @Zanshin13 - 我更新了 jsfiddle 中外部资源的 URL,但我认为它实际上没有起作用,因为 ajax 调用无效。
    【解决方案3】:

    要设置初始值,您需要使用 jQuery 将必要的选项标签添加到 select 元素,然后使用 select2 的 val 方法将这些选项定义为选中,最后触发 select2 的 'change' 事件。

    1.-$('#selectElement').append('<option value=someID>optionText</option>');
    2.-$('#selectElement').select2('val', someID, true);
    

    第三个布尔参数告诉 select2 触发更改事件。

    欲了解更多信息,请参阅https://github.com/select2/select2/issues/3057

    【讨论】:

    • 您不能将选择元素用于远程数据 (ajax)。
    【解决方案4】:

    小心,“已验证”的评论有误。

    autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});
    

    正确的做法是

    autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});
    

    使用 text 代替 label

    【讨论】:

    • 对我来说是名称而不是文本/标签 :)
    • 如果您查看 OP 的 jsfiddle,您会看到 OP 提供了 formatResultformatSelection 选项。这些函数的编写方式,他们希望项目具有“标签”属性,而不是“文本”属性。我已经添加到我的答案中,以向其他人说明这一点。
    【解决方案5】:

    使用 Select2 版本 4+,实际上您不需要做任何特别的事情。最后带有“更改”事件触发器的标准 jQuery 将起作用。

    var $select = $("#field");
    var items = {id: 1, text: "Name"}; // From AJAX etc
    var data = $select.val() || [];    // If you want to merge with existing
    
    $(items).each(function () {
      if(!$select.find("option[value='" + this.id + "']").length) {
        $select.append(new Option(this.text, this.id, true, true));
      }
      data.push(this.id);
    });
    
    $select.val(data).trigger('change'); // Standard event notifies select2
    

    Select2 文档中有一个基本示例: https://select2.org/programmatic-control/add-select-clear-items

    【讨论】:

      【解决方案6】:

      从他们的例子 https://select2.github.io/examples.html

      程序化访问:

      var $example = $(".js-example-programmatic").select2();
      var $exampleMulti = $(".js-example-programmatic-multi").select2();
      $(".js-programmatic-set-val").on("click", function () { $example.val("CA").trigger("change"); });
      $(".js-programmatic-open").on("click", function () { $example.select2("open"); });
      $(".js-programmatic-close").on("click", function () { $example.select2("close"); });
      $(".js-programmatic-init").on("click", function () { $example.select2(); });
      $(".js-programmatic-destroy").on("click", function () { $example.select2("destroy"); });
      $(".js-programmatic-multi-set-val").on("click", function () { $exampleMulti.val(["CA", "AL"]).trigger("change"); });
      $(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(null).trigger("change"); });
      

      【讨论】:

        【解决方案7】:

        您所要做的就是设置值然后执行:$ ('#myselect').select2 ();$ ('select').select2 ();。 而且一切都更新得很好。

        【讨论】:

          【解决方案8】:

          如果您从小提琴中删除.trigger('change'),它会记录Object {id: 1, label: "NEW VALUE"}(需要单击两次,因为记录是在值更改之前)。这就是你要找的吗?

          【讨论】:

          • 是的,我也删除了 .trigger('change');,它对我有用 (Chrome)
          • 不幸的是,我需要触发更改,而 JohnS 的答案触及问题的根源,因此我接受了该答案。
          【解决方案9】:

          当使用带有多个选项的 select2 时,请使用以下构造:

          $(element).select2("data", $(element).select2("data").concat(newObject), true);
          

          【讨论】:

            【解决方案10】:

            就是这样:

            $("#tag").select2('data', { id:8, title: "Hello!"});
            

            【讨论】:

              【解决方案11】:

              适用于 3.5.3 版

                  $(".select2").select2('data',{id:taskid,text:taskname}).trigger('change');
              

              基于John S' answer 。只有在初始化 select2 时 initSelection 选项未初始化时,上述方法才有效。

              $(".select2").select2({
                    //some setup
              })
              

              【讨论】:

                【解决方案12】:

                对于仍在使用 3.5 或更高版本的用户。请确定您如何将 select2.js 引用到您的页面。如果您使用异步或延迟加载。此插件的行为可能有所不同。

                想提一下。

                【讨论】:

                  【解决方案13】:

                  在我的情况下,我能够使用 PHP 将预选选项呈现到 HTML 服务器端。

                  在我的页面加载过程中,我已经知道了option的值,所以我的&lt;select name="team_search"&gt;&lt;/select&gt;变成了下面这样;

                          <select name="team_search">
                              <?php echo !empty($preselected_team) 
                                      ? '<option selected="selected" value="'. $preselected_team->ID .'">' . $preselected_team->team_name . '</option>' 
                                      : null ?>
                          </select>';
                  

                  如您所见,当我有可用的$preselected_team 时,我会在带有selected 属性、value 和标签集的选项中呈现。而且,如果我没有值,则不会呈现选项。

                  这种方法可能并不总是可行(并且在 OP 的情况下没有提到),但它确实带来了额外的好处,即在 JavaScript 执行之前准备好页面加载。

                  【讨论】:

                    【解决方案14】:

                    添加一个带有 id 和文本的新选项

                    let $newOption = $("<option selected='selected'></option>").val(1).text('New Text goes here');
                    $("#selector").append($newOption).trigger('change');
                    

                    【讨论】:

                      猜你喜欢
                      • 2011-02-14
                      • 2017-05-13
                      • 2016-12-10
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-07-25
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多