Problem with dropdown in Razor - asp.net-mvc-3

I have 2 table in db: MixedType(id and name) and Block(id, name, idMixedType).
I want to make strongly-typed view for Block (Create view).
Controller is following:
public ActionResult Create()
{
return View();
}
Block() is a partial class (I use Entity Framework + POCO).
I have no problem with text fields, it works fine:
<div class="editor-label">
#Html.LabelFor(model => model.name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.name)
#Html.ValidationMessageFor(model => model.name)
</div>
But I want to make dropdown for idMixedType field with values from MixedType table.
I tried to do it in following way (according to this answer Create a Dropdown List for MVC3 using Entity Framework (.edmx Model) & Razor Views && Insert A Database Record to Multiple Tables):
<div class="editor-label">
#Html.LabelFor(model => model.idMixedType)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.idMixedType, new SelectList(Model.MixedType, "id", "name"))
#Html.ValidationMessageFor(model => model.idMixedType)
</div>
But I have a error
The best overloaded method match for 'System.Web.Mvc.SelectList.SelectList(System.Collections.IEnumerable, string, string)' has some invalid arguments
What is wrong?

You're passing in Model.MixedType to the SelectList constructor. Presumably Model.MixedType is not IEnumerable.
Is it possible it should be a lowercase "m" (model.MixedType)?
If not, you need to review the static MixedType property and make sure it is a collection that implements IEnumerable (and that the objects it enumerates have "id" and "name" properties, but I presume that's the case).

Related

Kendo Grid - Customize Edit Popup

I'm using Kendo Grid with several columns which are used for overview row data. When users click Add/Edit buttons, the popup will be shown with some additional data which includes some checkboxes.
I have a problem when binding the checkboxes with the current MVVM model because, when adding a new row, Kendo treats the model as a variable, not an array. This causes many checkboxes to be checked when one is checked(clicked). After taking a look at Kendo MVVM, I intended to get the MVVM model of current popup in order to manipulate some data but was not successful. Therefore I would look for the help in:
Getting the current MVVM model of the popup (So that I can edit the model)
Any recommendation in binding many checkboxes when clicking the Add button(there is no initial data).
you need to write a template for this
then write this to the grid
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("myTemplate"))
this is a sample template:
#model teknik.Models.Magaza_Viewmodel
#Html.HiddenFor(model => model.ID)
<div class="editor-label">
#Html.LabelFor(model => model.ADI)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ADI)
#Html.ValidationMessageFor(model => model.ADI)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ADRES)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ADRES)
#Html.ValidationMessageFor(model => model.ADRES)
</div>

Reduce repetition in Asp.net MVC Razor views

I am creating LOB business application using ASP.NET MVC. In my views I find this pattern repeated a lot:
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
It must be possible to write a helper to reduce it down to something like this:
#EditorForField(model => model.Name)
This will make the views simpler, and make it easier to change the form layout to table based layout (if required)
Any ideas how to make such a helper method?
Thanks!
I was able to make this work by this code:
public static class HelperExtensions
{
public static MvcHtmlString EditorForField<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression)
{
const string template = #"<div class=""editor-label"">{0}</div><div class=""editor-field"">{1}{2}</div>";
string markup = string.Format(template,
html.LabelFor(expression),
html.EditorFor(expression),
html.ValidationMessageFor(expression));
return new MvcHtmlString(markup);
}
}
In your View:
#Html.EditorForField(model => model.Name)

ASP.NET MVC 3 Partial View Template

To be honest, I have no idea what to call this or how to start to search it.
I have a display page with a standard layout.
<div>
<label for="field">Field Name:</label>
#Model.Field
</div>
While trying to make this more change friendly, I want to make a template instead of typing out each field with the above code.
I created a partial view with the following:
#model System.Object
<div>
#Html.LabelFor(m => m)
#Html.DisplayFor(m => m)
</div>
On my view, I added the following:
#Html.Partial("_BillField", Model.Field)
The model then has a description with like:
public ModelName {
[Display(Name="Field Description")]
public decimal Field { get; set; }
}
This works when on the main view, but the label is missing when using the template. What am I missing?
Update: Per #K. Bob I make the change to the partial view:
<div>
#Html.LabelFor(m => m)
#Html.DisplayFor(m => m)
</div>
Update 2: For clarity of what I want.
In the end, I want to be able to do:
#Html.Partial("_BillField", Model.Field1)
#Html.Partial("_BillField", Model.Field2)
#Html.Partial("_BillField", Model.Field3)
And have the equivalent of:
<div>
<label for="field1">Field 1 Name:</label>
#Model.Field1
</div>
<div>
<label for="field2">Field 2 Name:</label>
#Model.Field2
</div>
<div>
<label for="field3">Field 3 Name:</label>
#Model.Field3
</div>
Sorry for not making that clearer.
The partial doesn't need told what the #model is, it'll use the parent #model, if you take out the #model in the partial does that help?
If I have this as the view....
#model MyApp.Models.ModelName
#{
ViewBag.Title = "Test";
}
<h2>Test</h2>
<div>
<div class="editor-label">
#Html.LabelFor(m => m.Field)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Field)
#Html.ValidationMessageFor(m => m.Field)
</div>
</div>
#Html.Partial("_partial", Model) #*note I pass the whole model*#
And this as the partial....
#model MyApp.Models.ModelName
<div>
<div class="editor-label">
#Html.LabelFor(m => m.Field)
</div>
<div class="editor-field">
#Html.TextBoxFor(m => m.Field)
#Html.ValidationMessageFor(m => m.Field)
</div>
</div>
Then it does what I think you want to do (obv. it does it twice but you could remove the code from the main view).
I'm not sure it gives you a huge benefit though. Maybe I've misunderstood something.
I think that potentially you should use Display/Editor templates for types, your model includes 3 fields of that type.
#Html.Partial("_BillField", Model.Field1)
#Html.Partial("_BillField", Model.Field2)
#Html.Partial("_BillField", Model.Field3)
Defining a Template for the type rather than a Partial view is possibly more effective. See ASP.NET MVC 3 - Partial vs Display Template vs Editor Template for a detailed comparison.
In this case your View would look more like:
#Html.DisplayFor(model => model.Field1)
#Html.DisplayFor(model => model.Field2)
#Html.DisplayFor(model => model.Field3)
Your model would be:
public class model
{
[DisplayName("Field1")]
public ComplexType Field1 {get;set;}
[DisplayName("Field2")]
public ComplexType Field2 {get;set;}
[DisplayName("Field3")]
public ComplexType Field3 {get;set;}
}
Or whatever the data annotation is for the display name.
Sounds like you want a DisplayFor(m => m):
http://buildstarted.com/2010/09/10/overriding-displayfor-and-editorfor-to-create-custom-outputs-for-mvc/
Function reference: http://buildstarted.com/2010/09/29/htmlhelper-guide-for-mvc-3-part-2/
You don't need to ToString() your property.
#Html.LabelFor(m => m)
UPDATED
Based on what you want to do, re-use views, take a look at this longer than normal post about reuse of validation and partial views I wrote up to the answer for ASP.NET MVC 3 - Model Validation. It is extremely detailed.
Added a new answer as the other one didn't answer the question once clarified.
This post LabelFor extension should be able to be adjusted to suit your needs I think, but rather than override better to create your own extension.
You'll need to call it slightly differently from how you've proposed because you need to use the m=>m.Field syntax. But I'm sure this should do what you need without having to use a partial view.
If you use Model.Field syntax you will only ever send in the actual value of the Field property, like 1.23 for your decimal, you need to use the m=>m.Field to get more than just the evaluation of the property so that you can change the text in the label.

How to keep model contents across View call

I have a Model that is being used in a view which can edit the model. A foreign key in the model is set before displaying the view, and is not touched in the view. The View shows a drop down for that field if it is zero, or skips the drop down if it is not zero.
#if (Model.RepairOrderId == 0)
{
<div class="editor-label">
#Html.LabelFor(model => model.RepairOrderId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.RepairOrderId, Model.Orders)
#Html.ValidationMessageFor(model => model.RepairOrderId)
</div>
}
else
{
}
When the HTTP POST controller method is called the model contains all the fields that were edited, but the foreign key property that wasn't touched is now empty. What should I put in the else block to keep the non-zero RepairOrderId?
#Html.HiddenFor(model => model.RepairOrderId)
This generates a hidden input in your html, this way the modelbinder will pick up the value and set it in your viewmodel.

How do I use Html.EditorFor() (and others) inside a custom Html Helper?

Basically, I want an Html helper (something like #Html.MyEditor(m => m.Property)) to produce this:
<div class="editor-label">
#html.LabelFor(m => m.Property)
</div>
<div class="editor-field">
#html.EditorFor(m => m.Property)
#html.ValidationMessageFor(m => m.Property)
</div>
Only problem is that I can't seem to access Html.EditorFor() or any of the other extension methods in side my own helper. Example attempt:
#helper Edit(this System.Web.Mvc.HtmlHelper<Spartacus.ViewModels.NewTaskItemModel> html)
{
<div class="editor-label">
#html.LabelFor(m => m.Property)
</div>
<div class="editor-field">
#html.EditorFor(m => m.Property)
#html.ValidationMessageFor(m => m.Property)
</div>
}
I also tried the extension method syntax:
public static string DatePickerFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
{
var sb = new StringBuilder();
sb.AppendLine("<div class=\"editor-label\">");
sb.AppendLine(html.LabelFor(expression));
sb.AppendLine("</div>");
sb.AppendLine("<div class=\"editor-field\">");
sb.AppendLine(html.EditorFor(expression));
sb.AppendLine(html.ValidationMessageFor(expression));
sb.AppendLine("</div>");
return sb.ToString();
}
in both attempts above, the LabelFor, EditorFor, and ValidationMessageFor throw compile errors ("could not be found").
Anyone know of a way to do this? Thanks in advance!
It should work if you have a namespace using for the System.Web.Mvc.Html namespace. The extension methods are defined in this namespace on various static extension classes (e.g. EditorExtensions).

Resources