Simple Razor question regarding Html.Editor helper (MVC3) - asp.net-mvc-3

Basically, I have a table with multiple editors like this:
<table>
<tr>
<td>#Html.EditorFor(x => x.Random1)</td>
<td>#Html.EditorFor(x => x.Random2)</td>
</tr>
<tr>
<td colspan="2">#Html.EditorFor(x=> x.Random3)</td>
</tr>
</table>
Now, my problem is, as you probably already figured out from the colspan="2", is that I want my third textbox to stretch all the way thorugh the two columns. In normal HTML is would naturally just add a width attribute. Is there a DataAnnotation like DataType.MultilineText that can change the width of the editors? Any other ideas?
UPDATE: If I change it to a TextBoxFor instead of EditorFor, I can actually add #Html.TextBoxFor(x => x.Random, new { style = "width: 500px;" }).
Only problem is, I have another textbox (lets say random4) and it somehow overrides my DataAnnotation MultilineText and makes it a plain 500px textbox. Guess ill have to digg into the CSS :(

You might find some of the answers to this question useful.
The good thing about templates is that if you don't like the way they work, you can simply drop-in your own implementation.
You can also try using CSS to specify the width for your control, based on it's ID.

Easiest solution is to just style the control in the css. For the random3 textbox ill use input[type="text"]{width:1px} and for the random4 multilinetext, ill use just use textarea{width:1px}

In the Property of the Model - in this case Random3 give it an annotation
public class ViewModelName
{
[DataType(DataType.MultilineText)]
public string Random3 { get; set; }
}
then when you can the Html.EditorFor(x => x.Random3) it will know it needs to be multiline

Related

mvc3 is there a way to change the naming system of razor

I have a partial view that allows Html and the rendered name attribute of the <textarea> is throwing everything off, for instance this is my text area
#Html.TextAreaFor(model => model.cars.mycars)
causes the attribute to render as name="cars.mycars", is there anyway to change that to cars_mycars without using #Name ?
The reason why I want cars_mycars is because it is a field that has AllowHtml in it in the model
[AllowHtml]
public string mycars { get; set; }
In order for AllowHtml to work I would need a strongly typed model such as #Html.TextAreaFor(model => model.mycars) but I am using multiple models in 1 view therefore I have
#Html.TextAreaFor(model => model.cars.mycars, #new{id="cars_mycars",#Name="cars_mycars"})
This is all in a partialview and when I try to submit it nothing happens at all. That is the only field in the form so the issue much lie there and in addition if I put
ValidateInput(False)
on the action method then everything works fine which leads me back to the #name convention not working .
You can try like this
#Html.TextArea("cars_mycars")

How do I display a collection of editable entities in MVC3 and process them on postback to the Action?

I have a collection of entities, called Accounts. A single user will have multiple Accounts and can set percentages for each Account.
The UI will list all the Accounts, the editable field for each Account is the Percentage property. This will be represented by a textbox.
Once the user makes any adjustments, they will post the form back for processing.
I have used MVC in a few other projects and I understand model binding, but I am not sure how to proceed when dealing with a collection of models.
I am not looking for code or for someone to write out the complete answer for me (although, honestly I wouldn't complain....). I am looking for guidance in the direction to take.
Thanks in advance.
Two things:
1) You'll want to use a List/Collection of Account or List/Collection of AccountViewModel in your overarching page view model
So, you would have
public class MyPageViewModel
{
public Collection<Account> AccountList;
//AccountViewModel is what I'd use but for simplicity
//Other properties for view model
}
You now have a view model that contains a list of accounts.
2)
In your view you have two options.
a) Just create a for loop to spit out the HTML you want for each account (not especially pretty)
b) Create an editor template so you don't have to do anything special
Your page would then have this.
#Html.EditorFor(model => model.AccountList)
Here's how editor templates are set up.
This is from a project I'm working on right now. The take away here should be that you add an "EditorTemplates" folder under the view folder that matches what you're working on. By convention, MVC will look in this folder for a template when you use EditorFor. Now you just insert whatever HTML you want in that strongly typed template (which would take an Account or AccountViewModel object) and you'd be done. No need for a for loop in your view to spit out HTML for each account.
Really, that would be it at that point. Your post action would model bind to a type of MyPageViewModel which would have the updated data you wanted
Hope that gets you pointed in the right direction.
Here is an example of how to solve your task
First lets define a model:
public class Account
{
public int Id { get; set; }
public string Number { get; set; }
public decimal Percentage { get; set; }
}
public class UserEditModel
{
public ICollection<Account> Accounts { get; set; }
}
UserEditModel is a view model. It contains property Accounts declared as collection of Account.
I'll describe a table in a view to show accounts and edit their percentages:
<form action="Url.Action("Save")" method="POST">
<table>
<thead>
<tr>
<td>Number</td>
<td>Percentage</td>
</tr>
</thead>
<tbody>
#for (var i = 0; i < Model.Accounts.Count(); i ++)
{
<tr>
<td>
#Html.HiddenFor(m => m.Accounts[i].Id)
#Html.HiddenFor(m => m.Accounts[i].Number)
#Model.Accounts[i].Number
</td>
<td>
#Html.TextBoxFor(m => m.Accounts[i].Id)
</td>
</tr>
}
</tbody>
</table>
</form>
After submitting the form in Accounts property of the view model we'll have changed by user values of percentages.

MVC3 HTML Helper for large Text area

I have an html helper:
#Html.EditorFor(model => model.Description)
But it is too small for the data in that property of my Model. Descriptino is a 1000 character string. I need the user to be able to enter several lines of text and have it wrap in the HTML object. How do I do this?
Try
Html.TextAreaFor(model => model.Description, new {#cols="80" , #rows="4" })
Use:
#Html.TextAreaFor(model => model.Description)
// or a full option-list is:
#Html.TextAreaFor(model => model.Description,
rows, // the rows attribute of textarea for example: 4
columns, // the cols attribute of textarea for example: 40
new { }) // htmlAttributes to add to textarea for example: #class = "my-css-class"
Notice: you can use null instead of new { } for htmlAttributes but it is not recommended! It's strongly recommended that use a blank new { } -that represents a new object-
You can use EditorFor, but in that case it's better to define your own EditorTemplate for rendering your TextArea, using TextAreaFor or whatever it's needed.
The main difference between the TextAreaFor and EditorFor is that, if I've understood well how everything works, when using EditorFor, Templates are taken into account, while when using TextAreaFor you choose the HTML Input used for rendering.
Templates seems interesting, I'm just starting digging into writing my own.
Sounds like you're after Html.TextAreaFor.

how to set CSS attributes of label in MVC 3

I am creating a static using Html.LabelFor(...).
I have to set Name attribute of the label dynamically using JQuery.
You can set the css class, and set inline styles and any other attribute (even non-existant ones like name) using the htmlAttributes parameter provided in one of the overloads of LabelFor
ie
<%: Html.LabelFor(model=>model.Title,
new { style="xyz", #class="abc", #name="MyTitle" }) %>
this would create a label something like:
<label for="Title" style="xyz" class="abc" name="MyTitle">Title</label>
The reason for the # before class, is that "class" is a reserved word in c#, so you need to qualify it using the # symbol.
If I understand your question and comments together, you're just trying to change the text of a label. The MVC LabelFor turns into an HTML <label> and that doesn't have any attributes like a text box does.
If you need to change it with JS/jQuery then give it an ID and use the html method.
Markup:
#Html.LabelFor(m => m.Something, new { id = "somethingLabel" })
#Html.TextBoxFor(m => m.Something)
jQuery:
$("#somethingLabel").html("New Label Text");
You could also use text instead of html - the difference is just that it escapes the input.

ASP.NET MVC 3 - edit items dynamically added to model collection in jquery dialog

I'm new to MVC, so I wasn't sure what the best approach would be here.
I have a view model that contains several collections like this:
public class MainViewModel{
public List<AViewModel> A { get; set; }
public List<BViewModel> B {get; set; }
...}
I'm using Steve Sanderson's approach here to dynamically add items to a collection, and it's working fine as long as the child items are editable on the main view.
The problem I'm having is returning a read only list with an edit link that will open the details to edit in a popup dialog.
Since these items may be newly added, I can't use the ID property to return a partial view from the controller. It seems like I'll have to render the editors in a hidden div like this:
<div class="AEditorRow">
#using (Html.BeginCollectionItem("A"))
{
#Html.DisplayFor(l => l.ID)
#Html.DisplayFor(l => l.Name)
#Html.DisplayFor(l => l.Code)
edit <text>|</text>
delete
<div class="ADetails" style="display: none">
#using (Html.BeginForm("EditA", "Controller"))
{<fieldset>
<legend>Location</legend>
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.Code)
</div>
Does anyone know of a better way to do this?
After working on this issue for a while now I was able to find a walk-through that worked for me.
http://jarrettmeyer.com/post/2995732471/nested-collection-models-in-asp-net-mvc-3
I think this is the most applicable technique for accomplishing dynamically added nested collection objects for MVC3. Most of the other suggestions I've found were meant for MVC2 or MVC1, and it seems that every iteration of MVC the best way to accomplish this changes slightly.
Hopefully this works for you.
I have the same question. Now looking for solution.
Seems like this resources can help:
http://www.joe-stevens.com/2011/06/06/editing-and-binding-nested-lists-with-asp-net-mvc-2/
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
Model binding nested collections in ASP.NET MVC

Resources