I am trying to figure out the best way to present/save the data in a view I am creating.
I am not wedded to the underlying table structure, and have played around with it trying to get the best outcome but no luck.
Effectively I have multiple textbox's that need to be saved back to the database, but due to the view layout (and it really needs to stay in this layout), I need to populate additional columns with hard coded info.
In my view I have just repeated the textbox ( I tried to index it, but got an error saying it wasn't possible on decimal data types?)
Below is my model
namespace Testing.Models
{
public partial class OnFarm
{
public int Id { get; set; }
public Guid? Tracker { get; set; }
public int Year { get; set; }
public decimal? Period1 { get; set; }
public decimal? Period2 { get; set; }
public decimal? Period3 { get; set; }
public decimal? Period4 { get; set; }
public decimal? Period5 { get; set; }
public decimal? Period6 { get; set; }
public decimal? Period7 { get; set; }
public decimal? Period8 { get; set; }
public decimal? Period9 { get; set; }
public decimal? Period10 { get; set; }
public decimal? Period11 { get; set; }
public decimal? Period12 { get; set; }
public int Version { get; set; }
public int Account { get; set; }
public int MvtType { get; set; }
public virtual Account AccountNavigation { get; set; }
public virtual MovementType MvtTypeNavigation { get; set; }
public virtual ProductionModule TrackerNavigation { get; set; }
public virtual Version VersionNavigation { get; set; }
public virtual Years YearNavigation { get; set; }
}
}
This is my controller as it stands currently
public IActionResult Create(Guid? id)
{
var query = _context.LegalEntities.FromSqlRaw("Select DISTINCT B.* From Client.Groups a Left join Client.[Legal Entities] b on b.Parent = a.ID left join client.Enterprises c on c.Parent = b.ID left join client.[Production Module] d on d.Parent = c.ID left join OnFarm.[On Farm] e on e.Tracker = d.ID Where e.id IS NOT NULL AND a.id = {0}", id).ToList();
List<SelectListItem> LEList = new List<SelectListItem>();
foreach (var m in query)
{
LEList.Add(new SelectListItem { Text = m.Name, Value = m.Id.ToString() });
}
ViewBag.LE = LEList;
var acclist = _context.Accounts.Where(x => x.AccountCatId == 92100).ToList().OrderBy(x => x.Description);
List<SelectListItem> listac = new List<SelectListItem>();
listac.Add(new SelectListItem { Text = "--Select Livestock Type--", Value = "0" });
if (acclist != null)
{
var i = 1;
foreach (var x in acclist)
{
listac.Add(new SelectListItem { Text = x.Description, Value = x.Number.ToString() });
i += 1;
}
}
ViewBag.Account = listac;
ViewData["MvtType"] = new SelectList(_context.MovementTypes, "Id", "Type");
ViewData["Tracker"] = new SelectList(_context.ProductionModules, "Id", "Name");
ViewData["Version"] = new SelectList(_context.Versions, "VersionId", "VersionName");
ViewData["Year"] = new SelectList(_context.Year, "Id", "Year");
return View();
}
Here is my view
<div class="row">
#foreach (var item in ViewBag.LE)
{
<div class="panel panel-default rounded shadow col-11">
<div class="panel-heading border-bottom">
<div class="no-gutters"><h4><b>#item.Text</b></h4></div>
</div>
<div class="panel-body">
<div class="row">
#foreach (var i in ViewBag.Tracker)
{
<div class="row d-flex align-items-center">
<div class="panel panel-default rounded shadow col">
<div class="panel-heading border-bottom">
<div class="no-gutters text-muted col-5"><h3><b> #i.Text</b></h3></div>
<div class="col-2">
<select asp-for="Account" class="form-control" asp-items="ViewBag.Account"></select>
</div>
</div>
<div class="panel-body">
<div class="row d-flex align-items-center">
<div class="col-1"><b>Month</b></div>
<div class="col-1 d-flex justify-content-center"><b>Opening Balance</b></div>
<div class="col-1 d-flex justify-content-center"><b>Births</b></div>
<div class="col-1 d-flex justify-content-center"><b>Deaths</b></div>
<div class="col-1 d-flex justify-content-center"><b>Purchases</b></div>
<div class="col-1 d-flex justify-content-center"><b>Sold</b></div>
<div class="col-1 d-flex justify-content-center"><b>Age In</b></div>
<div class="col-1 d-flex justify-content-center"><b>Age Out</b></div>
<div class="col-1 d-flex justify-content-center"><b>Adjustments</b></div>
<div class="col-1 d-flex justify-content-center"><b>Closing Balance</b></div>
</div>
<div class="row d-flex align-items-center">
<div class="col-1">
Apr
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control", disabled = "disabled" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control", disabled = "disabled" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
}
</div>
Now the panel body is repeated 12 times (for each month of the year).
When saving data back, I will have some hidden fields for some of the core info. BUT what i need to be able to do is when saving back the first text box it also needs to save the MvtType (hard coded as column headings) as a column value.
I will wrap the panels into a form so it will submit when a button is clicked.
Finally, the underlying table. I used to have a column called period, one called value, as thought that might have been a better way of doing it? Rather than each period separated out.
Oh and sorry, I will need to load data to these textboxes when loading the page
Any help is much appreciated
EDIT
Ok, so i have made some progress here. I have tided up my view (See below) and can now get my view to pass back the first column of movement types, but nothing in the other columns. I effectively want to be able to post back a value into the period column while adding a value to the Mvt Type Column.
<div class="row">
#foreach (var item in ViewBag.LE)
{
<div class="panel panel-default rounded shadow col-11">
<div class="panel-heading border-bottom">
<div class="no-gutters"><h4><b>#item.Text</b></h4></div>
</div>
<div class="panel-body">
<div class="row">
#foreach (var i in ViewBag.Tracker)
{
<form asp-action="Create" class="form-group">
<div class="form-group">
<label asp-for="Tracker" class="control-label"></label>
<select asp-for="Tracker" class="form-control" asp-items="ViewBag.Tracker"></select>
</div>
<div class="form-group">
<label asp-for="Year" class="control-label"></label>
<select asp-for="Year" class="form-control" asp-items="ViewBag.Year"></select>
</div>
<div class="form-group">
<label asp-for="Version" class="control-label"></label>
<select asp-for="Version" class="form-control" asp-items="ViewBag.Version"></select>
</div>
<div class="row d-flex align-items-center">
<div class="panel panel-default rounded shadow col">
<div class="panel-heading border-bottom">
<div class="no-gutters text-muted col-5"><h3><b> #i.Text</b></h3></div>
<div class="col-2">
<select asp-for="Account" class="form-control" asp-items="ViewBag.Account"></select>
</div>
</div>
<div class="panel-body">
<div class="row d-flex align-items-center">
<div class="col-1"><b>Month</b></div>
<div class="col-1 d-flex justify-content-center"><b>Opening Balance</b></div>
#foreach (var mvt in ViewBag.MVtType)
{
<div class="col-1 d-flex justify-content-center">
<b>#mvt.Text</b>
</div>
}
<div class="col-1 d-flex justify-content-center"><b>Closing Balance</b></div>
</div>
<div class="row d-flex align-items-center">
<div class="col-1">
Apr
</div>
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control", disabled = "disabled" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
#for (int z = 0; z < ViewBag.MvtType.Count; z++)
{
<div class="col-1">
<select asp-for= "MvtType" class="form-control" asp-items="ViewBag.MvtType"></select>
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
}
<div class="col-1">
#Html.TextBoxFor(m => m.Period1, new { #class = "form-control", disabled = "disabled" })
<span asp-validation-for="Period1" class="text-danger"></span>
</div>
</div>
</div>
</div>
</div>
<div class="row d-flex align-items-center">
<div class="col-8"></div>
<div class="col-2">
<input type="submit" value="Save" class="btn btn-primary float-right" />
</div>
</div>
</form>
}
</div>
</div>
</div>
}
</div>
Righto, I have managed to find the answer.
Following this guide here Editing Multiple records using model binding in MVC
I have gotten my answer.
My view now looks like this, allowing indexing of the textboxes so I can edit multiple records, and not just one! I will update it to make it look prettier, and to hide certain fields
<div class="panel-body">
#using (Html.BeginForm("Index","OnFarms", FormMethod.Post))
{
<table class="table">
#for (int z = 0; z < Model.Count; z++)
{
<tr>
<td>
#Html.TextBox("OnFarms[" + #z + "].Id", Model[z].Id, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Tracker", Model[z].Tracker, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Year", Model[z].Year, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period1", Model[z].Period1, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period2", Model[z].Period2, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period3", Model[z].Period3, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period4", Model[z].Period4, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period5", Model[z].Period5, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period6", Model[z].Period6, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period7", Model[z].Period7, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period9", Model[z].Period9, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period10", Model[z].Period10, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period11", Model[z].Period11, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Period12", Model[z].Period12, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Version", Model[z].Version, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].Account", Model[z].Account, new { #class = "form-Control" })
</td>
<td>
#Html.TextBox("OnFarms[" + #z + "].MvtType", Model[z].MvtType, new { #class = "form-Control" })
</td>
<td>
</td>
</tr>
}
</table>
<input type="submit" value="Submit" />
}
</div>
But the key was to change the #model to be #model List<Testing.Models.OnFarm> not just Testing.Models.OnFarm
and my controller is simply
public ActionResult Index(List<OnFarm> OnFarms)
{
foreach (OnFarm frm in OnFarms)
{
OnFarm Existed_Mvt = _context.OnFarms.Find(frm.Id);
Existed_Mvt.Tracker = frm.Tracker;
Existed_Mvt.Year = frm.Year;
Existed_Mvt.Period1 = frm.Period1;
Existed_Mvt.Period2 = frm.Period2;
Existed_Mvt.Period3 = frm.Period3;
Existed_Mvt.Period4 = frm.Period4;
Existed_Mvt.Period5 = frm.Period5;
Existed_Mvt.Period6 = frm.Period6;
Existed_Mvt.Period7 = frm.Period7;
Existed_Mvt.Period8 = frm.Period8;
Existed_Mvt.Period9 = frm.Period9;
Existed_Mvt.Period10 = frm.Period10;
Existed_Mvt.Period11 = frm.Period11;
Existed_Mvt.Period12 = frm.Period12;
Existed_Mvt.Version = frm.Version;
Existed_Mvt.Account = frm.Account;
Existed_Mvt.MvtType = frm.MvtType;
}
_context.SaveChanges();
Related
I want to post my data to the action which is HttpPost. I always do it but this time I don't know what happens here. Submit button sends view data to Get action (I mean Detail action which is HttpGet) the button type is submit as you see and in the Html.BeginForm as you see I have used FormMethod.Post but just sends dar. I searched here but found nothing.
View:
#using MF_Urmia.Models.ViewModels
#using Kendo.Mvc.UI
#model CourseVm
#{
Layout = "~/Areas/Admin/Views/Shared/_LayoutPage.cshtml";
}
#using(Html.BeginForm("Detail", "Course", FormMethod.Post))
{
#Html.HiddenFor(m => m.CourseId)
#Html.ValidationSummary(true)
<div class="form-column">
<h1 class="form-title-box">
<span class="form-title">
#ViewBag.title
</span>
</h1>
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.CourseName)
</div>
<div class="form-field">
#Html.TextBoxFor(m => m.CourseName, new { #class = "k-textbox" })
</div>
</div>
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.TypeName)
</div>
<div class="form-field">
#(Html.Kendo().DropDownListFor(m => m.CourseTypeId)
.BindTo((IEnumerable<SelectListItem>)ViewBag.CourseTypeList)
.OptionLabel("(Select One)")
.DataValueField("Value")
.DataTextField("Text")
.HtmlAttributes(new { id = "CourseType" }))
</div>
</div>
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.Price)
</div>
<div class="form-field">
#Html.TextBoxFor(m => m.Price, new { #class = "k-textbox", #type = "number"})
</div>
</div>
<br />
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.Copacity)
</div>
<div class="form-field">
#Html.TextBoxFor(m => m.Copacity, new { #class = "k-textbox", #type = "number" })
</div>
</div>
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.TeacherName)
</div>
<div class="form-field">
#Html.TextBoxFor(m => m.TeacherName, new { #class = "k-textbox" })
</div>
</div>
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.DurationTime)
</div>
<div class="form-field">
#Html.TextBoxFor(m => m.DurationTime, new { #class = "k-textbox", #type = "number" })
</div>
</div>
<br />
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.ClassStart)
</div>
<div class="form-field">
#Html.TextBoxFor(model => model.ClassStart, new { #class = "form-control kendo-date-picker", value = "", placeholder = "مثال :1396/05/20" })
</div>
</div>
<div class="frm-group">
<div class="form-label">
#Html.LabelFor(m => m.RegisterLimit)
</div>
<div class="form-field">
#Html.TextBoxFor(model => model.RegisterLimit, new { #class = "form-control kendo-date-picker", value = "", placeholder = "مثال :1396/05/20" })
</div>
</div>
<hr />
<div class="frm-group">
<div class="form-label form-required">
#Html.LabelFor(m => m.CourseImage)
</div>
<div class="form-field-2xl">
#Html.Kendo().Upload().Name("ImageFile").Messages(m => m.Select("select")).Multiple(false)
</div>
</div>
<hr />
<div class="frm-group">
<div class="form-label">
#Html.LabelFor(m => m.Description)
</div>
<div class="form-field full-width">
#Html.TextAreaFor(m => m.Description, new { #class = "k-textbox ck-editor-box" })
</div>
</div>
<hr />
<input value="submit" type="submit" class="btn btn-success form-btn" />
</div>
}
Controller:
public ActionResult Detail(int? id)
{
var courseId = id;
using (var db = new MFUEntities())
{
var courseTypeList = db.CourseType.ToList();
ViewBag.CourseTypeList = new SelectList(courseTypeList,
nameof(CourseType.CourseTypeId), nameof(CourseType.DisplayName));
if (courseId.HasValue)
{
//ويرايش
ViewBag.title = "Edit";
return View();
}
else
{
//ثبت
ViewBag.title = "Create";
return View();
}
}
}
[HttpPost]
public ActionResult Detail(CourseVm vm)
{
var courseId = vm.CourseId;
using (var db = new MFUEntities())
{
if (courseId > 0)
{
//Edit
var course = db.Course.FirstOrDefault(c => c.CourseId == vm.CourseId);
if (course == null)
{
return HttpNotFound();
}
//ويرايش عکس دوره
var oldImage = course.CourseImage;
//عکس قبلي را پاک کند
System.IO.File.Delete(Server.MapPath("/Images/CourseImage/Images/" + oldImage));
System.IO.File.Delete(Server.MapPath("/Images/CourseImage/Thumb/" + oldImage));
vm.CourseImage = Guid.NewGuid().ToString().Replace("-", "") +
Path.GetExtension(vm.ImageFile.FileName);
vm.ImageFile.SaveAs(Server.MapPath("/Images/CourseImage/Images/" + vm.CourseImage));
ImageResizer img = new ImageResizer();
img.Resize(Server.MapPath("/Images/CourseImage/Images/" + vm.CourseImage),
Server.MapPath("/Images/CourseImage/Thumb/" + vm.CourseImage));
Mapper.Map(vm, course);
}
else
{
//Create
//ثبت عکس دوره
vm.CourseImage = Guid.NewGuid().ToString().Replace("-", "") +
Path.GetExtension(vm.ImageFile.FileName);
vm.ImageFile.SaveAs(Server.MapPath("/Images/CourseImage/Images/" + vm.CourseImage));
ImageResizer img = new ImageResizer();
img.Resize(Server.MapPath("/Images/CourseImage/Images/" + vm.CourseImage),
Server.MapPath("/Images/CourseImage/Thumb/" + vm.CourseImage));
var course = new Course();
Mapper.Map(vm, course);
course.Remained = vm.Copacity;
course.CreateDate = DateTime.Now;
db.Course.Add(course);
}
db.SaveChanges();
return RedirectToAction("Index", "Course");
}
}
I have foreach loop which contains some data. What I want is if user click on add button, save the details to the database as well as empty input values and go to the next iteration of the foreach loop.
Following is my code that I tried so far.
#model ModelLib.Models.PaymentDetails
#{
Layout = null;
var fullCount = Model.listRoomDetails.Max(x => x.FullCount);
}
<div class="row">
#Html.AntiForgeryToken()
<div class="row">
<div>You have to add <span id="passangerCount">#fullCount</span> Passanger details</div>
#foreach (var item in Model.listRoomDetails) {
<span>#item.RoomType RoomType Passanger Count : </span ><div id="#item.RoomType">#item.Count</div>
}
#foreach (var item in Model.listRoomDetails) {
<div class="row">
Room Type - <span id="existing_RoomType">#item.RoomType</span>
Room Category - <span id="existing_RoomCategory">#item.RoomCategory</span>
<div class="row">
<div class="col-lg-12">
<div class="panel panel-info" style="background-color:#ffffff;">
<div class="panel-heading" id="payment_heading" style="border-style: double; text-align: center; background-color: #f59e6b; border-color: black; color: black; font-weight: bold;">Add Payment Details<i class="fa fa-chevron-circle-down" style="font-size: 24px; float: right; margin-right: -17px; margin-top: 6px;"></i></div>
<div class="panel-body" id="payment_body">
<div class="row">
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.TicketNumber, new { #class = "label_class" })
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(model => model.TicketNumber, new { type = "text", maxlength = "13", #id = "ticketNumber", #class = "form-control", data_toggle = "tooltip", title = "Enter Ticket Name" })
</div>
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.PassangerName, new { #class = "label_class" })
</div>
<div class="col-sm-6">
#Html.TextBoxFor(model => model.PassangerName, new { #id = "passangerName", #class = "form-control", data_toggle = "tooltip", title = "Enter passanger Name" })
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.PassportNumber, new { #class = "label_class" })
</div>
<div class="col-sm-6">
#Html.TextBoxFor(model => model.PassportNumber, new { #id = "passportNumber", #class = "form-control", data_toggle = "tooltip", title = "Enter passport number", maxlength = 8 })
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.PkgVal, new { #class = "label_class" })
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(model => model.PkgVal, new { type = "number", #min = "0", #id = "pkgVal", data_toggle = "tooltip", title = "Enter valid pkg value", #class = "form-control" })
</div>
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.AirFare, new { #class = "label_class" })
</div>
<div class="col-sm-6">
#Html.TextBoxFor(model => model.AirFare, new { type = "number", #min = "0", #id = "airFare", data_toggle = "tooltip", title = "Enter valid airfare", #class = "form-control" })
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.Tax, new { #class = "label_class" })
</div>
<div class="col-sm-6">
#Html.TextBoxFor(model => model.Tax, new { type = "number", #min = "0", #id = "tax", data_toggle = "tooltip", title = "Enter valid tax", #class = "form-control" })
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.DateChangeFee, new { #class = "label_class" })
</div>
<div class="col-sm-6">
#Html.TextBoxFor(model => model.DateChangeFee, new { type = "number", #min = "0", #id = "dateChangeFee", data_toggle = "tooltip", title = "Enter valid date change fee value", #class = "form-control" })
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.CommissionToAgent, new { #class = "label_class" })
</div>
<div class="col-sm-6">
#Html.TextBoxFor(model => model.CommissionToAgent, new { type = "number", #min = "0", #id = "commissionToAgent", data_toggle = "tooltip", title = "Enter valid commission to agent value", #class = "form-control" })
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.VMPDNumber, new { #class = "label_class" })
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(model => model.VMPDNumber, new { type = "text", maxlength = "13", #id = "vmpdNumber", data_toggle = "tooltip", title = "Enter vmpd number", #class = "form-control" })
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.EMDNumber, new { #class = "label_class", #style = "margin-top: -3px;" })
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBoxFor(model => model.EMDNumber, new { type = "text", maxlength = "13", #id = "emdNumber", data_toggle = "tooltip", title = "Enter emd number", #class = "form-control" })
</div>
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.RoomType, new { #class = "label_class", #style = "margin-top: -3px;" })
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBox(item.RoomType, new { type = "text", #id = "roomType", #class = "form-control" })
</div>
</div>
</div>
<div class="col-sm-4">
<div class="col-sm-6">
#Html.LabelFor(model => model.RoomCat, new { #class = "label_class", #style = "margin-top: -3px;" })
</div>
<div class="col-sm-6">
<div class="form-group">
#Html.TextBox(item.RoomCategory, new { type = "text", #id = "roomCat", #class = "form-control" })
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<p>
<input type="button" class="btn btn-info btn-add" name="PaymentDetails" id="PaymentDetails_btn" value="Add" data-url="#Url.Action("PaymentDetails", "EVoucher")" />
</p>
</div>
}
</div>
</div>
I can save the value to database when the user clicks on add button by using Ajax call. But How can I change the foreach loop value according the relevant iteration?
Any help will really appreciate. Thanks
Update - #Liam, I want to change #item.RoomType, #item.RoomCategory according to the foreach loop value. But I dont want to display all the inputs at one time. For ex if I have count 20, I only want to display one at a time. not all 20.
Form having dropdown country list when i click on submit button country ID value is passed to the controller..when i click on F10 keybord button country bind method is called .so again return to starting point so that again country value is Null Below i attached the screen shot:
<div class="page-content">
<div class="container-fluid">
<header class="section-header">
<div class="tbl">
<div class="tbl-row">
<div class="tbl-cell">
<h2>Company Registration Form</h2>
</div>
</div>
</div>
</header>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<section class="tabs-section">
<div class="tabs-section-nav tabs-section-nav-icons">
<div class="tbl">
<ul class="nav" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="#tabs-1-tab-1" role="tab" data-toggle="tab">
<span class="nav-link-in">
<i class="font-icon font-icon-cogwheel"></i>
Company Registration Form
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tabs-1-tab-2" role="tab" data-toggle="tab">
<span class="nav-link-in">
<span class="glyphicon glyphicon-music"></span>
Company Social Network
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tabs-1-tab-3" role="tab" data-toggle="tab">
<span class="nav-link-in">
<i class="fa fa-product-hunt"></i>
Company Reference
</span>
</a>
</li>
</ul>
</div>
</div><!--.tabs-section-nav-->
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active show" id="tabs-1-tab-1">
<br />
<br />
<section>
<div>
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => Model.company.CompanyName, new { #class = "form-label semibold control-label" })
#Html.TextBoxFor(model => model.company.CompanyName, new { #class = "form-control", #id = "txtCompanyName", placeholder = "Enter the Company Name" })
#Html.ValidationMessageFor(model => model.company.CompanyName)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.ShortName, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.ShortName, new { #class = "form-control", #id = "txtShortName", placeholder = "Enter the Short Name" })
#Html.ValidationMessageFor(model => model.company.ShortName)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Division, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Division, new { #class = "form-control", #id = "txtDivision", placeholder = "Enter the Division" })
#Html.ValidationMessageFor(model => model.company.Division)
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Email, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Email, new { #class = "form-control", #id = "txtEmail", placeholder = "Enter your Email" })
#Html.ValidationMessageFor(model => model.company.Email)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Address1, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Address1, new { #class = "form-control", #id = "txtAddress1", placeholder = "Enter your Address Line 1" })
#Html.ValidationMessageFor(model => model.company.Address1)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Address2, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Address2, new { #class = "form-control", #id = "txtAddress2", placeholder = "Enter your Address Line 2" })
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Country, new { #class = "form-label semibold" })
#Html.DropDownList("Country", null, "--- Select Country ---", new { #class = "select2-arrow" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.State, new { #class = "form-label semibold" })
<select id="state" class="select2-arrow"></select>
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.City, new { #class = "form-label semibold" })
<select id="city" class="select2-arrow"></select><br />
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Pincode, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Pincode, new { #class = "form-control", #id = "txtPincode", placeholder = "Enter your Pincode" })
#Html.ValidationMessageFor(model => model.company.Pincode)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.CountryCode, new { #class = "form-label semibold" })
#*#Html.DropDownList("CountryCode", null, "---Select CountryCode---", new { #class = "select2-arrow" })*#
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.MobileNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.MobileNo, new { #class = "form-control", #id = "txtMobileNo", placeholder = "Enter your Mobile Number" })
#Html.ValidationMessageFor(model => model.company.MobileNo)
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.PhoneNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.PhoneNo, new { #class = "form-control", #id = "txtPhoneNo", placeholder = "Enter your PhoneNo" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.PanNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.PanNo, new { #class = "form-control", #id = "txtPanNo", placeholder = "Enter Company PanNo" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.TinNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.TinNo, new { #class = "form-control", #id = "txtTinNo", placeholder = "Enter Company TinNo" })
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.GSTno, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.GSTno, new { #class = "form-control", #id = "txtGSTno", placeholder = "Enter Company GSTno" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.IECCode, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.IECCode, new { #class = "form-control", #id = "txtIECCode", placeholder = "Enter Company IECCode" })
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label semibold">Upload Company Logo</label>
<input type="file" name="file" id="txtUploadImage" style="cursor:pointer;" />
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label semibold">Perview Image</label>
<img id="image_upload_preview" src="http://placehold.it/100x100" alt="your image" />
<a id="remove" onclick="javascript:ClearFileUploadControl();" style="display: none; cursor: pointer;">Remove</a>
</fieldset>
</div>
</div>
<br />
<input type="submit" name="Submit" id="SaveCompany" value="Save" class="btn btn-rounded btn-inline btn-success" />
</div>
</section>
</div><!--.tab-pane-->
<div role="tabpanel" class="tab-pane fade" id="tabs-1-tab-2">
<br />
<section>
<div>
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.CompanySocial.FaceBookID, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.CompanySocial.FaceBookID, new { #class = "form-control", #id = "txtFaceBookID", placeholder = "Enter the Facebook Link" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.CompanySocial.TwitterID, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.CompanySocial.TwitterID, new { #class = "form-control", #id = "txtTwitterID", placeholder = "Enter the Twitter Link" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.CompanySocial.linkedinID, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.CompanySocial.linkedinID, new { #class = "form-control", #id = "txtlinkedinID", placeholder = "Enter the Linkedin Link" })
</fieldset>
</div>
</div><!--.row-->
</div>
</section>
<input type="submit" name="Submit" value="Previous" class="btn btn-rounded btn-inline btn-primary prev-step " />
<input type="submit" name="Submit" id="saveSocial" value="Next" class="btn btn-rounded btn-inline btn-success" />
</div><!--.tab-pane-->
<div role="tabpanel" class="tab-pane fade" id="tabs-1-tab-3">
Tab 3
<br />
<br />
<input type="submit" name="Submit" value="Previous" class="btn btn-rounded btn-inline btn-primary prev-step" />
<input type="submit" name="Submit" value="Finish" class="btn btn-rounded btn-inline btn-success" />
</div><!--.tab-pane-->
</div><!--.tab-content-->
</section><!--.tabs-section-->
}
</div>
</div>
Scripts:
<script>
function GetInfo() {
var Company = {
CompanyName: $("#txtCompanyName").val(), ShortName: $("#txtShortName").val(), Division: $("#txtDivision").val(), Email: $("#txtEmail").val(), Address1: $("#txtAddress1").val(), Address2: $("#txtAddress2").val(), Country: $("#Country").val(), State: $("#state").val(), City: $("#city").val(),
Pincode: $("#txtPincode").val(), MobileNo: $("#txtMobileNo").val(), PhoneNo: $("#txtPhoneNo").val(), PanNo: $("#txtPanNo").val(), TinNo: $("#txtTinNo").val(), GSTno: $("#txtGSTno").val(), IECCode: $("#txtIECCode").val()
};
var mainModel = {};
mainModel.Company = Company;
$.ajax({
type: "POST",
url: "/Company/AddCompany",
data: JSON.stringify(mainModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
}
});
}
function OnSuccess(response) {
alert(response.d);
}
$(document).ready(function () {
$("#saveSocial").click(function (e) {
e.preventDefault();
GetInfo1();
});
$("#SaveCompany").click(function (e) {
//e.preventDefault();
GetInfo();
});
});
function GetInfo1() {
var Social = { FaceBookID: $("#txtFaceBookID").val(), TwitterID: $("#txtTwitterID").val(), linkedinID: $("#txtlinkedinID").val() };
var mainModel = {};
mainModel.CompanySocial = Social;
$.ajax({
type: "POST",
url: "/Company/AddSocial",
data: JSON.stringify(mainModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
}
});
}
</script>
<script>
$(document).ready(function () {
$("#Country").change(function () {
var id = $(this).val();
$("#state").empty();
$.get("State_Bind", { CountryID: id }, function (data) {
var v = "<option>--- Select State ---</option>";
$.each(data, function (i, v1) {
v += "<option value=" + v1.Value + ">" + v1.Text + "</option>";
});
$("#state").html(v);
});
});
$("#state").change(function () {
var id = $(this).val();
$("#city").empty();
$.get("City_Bind", { StateID: id }, function (data) {
var v = "<option>--- Select City---</option>";
$.each(data, function (i, v1) {
v += "<option value=" + v1.Value + ">" + v1.Text + "</option>";
});
$("#city").html(v);
});
});
});
</script>
Class value:
public int Country { get; set; }
public int State { get; set; }
public int City { get; set; }
Screen shot:
ActionResult:
[HttpPost]
public ActionResult AddCompany(MainModel mainModel)
{
try
{
Country_Bind();
if (ModelState.IsValid)
{
dp obj = new dp();
if (obj.AddNewCompany(mainModel))
{
ViewBag.Message = "Company added successfully";
}
}
return View();
}
catch
{
return View();
}
}
Country code:
public void Country_Bind()
{
DataSet ds = dblayer.Get_Country();
List<SelectListItem> coutrylist = new List<SelectListItem>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
coutrylist.Add(new SelectListItem { Text = dr["CountryName"].ToString(), Value = dr["CountryID"].ToString() });
}
ViewBag.Country = coutrylist;
}
You are currently calling the Country_Bind() method as the first statement inside your httppost action method. You actually need to do that when you want to rerender the dropdown list when re rendering the same view.
If you are not doing an ajax post,You should follow the PRG pattern. On successful save of the data, you should redirect to the GET action method which render the view. If the Modelstate validation fails, that is when you return the same view (so that you can show the validation message to user) and you need to repopulate the dropdown data before that.
When you do a Redirect, ViewData does not work to transfer messages.Use TempData instead.
[HttpPost]
public ActionResult AddCompany(MainModel mainModel)
{
try
{
if (ModelState.IsValid)
{
dp obj = new dp();
if (obj.AddNewCompany(mainModel))
{
TempData.Message = "Company added successfully";
return RedirectToAction("CompanyList");
}
}
// We need to repopulate the data needed for rendering dropdown
Country_Bind();
return View(mainModel);
}
catch(Exception ex)
{
// to do : Make sure to log the error
return View("Error");
}
}
In your case, when you do an ajax post returning a redirect result does not makes sense. You may return the url to the next page if needed as part of a json response and use that in your ajax calls success/done event handler and do appropriate things (redirect to the new page/show a message to user)
[HttpPost]
public ActionResult AddCompany(MainModel mainModel)
{
try
{
if (ModelState.IsValid)
{
dp obj = new dp();
if (obj.AddNewCompany(mainModel))
{
return Json(new { Message="Company added successfully"});
}
}
return Json(new { Message="Validation errors!"});
}
catch(Exception ex)
{
// must log the exception
return Json(new { Message="Error "});
}
}
Make sure to update your success/done event handler of your ajax call to read the response (the json and do something like showing message to user/hiding or showing the next tab)
I also noticed an issue with your ajaxifying code. Since you are making an ajax form submission, you should prevent the default form submit behavior by calling the event.preventDefault method.
$("#SaveCompany").click(function (e) {
e.preventDefault();
GetInfo();
});
I would also recommend to use a flat-lean view model specific for the view. So your properties will not be nested level and when you use the helper methods (TextBoxFor etx), It will generate the correct input field names and you do not need to manually build the Js object you want to send. You may simply use the jquery serialize() method on your form object and send that as the data for the ajax call.
I need to do a loop in another loop and I get a strange error as if it lacked a closing } and I get a compile error on the page. As against the project compiles . the error message is
CS1513 : } expected.
The source indicates the line of code in 1238 while I was not more than 150 lines of code in the page, really strange . help please
#using (Html.BeginForm("VCreateCommande", "CCommande", new { id = "formretouche" }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="control-label col-md-2">Support papier</div>
<div class="col-md-10">
#Html.CheckBoxFor(model => model.Tretouche.Supportpapier, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Tretouche.Supportpapier, "", new { #class = "text-danger" })
</div>
</div>
var i = 1;
foreach (var item in Model.Tformats)
{
var idformat = "idformat" + i;
var idquantite = "qteformat" + i;
var idtxt="qte" + #item.Idformat;
int qteretoucheformat=0;
foreach (var itemretoucheformat in Model.Tretouchesformats)
{
if(itemretoucheformat.IdFormat ==item.Idformat)
{
qteretoucheformat = itemretoucheformat.Quantité;
}
}
<div>
<div class="form-group">
<div class="control-label col-md-2 fltleft">Quantité #item.Format</div>
<div class="col-md-10 fltleft">
#Html.TextBoxFor(model => model.Tretoucheformat.Quantité, new { id = idtxt, Name=idtxt })
#Html.ValidationMessageFor(model => model.Tretoucheformat.Quantité, "", new { #class = "text-danger" })
</div>
</div>
</div>
i = i + 1;
}
<div class="form-group">
<div class="control-label col-md-2">Photo...</div>
<div class="col-md-10">
#Html.TextBoxFor(model => model.Tretouche.fichierphoto, new { type = "file" })
</div>
</div>
<input id="idtyperetouche" name="idtyperetouche" type="text" value="#idtyperetouche" class="hdn" />
<input name="idcommande" type="text" value="#idtyperetouche" class="hdn" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Ajouter" class="btn btn-default" />
</div>
</div>
}
<table class="table">
<tr>
<th>Papier</th>
<th>Quantite</th>
<th>Type de retouche</th>
<th>Photo</th>
</tr>
#foreach (var item in Model.Tretouches)
{
var prix = 0;
<tr>
<td>
#Html.CheckBox("Papier", item.Supportpapier)
</td>
<td>
#Html.DisplayFor(modelItem => item.Quantite)
</td>
#foreach (var typeretouche in Model.Ttyperetouches)
{
if (item.Idtyperetouche == typeretouche.Idtyperetouche)
{
<td>#typeretouche.Libelle</td>
prix = (typeretouche.Prix * item.Quantite);
}
}
<td>
<img src="#item.SRCphoto" class="">
</td>
<td>
#prix €
</td>
<td>
#Html.ActionLink("Modifier", "Edit", "TRetouches", new { id = item.Idretouche }, null) |
#Html.ActionLink("Supprimer", "Delete", "TRetouches", new { id = item.Idretouche }, null)
</td>
</tr>
}
For Razor views (at least MVC 4 and earlier), unlike for a .cs file, the { needs to be on its own line
foreach (var itemretoucheformat in Model.Tretouchesformats)
{
}
Henk's comment suggests this may have been improved in MVC 5.
I´m writing a project to manage a pool of users of asp.net identity 2.0, and i want to create a user and add roles to the user in the same view, so when i post the model just simple create the user and add the roles in the same action.
I don't know how to generate the roles list for the user, for example i have a dropdownlist for with the roles and id´s and my view is something like this
<div class="form-horizontal">
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">Datos personales</div>
<div class="panel-body">
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.Nombre)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.Nombre, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.Apellido)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.Apellido, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.DependenciaId)
</div>
<div class="col-md-8">
#Html.DropDownListFor(m => m.User.DependenciaId, new SelectList(ViewBag.ListaDependencia, "Id", "Descripcion"), "Ninguno", new { #class = "form-control" })
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">Datos usuario</div>
<div class="panel-body">
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.UserName)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.UserName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.NetUser)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.NetUser, new { #class = "form-control" })
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">Datos usuario</div>
<div class="panel-body">
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.Roles)
</div>
<div class="col-md-8">
#Html.DropDownListFor(m => m.User.Roles, new SelectList(ViewBag.RolesList, "Id", "Name"), "Ninguno", new { #class = "form-control" })
</div>
</div>
<table>
Here must present the roles to add to the user
</table>
</div>
</div>
I found a way
first a helper for offline collections, that a i found on internet
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
if (html.ViewData["ContainerPrefix"] != null)
{
collectionName = string.Concat(html.ViewData["ContainerPrefix"], ".", collectionName);
}
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
var itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
var htmlFieldPrefix = string.Format("{0}[{1}]", collectionName, itemIndex);
html.ViewData["ContainerPrefix"] = htmlFieldPrefix;
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex));
return BeginHtmlFieldPrefixScope(html, htmlFieldPrefix);
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
var key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null)
{
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (var previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
then using an editor template
<tr>
#using (Html.BeginCollectionItem("ListaObraSocialPrepagasSeleccionadas"))
{
<td>
<input type="radio" name="RolesUserTableRadio" />
#Html.HiddenFor(model => model.Id, new { #readonly = "readonly" })
</td>
<td>
#Html.HiddenFor(model => model.Id, new { #readonly = "readonly" })
#Html.DisplayTextFor(model => model.Name)
</td>
}
a partial view to manage the list
<script type="text/javascript">
$(document).ready(function () {
$("#btnAddRoles").click(function () {
var rolId = $("#ddRoles").val();
if (rolId == null || rolId == '') {
alert("Debe seleccionar un rol.");
return;
}
var foundRol = $("#RolesUserTable").find("input[value='" + rolId + "']");
if (foundRol.size() > 0) {
alert("Ya se ha agregado el rol.");
return;
}
$.ajax({
url: '#Url.Action("AddRoles", "Users")',
data: {
rolId: rolId
},
type: 'GET',
contentType: 'application/x-www-form-urlencoded',
success: function (data) {
if (data.Valid) {
$("#RolesUserTable").append(data.html);
} else {
alert('El rol seleccionado no existe');
}
},
error: function (jqXHR, exception) {
alert('Error durante la llamada al servidor.' + jqXHR.responseText);
},
complete: function () {
}
});
});
$("#btnDeleteRoles").click(function () {
var myRadio = $('input[name=RolesUserTableRadio]');
var radio = myRadio.filter(':checked');
if (radio.size() == 0) {
alert("Debe seleccionar un rol.");
return;
}
if (!confirm("¿Confirma que desea eliminar el rol seleccionado?")) {
return;
}
$(radio).closest('tr').remove();
});
});
</script>
<div style="width: 100%; overflow-x: auto;">
<table id="RolesUserTable" class="table table-striped">
<thead>
<tr>
<th></th>
<th>Rol</th>
</tr>
</thead>
#Html.EditorFor(m => m.Roles)
</table>
</div>
and finnaly the dropdown and the table
<div class="form-group">
<label for="ddRoles" class="col-sm-2 control-label">Roles</label>
<div class="col-sm-3">
#Html.DropDownList("ddRoles", new SelectList(ViewBag.Roleslist, "Id", "Name", null), "Seleccione un rol", new { #class = "selectpicker", data_live_search = "true" })
</div>
<div class="btn-group">
<button id="btnAddRoles" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span></button>
<button id="btnDeleteRoles" type="button" class="btn btn-default"><span class="glyphicon glyphicon-minus"></span> </button>
</div>
</div>
<div>
#Html.Partial("_Roles")
</div>