I am writing a custom validation set that will display all missing elements on a div. I'd like to be able to use a custom @Html.BeginForm()
method that will write out that div but I'm really not sure where to even begin as this nut is a little tougher to crack than just a html extension that writes out a Tag or String (the form encapsulates data/controls and is closed by }
at the end).
I looked at the metadata version of the built in BeginForm()
method and it wasn't much help to me. Essentially, I just want to extend that method if possible and have it write out a MvcHtmlString
of a div
that will be show/hidden from JavaScript.
ultimately where I'm struggling is figuring out how to write this custom helper that has the beginning and ending component to it.
@using(Html.BeginForm())
{
...
}
I'd want to be able to do something like this:
@using(Html.VBeginForm())
{
...
}
and have that render my extra html
EDIT: adding code from suggestion below
public class VBeginForm : IDisposable
{
private readonly HtmlHelper _helper;
public VBeginForm(HtmlHelper htmlHelper, string areaName)
{
_helper = htmlHelper;
var container = new TagBuilder("form");
container.GenerateId(areaName);
var writer = _helper.ViewContext.Writer;
writer.Write(container.ToString(TagRenderMode.StartTag));
}
public void Dispose()
{
_helper.ViewContext.Writer.Write("</form>");
}
}
You need to write an extension method for the
HtmlHelper
class that prints tohelper.ViewContext.Writer
.The method should return an
IDisposable
that prints the closing tag in itsDispose
method.SLaks answer is right, but is missing some extra information.
If you want to use traditional (not unobtrusive) client side validation, you need to supply a formContext, and give it an id, so that the client side validation can work. In his explanation this part is missing.
The easiest way to achieve this is to use return an instance of the
MvcForm
class, that creates theformContext
, and implements theIDisposable
interface.In this implementation I needed to supply the form's id:
Of course this can be customized for your particular case. If you only want to provide an id for your form when absolutely neccesary, check this contidition:
In this case you must be careful to create different Ids for each form in a page. For example you can add an integer suffix, that can be stored in HttpContext.Items and incremented every time a new Id is generated. This ensures that in a single page all generated ids are different.