0

I have an ASP.NET MVC application, which does the next:

  • Shows a form with a table in there, and some fields per row to be filled
  • Validates the input in the fields via server validation
  • A submit button, which when user clicks on it, process the request in the server (long time process, > 5 seconds)

Having such scenario, I've implemented:

  1. Razor view with the proper logic to show the form
  2. Controller to receive the action addressed by the Submit button
  3. Model with the properties to exchange between controller and view

I would like to fulfill the next requirement:

-When Submit button is clicked

  • EITHER disable it (till success or error)
  • OR show a modal progress bar (till success or error)

All these, in order to avoid the user to click again in the submit button while the server is processing the request.

If I disable the button via Javascript , the controller post action is never called, so disabling it via Javascript is not a solution

Implementing the PRG pattern does help, as the button is still enabled.

Controller:

    public ActionResult Index()
    {
        var viewModel = Initialize();
        return View(viewModel);
    }

    [HttpPost]
    public ActionResult HandleErrors(List<elements> entries)
    {
        var viewModel = new MyViewModel();

            entries.ForEach(entry =>
            {
                //Add validation errors to UI via ModelState when applies
                //validate CorrectionInfo
                if (string.IsNullOrEmpty(entry.Property1))
                {
                    ModelState.AddModelError("Property1" + entry.Key, "Correction info is required");
                }

                //more validations ......
            });

        if (ModelState.IsValid)
        {
            //save changes in DB
            if (DataBaseManager.SaveChanges(entries))
            {
                return RedirectToAction("Index", "MyController");
            }
            else // there were errors saving entries into the DB
            {
                viewmodel.Error = true;
                return View("Index", viewModel);
            }

        }
        else //ModelState is not valid
        {
            viewModel.ValidationErrors = true;
            return View("Index", viewModel);
        }

    }

View:

using (Html.BeginForm("HandleErrors", "MyController", FormMethod.Post))
    {
        <table id="filesTable" class="table table-striped table-bordered">
            <thead>
            <tr>
                <td>Column 1</td>
                <td>Column 2</td>
                ...
                ...
            </tr>
            </thead>
            <tbody>
            @for (int i = 0; i < Model.Entries.Count; i++)
            {
                <tr>
                    <td>
                        @Model.Entries[i].Property1
                    </td>
                    <td>
                        @Model.Entries[i].Property2
                    </td>
                    ...
                    ...
                </tr>
            }
            </tbody>
            <tfoot>
            <tr>
                <td colspan="4">
                    <input type="submit" value="Submit" />
                </td>
            </tr>
            </tfoot>
        </table>

    }

Thank you!!

Carlos
  • 456
  • 2
  • 7
  • 21
  • 3
    "If I disable the button via Javascript , the controller post action is never called". Can you show what you did to achieve the disabling please? I'm not aware of this kind of thing creating a problem normally when submitting forms. Possibly you didn't do it quite right. – ADyson Feb 06 '18 at 13:54
  • I think you could disable the button once the form is submitted via javascript. – Javier Gonzalez Feb 06 '18 at 13:56
  • have a look at this. A well practiced approach is to use the bootstrap overlay to cover the button until processing is completed. Have a look at this https://stackoverflow.com/questions/23452449/how-do-i-show-a-loading-spinner-when-submitting-for-a-partial-view-in-asp-net-mv – Wheels73 Feb 06 '18 at 13:58
  • 2
    If you're using bootstrap, you can simply call the button('loading') method on your button when clicked. Like so: https://codepen.io/anon/pen/RQGarK?editors=1010 – Paras Daryanani Feb 06 '18 at 14:13

0 Answers0