web-dev-qa-db-ja.com

コントロールを再構築せずにselect2データを更新する

<input type="hidden">をselect2ドロップダウンに変換し、クエリメソッドを介してデータをフィードしています

$('#inputhidden').select2({
    query: function( query ) {
        query.callback( data ); // the data is in the format select2 expects and all works well..
    );
});

問題は、select2 UIをハックし、検索バーの上に2つのボタンを配置する必要があることです。クリックすると、ajax呼び出しが実行され、select2コンテンツを更新する必要があります。

enter image description here

今、select2を完全に再構築せずに、ドロップダウンのアイテムを更新するだけで、これらの更新が必要になります。既に作成されたselect2コントロールに新しいデータセットを渡す方法が見つかりません。それは可能ですか?

38
mfreitas

select2 v3.x

オプション付きのローカル配列(ajax呼び出しで受信)がある場合、選択ボックスの結果を返す関数としてdataパラメーターを使用する必要があると思います。

var pills = [{id:0, text: "red"}, {id:1, text: "blue"}]; 

$('#selectpill').select2({
    placeholder: "Select a pill",
    data: function() { return {results: pills}; }
});

$('#uppercase').click(function() {
    $.each(pills, function(idx, val) {
        pills[idx].text = val.text.toUpperCase();
    });
});
$('#newresults').click(function() {
    pills = [{id:0, text: "white"}, {id:1, text: "black"}];
});

FIDDLEhttp:// jsfiddle .net/RVnfn/576 /

Select2インターフェイスをボタンでカスタマイズする場合は、updateResultsを呼び出すだけです(このメソッドはselect2オブジェクトの外部から呼び出すことはできませんが、必要に応じてselect2のallowedMethods配列に追加できます)。データ配列の更新(例では丸薬)。


select2 v4:カスタムデータアダプター

追加のupdateOptions(元のArrayAdapterにこの機能がない理由は不明)メソッドを使用したカスタムデータアダプターを使用して、オプションリスト(この例ではすべてのオプション)を動的に更新できます。

$.fn.select2.AMD.define('select2/data/customAdapter',
    ['select2/data/array', 'select2/utils'],
    function (ArrayAdapter, Utils) {
        function CustomDataAdapter ($element, options) {
            CustomDataAdapter.__super__.constructor.call(this, $element, options);
        }
        Utils.Extend(CustomDataAdapter, ArrayAdapter);
        CustomDataAdapter.prototype.updateOptions = function (data) {
            this.$element.find('option').remove(); // remove all options
            this.addOptions(this.convertToOptions(data));
        }        
        return CustomDataAdapter;
    }
);

var customAdapter = $.fn.select2.AMD.require('select2/data/customAdapter');

var sel = $('select').select2({
    dataAdapter: customAdapter,
    data: pills
});

$('#uppercase').click(function() {
    $.each(pills, function(idx, val) {
        pills[idx].text = val.text.toUpperCase();
    });
    sel.data('select2').dataAdapter.updateOptions(pills);
});

FIDDLEhttps:// jsfiddle .net/xu48n36c/1 /


select2 v4:ajaxトランスポート機能

v4では、ローカルデータ配列(thx @Caleb_Kiageなど、正常に再生できました)で動作するカスタムトランスポートメソッドを定義できます

docs: https://select2.github.io/options.html#can-an-ajax-plugin-other-than-jqueryajax-be-used

Select2は、ajax.transportで定義されたトランスポートメソッドを使用して、APIにリクエストを送信します。デフォルトでは、このトランスポート方法はjQuery.ajaxですが、これは変更できます。

$('select').select2({
    ajax: {
        transport: function(params, success, failure) {
            var items = pills;
            // fitering if params.data.q available
            if (params.data && params.data.q) {
                items = items.filter(function(item) {
                    return new RegExp(params.data.q).test(item.text);
                });
            }
            var promise = new Promise(function(resolve, reject) {
                resolve({results: items});
            });
            promise.then(success);
            promise.catch(failure);
        }
    }
});

しかし、このメソッドでは、配列のオプションのテキストが変更された場合、オプションのIDを変更する必要があります-内部select2 domオプション要素リストは変更されませんでした。配列内のオプションのIDが同じ場合-配列から更新される代わりに、以前に保存されたオプションが表示されます! 配列に新しいアイテムを追加するだけで変更された場合、ほとんどの場合は問題ありません。

FIDDLE:https://jsfiddle.net/xu48n36c/3 /

43
ndpu

データを直接引き渡すだけで十分だと思います。

$("#inputhidden").select2("data", data, true);

2番目のパラメーターは、更新が必要であることを示しているように見えることに注意してください。

this のサポートについて@Bergiに感謝します。


自動的に更新されない場合は、updateResultsメソッドを直接呼び出してみてください。

$("#inputhidden").select2("updateResults");

または、次のように「input.select2-input」にトリガーを送信して間接的にトリガーします。

var search = $("#inputhidden input.select2-input");
search.trigger("input");
17
zsawyer

MeteorでSelect2 4.0を使用すると、次のようなことができます。

Template.TemplateName.rendered = ->

  $("#select2-el").select2({
    data  : Session.get("select2Data")
  })

  @autorun ->

    # Clear the existing list options. 
    $("#select2-el").select2().empty()

    # Re-create with new options.
    $("#select2-el").select2({
      data  : Session.get("select2Data")
    })

何が起こっていますか:

  1. テンプレートがレンダリングされるとき...
  2. Sessionのデータを使用してselect2コントロールを初期化します。
  3. @autorun(this.autorun)関数は、Session.get( "select2Data")の値が変わるたびに実行されます。
  4. セッションが変更されるたびに、既存のselect2オプションをクリアし、新しいデータで再作成します。

これは、Session.get()だけでなく、Collection.find()。fetch()などのリアクティブデータソースで機能します。

注:Select2バージョン4.0では、新しいオプションを追加する前に既存のオプションを削除する必要があります。 詳細については、このGitHubの問題を参照 。既存のオプションをクリアせずに「オプションを更新」する方法はありません。

上記はcoffeescriptです。 Javascriptでも非常に似ています。

13
Data Meister

この問題は、ajaxオプションを使用してカスタムトランスポート関数を指定することで解決しました。

このフィドルをご覧ください Select2 dynamic options demo

これを機能させるための関連するjsを次に示します。

var $items = [];

let options = {
ajax: {
    transport: function(params, success, failure) {
    let items = $items;

    if (params.data && params.data.q) {
        items = items.filter(function(item) {
        return new RegExp(params.data.q).test(item.text);
        });
    }

    let promise = new Promise(function(resolve, reject) {
        resolve({
        results: items
        });
    });

    promise.then(success);
    promise.catch(failure);
    }
},
placeholder: 'Select item'
};

$('select').select2(options);

let count = $items.length + 1;

$('button').on('click', function() {
$items.Push({
    id: count,
    text: 'Item' + count
});
count++;
});
3
Caleb Kiage

var selBoxObj = $( '#selectpill'); selBoxObj.trigger( "change.select2");

2
karthipan raj

これを試してください:

var data = [{id: 1, text: 'First'}, {id: 2, text: 'Second'}, {...}];
$('select[name="my_select"]').empty().select2({
    data: data
});
1
SpinyMan

Select2 4.Xの場合

var instance = $('#select2Container').data('select2');
var searchVal = instance.dropdown.$search.val();
instance.trigger('query', {term:searchVal});
1

私の知る限り、リスト全体を更新するか、検索テキストを入力してクエリ機能を使用しないと、select2オプションを更新することはできません。

これらのボタンは何をすることになっていますか?それらを使用して選択オプションを決定する場合、選択ボックスの外側に配置し、プログラムで選択ボックスのデータを設定してから開いてみませんか?なぜそれらを検索ボックスの上に配置したいのか理解できません。ユーザーが検索することになっていない場合、minimumResultsForSearchオプションを使用して検索機能を非表示にできます。

Edit:これはどうですか...

HTML

<input type="hidden" id="select2" class="select" />

Javascript

var data = [{id: 0, text: "Zero"}],
    select = $('#select2');

select.select2({
  query: function(query) {
    query.callback({results: data});
  },
  width: '150px'
});

console.log('Opening select2...');
select.select2('open');

setTimeout(function() {
  console.log('Updating data...');
  data = [{id: 1, text: 'One'}];
}, 1500);

setTimeout(function() {
  console.log('Fake keyup-change...');
  select.data().select2.search.trigger('keyup-change');
}, 3000);

Plunker

編集2:それは少なくともリストを更新するためにそれを取得しますが、keyup-changeイベント。

1
rtcherry