禁止HTML选择列表

时间:2014-02-16 22:25:40

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

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

<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>

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

@{
    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新手...
UPD。
还有一个细节,一些下拉列表是根据showEditModal表的值在amenitiesPrioritiesTable函数的工作期间选择的特定选项。

1 个答案:

答案 0 :(得分:0)

工作脚本,请注意.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);
}