javascriptsortingoptgrouptom-select

option group sorting doesn't work in tom-select


the option groups are not sorting.

To Reproduce

$(document).ready(function () {
    alert("start tomselect");
    var selectCurrency = new TomSelect("#cursel", {
        create: false,
        placeholder: "currency",
        optgroupLabelField: 'label',
        optgroupOrder: ['Active', 'Inactive'],
        optgroupSorter: function(a, b) {
        return a.label.localeCompare(b.label);
    },
        sortField: {
            field: "text",
            direction: "asc"
        },
        plugins: ["checkbox_options", "clear_button"]
    });
    
    var selectAlt = new TomSelect("#curselalt", {
        create: false,
        placeholder: "alt",
        sortField: {
            field: "text",
            direction: "asc"
        },
        plugins: ["checkbox_options", "clear_button"]
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><link href="https://cdn.jsdelivr.net/npm/tom-select@2.2.2/dist/css/tom-select.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tom-select/2.2.2/js/tom-select.complete.js"></script>
<select id="cursel" multiple>
    <optgroup label="Inactive">
        <option>AED</option>
        <option>BAM</option>
    </optgroup>
    <optgroup label="Active">
        <option>EUR</option>
        <option>BGN</option>
    </optgroup>
</select>

<select id="curselalt" multiple>
    <optgroup label="Inactive">
        <option>AED</option>
        <option>BAM</option>
    </optgroup>
    <optgroup label="Active">
        <option>EUR</option>
        <option>BGN</option>
    </optgroup>
</select>

For one select I added all settings suggested on bing chat, the other select I left like suggested in the tom-select documentation. None is sorting properly.

Expected behavior. I'm using tom-select.js and I would like to get the option groups sorted alphabetically in asc order.

Unfortunately, I can't get it working properly. The option items sort properly, but the optgroup doesn't sort.

Additional context: OS: Windows 11 Browser: chrome Version: 116.0.5845.141 (Official Build) (64-bit} Device: laptop

Any help or suggestions would be welcome.


Solution

  • If you look at the description of lockOptgroupOrder is says:

    If truthy, all optgroups will be displayed in the same order as they were added (by the $order property). Otherwise, it will order based on the score of the results in each.

    Since we don't want to use order (we want to ignore the DOM), we have to change the scoring of each item (i.e. option) to take optgroups into account. Fortunately we can do this, where the optgroup field is the order added unless optgroupValueField is defined:

        optgroupValueField: "label",
        sortField: [
            { field: "optgroup", direction: "asc" },
            { field: "text", direction: "asc" },
        ],
    

    $(document).ready(function () {
        var selectCurrency = new TomSelect("#cursel", {
            create: false,
            placeholder: "currency",
            optgroupValueField: "label",
            sortField: [
                { field: "optgroup", direction: "asc" },
                { field: "text", direction: "asc" },
            ],
            plugins: ["checkbox_options", "clear_button"]
        });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><link href="https://cdn.jsdelivr.net/npm/tom-select@2.2.2/dist/css/tom-select.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tom-select/2.2.2/js/tom-select.complete.js"></script>
    <select id="cursel" multiple>
        <optgroup label="Inactive">
            <option>AED</option>
            <option>BAM</option>
        </optgroup>
        <optgroup label="Active">
            <option>EUR</option>
            <option>BGN</option>
        </optgroup>
    </select>