HTML.DropDownListFor class assignment - asp.net

Is it possible to assign my own class to the HTML.DropDownListFor() helper?

One of the overloaded method has an object htmlAttributes as last parameter in which you can specify extra attributes to be added to the generated html:
Html.DropDownListFor(..., new { "class" = "myclassname" };
http://msdn.microsoft.com/library/ee703670.aspx

Didier's answer is mostly correct, but to define a class value in htmlAttributes object, you need to use this syntax:
Html.DropDownListFor(..., new { #class = "myclassname" } );
The "#" is to let the compiler know that this is not the keyword "class". Using "class" will result in a compilation error.

You can use any of the below logic.
#Html.DropDownList("CourseId", new List<SelectListItem>(), new {#class="myclassname"} )
OR
#Html.DropDownList("CourseId", (IEnumerable<SelectListItem>)ViewBag.CourseId, new { #class="myclassname" })
OR
#Html.DropDownListFor(x => x.CourseId, (IEnumerable<SelectListItem>)ViewBag.CourseId, new { #class = "myclassname" })

Related

Razors Html Helpers

How do you make a Razors helper "Dropdownlist" or what arguments would have to pass to make it editable. For example if I want to scroll down it should let me or if I want type Instead it should let aswell.
#Html.DropDownList("CustomerId", null, htmlAttributes: new { #class = "form-control" } )
Also, if you I choose to use twitter-typeahead with EF razors how do use the "Editfor" so that once the user click on the right item, it sends the ID of that item to the database. In-other words, how do use a navigation property with razors "Editfor" helper.
#Html.EditorFor(model => model.CustomerId, null, "customer",new {htmlAttributes = new { #class = "form-control" } })
I will try to help you convert the basic example of the following page to a razor page equivalent.
http://twitter.github.io/typeahead.js/examples/
You must know that this jquery plugin displays just a list of strings and the user will select one of the values and then you will have to find the id using C# code. I will just show you how to implement the twitter typehead using razor pages but you will have to make some extra work in order to get the id.
First of all you will need the html part
<div id="the-basics">
<input class="typeahead" type="text" placeholder="States of USA">
</div>
Next you need to declare your list using C#.
List<string> Values = new List<string> { "Value 1", "Value 2", "Value 3" };
Now you will have the following HTML.
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
};
var states = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Values));
$('#the-basics .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
source: substringMatcher(states)
});
I hope it helps.

ASP.MVC concatenation in Html.LabelFor helper or model Display Name annotation

In my view i use the Html helper:
#Html.LabelFor(model => model.name)
The model contains the annotation for getting display name from resources
[Display(Name = "name", ResourceType = typeof(Resources.Models.ModelName))]
My resources provide translations without ":". If I put ":" after Html.LabelFor helper it won't be placed in label tag, but out of it:
<label for="name">Name</label>:
Is there any way to concatenate a postfix to the Html.LabelFor helper or the Display Name annotation?
Yes I know I can solve this problem by not using labelFor helper at all or concatenating ":" with jQuery, but I'm trying to find an elegant solution.
You can use css to add the : if you give your labels a class name:
#Html.LabelFor(model => model.name, { #class = 'postfix'} )
CSS:
label.postfix:after
{
content: ":";
}
Or you can create an extension helper and call it as
#Html.LabelForPostfix(model => model.name)

Razor: add class to LabelFor if field is not valid

In my form I have:
#Html.LabelFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
#Html.TextBoxFor(m => m.Name, new { #class = "", placeholder = "Full Name" })
Q: How to check if field is valid and add a class to the LabelFor if it's specific field is not valid?
#Html.LabelFor(m => m.Name, if !valid: new { #class="error"} )
You're along the right lines but try this:
#Html.LabelFor(m => m.Name, new { #class= !ViewData.ModelState.IsValid ? "error" : ""} )
Using a ternary statement should work in this scenario as I use them myself on a frequent basis in normal DIV and INPUT HTML.
Edit: After chatting with Alex for a while in the StackOverflow chat system, this is the final working solution I came up with. Unfortunately, Alex is using Unobstrusive JQuery so the below code will only work if client side validation is not added.
#{
var errorCollection = new ModelErrorCollection();
if (ViewData.ModelState.Any(a => a.Value.Errors.Count > 0)) {
errorCollection = ViewData.ModelState["PropertyName"].Errors;
}
}
#Html.LabelFor(m => m.PropertyName, null, new { #class =
errorCollection.Any() ? "cssClassName" : "" })

Applying css on ActionLink in mvc?

I am working in mvc5. I made a simple action link in a view using this syntax
#Html.ActionLink("Manage List", "Index", new { #class = "ManageLink" });
But css was not working untill i added controller name like this:
#Html.ActionLink("Manage List", "Index",new { controller = "ControllerName" }, new { #class = "ManageLink" });
I want to know why we need to define controller name here while it is quite obvious that every view is related to some action method of a controller ? I am very new to mvc so need to know these kind of things.
Thanks for the help.
You could also have fixed this by simply specifying the name of the optional parameter you wanted to set:
#Html.ActionLink("Manage List", "Index", htmlAttributes: new { #class = "ManageLink" });
Otherwise, the Razor engine has to try to figure out which overload of the ActionLink method you're trying to call; sounds like in your case it thought the third argument was for the routeValues parameter.
This would also work:
#Html.ActionLink("Manage List", "Index", "ControllerNameHere", new { #class = "ManageLink" });

Using EditorFor with Twitter Bootstrap to render a form label, input and validation message

I've overridden the default editor template (Object.ascx) to produce form (body) HTML that follows to Twitter Bootstrap's guidelines (http://twitter.github.io/bootstrap/base-css.html#forms) which is executed via Html.EditorForModel().
#if (ViewData.TemplateInfo.TemplateDepth > 1)
{
#(Model == null ? ViewData.ModelMetadata.NullDisplayText : ViewData.ModelMetadata.SimpleDisplayText)
}
else
{
foreach (var property in ViewData.ModelMetadata.Properties.Where(m => m.ShowForEdit #*&& m.ModelType != typeof (System.Data.EntityState)*# && !m.IsComplexType && !ViewData.TemplateInfo.Visited(m)))
{
if (property.HideSurroundingHtml)
{
#Html.Editor(property.PropertyName)
}
else
{
<div class="control-group #(!ViewData.ModelState.IsValidField(property.PropertyName) ? "error" : ViewData.ModelState.ContainsKey(property.PropertyName) ? "success" : "" )">
#if (!string.IsNullOrEmpty(Html.Label(property.PropertyName).ToHtmlString()))
{
#Html.Label(property.GetDisplayName() + (property.IsRequired ? " *" : ""), new { #class = "control-label" })
}
<div class="controls">
#Html.Editor(property.PropertyName)
#Html.ValidationMessage(property.PropertyName, "*", new { #class = "help-inline" })
</div>
</div>
}
}
}
This works well unless I want to tweak the form (e.g. change the ordering or add fieldsets). I basically want to separate part of the above code into another editor template, which resulted in Property.ascx. This will render a label, input and validation message for a given property, executed via Html.Editor("{PropertyName"}) or Html.EditorFor(m => m.{PropertyName}).
<div class="control-group #(!ViewData.ModelState.IsValidField(ViewData.ModelMetadata.PropertyName) ? "error" : ViewData.ModelState.ContainsKey(ViewData.ModelMetadata.PropertyName) ? "success" : "" )">
#if (!string.IsNullOrEmpty(Html.Label(ViewData.ModelMetadata.PropertyName).ToHtmlString()))
{
#Html.Label(ViewData.ModelMetadata.GetDisplayName() + (ViewData.ModelMetadata.IsRequired ? " *" : ""), new { #class = "control-label" })
}
<div class="controls">
#Html.Editor(ViewData.ModelMetadata.PropertyName)
#Html.ValidationMessage(ViewData.ModelMetadata.PropertyName, "*", new { #class = "help-inline" })
</div>
</div>
The problem with the above editor template is that it doesn't render the correct input for the given type. So a date/time property will just render a normal text box without the type attribute.
Am I going about this the right way? Should I be using a standard HTML helper or a partial view? If so, how do we handle the generic nature?
MVC 5.1 includes a fix for exactly this case, Bootstrap support for editor templates.
You can include additional properties for the markup by supplying an anonmyous object as the second parameter to EditorFor
#Html.EditorFor(model => model, new { htmlAttributes = new { #class = "form-control" }, })

Resources