Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Petar Petrov 1 post 71 karma points
    Mar 29, 2022 @ 21:33
    Petar Petrov
    0

    Form does not keep the submitted data when validation fails

    I have the following problem:

    simple contact form. If I omit for example a required field, then the form displays errors, but the data that was filled does not appear.

    I would greatly appreciate if someone can explain to me why the submitted that is not displayed back.

    I would expect that CurrentUmbracoPage(); just resubmits the POST method. instead it redirects to the RenderForm. Is this normal? Given that flow, how could I even expect the submitted model given I have a line that creates new one:

                ContactUsViewModel model = this.contactUsViewModelFactory.CreateContactUsViewModel();
    

    I am missing something - either the flow should not be returning to the RenderForm or somehow the old data from the post should be passed to it.

    Here is the code:

        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
        public ActionResult RenderForm(int id, string recaptchaKey)
        {
            ContactUsViewModel model = this.contactUsViewModelFactory.CreateContactUsViewModel();
            model.Id = id;
            model.RecaptchaKey = recaptchaKey;
            return this.PartialView("~/Views/Partials/Forms/_ContactUsForm.cshtml", model);
        }
    
        [HttpPost]
        [ValidateInput(false)]
        public async Task<ActionResult> ContactUs(ContactUsViewModel contactUsModel)
        {
            if (!await this.recaptchaService.Validate(this.Request))
            {
                this.ModelState.AddModelError("RecaptchaKey", "Recaptcha error");
            }
    
            if (this.ModelState.IsValid)
            {
                // send email
    
                return this.RedirectToUmbracoPage(contactUsModel.Id);
            }
    
            return this.CurrentUmbracoPage();
        }
    

    The viewmodel is pretty standard I believe:

    public class ContactUsViewModel
    {
        public int Id { get; set; }
    
        public string RecaptchaKey { get; set; }
    
        [Required(ErrorMessageResourceName = "RequiredField", ErrorMessageResourceType = typeof(FormTranslations))]
        public string Name { get; set; }
    
        [Required(ErrorMessageResourceName = "RequiredField", ErrorMessageResourceType = typeof(FormTranslations))]
        [EmailAddress(ErrorMessageResourceName = "EmailError", ErrorMessageResourceType = typeof(FormTranslations))]
        public string Email { get; set; }
    
        [Required(ErrorMessageResourceName = "RequiredField", ErrorMessageResourceType = typeof(FormTranslations))]
        public string Message { get; set; }
    }
    

    The partial _ContactUsForm.cshtml:

    @inherits UmbracoViewPage<ACS.Web.Models.ContactUs.ContactUsViewModel>
    @using ACS.Web.Translations;
    @{
    this.Layout = null;
    
    string currentCulture = (string)ViewBag.CurrentCulture;
    string inactiveCulture = (string)ViewBag.InactiveCulture;
    
    }
    
    @using (Html.BeginUmbracoForm("ContactUs", "Contact", new { }, new { id = "contact-us-form" }, FormMethod.Post))
    
    {
    <div class="row">
        <div class="col-md-12">
            <div class="ac-contact-us-form-title mx-auto"><h1 @if (currentCulture.Equals("bg-BG")) { <text> style="line-height: 1;" </text> }>@FormTranslations.ContactFormTitle</h1></div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-8 col-lg-5 mx-auto">
            <div class="ac-contact-us-form-fields">
                <div>@Html.HiddenFor(x => x.Id)</div>
    
                <div class="ac-contact-us-form-name form-group">
                    @Html.TextBoxFor(x => x.Name, new { @class = "form-control", placeholder = FormTranslations.Name })
                    @Html.ValidationMessageFor(x => x.Name)
                </div>
    
                <div class="ac-contact-us-form-emial form-group">
                    @Html.TextBoxFor(x => x.Email, new { @class = "form-control", placeholder = FormTranslations.Email })
                    @Html.ValidationMessageFor(x => x.Email)
                </div>
    
                <div class="ac-contact-us-form-message form-group">
                    @Html.TextAreaFor(x => x.Message, new { @class = "form-control", @rows = 10, placeholder = FormTranslations.Message })
                    @Html.ValidationMessageFor(x => x.Message)
                </div>
    
                <div class="btn-wrapper" id="contact-submit-btn" type="submit" style="float: right">
                    <svg height="50" width="265" xmlns="http://www.w3.org/2000/svg">
                        <rect id="shape1" height="50" width="265" />
                        <rect id="shape" height="50" width="265" />
                        <div id="text">
                            <a href="#">
                                <span class="spot">@FormTranslations.Send</span>
                            </a>
                        </div>
                    </svg>
                </div>
                <div class="text-center loader-container hidden">
                    <img src="@Url.Content("~/Media/img/loading_spinner.gif")" alt="Alternate Text" />
                </div>
            </div>
        </div>
    </div>
    
    <div style="position: relative; z-index: 500;">
        <div>@Html.ValidationMessageFor(x => x.RecaptchaKey)</div>
        <div id='recaptcha' class="g-recaptcha"
             data-sitekey="@Model.RecaptchaKey"
             data-callback="onSubmit"
             data-size="invisible"></div>
    </div>
    }
    

    And the view itself has just slightly been modified to use the recaptcha:

        <script>
        function onSubmit(token) {
            $(".btn-wrapper").addClass("hidden");
            $(".loader-container").removeClass("hidden");
            $("#contact-us-form").submit();
        }
    
        function validate(e) {
            e.preventDefault();
    
            grecaptcha.execute();
        }
    
        function onload() {
            var element = document.getElementById('contact-submit-btn');
            element.onclick = validate;
        }
    </script>
     @{ Html.RenderAction("RenderForm", "Contact", new { id = successPageId, recaptchaKey = RecaptchaSiteKey }); }
    
  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies