Reputation: 231
I've been struggling with how to change the following to fit my needs. This is for a form I have with simple inputs. The way the code is now it simply displays a label, the field and a validation message vertically, but I want to make it horizontal (using a <table>
).
Currently I have this code:
var wrapper = new TagBuilder("div");
wrapper.AddCssClass("field-wrapper");
var table = new TagBuilder("table");//This is my test to insert a table
var label = new TagBuilder("div");
label.AddCssClass("field-label");
if (metadata.IsRequired && !metadata.IsReadOnly)
{
if (metadata.ModelType != typeof (bool))
{
label.InnerHtml += "* ";
wrapper.AddCssClass("required");
}
}
label.InnerHtml += html.LabelFor(expression);
wrapper.InnerHtml += label;
var input = new TagBuilder("div");
input.AddCssClass("field-input");
input.InnerHtml += html.EditorFor(expression);
if (!string.IsNullOrEmpty(metadata.Description))
{
input.InnerHtml += html.TooltipFor(expression);//declared elsewhere to show a tooltip
}
input.InnerHtml += html.ValidationMessageFor(expression);
wrapper.InnerHtml += input;
wrapper.InnerHtml += table;//This is my test to insert a table
return MvcHtmlString.Create(wrapper + "\r\n");
I tried inserting a <table>
but this is the structure of the HTML with that code:
<div class="field-wrapper">
<div class="field-label">
<label for="Name">Name</label>
</div>
<div class="field-input">
* <input class="text-box single-line input-validation-error" data-val="true" data-val-required="The Name field is required." id="Name" name="Name" type="text" value="">
<!--tooltip would ordinarily show up here-->
<span class="field-validation-error" data-valmsg-for="Name" data-valmsg-replace="true">
<span for="Name" generated="true" class="">The Name field is required.</span>
</span>
</div>
<table></table><!--This is my table-->
</div>
This is what it looks like after validation-error:
What I am going for is this structure:
<div class="field-wrapper">
<table border="0">
<tbody>
<tr>
<td width="40%">
<div class="field-label">
<label class="mylabelstyle" for="FirstName" title="Enter first name.">First Name:</label>
</div>
</td>
<td width="60%">
<div class="field-input">
<input data-val="true" data-val-required="First Name required." id="FirstName" name="FirstName" type="text" value="" />
<!--tooltip here as necessary-->
<span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Visually, this is what I am after:
A couple of things to note:
<table>
is inside a <div>
that's floated left. I have some static content on the right which is not the problem (it shows up under the validation in the second image), so that's also not important.I am not good with the TagBuilder
and have just been making a mess of everything. Any help is greatly appreciated. Thanks!
Upvotes: 0
Views: 3463
Reputation: 1039268
There you go:
public static IHtmlString MyEditorFor<TModel, TProperty>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TProperty>> expression
)
{
var metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, html.ViewData);
var wrapper = new TagBuilder("div");
wrapper.AddCssClass("field-wrapper");
var table = new TagBuilder("table");
table.Attributes["border"] = "0";
var tbody = new TagBuilder("tbody");
var tr = new TagBuilder("tr");
var td1 = new TagBuilder("td");
td1.Attributes["width"] = "40%";
var label = new TagBuilder("div");
label.AddCssClass("field-label");
if (metadata.IsRequired && !metadata.IsReadOnly)
{
if (metadata.ModelType != typeof(bool))
{
label.InnerHtml += "* ";
wrapper.AddCssClass("required");
}
}
label.InnerHtml += html.LabelFor(expression);
td1.InnerHtml = label.ToString();
var td2 = new TagBuilder("td");
td2.Attributes["width"] = "60%";
var input = new TagBuilder("div");
input.AddCssClass("field-input");
input.InnerHtml += html.EditorFor(expression);
if (!string.IsNullOrEmpty(metadata.Description))
{
input.InnerHtml += html.TooltipFor(expression);
}
input.InnerHtml += html.ValidationMessageFor(expression);
td2.InnerHtml = input.ToString();
tr.InnerHtml = td1.ToString() + td2.ToString();
tbody.InnerHtml = tr.ToString();
table.InnerHtml = tbody.ToString();
wrapper.InnerHtml = table.ToString();
return new HtmlString(wrapper + Environment.NewLine);
}
Upvotes: 2