Changing font colour conditionally in MVC - javascript

I'm new to MVC and still learning the best way to go about things.
My problem is I want to change a font colour conditionally. For example, if something gets deleted. I want the font colour of the item to change to red.
For reference I will add the relevant data to this question below.
VIEW (What I want to be changed to red when deleted)
<div class="well text-center">
<h1><b>Purchase Order #Html.DisplayFor(model => model.OrderID)</b></h1>
</div>
Controller
public ActionResult DeleteConfirmed(int id)
{
PurchaseOrder purchaseOrder = db.PurchaseOrders.Find(id);
purchaseOrder.deleted = !purchaseOrder.deleted;
db.SaveChanges();
db.Entry(purchaseOrder).Reference("Supplier").Load();
if (purchaseOrder.deleted)
{
TempData["message"] = string.Format("Purchase Order - {0} has been deleted\nCompany: {1}\nExpected Date:{2}\nNotes:{3}\n\nLink: {4}/PurchaseOrders/Details/{5}", purchaseOrder.ID, purchaseOrder.Supplier.Company, purchaseOrder.DeliveryDate, purchaseOrder.Details, IGT.baseUrl, purchaseOrder.ID);
}
else
{
TempData["message"] = string.Format("Purchase Order - {0} has been undeleted\nCompany: {1}\nExpected Date:{2}\nNotes:{3}\n\nLink: {4}/PurchaseOrders/Details/{5}", purchaseOrder.ID, purchaseOrder.Supplier.Company, purchaseOrder.DeliveryDate, purchaseOrder.Details, IGT.baseUrl, purchaseOrder.ID);
}
return RedirectToAction("Index");
}
Thanks!

Just keep things simple :)
Put a span around the DisplayFor and use a ternary operator on the deleted property to set a css class that will either turn the text red if deleted or a different color if not.
<div class="well text-center">
<h1>
<b>Purchase Order <span class="#(Model.deleted ? "DeletedCSSClass" : "ActiveCSSClass")"> #Html.DisplayFor(model => model.OrderID)</span></b>
</h1>
</div>

Looks like your using bootstrap so here's one approach.
Create a class representing your colours:
public sealed class TextColour
{
public string CssClass { get; }
private static IDictionary<string, TextColour> _instances = new Dictionary<string, TextColour>();
private TextColour(string cssClass)
{
CssClass = cssClass;
}
private static TextColour GetInstance(string cssClass)
{
if (!_instances.ContainsKey(cssClass))
{
_instances[cssClass] = new TextColour(cssClass);
}
return _instances[cssClass];
}
public static TextColour Primary => GetInstance("text-primary");
public static TextColour Secondary => GetInstance("text-secondary");
// Add others here
}
Add a property to your view model:
public class PurchaseOrderModel
{
public bool Deleted { get; set; }
public TextColour TextColour => Deleted ? TextColour.Primary : TextColour.Secondary;
}
Then in your view:
<div class="well text-center #Model.TextColour.CssClass">
<h1><b>Purchase Order #Html.DisplayFor(model => model.OrderID)</b></h1>
</div>

Related

ASP.NET Core - Updateing Table Row Using Drop-Down List

I have a table containing a list of games. Each row contains a game ID, a drop-down list containing all the versions of the game and a status which currently shows the status of the latest version.
I want to update a single row on the table based on what the version drop-down list value contains which should change the value of the status cell.
This change should also change the ActiveVersion field in the view model.
I think this is achievable by using AJAX, model binding and potentially partial views but I'm unsure on how to do it.
I have attempted to simplify my problem by using versioning of games with strings and integers as data types as an example as I am using complex models and viewmodels in my webapp.
I have an MVC view as follows
#model IEnumerable<GameViewModel>
...
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => #item.Versions.Where(x => x.Version == item.ActiveVersion).FirstOrDefault().Status)
</td>
<td>
<select asp-for="#item.ActiveVersion" asp-items="#item.VersionsList"></select>
</td>
</tr>
}
</tbody>
My view model is as follows
public class GameViewModel
{
public string Id { get; set; }
public List<GameVersion> Versions { get; set; }
public string ActiveVersion { get; set; }
//Constructor - initialises active version to highest version
public GameViewModel(Game game)
{
Id = game.Id;
Versions = game.Versions;
ActiveVersion = game.Versions.Max(x => x.Version).ToString();
}
//Returns a list of all versions to be used in dropdown
public List<SelectListItem> VersionsList
{
get
{
List<SelectListItem> versionList = new List<SelectListItem>();
foreach (GameVersion gv in Versions)
{
versionList.Add(new SelectListItem { Value = gv.Version.ToString(), Text = gv.Version.ToString() });
}
return versionList;
}
}
}
My models are as follows
public class GameVersion
{
public int Version { get; set; }
public string Status { get; set; }
}
public class Game
{
public string Id { get; set; }
public List<GameVersion> Versions { get; set; }
}
I am using ASP.NET Core 3.1 to develop a MVC webapp.
You can use jQuery to control the implementation of the drop-down list to dynamically update the value of the state, according to the model you provide.
Here is a working demo like below:
Model:
public class GameVersion
{
public int Version { get; set; }
public string Status { get; set; }
}
public class Game
{
public string Id { get; set; }
public List<GameVersion> Versions { get; set; }
}
public class GameViewModel
{
public string Id { get; set; }
public List<GameVersion> Versions { get; set; }
public string ActiveVersion { get; set; }
//Constructor - initialises active version to highest version
public GameViewModel(Game game)
{
Id = game.Id;
Versions = game.Versions;
ActiveVersion = game.Versions.Max(x => x.Version).ToString();
}
//Returns a list of all versions to be used in dropdown
public List<SelectListItem> VersionsList
{
get
{
List<SelectListItem> versionList = new List<SelectListItem>();
foreach (GameVersion gv in Versions)
{
versionList.Add(new SelectListItem { Value = gv.Version.ToString(), Text = gv.Version.ToString() });
}
return versionList;
}
}
}
View(Index.cshtml):
#model IEnumerable<GameViewModel>
<table>
<tbody>
#foreach (var item in Model)
{
<tr id="#item.Id">
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
<span>
#*change this line*#
#Html.DisplayFor(modelItem => #item.Versions.Where(x => x.Version.ToString() == item.ActiveVersion).FirstOrDefault().Status)
</span>
</td>
<td>
<select class="activeVersion_#item.Id" asp-for="#item.ActiveVersion" asp-items="#item.VersionsList"></select>
</td>
</tr>
}
</tbody>
</table>
#section Scripts{
<script>
$(function () {
var gameModel =#Json.Serialize(Model);
$('*[class^="activeVersion"]').change(function () {
var vers = $(this).find('option:selected').val()
console.log(vers)
var stat = $(this).parent().prev().find('span');
stat.empty();
var nodeid = $(this).attr('class').split('_')[1]
$.each(gameModel, function (index, game) {
if (nodeid == game['id']) {
console.log(game['versions'])
$.each(game['versions'], function (indx, version) {
if (vers == version['version'])
stat.text(version['status'])
})
}
})
})
})
</script>
}
Controller(For easy testing,I set the value manually):
public IActionResult Index()
{
var games = new Game
{
Id = "game",
Versions = new List<GameVersion> {
new GameVersion{ Version=1,Status="Status1"},
new GameVersion{ Version=2,Status="Status2"},
new GameVersion{ Version=3,Status="Status3"},
},
};
var games2 = new Game
{
Id = "game2",
Versions = new List<GameVersion> {
new GameVersion{ Version=4,Status="Status4"},
new GameVersion{ Version=5,Status="Status5"},
new GameVersion{ Version=6,Status="Status6"},
},
};
var gameviewModels = new List<GameViewModel> {
new GameViewModel(games),
new GameViewModel(games2)
};
return View(gameviewModels);
}
Result:
There are a number of ways to achieve this.
A simple one that doe snot require Ajax is to wrap each select within a form tag which posts to an action that takes an ID and VERSION. Within this form add a hidden field for the ID.
Add an OnChange event to the select and use javascript to post back the form.
At the action, perform your update and redirect back to your index action that displays the list
If you want to use ajax then create a javascript method passes your select control as a parameter instead of posting back. From this parameter you can get the select value. You can get the previous control (the hidden ID input) to get that value then pass these back to your action.
Your action can pass back a JSON result of OK or an error or even the table cell html. Assuming success, either with HTML passed back by the action (you can use a partial view which replaces the original table cell content) or already knowing having the correct select action already displayed then you are done. If there is an error you have to decide to show that message and whether to put the select back to the original value

How to create a custom validation attribute with parameters consisting of model properties

I am currently trying to make a site on asp.net core. When i press the submit button, i want all the validation messages to come up if there is incorrect input.
For now, i have the name and the phone number validation messages working using 'asp-validation-for=Client.Name' and Client.ContactNumber. Now i want to be able to validate from the server side if the user has checked at least one of the boxes off, or filled in the 'Other' field. So i tried to see if i can make a custom attribute which would validate it but havent gotten any luck. I have tried sending in the properties of the Client class but it throws an error saying "An object reference is required for the non-static field, method, or property 'Client.'". I have also tried the top solution here CS0120: An object reference is required for the nonstatic field, method, or property 'foo' , but I think in my case those solutions are not possible.
My code for the files that i am working with are below
Code for Client.cs (model class)
public class Client
{
//some attributes
[Required]
public string Name { get; set; }
[Required]
[DisplayName("Bookkeeping")]
public bool Bookkeeping { get; set; }
[Required]
[DisplayName("Personal Income Taxation")]
public bool Personal_Income_Taxation { get; set; }
[Required]
[DisplayName("Self-Employed Business Taxes")]
public bool Self_Employed_Business_Taxes { get; set; }
[Required]
[DisplayName("GST/PST/WCB Returns")]
public bool GST_PST_WCB_Returns { get; set; }
[Required]
[DisplayName("Tax Returns")]
public bool Tax_Returns { get; set; }
[Required]
[DisplayName("Payroll Services")]
public bool Payroll_Services { get; set; }
[Required]
[DisplayName("Previous Year Filings")]
public bool Previous_Year_Filings { get; set; }
[Required]
[DisplayName("Govt. Requisite Form Applicaitons")]
public bool Government_Requisite_Form_Applications { get; set; }
public string Other { get; set; }
[CheckboxAndOtherValidation(bookkeeping: Bookkeeping,
personal_Income_Taxation: Personal_Income_Taxation,
self_Employed_Business_Taxes: Self_Employed_Business_Taxes,
gST_PST_WCB_Returns: GST_PST_WCB_Returns,
tax_Returns: Tax_Returns,
payroll_Services: Payroll_Services,
previous_Year_Filings: Previous_Year_Filings,
government_Requisite_Form_Applications: Government_Requisite_Form_Applications,
other: Other)]
public bool AreCheckboxesAndOtherValid { get; set; }
FreeConsultation.cshtml (view page)
<div class="container" style="padding:30px;">
<br />
<h1 class="text-info">Create New Client</h1><br />
<form method="post">
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<div class="form-group row">
<div class="col-3">
<label asp-for="Client.Name"></label>
</div>
<div class="col-6">
<input type="text" asp-for="Client.Name" class="form-control" />
</div>
<span class="text-danger col-3" asp-validation-for="Client.Name"></span>
</div>
<!-- More code -->
My utility class i created for custom validation attribute - CheckboxAndOtherValidation.cs
public class CheckboxAndOtherValidation : ValidationAttribute
{
private readonly bool Bookkeeping;
private readonly bool Personal_Income_Taxation;
private readonly bool Self_Employed_Business_Taxes;
private readonly bool GST_PST_WCB_Returns;
private readonly bool Tax_Returns;
private readonly bool Payroll_Services;
private readonly bool Previous_Year_Filings;
private readonly bool Government_Requisite_Form_Applications;
private readonly string Other;
public CheckboxAndOtherValidation(bool bookkeeping,
bool personal_Income_Taxation,
bool self_Employed_Business_Taxes,
bool gST_PST_WCB_Returns,
bool tax_Returns,
bool payroll_Services,
bool previous_Year_Filings,
bool government_Requisite_Form_Applications,
string other)
{
this.Bookkeeping = bookkeeping;
this.Personal_Income_Taxation = personal_Income_Taxation;
this.Self_Employed_Business_Taxes = self_Employed_Business_Taxes;
this.GST_PST_WCB_Returns= gST_PST_WCB_Returns;
this.Tax_Returns = tax_Returns;
this.Payroll_Services = payroll_Services;
this.Previous_Year_Filings = previous_Year_Filings;
this.Government_Requisite_Form_Applications = government_Requisite_Form_Applications;
this.Other = other;
}
public override bool IsValid(object value)
{
return base.IsValid(value);
}
}
Is there any other way to tackle this? (Preferably with custom attribute). First time posting a question so pardon me if there is anything missing. Thanks
EDIT
I was able to make the checkbox error come from the server side with the help of a solution, but i still have the issue that when i press the submit button, the checkbox error doesn't come at the same time as the other two. By following a tutorial, i was able to show the other two errors from the client side by including this piece of code in my view which comes with the creation of an asp.net core project
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
_ValidationScriptsPartial.cshtml
<environment include="Development">
<script src="~/Identity/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"
asp-fallback-src="~/Identity/lib/jquery-validation/dist/jquery.validate.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator"
crossorigin="anonymous"
integrity="SOME INFO">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js"
asp-fallback-src="~/Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
crossorigin="anonymous"
integrity="SOME INFO">
</script>
</environment>
Some references are here
Article custom-data-annotation-validation-in-mvc
Source code of CompareAttribute.cs and ComparePropertyAttribute.cs
3rd-party ExpressiveAnnotations
So in a similar way, a custom ValidationAttribute can use reflection to get runtime value by its property name (the name from declaration or argument) to see if the property have the required value or format you need.
public class CheckboxAndOtherValidation : ValidationAttribute
{
readonly object TRUE = true;
string[] _alltheOtherProperty;
public CheckboxAndOtherValidation(params string[] alltheOthersProperty)
{
_alltheOtherProperty = alltheOthersProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (_alltheOtherProperty?.Count() > 0 != true)
{
return ValidationResult.Success;
}
var otherPropertyInfo = validationContext.ObjectType.GetProperty(nameof(Client.Other));
if (otherPropertyInfo != null)
{
object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue != null && !string.IsNullOrEmpty(otherPropertyValue.ToString()))
{
return ValidationResult.Success;
}
}
for (var i = 0; i < _alltheOtherProperty.Length; ++i)
{
var prop = _alltheOtherProperty[i];
var propertyInfo = validationContext.ObjectType.GetProperty(prop);
if (propertyInfo == null)
{
continue;
}
object propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
if (Equals(TRUE, propertyValue))
{
return ValidationResult.Success;
}
}
return new ValidationResult("Must exist at least one field is true", _alltheOtherProperty);
}
}
Cus I choose passing property name array list as argument, now class Client could have a simplified and clearer usage like this,
public class Client
{
[CheckboxAndOtherValidation(nameof(Bookkeeping),
nameof(Personal_Income_Taxation),
nameof(Self_Employed_Business_Taxes),
nameof(GST_PST_WCB_Returns),
nameof(Tax_Returns),
nameof(Payroll_Services),
nameof(Previous_Year_Filings),
nameof(Government_Requisite_Form_Applications))]
public bool AreCheckboxesAndOtherValid { get; set; }
}

RadioButtonFor in mvc shows required validation even though not applied required validation

I have one view in which I put two radio button for attribute in my model
I just put data annotation for other field but not the radiobutonfor field but steel it show required validation.Below is my code.I the attribute is int type in model.I used javascript unobtrusive library inn view as well.
<td>
<label>#Html.RadioButtonFor(m => m.OneToOne, 1) Hours </label>
<label>#Html.RadioButtonFor(m => m.OneToOne, 2) Unit </label>
</td>
I am using Html.begin from to post this value.
The RadioButtonFor helper method generates html markup for the radio button input with data-val-required attribute unless you specify the property as nullable type! The jQuery validate plugin does validation on this input because of the existence of this attribute.
If you do not want client side validation on this input, You should change the property type from int to nullable int(int?).
public class YourViewModel
{
// Other properties
public int? OneToOne { set; get; }
}
If radio buttons are not required to select, I personally like to use mutually exclusive checkboxes.
Mainly, if a user accidental selects a radio button, s/he won't be able to uncheck it back unless the user refreshes the entire page. I feel like it is really annoying.
Sample at jsfiddle.net
Model
public class ViewModel
{
public bool OneToOneHours { get; set; }
public bool OneToOneUnit { get; set; }
}
View
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post))
{
<div class="form-control">
#Html.CheckBoxFor(model => model.OneToOneHours, new {#class = "mutually-exclusive"}) Hours
#Html.CheckBoxFor(model => model.OneToOneUnit, new {#class = "mutually-exclusive"}) Unit
</div>
<button id="btnSubmit" type="submit">Submit</button>
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$('input.mutually-exclusive').click(function () {
var checkedState = $(this).val();;
$('input.mutually-exclusive').attr("checked", false);
$(this).prop("checked", checkedState);
});
</script>
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(ViewModel model)
{
int? oneToOne;
if (model.OneToOneHours)
oneToOne = 1;
else if (model.OneToOneUnit)
oneToOne = 2;
return View(model);
}
}

How to clear textboxes besides using JS

I am building an app using MVC, and this question pertains to the Create page and action.
Lets say my model has 2 decimal properties along with other properties but aren't necessary for this example:
public class TestClass
{
public int ID { get; set; }
public decimal DecimalProperty { get; set; }
public decimal SecondDecimalProperty { get; set; }
// more properties below this, but deemed unnecessary for this question
}
Obviously these properties are non-nullable, so in my Create View they appear as so on page load (ignore the 2nd textbox):
Now my goal is to clear those textboxes out, so they are just blank.. so I used JS to achieve that by doing:
$(".clear-textbox").val("");
I put a class called clear-textbox on those input fields.. works perfectly.. but now in my HttpPost Create Action I have conditional statements checking to see if other fields are valid, and if not return the object.. like so:
if (object.property== 0)
{
ModelState.AddModelError("property", "This field is required!");
return View(object);
}
This results in the Create view to be redisplayed with the values that the user has already entered, along with an error message below the one property that needs to be changed.. and this is where the problem lies. Once the Create view is reloaded.. then so are the scripts for clear-textbox, resulting in DecimalProperty and SecondDecimalProperty to be empty text-boxes.. instead of keeping what the user originally entered for them.
So my question, is there another way to clear out textboxes for decimal properties other than using javascript?
Any help is appreciated.
UPDATE
Here is the cshtml.
<div class="form-group">
#Html.LabelFor(model => model.DecimalProperty, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.DecimalProperty, new { htmlAttributes = new { #class = "form-control clear-textbox" } })
#Html.ValidationMessageFor(model => model.DecimalProperty, "", new { #class = "text-danger" })
</div>
</div>
Either you have to do it via Javascript on load like following
$(".clear-textbox").each(function(){
if($(this).val() <= 0 )
$(this).val("");
});
OR
You can create your own MVC Html Helper which will do things as you need for your special needs. Let me know if you want code for that...
You can also refer this link
You can set the default value as a data- attribute of the textbox and clear it only if they match. Like:
$(".clear-textbox").each(function(){
var $this = $(this);
if( $this.val() == $this.data().defaultvalue ) $this.val('');
});
It's hard to come up with an answer without knowing how the text boxes are being rendered. However, I'm assuming you are using something like
#Html.TextBoxFor
or
#Html.EditorFor
There are two ways to do this.
1. Add a DisplayFormat attribute to the model fields and use EditorFor:
public class TestClass
{
public int ID { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:#.#}")]
public decimal DecimalProperty { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:#.#}")]
public decimal SecondDecimalProperty { get; set; }
}
#Html.EditorFor(model => model.DecimalProperty)
2. Use the inline format attribute:
#Html.TextBoxFor(model => model.DecimalProperty, "{0:#.#}")

MVC 5 Razor view template binding hide script to a model radiobutton

Currently have a custom EditorTemplate which dynamically populates based on the incomming Model () in the Razor page.
The aim is to be able to hide the individual div 'Sub_Text' in the editor template based on the radio value.
Model: Prime.cs
public class Prime{
public List<QuestionModel> Questions { get; set; }
}
Model: QuestionModel.cs
public class QuestionModel{
public int Id { get; set; }
public string Question { get; set; }
public string Answer { get; set; }
public string SubText { get; set; }
}
Main View: _Reporting.cshtml
#model ViewModels.Prime
#for (int i = 0; i < Model.Questions.Count(); i++) //Dynamically generate and model bind database PolicyHolderKeyQuestions
{
#Html.EditorFor(x => x.Questions[i], "QuestionModel")
}
EditorTemplate: QuestionModel.cshtml
#model ViewModels.QuestionModel
#{
<div class="col-lg-2">
#Html.RadioButtonFor(Model => Model.Answer, YesNoNAOptions.Yes)
#Html.RadioButtonFor(Model => Model.Answer, YesNoNAOptions.No)
#Html.RadioButtonFor(Model => Model.Answer, YesNoNAOptions.NA)
</div>
<div class="col-lg-9">
<div class="row">
<p>
<strong>#Model.Question</strong>
</p>
</div>
<div class="row" name="**Sub_Text**"> #* **Hide Me!** *#
#Model.SubText
</div>
</div>
}
So far the closest idea I have found is to add a script something like this to the bottom of the template:
<script type="text/javascript">
$(':radio[name=Answer').change(function () {
// read the value of the selected radio
var value = $(this).val();
var doc
if (value == 1) {
$('#Sub_Text').show();
}else{
$('#Sub_Text').hide();
}
});
</script>
Which seems to be able to work for something simpler without using #Html.EditorFor() in a loop.
It looks as if the script does not follow the same automatic naming changes as those that happen to the RadioButtonFor elements. Resulting in things like this:
Radio:
<input id="Questions_0__Answer" name="Questions[0].Answer" type="radio" value="No" />
While the divs and scripts keep referencing only what was directly entered.
How can you dynamically hide the "Sub_Text" div based on the radiobutton when it is nested in this way?
If there is a way to do this without feeding in a script per EditorFor radio group that would be even better, but all solutions are welcome.
Wrap the html generated by the EditorTemplate in a container so that you can use relative selectors
#model ViewModels.QuestionModel
<div class="question"> // container
<div class="col-lg-2">
#Html.RadioButtonFor(Model => Model.Answer, YesNoNAOptions.Yes)
....
</div>
<div class="col-lg-9">
....
<div class="row">#Model.SubText</div>
</div>
</div>
and then the script can be
$(':radio').change(function () {
// get the associated element containing the SubText value
var row = $(this).closest('.question').find('.row');
if ($(this).val() == 1) {
row.show();
} else {
row.hide();
}
});
Side note: If your QuestionModel.cshtml is in the /Views/Shared/EditorTemplates or /Views/yourControllerName/EditorTemplates folder (which it should be) then the code in _Reporting.cshtml should be just
#model ViewModels.Prime
#Html.EditorFor(x => x.Questions)
No loop is required. The EditorFor() accepts IEnumerable<T> and generates the correct html for each item in the collection.

Categories

Resources