Disable select option if already selected in another select box

veröffentlicht am 27. September 2019 — letzte Aktualisierung: 07. October 2020

For a customer project we needed a possibility to assign different properties to an object (the "object" is a room in my case).

But... if a property was selected before, then the possibility to add this property again should be disabled.

As we found no reliable solution after some googling, we wrote a JavaScript (jQuery) to the rescue.

Here you can see it in action

Live example with jQuery

ProcessWire integration

We integrated a slightly modified version of the script into ProcessWire where it should be used in conjunction with ProFields: Table and a page reference field (which is used for the property).

function disableUsedOptions($table) {
    $selects = $table.find("select");
    $selects.on("change", function () {
        $selects = $table.find("select");

        if (config.debug === true) console.log("In table:");
        if (config.debug === true) console.log($table);
        if (config.debug === true) console.log("there are " + $selects.length + " selects");
        if ($selects.length <= 1) return;
        let selected = [];

        $selects.each(function (index, select) {
            if (select.value !== "") {
                selected.push(select.value);
            }
        });

        if (config.debug === true) console.log("option values, that are being deactivated: " + selected);
        if (config.debug === true) console.log($(this));
        $table.find("option").prop("disabled", false);
        for (var index in selected) {
            $table
                .find('option[value="' + selected[index] + '"]:not(:selected)')
                .prop("disabled", true);
        }
    });
    $selects.trigger("change");
}

$(document).ready(function () {
    $tables = $("table.InputfieldTable:not(.InputfieldTableSearch)");
    $tables.each(function () {
        $table = $(this);
        disableUsedOptions($table);
    });
});

then add the following lines

$config->scripts->add($config->urls->templates . "scripts/admin.js");
$config->styles->add($config->urls->templates . "styles/admin.css");

before the line that reads

require($config->paths->adminTemplates . 'controller.php');
JavaScript jQuery ProcessWire