Chosenの複数選択を使用しています。ユーザーが選択した注文を追跡できるようにしたい。たとえば、ユーザーが最初にoption2を選択し、次にoption1を選択した場合、option2とoption1の順序で結果を取得します。ただし、chosenはユーザーが選択したオプションをソートします。結果をソートしないように選択したことを伝える方法はありますか?
Chosenと一緒に使用する簡単なプラグインを作成しました。選択した複数の選択要素の選択順序を取得し、配列から設定することもできます順序付けられた値。
Githubで入手できます: https://github.com/tristanjahier/chosen-order
これは、Chosen 1.0+およびjQueryとPrototypeの両方のバージョンと互換性があります。各フレームワーク用のプラグインもあり、次のようなことができます。
var selection = $('#my-list').getSelectionOrder();
var order = ['nioup', 'plop', 'fianle']; // Ordered options values
$('#my-list').setSelectionOrder(order);
見てみな。
https://github.com/mrhenry/jquery-chosen-sortable/ プラグインが利用可能になり、選択したv1のジョブを実行します。
選択されたの新しいバージョンの場合は、github JSファイルでchzn-をchosen-に置き換える必要があります。
使用するには、次のコードを使用します。
jQuery('#myselect').addClass('chosen-sortable').chosenSortable();
これは非常にうまく機能しますが、選択された要素が読み込まれた後にフィールドを再度編集して要素を並べ替える場合は、さらにコードが必要になります。
これには以下を使用します。 SortedElementsのリストと$ select = jQuery( '#myselect')を指定すると、次のようになります。
var $container = $select.siblings('.chosen-container')
var $list = $container.find('.chosen-choices');
// Reverse the list, as we want to prepend our elements.
var sortedElements = sortedElements.reverse();
for (var i = 0; i < sortedElements.length; i++) {
var value = sortedElements[i];
// Find the index of the element.
var index = $select.find('option[value="' + value + '"]').index();
// Sort the item first.
$list
.find('a.search-choice-close[data-option-array-index="' + index + '"]')
.parent()
.remove()
.prependTo($list);
}
これはここで非常にうまく機能します。
手遅れにならない場合は Select2 を使用することをお勧めします。選択されたものと同じように見えますが、APIとドキュメントの方が優れています。
Select2では、[unested code]のようになります。
var results = [];
$("#e11").on("change", function(e) {
results.Push(e.val)
})
変更イベントで自分でアイテムを追加/削除できます。
// Your collection Array
var collectionArray = []
// make change event on chosen select field
chosenSelect.change(function () {
// first get the chosen results which might be in wrong order
var currentValues = $(this).val();
// get your current collection that is in the right order
var pastValues = collectionArray;
// see if you need to add or drop
if (currentValues.length > pastValue.length) {
// loop to get just the new item
pastValues.forEach(function(pastValue) {
currentValue = $.grep(currentValue, function(newItemOnly) {
return newItemOnly != pastValue;
});
});
// add your newItemOnly
collectionArray.Push(currentValue[0]);
} else {
// here loop to get only the dropped value
currentValues.forEach(function(currentValue) {
pastValues = $.grep(pastValues, function(droppedValueOnly) {
return droppedValueOnly != currentValue;
});
});
// drop the value dropped from your collection
collectionArray = $.grep(collectionArray, function(updatedArray) {
return updatedArray != pastValues[0];
});
}
});
カスタム.change()
イベントハンドラーを挿入して動作させました:
$('.chosen-select').chosen({});
に:
$('.chosen-select').chosen({}).change((event, info) => {
if (info.selected) {
var allSelected = this.querySelectorAll('option[selected]');
var lastSelected = allSelected[allSelected.length - 1];
var selected = this.querySelector(`option[value="${info.selected}"]`);
selected.setAttribute('selected', '');
lastSelected.insertAdjacentElement('afterEnd', selected);
} else { // info.deselected
var removed = this.querySelector(`option[value="${info.deselected}"]`);
removed.setAttribute('selected', false); // this step is required for Edge
removed.removeAttribute('selected');
}
$(this).trigger("chosen:updated");
});
これにより、選択の場合はDOMが移動し、選択解除の場合は移動しません。 setAttribute
/removeAttribute
は、<option>
DOMに目に見える変化をもたらすものです。
これが、送信時に何もせずにそれを行う方法をまだ探している人を助けることを願っています。
PS:このコードのコンパクトなjQueryバージョンは、必要に応じて記述できます。 :)
これがselect2の古いバージョン(v4未満)を使用している人にとって役立つことを願っています。この場合、select2-selectingおよびselect2-removingオプションが役立ちます。配列を使用し、選択したら値を追加すると、選択の順序を維持でき、特定のオプションの選択を解除しながら、splice()を使用してインデックスを見つけ、配列から削除できます。
var selected = [];
$('#multiSelect').on("select2-selecting", function(evt) {
var selectedOption = evt.val;
selected.Push(selectedOption);
}).on("select2-removing", function(evt) {
index = selected.indexOf(evt.val);
selected.splice(index,1);
});
バージョン4以降では、select2:selectおよびselect2:unselectを使用できます。 :)