Select2 4.0.0 Ajaxでの初期値


97

select2 v4.0.0がAjaxアレイから読み込まれています。select2の値を設定すると、JavaScriptのデバッグで正しい項目(私の場合は#3)が選択されていることがわかりますが、これは選択ボックスに表示されず、プレースホルダーがまだ表示されています。 ここに画像の説明を入力してください

一方、私はこのようなものを見るべきでした: ここに画像の説明を入力してください

私のフォームフィールド:

<input name="creditor_id" type="hidden" value="3">
<div class="form-group minimal form-gap-after">
    <span class="col-xs-3 control-label minimal">
        <label for="Creditor:">Creditor:</label>
    </span>
    <div class="col-xs-9">
        <div class="input-group col-xs-8 pull-left select2-bootstrap-prepend">
            <select class="creditor_select2 input-xlarge form-control minimal select2 col-xs-8">
                <option></option>
            </select>
        </div>
    </div>
</div>

私のjavascript:

var initial_creditor_id = "3";
$(".creditor_select2").select2({
    ajax: {
       url: "/admin/api/transactions/creditorlist",
       dataType: 'json',
       delay: 250,
       data: function (params) {
           return {
                q: params.term,
                c_id: initial_creditor_id,
                page: params.page
           };
       },
       processResults: function (data, page) {
            return {
                results: data
            };
       },
       cache: true
   },
   placeholder: "Search for a Creditor",
   width: "element",
   theme: "bootstrap",
   allowClear: true
   }).on("select2:select", function (e) {
      var selected = e.params.data;
      if (typeof selected !== "undefined") {
           $("[name='creditor_id']").val(selected.creditor_id);
           $("#allocationsDiv").hide();
           $("[name='amount_cash']").val("");
           $("[name='amount_cheque']").val("");
           $("[name='amount_direct']").val("");
           $("[name='amount_creditcard']").val("");
        }
    }).on("select2:unselecting", function (e) {
        $("form").each(function () {
            this.reset()
        });
        ("#allocationsDiv").hide();
        $("[name='creditor_id']").val("");
    }).val(initial_creditor_id);

選択ボックスにプレースホルダーではなく選択したアイテムを表示するにはどうすればよいですか?これをAJAX JSON応答の一部として送信する必要がありますか?

以前は、Select2には、カスタムデータソースが使用されているときに常に定義されるinitSelectionと呼ばれるオプションが必要でした。これにより、コンポーネントの初期選択を決定できました。これはv3.5で問題なく動作しました。


どのように可能ですか?バインドしようとするselectajaxエラーが発生し、そのオプションは選択では許可されません...
Daggeto

回答:


109

あなたはほとんどのことを正しく行っています、あなたが打っている唯一の問題changeは、新しい値を設定した後にメソッドをトリガーしていないことです。なければchangeイベント、Selectセレクトは、それが唯一のプレースホルダが表示されますので、基本となる値が変更されたことを知ることができません。最後の部分を

.val(initial_creditor_id).trigger('change');

問題が修正され、UIの更新がすぐに表示されます。


これは、あなたが持っていると仮定され<option>、既に持っているvalueのをinitial_creditor_id。Select2を使用しない場合、ブラウザは、切り替えるオプションがないため、実際には値を変更できず、Select2は新しい値を検出しません。<select>プレースホルダー用のオプションが1つだけ含まれていることに気付きました。つまり、新しいオプションを<option>手動で作成する必要があります。

var $option = $("<option selected></option>").val(initial_creditor_id).text("Whatever Select2 should display");

そして、<select>Select2を初期化したに追加します。テキストを外部ソースから取得する必要がある場合がありますinitSelection。これは、実際に使用される場所であり、Select2 4.0.0でも可能です。これは、標準の選択と同様に、値を取得するためにAJAXリクエストを<option>作成し、その場でテキストを調整して調整する必要があることを意味します。

var $select = $('.creditor_select2');

$select.select2(/* ... */); // initialize Select2 and any events

var $option = $('<option selected>Loading...</option>').val(initial_creditor_id);

$select.append($option).trigger('change'); // append the option and update Select2

$.ajax({ // make the request for the selected data object
  type: 'GET',
  url: '/api/for/single/creditor/' + initial_creditor_id,
  dataType: 'json'
}).then(function (data) {
  // Here we should have the data object
  $option.text(data.text).val(data.id); // update the text that is displayed (and maybe even the value)
  $option.removeData(); // remove any caching data that might be associated
  $select.trigger('change'); // notify JavaScript components of possible changes
});

これは多くのコードのように見えるかもしれませんが、すべての変更が確実に行われるように、Select2以外の選択ボックスに対して行う方法まったく同じです


14
複数選択ボックスの複数オプションを事前選択する方法はありますか?
user396404

6
@ user396404同じ概念を適用する必要がありますval()。単一のIDではなくIDのリストを渡すだけです。または、複数<option selected>を追加すると、自動的に処理されます。
Kevin Brown

5
この回答は1年以上前のものであることに気付きましたが、Select2のFAQの質問のドキュメント:「AJAXを使用するときに、最初に選択したオプションをどのように設定できますか?」まだこれを指しています。JSFiddleをv4.0.3の
クリント

2
問題があります。IDとテキスト以外のものもリクエストしたい場合はどうすればよいですか?私は試しましたが、dataオプションはtemplateResultのデータのみを取得し、templateSelectionでは無視します。何か案が?
ClearBoth 2017年

2
また、私はこの解決策を試しましたが、残念ながら$select.trigger('change');、オプションを呼び出した後も、希望どおりのテキストがあったとしても、オプションはまだLoading ...テキストのままdata.textです。たぶん、これは4.0.6でサポートされなくなりました。
Alisson 2018

28

私がやったことはよりきれいで、2つの配列を作る必要があります:

  • 1つはIDとテキスト(私の場合は、templateResultに応じてIDと名前)を持つオブジェクトのリストを含みます(ajaxクエリから取得したもの)
  • 2番目は、ID(選択値)の配列のみです。

最初の配列をデータとして使用し、2番目の配列をvalとして使用して、select2を初期化します。

id:nameのdictをパラメーターとして使用する関数の例。

function initMyList(values) {
    var selected = [];
    var initials = [];

    for (var s in values) {
        initials.push({id: s, name: values[s].name});
        selected.push(s);
    }

    $('#myselect2').select2({
        data: initials,
        ajax: {
            url: "/path/to/value/",
            dataType: 'json',
            delay: 250,
            data: function (params) {
                return {
                    term: params.term,
                    page: params.page || 1,
                };
            },
            processResults: function (data, params) {
                params.page = params.page || 1;

                return {
                    results: data.items,
                    pagination: {
                        more: (params.page * 30) < data.total_count
                    }
                };
            },
            cache: true
        },
        minimumInputLength: 1,
        tokenSeparators: [",", " "],
        placeholder: "Select none, one or many values",
        templateResult: function (item) { return item.name; },
        templateSelection: function (item) { return item.name; },
        matcher: function(term, text) { return text.name.toUpperCase().indexOf(term.toUpperCase()) != -1; },
    });

    $('#myselect2').val(selected).trigger('change');
}

ajax呼び出しを使用して初期値をフィードし、jquery promiseを使用してselect2の初期化を行うことができます。


3
これは間違いなくそれを行うためのより良い方法です。追加によるDOMの操作は<option>、そのための最も論理的な方法ではないようです。これは4.0での
やり方です

2
@ firebird631、あなたのソリューションは素晴らしいです、それは機能し、非常に感謝します!
userlond

これは、私がこれまでに見た中で最もクリーンなソリューションです
Jimmy Ilenloa

内部的には、dataオプションは<option>タグを生成してselectに追加するだけであることに注意します。この回答では、より多くの情報を取得するためにAPIにアクセスする必要がある場合の処理​​方法については説明していませんが、これはそれほど一般的ではないケースだと思います。
ケビン・ブラウン

こんにちはajaxです。できません。2つのオブジェクトを含むリストを送信すると、問題はありません。これらの2つのオブジェクトを挿入しようとしますが、1つだけを挿入します。すでに自動的に選択されています。2つのアイテムを送信しても、2つのオプションが表示されません。
SahinYanlık2017年

7

それは私にとってはうまくいきます...

jQueryのを使用しないでください、だけでHTML:作成オプションの値として使用すると、表示される選択を。IDがselect2データにある場合は、自動的に選択されます。

<select id="select2" name="mySelect2">
  <option value="mySelectedValue">
        Hello, I'm here!
  </option>
</select>

Select2.org-デフォルトの事前選択値


6

トリガーにtrigger('change')カスタムコードがありchange、ユーザーがドロップダウンのオプションを変更した場合にのみトリガーされるため、強制的に強制された問題。IMO、開始時に初期値を設定するときに変更をトリガーしないでください。

私は深く掘り下げて、以下を見つけました:https : //github.com/select2/select2/issues/3620

例:

$dropDown.val(1).trigger('change.select2');


4

私が人々が実際に回答するのを見たことがない1つのシナリオは、オプションがAJAXソースであり、複数を選択できる場合に事前選択を行う方法です。これはAJAX事前選択の主要ページなので、ここにソリューションを追加します。

$('#mySelect').select2({
    ajax: {
        url: endpoint,
        dataType: 'json',
        data: [
            { // Each of these gets processed by fnRenderResults.
                id: usersId,
                text: usersFullName,
                full_name: usersFullName,
                email: usersEmail,
                image_url: usersImageUrl,
                selected: true // Causes the selection to actually get selected.
            }
        ],
        processResults: function(data) {

            return {
                results: data.users,
                pagination: {
                    more: data.next !== null
                }
            };

        }
    },
    templateResult: fnRenderResults,
    templateSelection: fnRenderSelection, // Renders the result with my own style
    selectOnClose: true
}); 

3

templateSelectionとajaxを使用している場合、これらの他の回答の一部が機能しない可能性があります。新しい作成しているようですoption要素をと設定valueし、textあなたのデータオブジェクトはidとテキスト以外の値を使用する場合、テンプレートメソッドを満たしています。

これが私のために働いたものです:

$("#selectElem").select2({
  ajax: { ... },
  data: [YOUR_DEFAULT_OBJECT],
  templateSelection: yourCustomTemplate
} 

ここでjsFiddleをチェックしてください:https://jsfiddle.net/shanabus/f8h1xnv4

私の場合、processResultsデータに必須フィールドidtextフィールドが含まれていなかったため、入らなければなりませんでした。これを行う必要がある場合は、同じ機能で最初の選択を実行する必要もあります。そのようです:

$(".js-select2").select2({
  ajax: {
    url: SOME_URL,
    processResults: processData
  },
  data: processData([YOUR_INIT_OBJECT]).results,
  minimumInputLength: 1,
  templateSelection: myCustomTemplate
});

function processData(data) {
  var mapdata = $.map(data, function (obj) {      
    obj.id = obj.Id;
    obj.text = '[' + obj.Code + '] ' + obj.Description;
    return obj;
  });
  return { results: mapdata }; 
}

function myCustomTemplate(item) {
     return '<strong>' + item.Code + '</strong> - ' + item.Description;
}

最後に!!!!!うわー、それはこれ以上苛立たしいことではありませんでした!「テキスト」の代わりに「名前」を使用していたので、それが私を殺していました。デフォルトの「テキスト」キーに切り替えたところ、完全に機能しています。ありがとうございました!
HTMLGuy 2017

1

数時間かけてソリューションを探した後、自分でソリューションを作成することにしました。彼はそれです:

 function CustomInitSelect2(element, options) {
            if (options.url) {
                $.ajax({
                    type: 'GET',
                    url: options.url,
                    dataType: 'json'
                }).then(function (data) {
                    element.select2({
                        data: data
                    });
                    if (options.initialValue) {
                        element.val(options.initialValue).trigger('change');
                    }
                });
            }
        }

また、この関数を使用して、selectを初期化できます。

$('.select2').each(function (index, element) {
            var item = $(element);
            if (item.data('url')) {
                CustomInitSelect2(item, {
                    url: item.data('url'),
                    initialValue: item.data('value')
                });
            }
            else {
                item.select2();
            }
        });

そしてもちろん、これがhtmlです。

<select class="form-control select2" id="test1" data-url="mysite/load" data-value="123"></select>

一般的な初期化手順の優れたアイデア。
Carlos Mora

1

シンプルでセマンティックなソリューションの場合、HTMLで初期値を定義することを好みます。例:

<select name="myfield" data-placeholder="Select an option">
    <option value="initial-value" selected>Initial text</option>
</select>

したがって$('select').select2({ ajax: {...}});、初期値を呼び出すinitial-valueと、そのオプションテキストはになりInitial textます。

私の現在のSelect2バージョンは4.0.3ですが、他のバージョンとの互換性は非常に高いと思います。


select値だけでなく、テキストもデータベースに保存しているので、そのようにして取得できます... sheesh!
ITDesigns.eu 2018

@ ITDesigns.eu、私はそうは思いませんがinitial-value、データベースへの値sendoはであり、テキストInitial textはプレースホルダーとして機能し、データベースに送信されません。それは私のアプリケーションで動作しています。
Marcio Mazzucato

実際のオプションで実際のテキストではなくプレースホルダーが必要なのはなぜですか?
ITDesigns.eu 2018

@ ITDesigns.eu、Select2がこの情報を取得し、それ自体をマウントします
Marcio Mazzucato 2018

1

https://github.com/select2/select2/issues/4272 これだけで問題が解決しました。オプションでデフォルト値を設定する場合でも、text属性を持つオブジェクトをフォーマットする必要があり、これがオプションで表示したいものです。そのため、フォーマット関数||は、空でない属性を選択するために使用する必要があります。


0

上記のコメントはできないので、主にこの回答を追加しています!@Nickiと彼女のjsfiddle、https: //jsfiddle.net/57co6c95/のコメントであることがわかり、最終的にこれが機能しました。

特に、必要なjsonのフォーマットの例を示しました。私がしなければならない唯一の変更は、私の最初の結果が他のajax呼び出しと同じ形式で返されたため、

$option.text(data[0].text).val(data[0].id);

のではなく

$option.text(data.text).val(data.id);

0

select2 4.0.3の初期の初期値で単純なajaxコンボを作成する

<select name="mycombo" id="mycombo""></select>                   
<script>
document.addEventListener("DOMContentLoaded", function (event) {
    selectMaker.create('table', 'idname', '1', $("#mycombo"), 2, 'type');                                
});
</script>  

ライブラリ.js

var selectMaker = {
create: function (table, fieldname, initialSelected, input, minimumInputLength = 3, type ='',placeholder = 'Select a element') {
    if (input.data('select2')) {
        input.select2("destroy");
    }
    input.select2({
        placeholder: placeholder,
        width: '100%',
        minimumInputLength: minimumInputLength,
        containerCssClass: type,
        dropdownCssClass: type,
        ajax: {
            url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type,
            type: 'post',
            dataType: 'json',
            contentType: "application/json",
            delay: 250,
            data: function (params) {
                return {
                    term: params.term, // search term
                    page: params.page
                };
            },
            processResults: function (data) {
                return {
                    results: $.map(data.items, function (item) {
                        return {
                            text: item.name,
                            id: item.id
                        }
                    })
                };
            }
        }
    });
    if (initialSelected>0) {
        var $option = $('<option selected>Cargando...</option>').val(0);
        input.append($option).trigger('change'); // append the option and update Select2
        $.ajax({// make the request for the selected data object
            type: 'GET',
            url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type + '&initialSelected=' + initialSelected,
            dataType: 'json'
        }).then(function (data) {
            // Here we should have the data object
            $option.text(data.items[0].name).val(data.items[0].id); // update the text that is displayed (and maybe even the value)
            $option.removeData(); // remove any caching data that might be associated
            input.trigger('change'); // notify JavaScript components of possible changes
        });
    }
}
};

とphpサーバー側

<?php
if (isset($_GET['getQuery']) && isset($_GET['table']) && isset($_GET['fieldname'])) {
//parametros carga de petición
parse_str(file_get_contents("php://input"), $data);
$data = (object) $data;
if (isset($data->term)) {
    $term = pSQL($data->term);
}else{
    $term = '';
}
if (isset($_GET['initialSelected'])){
    $id =pSQL($_GET['initialSelected']);
}else{
    $id = '';
}
if ($_GET['table'] == 'mytable' && $_GET['fieldname'] == 'mycolname' && $_GET['type'] == 'mytype') {

    if (empty($id)){
        $where = "and name like '%" . $term . "%'";
    }else{
         $where = "and id= ".$id;
    }

    $rows = yourarrayfunctionfromsql("SELECT id, name 
                    FROM yourtable
                    WHERE 1 " . $where . "
                    ORDER BY name ");
}

$items = array("items" => $rows);
$var = json_encode($items);
echo $var;
?>

-4

こんにちはほぼこれをやめて、選択3.5.1に戻ります。しかし、最終的に私は答えを得ました!

$('#test').select2({
    placeholder: "Select a Country",
    minimumResultsForSearch: 2,
    ajax: {
        url: '...',
        dataType: 'json',
        cache: false,
        data: function (params) {
                var queryParameters = {
                    q: params.term
                }
                return queryParameters;
        },
        processResults: function (data) {
            return {
                results: data.items
            };
        }
    }
});

var option1 = new Option("new",true, true);

$('#status').append(option1);

$('#status').trigger('change');

新しいオプションがselect2オプションの1つであることを確認してください。私はこれをjsonで取得します。


こんにちは-「#status」とは何ですか?それは '#test'である必要がありますか?
user2808054 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.