Проверка модальной формы в asp.net core 2.1 и страницах Razor - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть страница Details.cshtml, отображающая сведения о клиенте, а также связанный список customer.sites.На странице я создал кнопку, чтобы добавить новый сайт, который открывает модал начальной загрузки, содержащий форму для входа на новый сайт.

У меня проблема с проверкой.Если форма недействительна, то страница перезагружается, но модал снова скрыт, то есть текст asp-validation-for не виден, пока пользователь снова не нажмет кнопку добавления сайта.Есть ли способ сделать так, чтобы когда ModelState.IsValid был недопустим, то модальное открывалось автоматически?

details.cshtml page

@page "{id:int?}"
@model ServiceManager.Pages.Customers.DetailsModel

@{
    ViewData["Title"] = "Details";
}
<h2>@Html.DisplayFor(model => model.Customer.Name)</h2>
<hr />
<!-- Modal -->
<div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" id="createSiteModal">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Add New Customer Site</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 method="post">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                    <div class="form-group">
                        <label asp-for="Site.Description" class="control-label"></label>
                        <input asp-for="Site.Description" class="form-control" />
                        <span asp-validation-for="Site.Description" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.AddressLine" class="control-label"></label>
                        <textarea asp-for="Site.AddressLine" class="form-control"></textarea>
                        <span asp-validation-for="Site.AddressLine" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.City" class="control-label"></label>
                        <input asp-for="Site.City" class="form-control" />
                        <span asp-validation-for="Site.City" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.County" class="control-label"></label>
                        <input asp-for="Site.County" class="form-control" />
                        <span asp-validation-for="Site.County" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Postcode" class="control-label"></label>
                        <input asp-for="Site.Postcode" class="form-control" />
                        <span asp-validation-for="Site.Postcode" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Country" class="control-label"></label>
                        <input asp-for="Site.Country" class="form-control" />
                        <span asp-validation-for="Site.Country" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Telephone" class="control-label"></label>
                        <input asp-for="Site.Telephone" class="form-control" />
                        <span asp-validation-for="Site.Telephone" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Fax" class="control-label"></label>
                        <input asp-for="Site.Fax" class="form-control" />
                        <span asp-validation-for="Site.Fax" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <input asp-for="Site.CommercialID" class="form-control" value="3" />
                    </div>
                    <div class="form-group">
                        <input type="button" value="Cancel" class="btn btn-danger" data-dismiss="modal" />
                        <input type="submit" value="Create" class="btn btn-success" />
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<div class="btn-group" role="group">
    <a class="btn btn-light" data-toggle="tooltip" data-placement="top" data-delay="200" title="Back to Customer List" asp-page="./Index">
        <span class="fas fa-arrow-left fa-1x" style="color:#007bff"></span>
    </a>
    @if (Model.Customer.CustomerType == "Domestic")
    {
        <a class="btn btn-light" asp-page="./EditDom" asp-route-id="@Model.Customer.ID" data-toggle="tooltip" data-placement="top" data-delay="200" title="Edit Customer">
            <span class="fas fa-user-edit fa-1x" style="color:#0c0cbe"></span>
        </a>
    }
    else
    {
        <a class="btn btn-light" asp-page="./Edit" asp-route-id="@Model.Customer.ID" data-toggle="tooltip" data-placement="top" data-delay="200" title="Edit Customer">
            <span class="fas fa-user-edit fa-1x" style="color:#0c0cbe"></span>
        </a>
    }
        <a class="btn btn-light" asp-page="./Delete" asp-route-id="@Model.Customer.ID" data-toggle="tooltip" data-placement="top" data-delay="200" title="Delete Customer">
            <span class="fas fa-user-times fa-1x" style="color:#b01111"></span>
        </a>
</div>
<div class="row">
    <div class="col-lg-4">
        <div class="card border-info mb-3">
            <h5 class="card-header bg-info text-white">Customer Details</h5>
            <div class="card-body">
                <dl class="row">
                    <dt class="col-5">
                        @Html.DisplayNameFor(model => model.Customer.AccountRef)
                    </dt>
                    <dd class="col-7">
                        @Html.DisplayFor(model => model.Customer.AccountRef)
                    </dd>
                    <dt class="col-5">
                        @Html.DisplayNameFor(model => model.Customer.ContactDate)
                    </dt>
                    <dd class="col-7">
                        @Html.DisplayFor(model => model.Customer.ContactDate)
                    </dd>
                    <dt class="col-5">
                        @Html.DisplayNameFor(model => model.Customer.Active)
                    </dt>
                    <dd class="col-7">
                        @Html.DisplayFor(model => model.Customer.Active)
                    </dd>
                </dl>
            </div>
        </div>
    </div>
    <div class="col-lg-4">
        <div class="card border-info mb-3">
            <h5 class="card-header bg-info text-white">Customer Sites</h5>
            <table class="table table-hover fixed-table">
                <tr>
                    <th>Description</th>
                    <th>Location</th>
                    <th>Telephone</th>
                </tr>
                @foreach (var item in Model.Customer.Sites)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Description)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.City)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Telephone)
                        </td>
                        <td>
                            <a class="rowlink" asp-page="/Sites/Details" asp-route-id="@item.ID"><i class="fa fa-chevron-right"></i></a>
                        </td>
                    </tr>
                }
            </table>
            <div class="card-footer">
                <!-- Button trigger modal -->
                <button class="btn btn-link float-right" data-toggle="modal" data-target="#createSiteModal">
                    <span class="fa-stack fa-lg">
                        <i class="fas fa-circle fa-stack-2x" style="color:tomato"></i>
                        <i class="fas fa-stack-1x fa-inverse">+</i>
                    </span>
                </button>
                <div class="clearfix"></div>
            </div>
        </div>
    </div>
</div>

Details.cshtml.cs page

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using ServiceManager.Models;

namespace ServiceManager.Pages.Customers
{
    public class DetailsModel : PageModel
    {
        private readonly CompanyContext _context;

        public DetailsModel(CompanyContext context)
        {
            _context = context;
        }

        public Commercial Customer { get; set; }


        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Customer = await _context.Commercial
                .Include(c => c.Sites)
                .Include(c => c.Contacts)
                .FirstOrDefaultAsync(m => m.ID == id);

            if (Customer == null)
            {
                return NotFound();
            }
            return Page();
        }

        [BindProperty]
        public Address Site { get; set; }

        public async Task<IActionResult> OnPostAsync(int? id)
        {

            if (!ModelState.IsValid)
            {
                Customer = await _context.Commercial
                .Include(c => c.Sites)
                .Include(c => c.Contacts)
                .FirstOrDefaultAsync(m => m.ID == id);

                return Page();
            }
            _context.Address.Add(Site);
            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");  
        }
    }
}

1 Ответ

0 голосов
/ 05 декабря 2018

Один из способов решения этой проблемы - выполнить проверку на стороне клиента с помощью jQuery перед отправкой формы.Таким образом, модальный режим остается открытым, и пользователь получает мгновенную обратную связь о том, что это за ошибки.

Другой альтернативой и, возможно, менее инвазивной в этом случае является передача флага от сервера обратно клиенту со статусом проверки модели, а затем открытие модального режима на основе значения такого флага, например

Контроллер :

   public async Task<IActionResult> OnPostAsync(int? id)
    {

        if (!ModelState.IsValid)
        {
            Customer = await _context.Commercial
            .Include(c => c.Sites)
            .Include(c => c.Contacts)
            .FirstOrDefaultAsync(m => m.ID == id);
            ViewData["ModelIsValid"] = false;
            return Page();
        }
        ViewData["ModelIsValid"] = true;
        _context.Address.Add(Site);
        await _context.SaveChangesAsync();
        return RedirectToPage("./Index");  
    }

Просмотр :

<script>
    $(document).ready(function () {
        @if(!(bool)ViewData["ModelIsValid"])
        {
            $("#createSiteModal").modal('show');
        }
    });
</script>

Основной недостаток второго подхода заключается в том, что модальноевсплывающее окно после отображения страницы вместо того, чтобы оставаться открытым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...