10

I have not ever had to submit a form in Sitecore before, in my previous experience I used WFFM, thus I didn't have to create or process forms.

My form is simply to take in some information and forward the information from the form via email, thus we are not saving the data to a database. Along with that I need to send back a confirmation note to my user

so, I have created two partial views (view Renderings) that I will use for this task. These view Renderings are components that sit inside of placeholders on my template sharing the page layout that I created for my site. These View renderings have their own datasource.

Visual Studio Solution

One of the View Renderings (FormGeneric.cshtml) contains the form below:

@model RenderingModel

@{ 

    var formTitle = "";
    var formSubTitle = "";
    var formText = "";
    var ImageUrl = "";
    var buttonText = "";

    try
    {

        formTitle = Model.Item.Fields["Heading"].Value;
        formSubTitle = Model.Item.Fields["Sub Heading"].Value;
        formText = Model.Item.Fields["Form Text"].Value;
        var formImage = (Sitecore.Data.Fields.ImageField) Model.Item.Fields["Image"];
        buttonText = Model.Item.Fields["Button Text"].Value;

        if (formImage.Value != "" && formImage != null)
        {
            ImageUrl = Sitecore.Resources.Media.MediaManager.GetMediaUrl(formImage.MediaItem);
        }

    }
    catch { }

}

<div class="container">

    <div class="col-sm-6">
        <h2>@formTitle</h2>

        <p class="large-subhead">@formSubTitle</p>

        <p>@formText</p>

        <img class="img-responsive" src="@ImageUrl">

    </div>



    <div class="col-sm-6">
        <form class="content-form">
            @using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post))
            {
            <div class="form-group form-group-lg">
                <input type="" class="form-control" id="" placeholder="Full Name">
            </div>
            <div class="form-group form-group-lg">
                <input type="" class="form-control" id="" placeholder="Street Address">
            </div>



            <div class="form-group form-group-lg">
                <input type="" class="form-control" id="" placeholder="City">
            </div>



            <div class="input-group input-group-lg">
                <input type="text" class="form-control" aria-label="...">
                <div class="input-group-btn">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">State <span class="caret"></span></button>
                    <ul class="dropdown-menu dropdown-menu-right">
                        <li><a href="#">Option</a></li>
                        <li><a href="#">Option</a></li>
                        <li><a href="#">Option</a></li>
                    </ul>
                </div><!-- /btn-group -->
            </div><!-- /input-group -->




            <div class="form-group form-group-lg">
                <input type="" class="form-control" id="" placeholder="Zip/Postal Code">
            </div>



            <div class="input-group input-group-lg">
                <input type="text" class="form-control" aria-label="...">
                <div class="input-group-btn">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Country <span class="caret"></span></button>
                    <ul class="dropdown-menu dropdown-menu-right">
                        <li><a href="#">Option</a></li>
                        <li><a href="#">Option</a></li>
                        <li><a href="#">Option</a></li>
                    </ul>
                </div><!-- /btn-group -->
            </div><!-- /input-group -->



            @Html.Sitecore().FormHandler("GreatAmericanCampoutController", "SignUp")
            <button type="submit" class="inline-btn">@buttonText</button>
            }
        </form>



    </div>

</div>

and as you can see I have placed a line

@Html.Sitecore().FormHandler("GreatAmericanCampoutController", "SignUp")

I added a controller called "GreatAmericanCampoutController" under my "controllers" folder in my solution, there will be more processing in this controller, but I just wanted to test the redirect to the Confirmation page

namespace Website.Controllers
{
    public class GreatAmericanCampoutController : Controller
    {
        // GET: GreatAmericanCampout
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult SignUp()
        {
            var options = new UrlOptions
            {
                AddAspxExtension = false,
                LanguageEmbedding = LanguageEmbedding.Never
            };

            var pathInfo = LinkManager.GetItemUrl(PageContext.Current.Item.Children.FirstOrDefault(), options);

            return RedirectToRoute(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, new { pathInfo = pathInfo.TrimStart(new char[] { '/' }) });

        }
    }
}

I created a partial view (FormConfirmation.cshtml) that contains my Confirmation message

@model RenderingModel

@{ 
    var subject = "";
    var textualContent = "";
    var signatureLine = "";

    try
    {
        subject = Model.Item.Fields["Subject"].Value;
        textualContent = Model.Item.Fields["Textual Content"].Value;
        signatureLine = Model.Item.Fields["Signature Line"].Value;
    }
    catch { }

}
<div class="container">
    <div class="col-sm-12 col-md-6 col-lg-9">
        <h2>@subject</h2>
        <br />
        <p>
        @textualContent
        </p>
        <br />
        <br />
        <p>Sincerely,
        <br />
        <br />
        @signatureLine
        </p>
        </div>
</div>

when I press the "submit" button ... Nothing happens. I don't know if it just can't locate the controller or what.

I have enclosed an illustration of my Visual Studio Solution

1
  • Also it's off topic, but you define variables for the fields at the top of the source, this wouldn't work well with the experience editor. Instead of defining variables, you should use @Html.Sitecore().Field("FieldName") for items coming from Sitecore. This will allow these fields to be edited by users in the experience editor. Hit me up on Slack if you have any questions. Jul 20, 2017 at 22:55

1 Answer 1

4

I think your main problem is that you have this:

<form class="content-form">
    @using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post))
    {
        @Html.Sitecore().FormHandler("GreatAmericanCampoutController", "SignUp")
        @* Contents of Form *@
        <button type="submit" class="inline-btn">@buttonText</button>
    }
</form>

You should be doing this instead:

    @using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post))
    {
        @Html.Sitecore().FormHandler("GreatAmericanCampoutController", "SignUp")
        @* Contents of Form *@
        <button type="submit" class="inline-btn">@buttonText</button>
    }

Also it's important to note, that the form will only post back to the current rendering. Which will cause problems if you are using a View Rendering. Typically forms should always be controller renderings. Although there might be a way around if you post the form directly to a controller action.

But Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName) will cause the entire page to post back, and all http verb post actions to fire for any renderings on the page, that's why you would use the Form Handler to prevent this, so only the correct Controller Action fires.

* Update * Added ViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Sitecore.Mvc.Presentation;

namespace Website.ViewModels
{
    public class FormViewModel : IRenderingModel
    {
        public string formTitle { get; set; }
        public string formSubTitle { get; set; }
        public string formText { get; set; }    
        public string imageUrl { get; set; }
        public string pageId { get; set; }

        public string buttonText { get; set; }
        public string fullName { get; set; }
        public string streetAddress { get; set; }
        public string city { get; set; }
        public string state { get; set; }
        public string zipCode { get; set; }
        public string country { get; set; }

        public void Initialize(Rendering rendering)
        {
            var dataSourceItem = rendering.Item;
            if (dataSourceItem == null)
            {
                return;
            }

            this.pageId = PageContext.Current.Item.ID.ToString();
            this.formTitle = dataSourceItem.Fields["Heading"].Value;
            this.formSubTitle = dataSourceItem.Fields["Sub Heading"].Value;
            this.formText = dataSourceItem.Fields["Form Text"].Value;
            this.buttonText = dataSourceItem.Fields["Button Text"].Value;
            var formImage = (Sitecore.Data.Fields.ImageField)dataSourceItem.Fields["Image"];

            if (formImage.Value != "" && formImage != null)
            {
                this.imageUrl = Sitecore.Resources.Media.MediaManager.GetMediaUrl(formImage.MediaItem);
            }


        }
    }
    } 
5
  • 1
    Thank you, as I said I haven't done this before. My next thought was to build this as a controller Rendering. Jul 21, 2017 at 10:20
  • You were correct, and I agree with you that this would not be an issue if I was passing a model and controller rendering, which I am going to make certain this is being handled properly, but I did get this to work by creating a View Model and implementing IRenderingModel and the Initialize() method, but in order to pull up the Thank you page ... I had to capture the PageContext.ID and pass that in the ViewModel in a hidden field to my controller "GreatAmericanCampout" ... sans the "controller". Jul 21, 2017 at 19:59
  • but this line is drving me crazy ... var pathInfo = LinkManager.GetItemUrl(PageContext.Current.Item.Children.FirstOrDefault(), options); the Pagecontext item (I was hoping would be my form page), but it keeps pulling up the sites homepage. How do I get to my form page without passing the pagecontext ID through the View Model? Jul 21, 2017 at 20:04
  • If I am not making sense, please disregard Jul 21, 2017 at 20:06
  • 1
    Also this line -GreatAmericanCampoutController you dont need the controller part. It can also be set as GreatAmericanCampout . Just saying!
    – Abhay Dhar
    Aug 18, 2017 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.