I have just created an MVC project and my view looks like this
{
#model Models.LeadModels
ViewBag.Title = "Add a Lead";
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<p>#ViewBag.SaveResult</p>
#using (Html.BeginForm("Add", "Lead"))
{
<p>#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName)</p>
<p>#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName)</p>
<p>#Html.LabelFor(m => m.Company)
#Html.TextBoxFor(m => m.Company)</p>
<p>#Html.LabelFor(m => m.Province)
#Html.TextBoxFor(m => m.Province)</p>
<p>#Html.LabelFor(m => m.Telephone)
#Html.TextBoxFor(m => m.Telephone)</p>
<p>#Html.LabelFor(m => m.EmailAddress)
#Html.TextBoxFor(m => m.EmailAddress)</p>
<p>#Html.LabelFor(m => m.LeadStatus)
#Html.TextBoxFor(m => m.LeadStatus)</p>
<p><input type="submit" value="Add Lead" /></p>
}
When this is rendered the labels are the same as my model properties, as in the text says "FirstName"
Questions.
Is there a way to put in a different label (First Name instead of FirstName) using a HTML Helper method?
Are there any neat stuff/tricks we can do to change the display? Such as set the labels to be a fixed width so they all line up?
Is there a way to use a HTML Helper method to output the submit button? Or do I need to manually write the HTML like I am doing?
Is there a way to put in a different label (First Name instead of
FirstName) using a HTML Helper method?
You can use Display attribute data annotation on your property name
public class LeadModels
{
[Display(Name = "First name")]
public string FirstName { set; get; }
}
LabelFor helper method will render the value you provided for the Name attribute
Are there any neat stuff/tricks we can do to change the display? Such
as set the labels to be a fixed width so they all line up?
You can use your css classes style the content. You may also consider using bootstrap css classes which does the alignment in a neat way
Is there a way to use a HTML Helper method to output the submit
button? Or do I need to manually write the HTML like I am doing?
No. There is no helper methods for that. You should write your html tag for the button.
Also, in the asp.net core version, tag helpers are available which allows us to write more HTML style code instead of calling the C# methods in view.
Related
I am trying to generate a unique label and and input text box for a partial view that is being used to render a list of user input rows.
By unique I mean that each input text box should have its unique html "id" and "name" so that when is submitted each input can be identified
In the View I have
#model UserDataModel
#{
var inpName = "benefName" + #Model.Row;
var inpAge = "benefAge" + #Model.Row;
}
#Html.LabelFor(x => x.Name, new { #class="labelhalf"})
#Html.EditorFor(x => x.Name, new { id = #inpName, htmlAttributes = new { #class = "form-control animated" } })
When the view is being render this is what I am seeing
<label class="labelhalf" for="Name">Nombre (Opcional)</label>
<input class="text-box single-line" id="Name" name="Name" type="text" value="">
As you can see the "name" and "id" attributes of the text input is "Name" and "Name" and is not using the value of the #inpName variable ("benefName1" for example)
Also I am trying to assign some CSS classes to that same input using "htmlAttributes"
I had previously tried this with this approach
<label form="FormStep_01" for=#inpName class="labelhalf">Nombre (Opcional)</label>
<input form="FormStep_01" id=#inpName class="form-control animated" pattern="^[_A-z0-9]{1,}$" type="text" placeholder="" required="">
...but the content of the input fields with this approach are not being submited and that is the reason I am trying to use the #Html.EditorFor
UPDATE
I am now using the TextBoxFor which takes the "id" and the "class" fine but not the "name" which is used in the submit
#Html.LabelFor(x => x.Name, new { #class = "labelhalf" })
#Html.TextBoxFor(x => x.Name, new { #id = #inpName, name = #inpName, #class = "form-control animated" })
Please let me know how to achieve this in MVC4
Issue 1 (Using EditorFor())
You cannot add html attributes using EditorFor() in MVC-4. This feature was not introduced until MVC-5.1, and then the correct usage is
#Html.EditorFor(m => m.SomeProperty, new { htmlAttributes = new { someAttribute = "someValue" }, })
Issue 2 (Using TextBoxFor())
You cannot change the value of the name attribute using new { name = "someValue" }. The MVC team built in a safe guard to prevent this because the whole purpose of using the HtmlHelper methods to generate form controls is to bind to your model properties, and doing this would cause binding to fail. While there is a workaround, if you do discover it, don't do it! As a side note - the following line of the private static MvcHtmlString InputHelper() method in the source code
tagBuilder.MergeAttribute("name", fullName, true);
is what prevents you overriding it.
Issue 3 (Manual html)
You not giving the inputs a name attribute. A form posts back a name/value pair based on the name and value attributes of successful controls, so if there is no name attribute, nothing will be sent to the controller.
Side note: If your manually generating html, there is no real need to add an id attribute unless your referring to that element in javascript or css.
Its unclear why your trying to create a input for something that does not appear to relate to your model, but if your trying to dynamically generate items for adding items to a collection property in your model, refer the answers here and here for some options which will allow you to bind to your model.
I have a question that feels like it should be easy to answer, but I am not sure where to go with it.
I have several cshtml pages that take different models. But, each of these models has a common property, called WebSiteSK, and the same razor and Kendo UI code that handles that property in each cshtml file. What I want to do is extract this common razor and Kendo UI into an EditerTemplate.
So, I have one cshtml page that takes a Model, which I'll call ModelA. Then, another that takes another model, called ModelB. Both ModelA and ModelB have an integer property called WebSiteSK, which the code that I want extract into an editor template receives.
Here is the code that I want to centralize in an editor template:
<script type="text/x-kendo-tmpl" id="site-droplist-template">
<span>#: data.WebSiteSK # - </span>
<span><b>#: data.SiteName # </b> - </span>
<span>#: data.EnvironmentNK #</span>
<br />
<span>#: data.SiteUrl #</span>
</script>
<div>
#Html.LabelFor(model => model.WebSiteSK, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#(Html.Kendo().DropDownList()
.Name("WebSiteSK_Target")
.DataTextField("SiteName")
.DataValueField("WebSiteSK")
.DataSource(d => d.Read("GetWebSiteList", "Site"))
.Height(300)
.TemplateId("site-droplist-template")
.Filter("contains")
.OptionLabel("Select a site")
.Events(d =>
{
d.DataBound("onSiteBound");
d.Change("onSiteChange");
})
)
#Html.ValidationMessageFor(model => model.WebSiteSK, string.Empty, new { #class = "text-danger" })
</div>
</div>
Does that make sense? Can anyone help me do this?
You can create a base class that contains only the property 'WebSiteSK'. All models that have have this property then should inherit from this base class. Then you can create a partial view '_WebSiteSK' with the code that you want to reuse.
Your models:
public class MyModel : WebSiteSKBaseClass
The partial view must be typed with the base class
#model MyProject.Models.WebSiteSKBaseClass
Finally you can replace the replicated code in all views with:
#Html.Partial("_WebSiteSK")
Is it possible to make a HtmlHelper for parts where another htmlherlper is already used.
like in this case:
<div class="control-group">
#Html.LabelFor(model => model.cLinks.Link2Privates)
<div class="controls">
#Html.TextBoxFor(model => model.cLinks.Link2Privates, new { #class = " span7"})
#Html.ValidationMessageFor(model => model.cLinks.Link2Privates)
</div>
</div>
I'm assuming you simply want a helper that will generate all this information for you. While it's technically possible to create a custom helper that will do just that, it's actually better to use editor templates:
Views\Shared\EditorTemplates\BootstrapControlGroup.cshtml
<div class="control-group">
#Html.Label("")
<div class="controls">
#Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { #class = " span7"})
#Html.ValidationMessage("")
</div>
</div>
Form
#Html.EditorFor(m => m.cLinks.Link2Privates, "BootstrapControlGroup")
That basically says to use this template to render the "editor" for this property. If you don't want to have to specify the template name, there's other ways. You can decorate your property with the UIHint attribute:
[UIHint("BoostrapControlGroup")]
public string Link2Privates { get; set; }
Or you can rely on a particular C# type or DataType. For example, if you wanted all strings to be handled this way, you could name that template String.cshtml instead and then just do:
#Html.EditorFor(m => m.cLinks.Link2Privates)
Razor would see that it was a string and use the String.cshtml editor template automatically if it existed. You can also use the DataType attribute, for example:
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
And, then create a Views\Shared\EditorTemplates\EmailAddress.cshtml template. Razor will use this template, then, any time you call Html.EditorFor for this property.
I have created a HtmlHelper extension library that works well with Twitter Bootstrap scenarios.
http://buildmvc.codeplex.com
There's even a HtmlHelper add-on for Twitter Bootstrap Form Groups:
https://www.nuget.org/packages/Build.Mvc.TwitterBootstrap
#using ( Html.BuildForm().Begin(FormRenderStyle.Horizontal) )
{
Html.UpdateFormBuilderContext(ctx =>
{
ctx.RenderValidationMessages = true;
});
<fieldset>
<legend>User Information</legend>
#Html.BuildTextBoxGroupFor(m => m.FirstName, b=> b.TextBox(t=> t.Autofocus()))
#Html.BuildTextBoxGroupFor(m => m.Nickname)
#Html.BuildTextBoxGroupFor(m => m.LastName)
</fieldset>
}
Note: The library expects you to be using TwitterBootstrap > v3. The example above has version 2.3.2 class names.
I'm going to bind data to a label using MVC4,But it's not success..Data come to model.
Here is my code.
<div class="newclass">
#Html.LabelFor(m => m.NewsTeam.NewsMgr, new { style = "width:100%", #class = "newcssval" })
</div>
Try like this:
#Html.LabelFor(m => Model.NewsTeam.NewsMgr)
or use DisplayFor
#Html.DisplayFor(m => m.NewsTeam.NewsMgr)
Hope it helps
This will only give you the name of the field (or it's display value from the class). I suspect what you need is the following.
#Html.TextBoxFor(m => m.NewsTeam.NewsMgr,
new { #class = "newcssval", #readonly = true })
This will give you a read-only text box wuth the content of your model data.
Hope that helps.
If your intent is to simply show the value of the property, use the Display or DisplayFor helper:
#Html.DisplayFor(m => m.NewsTeam.NewsMgr)
Or, forget the helper entirely:
#Model.NewsTeam.NewsMgr
If the property contains HTML, you'll need to use the Raw helper:
#Html.Raw(Model.NewsTeam.NewsMgr)
Use this,
#Model.NewsTeam.NewsMgr
It will just show the value of property as label
Or Use,
#Html.DisplayFor(m => m.NewsTeam.NewsMgr)
I have a collection of objects that I'm trying to display, however the span generated by the ValidationMessageFor does not include all the validation attributes:
<span class="field-validation-error">This field is required</span>
instead of:
<span class="field-validation-error" data-valmsg-replace="true" data-valmsg-for="Questions[0].SingleAnswer"></span>
This is how I'm generating the html:
<fieldset id="dr_profileUpdates">
#Html.EditorFor(model => model.Questions)
</fieldset>
And here is my editor template:
#Html.ValidationMessageFor(model => model.SingleAnswer)
#Html.TextBoxFor(model => model.SingleAnswer, new { #class = "textBoxDefault" })
The validation works, however the span does not dissapear after filling out the textbox and focusing out of it - I would assume this is because the span does not get generated correctly
Any help is appreciated.
EDIT: Actually it appears that after posting back to the server and returning the partial view (assuming the ModelState is invalid), those attributes do not get generated again - it only seems to affect the ValidationMessage. Any ideas?
Thanks,
Try add on top of your razor file
#{
Html.EnableUnobtrusiveJavaScript();
}