катится мой собственный @ Html.BeginfBrm () - PullRequest
7 голосов
/ 17 июня 2011

Я пишу пользовательский набор проверки, который будет отображать все недостающие элементы в div. Я хотел бы иметь возможность использовать пользовательский метод @Html.BeginForm(), который будет записывать этот div, но я действительно не уверен, с чего начать, так как этот орех немного сложнее взломать, чем просто расширение HTML, которое записывает Tag или String (форма инкапсулирует данные / элементы управления и закрывается на } в конце).

Я посмотрел на версию метаданных встроенного BeginForm() метода, и это мне не сильно помогло. По сути, я просто хочу расширить этот метод, если это возможно, и сделать так, чтобы он записал MvcHtmlString из div, который будет отображаться / скрываться от JavaScript.

В конечном счете, я пытаюсь понять, как написать этот пользовательский помощник, в котором есть начальный и конечный компоненты.

@using(Html.BeginForm())
{
...

}

Я бы хотел иметь возможность сделать что-то вроде этого:

@using(Html.VBeginForm())
{
...

}

и пусть это сделает мой лишний html

РЕДАКТИРОВАТЬ: добавление кода из предложения ниже

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>");
    }
}

Ответы [ 2 ]

6 голосов
/ 17 июня 2011

Вам необходимо написать метод расширения для класса HtmlHelper, который печатает в helper.ViewContext.Writer.

Метод должен вернуть IDisposable, который печатает закрывающий тег в своем методе Dispose.

4 голосов
/ 31 июля 2013

SLaks ответ правильный, но отсутствует некоторая дополнительная информация.

Если вы хотите использовать традиционную (не ненавязчивую) проверку на стороне клиента, вам нужно предоставить formContext и дать ему идентификатор, чтобыпроверка на стороне клиента может работать.В его объяснении эта часть отсутствует.

Самый простой способ достичь этого - использовать экземпляр класса MvcForm, который создает formContext и реализует интерфейс IDisposable.

В этой реализации мне нужно было указать идентификатор формы:

public static MvcForm BeginFormDatosAdicionales(this HtmlHelper htmlHelper, 
   string id, ..., IDictionary<string, object> htmlAttributes = null)
{
  TagBuilder form = new TagBuilder("form");
  // attributes
  form.MergeAttributes(htmlAttributes);
  // action
  string formAction = ...;
  form.MergeAttribute("action", formAction);
  // method
  FormMethod method = ...;
  form.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
  // id
  form.MergeAttribute("id", id);

  // writes the form's opening tag in the ViewContext.Writer
  htmlHelper.ViewContext.Writer.Write(form.ToString(TagRenderMode.StartTag));

  // creates an MvcForm (disposable), which creates a FormContext, needed for
  // client-side validation. You need to supply and id for it
  MvcForm theForm = new MvcForm(htmlHelper.ViewContext);
  htmlHelper.ViewContext.FormContext.FormId = form.Attributes["id"];

  // The returned object implements IDisposable, and writes the closing form tag
  return theForm;
  }

Конечно, это можно настроить для вашего конкретного случая.Если вы хотите предоставить идентификатор для своей формы только в случае крайней необходимости, проверьте это условие:

bool idRequired = htmlHelper.ViewContext.ClientValidationEnabled
&& !htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled;

В этом случае вы должны быть осторожны при создании разных идентификаторов для каждой формы на странице.Например, вы можете добавить целочисленный суффикс, который можно сохранить в HttpContext.Items и увеличивать при каждом создании нового идентификатора.Это гарантирует, что на одной странице все сгенерированные идентификаторы будут разными.

HttpContext.Current.Items["lastFormId"]
...