我有一个打印到屏幕的数据列表。在屏幕的底部(滚动),我有一个带有文本字段的表单,用户可以在其中输入数据。当他们单击提交并且表单无效时,错误会正确显示,但用户现在正在查找在页面的最顶部。因此,他们没有看到页面底部有错误。我希望它跳到页面底部的表单,以便用户可以看到发生了错误。
我想过使用锚点,但问题是;因为当我意识到表单无效时我已经在控制器中,所以我需要重定向回相同的控制器,将主题标签附加到URL。对我而言,这看起来并不是一种好的做法,而是一种浪费。
有谁知道更好的方法吗?
答案 0 :(得分:3)
执行此操作的一种方法是始终发布到锚点,并在视图中确定放置锚点的位置。如果存在模型错误,则将命名锚点放在页面底部,如果没有错误,则将锚点放在页面顶部。使这一点复杂化的一件事是没有Html.BeginForm重载需要一个锚点。你可以像这样实现它
<form action="@Url.Action("actionName", "controllerName")#anchor_name" method="post">
..... form contents .....
</form>
或者您可以编写自定义HTML帮助程序
public static class FormExtensions
{
public static MvcForm CustomBeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, string fragment)
{
var formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, htmlHelper.ViewContext.HttpContext.Request.Url.Scheme, null, fragment, null, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
var builder = new TagBuilder("form");
builder.MergeAttribute("action", formAction);
builder.MergeAttribute("method", "post", true);
htmlHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
return new MvcForm(htmlHelper.ViewContext);
}
}
然后你可以使用@Html.CustomBeginForm('action', 'controller', 'anchor_name')
This question很有用并告知我的回答
答案 1 :(得分:1)
public static MvcForm BeginFormAnchor(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes, string hashTag)
{
var formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, htmlHelper.ViewContext.HttpContext.Request.Url.Scheme, null, hashTag, ConvertToRouteValueDictionary(routeValues), htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
var builder = new TagBuilder("form");
builder.MergeAttribute("action", formAction);
builder.MergeAttribute("method", method.ToString(), true);
foreach (KeyValuePair<string, string> attribute in ConvertToDictionaryStringString(htmlAttributes))
{
builder.MergeAttribute(attribute.Key, attribute.Value);
}
htmlHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
return new MvcForm(htmlHelper.ViewContext);
}
private static Dictionary<string, string> ConvertToDictionaryStringString(object obj)
{
return obj.GetType().GetProperties().ToDictionary(o => o.Name, o => o.GetValue(obj, null).ToString());
}
private static RouteValueDictionary ConvertToRouteValueDictionary(object obj)
{
RouteValueDictionary rvd = new RouteValueDictionary();
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
foreach (PropertyDescriptor prop in props)
{
rvd.Add(prop.Name, prop.GetValue(obj));
}
return rvd;
}
我用这样的形式称呼它:
@using (Html.BeginFormAnchor("Action", "Controller", new { id = Model.ID }, FormMethod.Post, new { @id = "formID" }, "anchorName"))