Ad

How I Can Focus On The Return Form That Have Validation Errors

- 1 answer

I am working on an asp.net mvc-5 web application , and i have the following contact us form at the middle of the contact Us view:-

 <div class="col-sm-8 col-sm-push-4">
                    <h2>Contact Us1</h2>
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    @if (TempData["message"] != null)
                    {

                        <div class="alert alert-success">
                            <a target="_blank" rel="nofollow noreferrer" href="#" class="close" data-dismiss="alert">&times;</a>

                            <strong> @TempData["message"].</strong>

                        </div>
                    }
                    @using (Html.BeginForm())
                    {
                        @Html.AntiForgeryToken()

                        <div class="form-horizontal">

                            <hr />

                            <div class="form-group">
                                @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                                <div class="col-md-10">
                                    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) <span style="color:red">*</span>
                                    @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                                </div>
                            </div>

                            <div class="form-group">
                                @Html.LabelFor(model => model.Telephone, htmlAttributes: new { @class = "control-label col-md-2" })
                                <div class="col-md-10">
                                    @Html.EditorFor(model => model.Telephone, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.Telephone, "", new { @class = "text-danger" })
                                </div>
                            </div>

                            <div class="form-group">
                                @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
                                <div class="col-md-10">
                                    @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
                                    @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
                                </div>
                            </div>

                            <div class="form-group">
                                @Html.LabelFor(model => model.Message, htmlAttributes: new { @class = "control-label col-md-2" })
                                <div class="col-md-10">
                                    @Html.TextAreaFor(model => model.Message, new { @cols = 60, rows = 10, @class = "form-control" })
                                    @Html.ValidationMessageFor(model => model.Message, "", new { @class = "text-danger" })
                                </div>
                            </div>

                            <div class="form-group">
                                <div class="col-md-offset-2 col-md-10">
                                    <input type="submit" value="Submit" class="btn btn-success" /><span id="progress" class="text-center" style="display: none;">
                                        <img src="~/img/ajax-loader.gif" />

                                    </span>
                                </div>
                            </div>
                        </div>
                    }
                </div>

and here the Get and Post action methods:-

 public ActionResult Contact()
        {
            ViewBag.Title = "Contact";
            ViewBag.Description = "Home";

            return View();
        }
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Contact(Contact c)
{

    if (ModelState.IsValid)
    {
        MailMessage mail = new MailMessage();
        //code goes here
        TempData["message"] = string.Format("Your Feedback has been submitted. Thanks");
        return RedirectToAction("Contact");
    }
    ModelState.AddModelError("", "Cannot submit you Contact Form, please review the Contact Form for any missing info.");
    return View(c);

}

now i am facing this problem:- 1. since the contact us form appear on the middle of the page, so users on small sized screens , might submit the form , then the Post request failed (model validation failed), where the contact us form will be rendered again with the validation errors shown, but users might not see the form, since by default the browser will move to the top. while on large screen the user can still see the form , but on mobile browser users might miss that there are errors on the form that they have just submit.

so i am thinking if there is a way to do this:-

  1. if the form is rendered with errors, to force the browser (using jquery form example) to go to the form is rendered with errors, to force the browser (using jquery form example) to go to the form , so that users can see the validation errors ? can anyone adivce on this please ?
Ad

Answer

Firstly you @Html.ValidationSummary() code should be inside the form tags in order for it to work correctly.

You can use javascript to scroll to the form in the view. Give the form (or an element near where you want to scroll to) an id attribute

@using (Html.BeginForm("Contact", "yourControllerName", FormMethod.Post, new { id = "form" }))

Then add the following script (inside document.ready)

if ('@ViewBag.HasError') {
    location.href = '#form'; // or location.hash = '#form';
}

and modify the POST method to add the ViewBag property if there are errors

ModelState.AddModelError("", "Cannot ..... info.");
ViewBag.HasError = true; // add this
return View(c)

Side note: Not tested, but you should also be able to use

if ('@ViewContext.ViewData.ModelState.Values.SelectMany(v => v.Errors).Any()') {

as an alternative to using a ViewBag property.

Ad
source: stackoverflow.com
Ad