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 508 posts 2076 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 508 posts 2076 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

Please Sign in or register to post replies

Write your reply to:

Draft