【问题标题】:Ban list for HTML SelectHTML Select 的禁止列表
【发布时间】:2014-02-18 20:58:51
【问题描述】:

我有一个模态窗口,上面有五个选择

<h4>Amenities</h4>
@Html.TextAreaFor(model => model.Amenities)
<br />

<div id="editPrioritiesModal" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-body">
        <h5>Set the priority to the items and then apply the desired changes</h5>

        <div><select id="AmenityDropDownP1" data-previous-value="" onfocus="updatePrevious(this);" onchange="refreshBans(this); this.oldvalue = this.value;"></select></div>
        <div><select id="AmenityDropDownP2" data-previous-value="" onfocus="updatePrevious(this);" onchange="    refreshBans(this); this.oldvalue = this.value;"></select></div>
        <div><select id="AmenityDropDownP3" data-previous-value="" onfocus="updatePrevious(this);" onchange="    refreshBans(this); this.oldvalue = this.value;"></select></div>
        <div><select id="AmenityDropDownP4" data-previous-value="" onfocus="updatePrevious(this);" onchange="    refreshBans(this); this.oldvalue = this.value;"></select></div>
        <div><select id="AmenityDropDownP5" data-previous-value="" onfocus="updatePrevious(this);" onchange="    refreshBans(this); this.oldvalue = this.value;"></select></div>

    </div>
    <div class="modal-footer">
        <a class="btn btn btn-danger" data-dismiss="modal">Close</a>
        <a class="btn btn-primary" id="reveretPrioritiesButton" onclick=" revertValues()">Revert</a>
        <a class="btn btn-primary" id="savePriorityButton" onclick="applyModalValues()">Save Changes</a>
    </div>
</div>

此模态窗口用于编辑多个优先级集,对应的“Sets”呈现如下:

@{
    var featuresList = new JavaScriptSerializer().Serialize(Model.SelectedFeatures);
}

<script>
    function initializeFeaturesList(featuresList) {
        window.availableFeaturesList = featuresList;
    }

    initializeFeaturesList(@Html.Raw(featuresList));
</script>

@{
    if (Model.AmenityPriorityConfigs != null)
    {
        <h4>Prioritisations</h4>
        <table class="table table-condensed table-bordered table-hover" id="amenitiesPrioritiesTable">
            <thead>
                <tr>
                    <th><strong>Product</strong></th>
                    <th>P1</th>
                    <th>P2</th>
                    <th>P3</th>
                    <th>P4</th>
                    <th>P5</th>
                    <th>Actions</th>
                </tr>
            </thead>

            @{
        int trNum = 0;

        foreach (var apcViewModel in Model.AmenityPriorityConfigs)
        {
            <tr>
                <td>@apcViewModel.Product.Name</td>
                <td class="AmenityP1">@(apcViewModel.AmenityP1 != null ? apcViewModel.AmenityP1.Name : string.Empty)</td>
                <td class="AmenityP2">@(apcViewModel.AmenityP2 != null ? apcViewModel.AmenityP2.Name : string.Empty)</td>
                <td class="AmenityP3">@(apcViewModel.AmenityP3 != null ? apcViewModel.AmenityP3.Name : string.Empty)</td>
                <td class="AmenityP4">@(apcViewModel.AmenityP4 != null ? apcViewModel.AmenityP4.Name : string.Empty)</td>
                <td class="AmenityP5">@(apcViewModel.AmenityP5 != null ? apcViewModel.AmenityP5.Name : string.Empty)</td>
                <td>
                    <a class="amenitiesModalLink" data-toggle="modal" data-amenity-configuration-id="@apcViewModel.Id" onclick="showEditModal(@Model.Id, @apcViewModel.Product.Id, '@apcViewModel.Product.Name', this, @featuresList)">
                        <i class="icon-edit" title="Delete"></i>
                    </a>
                </td>
            </tr>

            trNum++;
        }
            }

        </table>
    }
}

在下面的 JS 中你可以看到所有的下拉菜单都是在模态打开时填充的:

var targetCentreId;
var targetProductId;
var targetConfigurationId;
var targetRow;
var availableFeaturesList;

$(function() {
    var previous;

    $("#editPrioritiesModal select").on('focus', function () {
        // Store the current value on focus and on change
        previous = this.value;
    }).change(function () {
        // Do something with the previous value after the change
        alert(previous);

        // Make sure the previous value is updated
        previous = this.value;
    });
});

function showEditModal(centreId, productId, productName, initiator) {

    initGlobals(centreId, productId, initiator);

    for (var i = 0; i < 5; i++) {
        var targetDropDown = $('#AmenityDropDownP' + (i + 1));

        populateDropDown(targetDropDown);
        updateDropdown(i, targetDropDown);
    }

    $('#editPrioritiesModal').modal('show');
}

function populateDropDown(targetDropDown) {
    $(targetDropDown).empty();
    var emptyOption = '';
    emptyOption += '<option value="null"></option>';
    $(targetDropDown).append(emptyOption);

    for (var j = 0; j < availableFeaturesList.length; j++) {
        var option = '';
        option += '<option value="' + availableFeaturesList[j].Id + '">' + availableFeaturesList[j].Name + '</option>';
        $(targetDropDown).append(option);
    }
}

function initGlobals(centreId, productId, initiator) {
    targetCentreId = centreId;
    targetProductId = productId;
    targetConfigurationId = $(initiator).data('amenity-configuration-id');
    targetRow = $(initiator).closest('tr');
}

function revertValues() {
    if (targetConfigurationId == 0) {
        $('#editPrioritiesModal select').each(function () {
            this.selectedIndex = 0;
        });

        targetRow.find('td').filter(function () {
            return this.className.match(/(AmenityP)(\d)/i);
        }).each(function () {
            this.innerText = '';
        });

    } else {
        getAmenityConfiguration(updateRowAndAllDropdowns);
    }
}

function applyModalValues() {
    MessageBox.AddLoader();

    //save => i need centreId, after saving i should rewrite the state of the table INCLUDING THE OPEN DROPDOWN LINK (item Id)
    var p1Value = $('#AmenityDropDownP1').val();
    var p2Value = $('#AmenityDropDownP2').val();
    var p3Value = $('#AmenityDropDownP3').val();
    var p4Value = $('#AmenityDropDownP4').val();
    var p5Value = $('#AmenityDropDownP5').val();

    $.ajax({
        url: '/centre/SaveAmenityPriotyConfiguration',
        data:
        {
            'configurationId': targetConfigurationId,
            'centreId': targetCentreId,
            'productId': targetProductId,
            'amenityP1Id': p1Value,
            'amenityP2Id': p2Value,
            'amenityP3Id': p3Value,
            'amenityP4Id': p4Value,
            'amenityP5Id': p5Value,
        },
        type: 'POST',
        success: function (data) {
            if (data) {
                updateRowAndAllDropdowns(data);
                updateModalLink(data.Id);
                MessageBox.AddInfo("Success!");
                $('#editPrioritiesModal').modal('hide');

            } else {
                alert("No such entity");
            }
        },
        error: function (req, status, error) {
            MessageBox.AddError("Server Error. " + req + " " + status + " " + error);
        }
    });
}

function updateDropdown(amenityIndex, targetDropDown) {
    var probableDataSource = $(targetRow).find('.AmenityP' + (amenityIndex + 1));

    if (probableDataSource.text() !== '') {
        $(targetDropDown).find("option").each(function () {
            var currText = $(this).text();

            if (currText === probableDataSource.text()) {
                $(this).attr('selected', 'selected');
                return false;
            }
        });
    } else {
        $(targetDropDown).prop('selectedIndex', -1);
    }
}

function updateRow(model) {
    targetRow.find('td').filter(function () {
        return this.className.match(/(AmenityP)(\d)/i);
    }).each(function () {
        this.innerText = model[this.className].Name;
    });
}

function updateRowAndAllDropdowns(model) {
    updateRow(model);

    for (var i = 0; i < 5; i++) {
        var targetDropDown = $('#AmenityDropDownP' + (i + 1));
        updateDropdown(i, targetDropDown);
    }
}

function getAmenityConfiguration(successCallback) {
    $.ajax({
        url: '/centre/GetAmenityPriorityConfiguration',
        data: { 'configurationId': targetConfigurationId },
        type: 'GET',
        success: function (data) {
            if (data) {
                successCallback(data);

            } else {
                alert("No such entity");
            }
        },
        error: function (req, status, error) {
            MessageBox.AddError("Server Error. " + req + " " + status + " " + error);
        }
    });
}

function updateModalLink(newItemId) {
    $(targetRow).find('a.amenitiesModalLink').first().data('amenity-configuration-id', newItemId);
}

function updateFeaturesList(checkboxItem) {
    var $checkboxItem = $(checkboxItem),
        featureId = $checkboxItem.data("id"),
        featureName = $checkboxItem.data("feature-name"),
        isChecked = $checkboxItem.is(":checked"),
        isPresentInList = false;

    var indexOfElement;

    for (var i in availableFeaturesList) {
        if (availableFeaturesList[i].Id == featureId) {
            isPresentInList = true;
            indexOfElement = i;
            break;
        }
    }

    if (isChecked && !isPresentInList) {
        availableFeaturesList.push({ Id: featureId, Name: featureName });

        availableFeaturesList.sort(function (a, b) {
            if (a.Name < b.Name)
                return -1;
            if (a.Name > b.Name)
                return 1;
            return 0;
        });
    }

    else if (!isChecked && isPresentInList) {
        availableFeaturesList.splice(indexOfElement, 1);
    }
}

function refreshBans(element) {
    alert(element.data("previous-value"));
    alert(element.value);
}

function updatePrevious(element) {
    element.data("previous-value", element.value);
}

问题:应该可以为每个特定的“优先级集”只选择一次下拉选项(一组的不同下拉列表中没有重复项),所以我认为应该有类似禁止列表的东西,即填充任何下拉列表中新选择的选项并将其从所有其他选项中删除,或者还有另一个更优雅的解决方案?提前感谢您的任何建议/批评,我是 JavaScript 新手...
更新。
更详细一点,在showEditModal 函数的工作过程中,一些下拉菜单会根据amenitiesPrioritiesTable 表的值选择特定选项。

【问题讨论】:

    标签: javascript jquery html asp.net-mvc razor


    【解决方案1】:

    工作脚本,关注.change事件和populateDropDownFromSource

    var targetCentreId;
    var targetProductId;
    var targetConfigurationId;
    var targetRow;
    var availableFeaturesList;
    
    $(function () {
        $("#editPrioritiesModal select").change(function () {
    
            var selectedElems = $("#editPrioritiesModal select").map(function () {
                return parseInt($(this).val());
            }).get();
            $("#editPrioritiesModal select").not(this).each(function () {
                var currVal = parseInt($(this).val());
                populateDropDownFromSource(this, selectedElems);
                $(this).val(currVal);
            });
        });
    });
    
    function showEditModal(centreId, productId, productName, initiator) {
    
        initGlobals(centreId, productId, initiator);
    
        for (var i = 0; i < 5; i++) {
            var targetDropDown = $('#AmenityDropDownP' + (i + 1));
    
            populateDropDown(targetDropDown);
            updateDropdown(i, targetDropDown);
        }
    
        $('#AmenityDropDownP1').trigger("change");//it's a hack, but is a simplest way to do it
    
        $('#editPrioritiesModal').modal('show');
    }
    
    function populateDropDown(targetDropDown) {
        $(targetDropDown).empty();
        var emptyOption = '';
        emptyOption += '<option value="null"></option>';
        $(targetDropDown).append(emptyOption);
    
        for (var j = 0; j < availableFeaturesList.length; j++) {
            var option = '';
            option += '<option value="' + availableFeaturesList[j].Id + '">' + availableFeaturesList[j].Name + '</option>';
            $(targetDropDown).append(option);
        }
    }
    
    function populateDropDownFromSource(targetDropDown, selectedElems) {
        var currentValue = parseInt($(targetDropDown).val());
        var notSelectedFeatures = $.grep(availableFeaturesList, function (e) {
            return selectedElems.indexOf(e.Id) == -1 || e.Id == currentValue;
        });
    
        $(targetDropDown).empty();
        var emptyOption = '';
        emptyOption += '<option value="null"></option>';
        $(targetDropDown).append(emptyOption);
    
        for (var j = 0; j < notSelectedFeatures.length; j++) {
            var option = '';
            option += '<option value="' + notSelectedFeatures[j].Id + '">' + notSelectedFeatures[j].Name + '</option>';
            $(targetDropDown).append(option);
        }
    }
    
    
    function initGlobals(centreId, productId, initiator) {
        targetCentreId = centreId;
        targetProductId = productId;
        targetConfigurationId = $(initiator).data('amenity-configuration-id');
        targetRow = $(initiator).closest('tr');
    }
    
    function revertValues() {
        if (targetConfigurationId == 0) {
            $('#editPrioritiesModal select').each(function () {
                this.selectedIndex = 0;
            });
    
            targetRow.find('td').filter(function () {
                return this.className.match(/(AmenityP)(\d)/i);
            }).each(function () {
                this.innerText = '';
            });
    
        } else {
            getAmenityConfiguration(updateRowAndAllDropdowns);
        }
    }
    
    function applyModalValues() {
        MessageBox.AddLoader();
    
        //save => i need centreId, after saving i should rewrite the state of the table INCLUDING THE OPEN DROPDOWN LINK (item Id)
        var p1Value = $('#AmenityDropDownP1').val();
        var p2Value = $('#AmenityDropDownP2').val();
        var p3Value = $('#AmenityDropDownP3').val();
        var p4Value = $('#AmenityDropDownP4').val();
        var p5Value = $('#AmenityDropDownP5').val();
    
        $.ajax({
            url: '/centre/SaveAmenityPriotyConfiguration',
            data:
            {
                'configurationId': targetConfigurationId,
                'centreId': targetCentreId,
                'productId': targetProductId,
                'amenityP1Id': p1Value,
                'amenityP2Id': p2Value,
                'amenityP3Id': p3Value,
                'amenityP4Id': p4Value,
                'amenityP5Id': p5Value,
            },
            type: 'POST',
            success: function (data) {
                if (data) {
                    updateRowAndAllDropdowns(data);
                    updateModalLink(data.Id);
                    MessageBox.AddInfo("Success!");
                    $('#editPrioritiesModal').modal('hide');
    
                } else {
                    alert("No such entity");
                }
            },
            error: function (req, status, error) {
                MessageBox.AddError("Server Error. " + req + " " + status + " " + error);
            }
        });
    }
    
    function updateDropdown(amenityIndex, targetDropDown) {
        var probableDataSource = $(targetRow).find('.AmenityP' + (amenityIndex + 1));
    
        if (probableDataSource.text() !== '') {
            $(targetDropDown).find("option").each(function () {
                var currText = $(this).text();
    
                if (currText === probableDataSource.text()) {
                    $(this).attr('selected', 'selected');
                    return false;
                }
            });
        } else {
            $(targetDropDown).prop('selectedIndex', -1);
        }
    }
    
    function updateRow(model) {
        targetRow.find('td').filter(function () {
            return this.className.match(/(AmenityP)(\d)/i);
        }).each(function () {
            this.innerText = model[this.className].Name;
        });
    }
    
    function updateRowAndAllDropdowns(model) {
        updateRow(model);
    
        for (var i = 0; i < 5; i++) {
            var targetDropDown = $('#AmenityDropDownP' + (i + 1));
            updateDropdown(i, targetDropDown);
        }
    }
    
    function getAmenityConfiguration(successCallback) {
        $.ajax({
            url: '/centre/GetAmenityPriorityConfiguration',
            data: { 'configurationId': targetConfigurationId },
            type: 'GET',
            success: function (data) {
                if (data) {
                    successCallback(data);
    
                } else {
                    alert("No such entity");
                }
            },
            error: function (req, status, error) {
                MessageBox.AddError("Server Error. " + req + " " + status + " " + error);
            }
        });
    }
    
    function updateModalLink(newItemId) {
        $(targetRow).find('a.amenitiesModalLink').first().data('amenity-configuration-id', newItemId);
    }
    
    function updateFeaturesList(checkboxItem) {
        var $checkboxItem = $(checkboxItem),
            featureId = $checkboxItem.data("id"),
            featureName = $checkboxItem.data("feature-name"),
            isChecked = $checkboxItem.is(":checked"),
            isPresentInList = false;
    
        var indexOfElement;
    
        for (var i in availableFeaturesList) {
            if (availableFeaturesList[i].Id == featureId) {
                isPresentInList = true;
                indexOfElement = i;
                break;
            }
        }
    
        if (isChecked && !isPresentInList) {
            availableFeaturesList.push({ Id: featureId, Name: featureName });
    
            availableFeaturesList.sort(function (a, b) {
                if (a.Name < b.Name)
                    return -1;
                if (a.Name > b.Name)
                    return 1;
                return 0;
            });
        }
    
        else if (!isChecked && isPresentInList) {
            availableFeaturesList.splice(indexOfElement, 1);
        }
    }
    
    function refreshBans(element) {
        alert(element.data("previous-value"));
        alert(element.value);
    }
    
    function updatePrevious(element) {
        element.data("previous-value", element.value);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多