Copied to clipboard

Flag this post as spam?

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


  • MarcC 49 posts 356 karma points
    Jul 10, 2016 @ 19:47
    MarcC
    0

    Fill out form, come back later. Query String for pre-fill?

    Hey all,

    I was hoping I could get some advice, I am building a bespoke solution just now to retrieve form fields and pre-populate the fields that have been filed.

    The forms are quite extensive.

    The issues I am seeing so far:

    • Nothing can be mandatory or else the full form needs filled in before submit, making pre fill useless. I would like to have some mandatory fields.

    • Can i fill any parts of the form with a query string?

    • Is there a current workflow for this type of situation?

    Thanks,

    Marc

  • David Armitage 510 posts 2082 karma points
    Jul 11, 2016 @ 04:39
    David Armitage
    1

    Hi,

    To handle complex forms I build my own.

    1. I build a model which handles all the validation rules.

    2. I build a Partial View to handle the front-end

    3. This links up to a SurfaceController handle the back-end submit.

    Here is my Model example

    namespace CMS.Models
    {
        public class ContactForm
        {
            [Required(ErrorMessage = "Please enter your first name")]
            [StringLength(50, ErrorMessage = "First name cannot exceed 50 characters")]
            public string FirstName { get; set; }
    
            [Required(ErrorMessage = "Please enter your last name")]
            [StringLength(50, ErrorMessage = "Last name cannot exceed 50 characters")]
            public string LastName { get; set; }
    
            [Required(ErrorMessage = "Please enter your email address")]
            [StringLength(255, ErrorMessage = "Email cannot exceed 255 characters")]
            [Email(ErrorMessage = "Please enter a valid email address")]
            public string Email { get; set; }
    
            [Required(ErrorMessage = "Please enter your phone number")]
            [StringLength(20, ErrorMessage = "Phone number cannot exceed 20 characters")]
            public string Phone { get; set; }
    
            [Required(ErrorMessage = "Please enter your enquiry")]
            [StringLength(1000, ErrorMessage = "Enquiry cannot exceed 1000 characters")]
            public string Enquiry { get; set; }
            public string OverrideEmail { get; set; }
    
            public HttpPostedFileBase Attachment { get; set; }
    
            public ContactForm()
            {
    
            }
    
        }
    }
    

    Here is my surface controller example. I store this in AppCode/Controllers/SurfaceControllers/FormsSurfaceController.cs. I would do the same. I wont give you the whole file as I handle a lot of forms. You need two methods though.

    [HttpGet]
            [ActionName("ContactForm")]
            public ActionResult ContactFormGet()
            {
                //override email
                ContactForm model = new ContactForm();
    
                Node currentPageNode = ContentManager.GetCurrentNode();
                if (currentPageNode.NodeTypeAlias == "contactMultiplePage")
                {
                    CMS.Models.ContactMultiplePage contactMultiplePage = new CMS.Models.ContactMultiplePage(currentPageNode);
                    if (contactMultiplePage != null)
                    {
                        model.OverrideEmail = contactMultiplePage.ContactFormEmail;
                    }
                }
    
                return PartialView("ContactForm", model);
            }
    
            [HttpPost]
            [ActionName("ContactForm")]
            public FileUploadJsonResult ContactFormPost(ContactForm model)
            {
                var errorMessage = string.Empty;
    
                if (!ModelState.IsValid)
                {
                    var errors = ModelState.Where(x => x.Value.Errors.Count > 0).Select(x => new { x.Key, x.Value.Errors }).ToArray();
                    errorMessage = "<h3>There were errors submitting your enquiry.....</h3>";
    
                    if (errors.Count() > 0)
                    {
                        foreach (var error in errors)
                        {
                            var message = "<span class='validation-error'>* " + error.Errors[0].ErrorMessage + "</span><br/>";
                            errorMessage += (message);
                        }
    
                        errorMessage += "<br/><br/>";
    
                        return new FileUploadJsonResult
                        {
                            Data = new
                            {
                                Success = false,
                                ErrorMessage = errorMessage
                            }
                        };
                    }
                }
    
                //send the submit resume emails here!
                EmailManager.ContactFormToUser(model);
                EmailManager.ContactFormToAdministrator(model);
    
                return new FileUploadJsonResult
                {
                    Data = new
                    {
                        Success = true,
                        ReturnUrl = SiteSettings.GetSiteSettingStringProperty("contactFormPage") + "/complete"
                    }
                };
            }
    

    Here is my PartialView

    @model CMS.Models.ContactForm
    
    @{ 
        string register = Request.QueryString["register"] != null ? Request.QueryString["register"].ToString() : string.Empty;
    }
    
    @using (Html.BeginUmbracoForm("ContactForm", "FormsSurface", FormMethod.Post, new { id = "ContactForm" }))
    {
        <div class="row enquiry">
            <h3>Make an Enquiry</h3>
    
            <div class="col-md-6 col1">
                <div class="row">
                    <div class="col-md-4 bold">
                        <span class="colorRed">*</span>
                        <span>First Name:</span>
                    </div>
                    <div class="col-md-8">
                        @Html.TextBoxFor(x => x.FirstName, new { maxlength = 50, @class = "form-control" })
                        @Html.ValidationMessageFor(x => x.FirstName)
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-4 bold">
                        <span class="colorRed">*</span>
                        <span>Last Name:</span>
                    </div>
                    <div class="col-md-8">
                        @Html.TextBoxFor(x => x.LastName, new { maxlength = 50, @class = "form-control" })
                        @Html.ValidationMessageFor(x => x.LastName)
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-4 bold">
                        <span class="colorRed">*</span>
                        <span>Phone:</span>
                    </div>
                    <div class="col-md-8">
                        @Html.TextBoxFor(x => x.Phone, new { maxlength = 20, @class = "form-control" })
                        @Html.ValidationMessageFor(x => x.Phone)
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-4 bold">
                        <span class="colorRed">*</span>
                        <span>Email:</span>
                    </div>
                    <div class="col-md-8">
                       @Html.TextBoxFor(x => x.Email, new { maxlength = 255, @class = "form-control" })
                        @Html.ValidationMessageFor(x => x.Email)
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                @Html.TextAreaFor(x => x.Enquiry, new { maxlength = 1000, @class = "form-control", placeholder = "Type your enquiry here" })
                @Html.ValidationMessageFor(x => x.Enquiry)
    
                <div class="group">
                    <div class="row">
                        <div class="col-md-4">
                            Attach File: <span class="colorda2037">*</span>
                        </div>
                        <div class="col-md-8">
                            @Html.TextBoxFor(model => model.Attachment, new { type = "file"})
                            @Html.ValidationMessageFor(x => x.Attachment)<br />
                        </div>
                    </div>
                </div>
    
                @Html.HiddenFor(x => x.OverrideEmail)
    
                <a  id="btnContact" class="btn btn-submit">SEND ENQUIRY <img id="contact-ajax-loader" alt="Form Loading Icon" style="display:none;" src="~/Frontend/Images/ajax-loader.gif" /></a>
            </div>
            <div class="message-section row">
                <div id="contact-error-message" style="display:none;">
                    <!--error message is populated through the json result-->
                </div>
            </div>
        </div>
    
    }
    
    <script>
        $(document).ready(function () {
            var $form = $('#ContactForm');
    
            $('#btnContact').click(function () {
                if ($("#ContactForm").valid()) {
                    $form.ajaxSubmit(submitOptions);
                }
            });
    
            var submitOptions = {
                iframe: true,
                dataType: 'json',
                timeout: 30000,
                beforeSubmit: function () {
                    $('#contact-ajax-loader').show();
                    $('#btnContact').attr("disabled", true);
                },
                success: function (response, statusText, xhr) {
    
                    if (!response.Success)
                    {
                        $("#contact-error-message").html(response.ErrorMessage);
                        $("#contact-error-message").show();
                        $("#contact-success-message").hide();
                    }
                    else
                    {
                        window.location.href = response.ReturnUrl;
                    }
    
                    $('#contact-ajax-loader').hide();
                    $('#btnContact').attr("disabled", false);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    $("#contact-error-message").html("<h3>There were errors submitting your enquiry.....</h3><span class='validation-error'>* Please try again</span><br/><span class='validation-error'>* If this error continues to happen please let us know</span><br/>");
                    $("#contact-success-message").show();
                    $('#contact-ajax-loader').hide();
                    $('#btnContact').attr("disabled", false);
                },
                complete: function (jqXHR, textStatus) {
                    $('#contact-ajax-loader').hide();
                    $('#btnContact').attr("disabled", false);
                }
            };
    
        });
    
    </script>
    
    <script type="text/javascript">
        $.validator.unobtrusive.adapters.addBool("mustbetrue", "required");
        $.validator.unobtrusive.parse();
    </script>
    

    And here is how to call your partial view and load the form

    @Html.Action("ContactForm", "FormsSurface")
    

    With this setup you have a lot of control. You can collect Query strings in the GET method and past them to the frontend etc.

    Hope this helps.

    Kind Regards

    David

  • MarcC 49 posts 356 karma points
    Jul 11, 2016 @ 15:32
    MarcC
    0

    Thanks David, this is a superb answer, wish I could high five you more for it.

    Ill need to take time to digest it properly, many thanks mate!

    M

  • David Armitage 510 posts 2082 karma points
    Jul 12, 2016 @ 03:18
    David Armitage
    1

    Hi Marc,

    No problems. Let me know if I can be any more help.

    Kind Regards

    David

  • 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