Tab Order in ASP.NET MVC 3 Helpers - asp.net

How can I use Tab Order property for following code:
<td>
#Html.EditorFor(model => model.Cost)
</td>
I tried this:
<td tabindex=1>
#Html.EditorFor(model => model.Cost)
</td>
any suggestions?

You can also specify the same html attribute in the helper itself as follows.
#Html.TextBoxFor(model => model.Cost, new { tabindex = 1 })

As a contrast to #Stuy1974's right answer, if you don't want to leave the EditorFor solution, you're going to have to wire up your own Editor Template.
#ModelType SomeApp.ViewModels.SomeNiftyViewModel
// be sure to include the TabIndex info in the ViewModel
#Html.TextBoxFor(model => model.Cost, new { tabindex = model.TabIndex })
You can also use the ViewData parameter already passed to the editor template directly rather than adding the tab index to the model:
// In the main view
#Html.EditorFor(model => model.Cost, new { TabIndex = 3 })
// In the editor template
#{ int tabIndex = (ViewData["TabIndex"] as int?) ?? 0; }
#Html.TextBoxFor(model => model, new { tabindex = tabIndex })

Simply do this
#Html.EditorFor(model => model.Cost, new { htmlAttributes = new { tabindex = 34 } })

Another option, allowing you to retain the EditorFor, is to set the tab index in javascript after the page has loaded with something like:
var myEditorFor = document.getElementById("MyEditorForId");
if (myEditorFor != null) {
myEditorFor.setAttribute("tabindex","18")
}

Unfortunately #Html.EditorFor method doesn't provide the ability to add HTML attributes. You can add these via a more specific method call. In the above case I'd use -
#Html.TextBoxFor(model => model.Cost, new { tabindex = 1 })

Related

Unable to apply a css class to my #Html.DisplayFor inside a WebGrid, inside my asp.net MVC 5 web application

I have the following code inside my asp.net MVC Razor view:-
#{
List<Marketing.Models.SalesData> allLevels = ViewBag.AllLevels;
var gridcolumns = new List<WebGridColumn>();
gridcolumns.Add(new WebGridColumn()
{
ColumnName = "Status",
Header = Html.DisplayNameFor(model => model.Content.FirstOrDefault().Status).ToString(),
CanSort = true,
Format =
(item) =>
{
var banner = item.Value as Marketing.Models.SalesData;
return Html.DisplayFor(modelItem => banner.Status, new { #class = banner.Status });
}
});
now what i am trying to do is to define a css class inside my Html.DisplayFor(modelItem => banner.Status, new { #class = banner.Status }); but this will render the without any css class, as follow:-
<td>succeed</td>
now i though the problem with the way i am defining the class, so i tried this test, to hard code the class name Html.DisplayFor(modelItem => banner.Status, new { #class = "testclass"}); but this did not render the css class.. so can anyone adivce on this please?
now i am using asp.net mvc version 5.2.3.0 which should support defining css classes inside my HTML helpers.
At first take a look to this example. #Html.LabelFor() Helper function renders a <label></label> tag. Suppose if you write #Html.LabelFor(m=>m.Name, new {#class = "form-control"}) it returns <label class = "form-control">David</label>.So we can apply class to label for helper function.
But #Html.DisplayFor() do not render any html tag. If you write #Html.DisplayFor(m=>m.Name) it returns your name only, like: David.
So you have to wrap #Html.DisplayFor() Helper inside a span and apply class to it.
Like: <span class = "form-control">#Html.DisplayFor(m=>m.Name)</span>. Then output will be <span class="form-control">David</span> . That means class applied on name property.
Hope this helps..

Correctly display data in View and save it using HiddenFor and DisplayFor

I want to use hiddenFor field to save record_time to database while displaying date in a html.display or similar to that field without editing.
CREATE action
public ActionResult Create()
{
Record newRecord = new Record();
newRecord.user_id = 1; //let it be 1 for simplicity
newRecord.record_time = System.DateTime.Now;
return View(newRecord);
}
CREATE view
<div class="form-group">
#Html.LabelFor(model => model.user_id, "User name", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.HiddenFor(model => model.user_id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.record_time, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.HiddenFor(model => model.record_time)
//this line I'm concerned about
#Html.DisplayFor(model => model.record_time, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
About user_id. Is it correct to use hiddenFor for new record, not editorFor?
About record_time. Is it correct to use both hiddenFor and displayFor? which one will be used to send data back to database? What is the correct way to just display a predefined datetime info and send it then to the database?
A form only submits the name/value pairs of its form controls (input, select, textarea) and DisplayFor() does not generate a form control.
If you want to format the date using DisplayFor(), then you can use the DisplayFormatAttribute, for example
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime record_time { get; set; }
or you can just use <div>#Model.record_time.ToString("MM/dd/yyyy")</div>
Note that DisplayFor() renders just text, not an element, and it does not have an overload that accepts htmlAttributes (there is no element to apply attributes to, so its just
#Html.DisplayFor(m => m.record_time)
As a side note, the names of both you properties indicate they are for the user who created/edited the record and the date the record was created. If that is the case, you view should not include any inputs for those values. Both should be set in the POST method immediately before you save the data model. And if its a create view, displaying the record_time (assuming it is the date the record was created) makes no sense either (it has not been created yet).

How can I use placeholder attribute with Html.EditorFor?

I want to use the placeholder attribute in the Html.EditorFor so I did just like in the first answer: Html5 Placeholders with .NET MVC 3 Razor EditorFor extension?
But in the final part, I don't have the EditorTemplates folder so I created it and when I tried to create the string.cshtml view I couldn't because the name "string" is reserved so I chose stringg.cshtml instead and it didn't work! Do I have to change the name elsewhere in my program? I did exactly like the answer...
Thank you!
Upgrade to MVC 5.1 and you can use HTML attributes in EditorFor:
#Html.EditorFor(m => m.variable, new { htmlAttributes = new { placeholder = "Your Placeholder Text" } })
http://www.asp.net/mvc/overview/releases/mvc51-release-notes
#Html.EditorFor(model => model.members_ssn, new { htmlAttributes = new { #class = "form-control", placeholder = "Your Example Here" } })
This works for MVC 5.
In my case i was looking to set the placeholder from the model metadata, like this:
#Html.EditorFor(model => model.name, new { htmlAttributes = new { #class = "form-control", placeholder = Html.DisplayNameFor(x => x.name) } })
When using TextBoxFor or TextAreaFor rather than EditorFor, use only the inner key-value pair from #Medo's answer, since the method directly expects an htmlAttributes object:
#Html.TextBoxFor(m => m.variable, new { placeholder = "Your Placeholder Text" })
(I realize this is tangential to the original question, but having this here would have helped me when I landed on this page earlier, looking for an answer to how to add placeholder text to an Html.TextAreaFor!)
Use some jquery, eg:
$("#FirstName").attr("placeholder", "Do not type name - use Search button");

How to refer to a CSS style using ASP.NET MVC?

In ASP.NET MVC I could define a textBox editor like this and give it a style.
#Html.TextBoxFor(m => m.Notes[i].Notes, new { style = "width: 500px;" });
How can I move the style to the Site.css file and just refer to it from the code above?
.myStyle {
width: 500px;
}
I tried this which compiles but doesn't seem to work:
#Html.TextBoxFor(m => m.Notes[i].Notes, "myStyle");
You want to give it a class attribute for your CSS rule to match:
#Html.TextBoxFor(m => m.Notes[i].Notes, new { #class = "myStyle" });
Note that the # in #class has no special meaning in ASP.NET MVC. It's simply there to turn class, a keyword in C#, into an identifier, so you can pass it in as a property and it'll compile.
One word of explanation. Normally if you want to add attributes, e.g. readonly, you would type:
#Html.TextBoxFor(m => m.Notes[i].Notes, new { readonly = "readonly" });
Notice there is no # in front of readonly. You have to put # in front of the class attribute, because it's a keyword in C#. If you do it in VB.NET you do not have to escape, because you define properties with a leading .:
#Html.TextBoxFor(Function(m) m.Notes[i].Notes, New With { .class = "myStyle" });

.NET MVC3 Html.HiddenFor inside of foreach loop expecting a collection?

Here is a portion of a partial:
#model IEnumerable<BLL.DomainModel.Jerk>
#foreach (var jerk in Model)
{
using (Html.BeginForm("AddJerk", "Jerk", FormMethod.Post, new { #class = "jerkListForm" }))
{
#Html.HiddenFor(jerk => )
#jerk.Name
...
}
}
The type that the HiddenFor lambda is looking for is the same as the #model (IEnumerable), whereas I'm looking for a single object within that IEnumerable.
What am I missing? Why is it still looking for a collection inside of the foreach loop?
#model IEnumerable<Type>
#foreach(var item in Model)
{
#Html.HiddenFor(model => item)
}
Don't forget that Type must be de/serializable in order for this to work.
All Html For Helpers provided by Asp.Net MVC use the model of the defined model for the page. What you can do is create an EditorTemplate. Create a subdirectory in your View folder called EditorTemplates such as in \Home\EditorTemplates\ and add a new view called Jerk.cshtml and assign your model that way.
Then you can use the Html.HiddenFor(f => f.Name) and so forth for each property. This will give you your typed access that you're expecting.
In your main view you would do the following:
#foreach(var jerk in Model) {
#Html.EditorFor(m => jerk)
}
or you can call EditorForModel where it will automatically loop through and look for the EditorTemplate.
#Html.EditorForModel()
The EditorFor will look for the EditorTemplate you created first then it will go from there until it either finds an override or it will output one MVC thinks you might need.
I would use a for loop instead. That way your hidden field will have the correct name. If you use the helpers like in your example, all the hidden fields will have a name of jerk, which won't post back correctly.
#foreach (var i = 0; i < Model.Count; i++)
{
var jerk = Model[i];
using (Html.BeginForm("AddJerk", "Jerk", FormMethod.Post, new { #class = "jerkListForm" }))
{
#Html.HiddenFor(model => model[i])
#jerk.Name
...
}
}
If binding doesn't matter to you on the postback, you can simply do
#Html.HiddenFor(jerk => jerk)

Resources