@ Html .DropDownListFor в модальном режиме без проверки и заполнения после недопустимого состояния модели - PullRequest
0 голосов
/ 09 мая 2020

Если состояние модели допустимо, все работает нормально, а если нет, то вот что происходит

Пример пользовательского интерфейса для ошибки

Код AddProduct2:

public async Task<IActionResult> AddProduct2(PurchaseDetailViewModel vmodel)
    {
        if (ModelState.IsValid)
        {
            PurchaseDetail model = _mapper.Map<PurchaseDetail>(vmodel);

            _context.Add(model);
            await _context.SaveChangesAsync();
        }

        return PartialView("_Create", vmodel);
    }

Код PurchaseDetailViewModel:

public class PurchaseDetailViewModel
{
    public int Id { get; set; }

    [Display(Name ="Product"), Required(ErrorMessage ="Please enter a valid value for product.")]
    [Remote("CheckPurchaseProduct", "Purchases", AdditionalFields = "PurchaseId", ErrorMessage = "Product already exists.")]
    public int ProductId { get; set; }

    [Display(Name = "Supplier"), Required(ErrorMessage = "Please enter a valid value for supplier.")]
    public int SupplierId { get; set; }

    //other fields here 
}

Код GetProducts и GetSuppliers:

[HttpGet]
    public async Task<JsonResult> GetProducts(int id = 0)
    {
        var products = await _context.Product
                       //.Where(a => a.RegionId == provinceId)
                       .Select(a => new SelectListItem { Value = a.Id.ToString(), Text = a.ProductName })
                       .ToListAsync();

        return Json(products);
    }

    [HttpGet]
    public async Task<JsonResult> GetSuppliers(int id = 0)
    {
        var products = await _context.Supplier
                       //.Where(a => a.RegionId == provinceId)
                       .Select(a => new SelectListItem { Value = a.Id.ToString(), Text = a.SupplierName })
                       .ToListAsync();

        return Json(products);
    }

_Create partial view code:

    @model intPOS.Models.Transactions.ViewModel.PurchaseDetailViewModel
@*
    For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
*@
    <div class="modal fade" id="add-product" tabindex="-1" role="dialog" aria-labelledby="addContactLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="addContactLabel">Add Product</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <form id="" asp-action="AddProduct2" autocomplete="off">
                        <div asp-validation-summary="ModelOnly" class="text-danger"></div>

                        @Html.HiddenFor(Model => Model.PurchaseId)
                        @Html.HiddenFor(Model => Model.PurchaseNumber)

                        <input name="IsValid" type="hidden" value="@ViewData.ModelState.IsValid.ToString()" />

                        <div class="form-group">
                            <label asp-for="ProductId" class="control-label"></label>
                            @Html.DropDownListFor(x => Model.ProductId, new SelectList(""), htmlAttributes: new { @class = "form-control", @id = "Product" })
                            <span asp-validation-for="ProductId" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="SupplierId" class="control-label"></label>
                            @Html.DropDownListFor(x => Model.SupplierId, new SelectList(""), htmlAttributes: new { @class = "form-control", @id = "Supplier" })
                            <span asp-validation-for="SupplierId" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="Qty" class="control-label"></label>
                            @Html.TextBoxFor(Model => Model.Qty, new { @class = "form-control calc" })
                            @Html.ValidationMessageFor(Model => Model.Qty, "", new { @class = "text-danger" })
                        </div>
                        <div class="form-group">
                            <label asp-for="UnitPrice" class="control-label"></label>
                            @Html.TextBoxFor(Model => Model.UnitPrice, new { @class = "form-control calc" })
                            <span asp-validation-for="UnitPrice" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label asp-for="TotalAmount" class="control-label"></label>
                            @Html.TextBoxFor(Model => Model.TotalAmount, new { @class = "form-control", @readonly = "readonly" })
                            <span asp-validation-for="TotalAmount" class="text-danger"></span>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-primary" data-save="modal">Save</button>
                </div>
            </div>
        </div>
    </div>

        @{
            await Html.RenderPartialAsync("_ValidationScriptsPartial");

            <script type="text/javascript">
                $(function () {

                    var products_url = '@Url.Action("GetProducts", "Purchases")'; // Don't hard code your url's!
                    var products = $('#Product'); // cache it

                    PopulateSelect(products_url, products);

                    var suppliers_url = '@Url.Action("GetSuppliers", "Purchases")'; // Don't hard code your url's!
                    var suppliers = $('#Supplier'); // cache it

                    PopulateSelect(suppliers_url, suppliers);

                })
                function PopulateSelect(url, select) {
                    //var id = $(this).val(); // Use $(this) so you don't traverse the DOM again
                    //$.getJSON(url, { provinceId: id }, function (response) {
                    $.getJSON(url, function (response) {
                        select.empty(); // remove any existing options
                        select.append($('<option>').text('***Please select***').val(null));
                        $.each(response, function (i, item) {
                            select.append($('<option>').text(item.text).val(item.value));
                        }); 
                    });
                }
            </script>
        }

Site. js code:

    $(function () {
    var placeholderElement = $('#modal-placeholder');

    $('button[data-toggle="ajax-modal"]').click(function (event) {
        var url = $(this).data('url');
        $.get(url).done(function (data) {
            placeholderElement.html(data);
            placeholderElement.find('.modal').modal('show');
        });
    });

    placeholderElement.on('click', '[data-save="modal"]', function (event) {
        event.preventDefault();

        var form = $(this).parents('.modal').find('form');
        var actionUrl = form.attr('action');
        var dataToSend = form.serialize();

        $.post(actionUrl, dataToSend).done(function (data) {

            var newBody = $('.modal-body', data);
            placeholderElement.find('.modal-body').replaceWith(newBody);

            var isValid = newBody.find('[name="IsValid"]').val() == 'True';
            if (isValid) {
                placeholderElement.find('.modal').modal('hide');
            }
        });
    });

});

Что мне здесь не хватает? Любые советы и улучшения в моем коде очень помогают.

Спасибо

...