Counter in EditorTemplates ASP.NET MVC - asp.net-mvc

I would like to display an incremental value in editor template.
My Razor View-
#model List<Target>
<form>
#Html.EditorForModel()
<input type="submit">
</form>
My Editor Template -
#model Target
<div>
<p>SL No.: ?? </p>
#Html.TextBoxFor(m => m.Quantity)
</div>
My question is how can I increment a variable i.e. counter here?

Related

how to create an editable partial view in ASP.NET MVC

I'm currently trying to create an edit view that consists of some user profile details and a list of roles that the user is assigned to. I thought that I could create an editable parent view that would contain all of the user profile textboxes and insert a partial view that would hold checkboxes for all of the roles.
However, I have found that when I try to update the textboxes in the partial view, those changes are not reflected in the parent model. Apparently, the partial view gets its own ViewData dictionary that is isolated from the parent's.
I was wondering if anyone had a solution that would allow me to pass changes made to a checkbox in a partial view back to the model of the parent. I have included some sample code below. Here is the parent view:
#model MvcWebsite.ViewModels.UserProfileEditViewModel
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>UserProfile</legend>
#Html.HiddenFor(model => model.UserId)
<div class="editor-label">
#Html.LabelFor(model => model.UserName)
</div>
... other properties of the user profile omitted for brevity
<div class="editor-field">
#Html.Partial("RoleCheckBoxEditTable", Model.Roles)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
We then have the child partial view:
#model List<MvcWebsite.ViewModels.RoleViewModel>
<table>
<tr>
#{
int count = 0;
foreach (var roleViewModel in Model)
{
if(count++ % 3 == 0)
{
#: </tr> <tr>
}
<td>
#Html.HiddenFor(r => roleViewModel.RoleName)
#Html.HiddenFor(r => roleViewModel.RoleId)
#Html.CheckBoxFor(r => roleViewModel.Assigned)
</td>
<td>
#Html.LabelFor(r => roleViewModel.Assigned, roleViewModel.RoleName)
</td>
}
}
</tr>
</table>
What I would like is to find a way to make both of these views update the same model, which could then be sent to the controller. Any help would be greatly appreciated.
I got around this problem by eliminating Partial Views entirely and replacing them with Display and Editor Templates.
Take the stuff from your View for that list of RoleViewModel, and create a new View under Views/Shared/EditorTemplates with the name RoleViewModel.cshtml (you might have to create the EditorTemplates directory first if you've never used it before).
On your top-level view, change Partial to EditorFor like this: #Html.EditorFor(model => model.Roles)
This approach works for me, and it preserves the baked in validation that I get by using the IValidatable interface on my Models.

ASP.NET MVC Checkbox with Textboxes

i have written this code in one of the view using ASP.NET MVC. MVC returns me the checkboxes values (only those are checked) and with textboxes it returns me all (0,1,2 etc). how can i co-relate which textbox value belongs to which checkbox (since only i get the checked checkbox values)
For Each item As InternalMailCalendarViewModel In ViewData("InternalMailCalendar")
End Code
<div class="editor-field">
#Html.CheckBox("InternalMailCalendarID", New With {.value = item.ID})
<label for="#item.ID">#item.Days</label>
</div>
<div class="editor-field">
<input type="text" id="RunsPerDay" name="RunsPerDay" placeholder="Runs Per Day" />
#Html.ValidationMessageFor(Function(model) model.RunsPerDay)
</div>
#*
<div class="editor-field">
<input type="checkbox" id="InternalMailCalendarID" name="InternalMailCalendarID" value="#item.ID" />
<label for="#item.ID">#item.Days</label>
</div>
<div class="editor-field">
<input type="text" id="RunsPerDay" name="RunsPerDay" placeholder="Runs Per Day" />
#Html.ValidationMessageFor(Function(model) model.RunsPerDay)
</div>
*#
#Code
Next
End Code
According to my understanding of your code and problem, I suggest you following solution:
Just assign hmtl "Name" property to textbox uniquely and that unique name assign to checkbox as a value. So that you can co-relate textbox with checkbox.

Html.BeginForm() does not submit if nothing is selected in a Html.Dropdownlist() helper with optional label

#using (Html.BeginForm("Boxing", "Company",FormMethod.Post))
{
<div class="box">
<div>
<div class="left">
<div class="topLabel">
Id No:</div>
<div class="input_text_65">
#Html.TextBoxFor(m => m.Id)
</div>
<div class="botLabel">
percentt:
</div>
<div>
<input type="text" style="width: 50px" name="percent" />%
</div>
</div>
<div class="lastDetailField">
<div class="topLabel">
D/C:
</div>
<div class="select_110">
#Html.DropDownListFor(m => m.cType, new SelectList((IEnumerable<Model.cType>)ViewData[ViewDataKeys.cTypes]), "----")
</div>
<div class="margin_top_45">
<input id="submit" type="submit" value="submit" />
</div>
</div>
</div>
</div>
}
If I didn't select any option in the dropdownlist (leaving the optionlabel "----" selected) and I press the submit button, the form will not be posted and the focus will be move to the dropdownlist
if I remove the optional Label, like this:
#Html.DropDownListFor(m => m.cType, new SelectList((IEnumerable)ViewData[ViewDataKeys.cTypes]))
then it will work just fine. I'm thinking if I will put an optional label, does that mean I am required to choose an item? I want the form to be submitted even if I leave the dropdownlist with the optionallabel selected.
thanks in advance!
Do you have a required attribute in your model/viewmoden on cType? I think the clientside validation is kicking in, but because you didn't set a validation helper, you're not seeing the message. The form won't submit though if you select the optional label.

Cannot get Editor Templates working in MVC3

I am converting a MVC2 app to MVC3.
I cannot seem to join up a View with an Editor Template.
So in my View the code is;
#model IEnumerable<ITOF.Models.LatestContractNumber>
#{
ViewBag.Title = "EditContractNumbers";
Layout = "~/Views/Shared/_Layout.cshtml";
}
using (Html.BeginForm())
{
<fieldset>
<legend>Edit Latest Contract Numbers</legend>
<div style="width:90%">
<div style="width:45%; float:left; vertical-align:top;">
<p>A contract number is in a format: AA/B999</p>
<p>Where AA is a 2 character code for the division, for example CD.</p>
<p>Where B is a letter for the contract, usually the first letter of the contract title.</p>
<p>999 is a 3 digit number.</p>
<p>The 999 number depends on the B letter. </p>
<p>Initially all the numbers start as 1 and are incremented each time the B letter is used.</p>
<p>This pages sets the initial 999 number for each B letter.</p>
<p>Once the application is up and running, this page should be used initially and then no more.</p>
#if (TempData["Message"] != null && TempData["Message"].ToString().Trim().Length > 0)
{
<p class="success">#TempData["Message"].ToString()</p>
}
</div>
<div style="width:45%; float:right; vertical-align:top;">
<div>
<table>
<tr>
<td>Letter</td>
<td>Number</td>
</tr>
#Html.EditorForModel(Model)
</table>
</div>
<div style="padding-top:20px">
<input type="submit" value="Submit Changes" />
</div>
</div>
</div>
</fieldset>
}
And my Editor Template is in the correct folder and now looks like;
#model ITOF.Models.LatestContractNumber
<tr>
<td>
#Html.HiddenFor(model => model.LatestContractNumberId)
#Html.DisplayFor(model => model.Letter)
</td>
<td>
#Html.TextBoxFor(model => model.Number, new { style = "width:30px" })
</td>
</tr>
The Model in #Html.EditorForModel(Model) relates to #model IEnumerable at the top of the page.
In the Editor Template, this should translate to a loop of ITOF.Models.LatestContractNumber, hence at the top of the template I have put #model ITOF.Models.LatestContractNumber
First, you are calling EditorForModel with a model of type IEnumerable<ITOF.Models.LatestContractNumber> (which is the Model for your View) but you should be calling it with ITOF.Models.LatestContractNumber (which is the Model your template expects to see/get). You need a foreach somewhere in there
foreach(ITOF.Models.LatestContractNumber number in Model) {
#Html.EditorForModel(number)
}
Second, not 100% sure, but EditorTemplates should be in Shared folder under the Views folder. So ~/Views/Shared/EditorTemplates/ and should be named after the class name so LatestContractNumber.cshtml.
HTH
The question turned out to be a red herring. The real problem was that having migrated to MVC and started prefixing partial views with _, the name of the Editor Template was invalid.
Thanks to Russ Cam for asking the right questions that got me the answer.

How to render an HTML attribute from a Razor view

I would like to use the same partial view for create, edit, and details views, to avoid duplicating the fieldset structure for an entity. Then, depending on which view renders the partial view, I would like to add a class of "read-only" to a div surrounding my fieldset and handle making the actual input fields read-only on the client, using css or jQuery, or whatever. How can I specify from my Razor view that I need this class added to the "item-details" div?
<div class="item-details">
<fieldset>
<legend>Product Details</legend>
#Html.HiddenFor(model => model.DetailItem.ProductId)
<div class="editor-label">
#Html.LabelFor(model => model.DetailItem.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.DetailItem.Name)
#Html.ValidationMessageFor(model => model.DetailItem.Name)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
</div>
I would generally have a variable on the model that would indicate if your data is editable, and use it like:
<div class="item-details #(Model.IsReadOnly ? "read-only" : "")">
If you don't have it on the model however, you can use the ViewBag. In your parent view:
#{
ViewBag.IsModelReadOnly = true;
}
In your partial view:
<div class="item-details #(ViewBag.IsModelReadOnly ? "read-only" : "")">
Your html output for a readonly view would be
<div class="item-details read-only">
You can then access the div via jQuery and do what you need: $(".read-only")...
Why not just use
#Html.DisplayFor(model => model.[whatEver Property you are trying to show])

Resources