I have a list of categories and each category may have subcategories. I am getting the list with correct records in my controller but if I try to use the list of subcategories in my view, it shows nothing.
Classes:
public class DashboardTile
{
public int ID { get; set; }
public int? CategoryID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class DashboardTileBO : DashboardTile
{
public bool IsChecked { get; set; }
public List<DashboardTileBO> DashboardTiles { get; set; }
}
public class AddTileVM
{
public List<DashboardTileBO> DashboardTiles { get; set; }
}
Controller:
public ActionResult AddTiles()
{
var allDashBoardTiles = BLL.PublicLayer.GetAllDashBoardTiles(SessionItems.UserId);
var addTileVm = new AddTileVM()
{
DashboardTiles = allDashBoardTiles,
};
return PartialView(addTileVm );
}
View:
#model Hugo.BusinessObjects.AddTileVM
<link href="~/Content/js/nestable/nestable.css" rel="stylesheet"/>
<script src="~/Content/js/nestable/jquery.nestable.js"></script>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Add/Remove Tiles to desktop</h4>
</div>
#using (Ajax.BeginForm("AddTiles", "Default",new AjaxOptions {OnSuccess = "OnSuccess" }))
{
#Html.AntiForgeryToken();
<div class="modal-body">
<div class="row">
<div class="col-lg-12">
#for (var i = 0; i < Model.DashboardTiles.Count; i++)
{
<div class="col-lg-5">
<label class="">
#Html.CheckBoxFor(a=> Model.DashboardTiles[i].IsChecked)
#Model.DashboardTiles[i].Description
</label>
</div>
#*if (#Model.DashboardTiles[i].DashboarTiles.Count > 0)
{
for (var j = 0; j < #Model.DashboardTiles[i].DashboarTiles.Count; j++)
{
<div class="col-lg-5">
<label class="">
#Html.CheckBoxFor(a => #Model.DashboardTiles[i].DashboarTiles[j].IsChecked)
#Model.DashboardTiles[i].DashboarTiles[j].Description
</label>
</div>
}
}*#
#Html.HiddenFor(a=> Model.DashboardTiles[i].ID)
}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-rounded btn-sm btn-tiles" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-rounded btn-sm btn-tiles" >Update</button>
</div>
}
</div><!-- /.modal-content -->
}
method to fetch list
public static List<BusinessObjects.DashboardTileBO> GetAllDashBoardTiles(long userId)
{
using (var context = new HugoInternalEntities())
{
var distincCategoryIds = context.DashboardTiles.Select(a => a.CategoryID).Distinct().ToList();
var allTiles = (context.DashboardTiles.Where(a => distincCategoryIds.Contains(a.ID)).Select(x=>
new BusinessObjects.DashboardTileBO
{
ID = x.ID,
Name = x.Name,
Description = x.Description,
})).ToList();
var list = context.DashboardUserTiles.Where(a => a.UserID == userId).Select(a => a.DashboardTileID).ToList();
allTiles.ForEach(a => a.IsChecked = list.Contains(a.ID));
allTiles.ForEach(a=>a.DashboardTiles=context.DashboardTiles.Where(b=>a.ID==b.CategoryID && b.ID != a.ID).Select(x=>
new BusinessObjects.DashboardTileBO
{
ID = x.ID,
Name = x.Name,
Description = x.Description,
}).ToList());
allTiles.ForEach(a => a.DashboardTiles.ForEach(b => b.IsChecked = list.Contains(b.ID)));
return allTiles;
}
}
In the above view my list of main categories is shown but if I uncomment my code for subcategories nothing is shown. Please see the screenshot of the list I am getting in addTileVm
List of tiles:
Related
I have a .net core 3.1 MVC project where i am displaying a custom made treeview along with 2 textbox.
Here is the Model i used:
public class DeviceGroupAvailabilityModel
{
public string ChapterTitle { get; set; }
public string ChapterDetail { get; set; }
public List<TreeViewModel> TreeViewModels { get; set; }
}
And
public class TreeViewModel
{
public string ParentNode { get; set; }
public bool isChecked { get; set; }
public List<TreeViewModel> ChildNodes { get; set; }
}
Here is the function that i use to display the tree full on the cshtml file.
Here is part of the cshtml file:
here is my controller:
public async Task<IActionResult> Index()
{
List<TreeViewModel> TreeModel = BuildModels(await prtgClient.GetExtendedGroupsAsync(_pRTGApiClient),1);
DeviceGroupAvailabilityModel deviceGroupAvailabilityModel = new DeviceGroupAvailabilityModel
{
ChapterTitle = "Device And Group Availability",
ChapterDetail = "",
TreeViewModels = TreeModel
};
return View("Index",deviceGroupAvailabilityModel);
}
public IActionResult Cancel()
{
return RedirectToAction("Index","Home");
}
[HttpPost]
public async Task<IActionResult> Save([FromForm]DeviceGroupAvailabilityModel deviceGroupAvailabilityModel)
{
int reportID = await _dbConnection.GetReportId(deviceGroupAvailabilityModel.ChapterTitle);
deviceGroupAvailabilityModel.TreeViewModels.Select(async group => await AddGroupToReport(group.ParentNode, reportID));
return View("Index");
}
private async Task AddGroupToReport(string groupName,int reportID)
{
int groupId = await _dbConnection.GetGroupId(groupName);
await _dbConnection.AddGroupToReport(groupId, reportID);
}
private List<TreeViewModel>BuildModels(List<ExtendedGroup>extendedGroups,int rootID)
{
List<TreeViewModel> TreeModel = new List<TreeViewModel>();
extendedGroups.ForEach(group =>
{
if (group.parentId == rootID)
{
TreeModel.Add(new TreeViewModel
{
ParentNode = group.name,
ChildNodes = BuildModels(extendedGroups, group.objid)
});
}
});
return TreeModel;
}
Model Binding from controller to view works great but from view to controller in only get the Two textbox not the list of treeview model.
Is there a way to solve this?
kind regards,
Edit: Full CSHTML Code withoud Title:
#model DeviceGroupAvailabilityModel
#functions{
void DisplayTree(List<TreeViewModel>models)
{
<ul>
#foreach (TreeViewModel treeViewModel in models)
{
<li>
<input type="checkbox" id="#treeViewModel.ParentNode" name="#treeViewModel.ParentNode" checked="#treeViewModel.isChecked" />
#treeViewModel.ParentNode
#if (treeViewModel.ChildNodes.Count > 0)
{
DisplayTree(treeViewModel.ChildNodes);
}
</li>
}
</ul>
}
}
#using (Html.BeginForm("Save", "DeviceGroupAvailability",FormMethod.Post)) {
<div class="container">
<div class="row">
<div class="col-auto">
<div class="card shadow" style="border-left-color:#0087e9;border-left-width:medium">
<h6 class="card-header text-center bg-warning">SELECT GROUP TO REPORT</h6>
<div class="card-body">
<div class="tree well">
#{
DisplayTree(Model.TreeViewModels);
}
</div>
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="card shadow ml-3 mb-3" style="border-left-color:#0087e9;border-left-width:medium">
<h6 class="card-header text-center bg-warning">CHAPTER TITLE</h6>
<div class="card-body">
#Html.TextBoxFor(m=>m.ChapterTitle)
</div>
</div>
</div>
<div class="row">
<div class="card shadow ml-3 mb-3" style="border-left-color:#0087e9;border-left-width:medium">
<h6 class="card-header text-center bg-warning">CHAPTER Description</h6>
<div class="card-body">
#Html.TextBoxFor(m=>m.ChapterDetail)
</div>
</div>
</div>
<div class="row">
<input type="submit" class="btn ml-5 bg-primary text-white" value="Save" />
<button type="button" class="btn bg-primary ml-5 text-white" onclick="location.href='#Url.Action("Cancel", "DeviceGroupAvailability")'">Cancel</button>
</div>
</div>
</div>
</div>
}
#section Scripts{
<script type="text/javascript">
$(":checkbox").change(function () {
//begin Cheking all child elements
var ulsiblings = $(this).siblings("ul");
var lichilt = ulsiblings.find("li");
var checkchild = lichilt.find(":checkbox");
checkchild.prop("checked", this.checked);
//begin checking Parent element
//if child is checked
var checkLiParent = $(this).parent();
var checkliSiblings = checkLiParent.siblings("li");
var lisibCheck = checkliSiblings.find(":checkbox");
var isAllChecked;
lisibCheck.each(function () {
if (this.checked) {
isAllChecked = true;
}
else {
isAllChecked = false;
}
})
if (isAllChecked) {
var checkParent = checkLiParent.parent();
var parentSib = checkParent.siblings(":checkbox");
parentSib.prop("checked", this.checked);
}
})
</script>
}
I am trying to populate a "Company" dropdown but I can not get the Razor syntax correct on it.
With the below code it makes my modal just not pop up. JS gets an undefined error for the company field and it errors out. If i remove #Html.DropDownListFor(c => c.SelectedCompany, Model.CompanyLists, "- Please select a state -", new { #class = "form-control" }) then the modal pops up fine, just with no items populated.
Any idea what I am doing wrong? I was using this article for reference. https://nimblegecko.com/using-simple-drop-down-lists-in-ASP-NET-MVC/ ; however, it has a hard-coded list instead of one pulling from DB.
<div class="tab-pane fade show active" id="user" role="tabpanel" aria-labelledby="user-tab">
<form method="post" class="mt-3">
<div class="form-group row text-center">
<label asp-for="Id" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input disabled asp-for="Id" class="formField inputDisabled" disabledclass="form-control">
</div>
</div>
<div class="form-group row text-center">
<label asp-for="FirstName" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="FirstName" class="formField" />
<span asp-validation-for="FirstName" class="text-danger"></span>
/div>
</div>
<div class="form-group row text-center">
<label asp-for="LastName" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="LastName" class="formField" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
</div>
<div class="form-group row text-center">
<label asp-for="Title" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="Title" class="formField" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
</div>
<div class="form-group row text-center">
<label asp-for="Email" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="Email" class="formField" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group row text-center">
<label asp-for="UserName" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="UserName" class="formField" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
</div>
<div class="form-group row text-center">
<label asp-for="CompanyLists" class="col-sm-3 text-right col-form-label labelFont"></label>
#*ISSUE IS HERE--------------------------------------------------------------------------------------*#
<div class="col-md-5">
#Html.DropDownListFor(c => c.SelectedCompany, Model.CompanyLists, "- Please select a state -", new { #class = "form-control" })
#Html.ValidationMessageFor(c => c.SelectedCompany, "", new { #class = "text-danger" })
</div>
#*------------------------------------------------------------------------------------------*#
</div>
<div class="form-group row text-center">
<label asp-for="Address" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="Address" class="formField" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
</div>
<div class="form-group row text-center">
<label asp-for="City" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="City" class="formField" />
<span asp-validation-for="City" class="text-danger"></span>
</div>
</div>
<div class="form-group row text-center">
<label asp-for="State" class="col-sm-3 text-right col-form-label labelFont"></label>
<div class="col-sm-8">
<input asp-for="State" class="formField" />
<span asp-validation-for="State" class="text-danger"></span>
</div>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
<button type="submit" class="btn btn-primary padFloat btnBlue" asp-action="EditUser" asp-controller="Administration" asp-route-id="#Model.Id">Update</button>
<a asp-action="UserMaint" class="btn btn-primary padFloat btnRed">Cancel</a>
</form>
</div>
Model:
namespace PortalDev.Models.ViewModels
{
public class EditUserViewModel
{
public EditUserViewModel()
{
Claims = new List<Claim>();
Roles = new List<Role>();
//CompanyLists = new List<ICompanyRepository>();
CompanyLists = new List<CompanyList>();
}
//ROLES ---------------------------------------------
public class Role
{
public string RoleName { get; set; }
public string RoleID { get; set; }
public bool IsSelected { get; set; }
}
public List<Role> Roles { get; set; }
//CLAIMS----------------------------------------------
public class Claim
{
public string ClaimType { get; set; }
public string ClaimID { get; set; }
public bool IsSelected { get; set; }
}
public List<Claim> Claims { get; set; }
//COMPANY DROPDOWN--------------------------------------
public class CompanyList
{
public string CompanyName { get; set; }
public int CompanyID { get; set; }
}
[Display(Name = "Company")]
public List<CompanyList> CompanyLists { get; set; } //List of Companies for dropdown
public string SelectedCompany { get; set; }
//USER INFORMATION --------------------------------------
public string Id { get; set; }
//[Required]
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
Method:
// EDIT USER : GET-----------------------------------------------------
[HttpGet]
public async Task<IActionResult> EditUser(string id)
{
//GET USER INFORMATION - EXIT IF USER DOESN'T EXIST
var user = await userManager.FindByIdAsync(id);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
return View("NotFound");
}
//USER INFORMATION ---------------------------------------
var model = new EditUserViewModel
{
Id = user.Id,
Email = user.Email,
UserName = user.UserName,
FirstName = user.FirstName,
LastName = user.LastName,
Title = user.Title,
Address = user.Address,
City = user.City,
State = user.State,
//CompanyId = user.CompanyId
};
// ViewBag.SelectedCommpany = user.CompanyId;
//COMPANY DROPDOWN INFO------------------------------------
var company = from c in companyRepository.GetCompanys() select c;
foreach (var c in company)
{
////Store this inforamtion into the company list in the viewmodel
var companyinfo = new EditUserViewModel.CompanyList
{
CompanyName = c.CompanyName,
CompanyID = c.CompanyId
};
model.CompanyLists.Add(companyinfo);
};
//GET LIST OF ROLES(RoleID, RoleName)
var roles = roleManager.Roles;
foreach (var RoleName in roles)
{
//Execute identity method to get full information for the Role and store into an object (roleinfo)
var roleString = RoleName.Name;
var fullRoleInfo = await roleManager.FindByNameAsync(roleString);
//Store this information into the Role list in the viewmodel
var roleinfo = new EditUserViewModel.Role
{
RoleName = fullRoleInfo.Name,
RoleID = fullRoleInfo.Id,
};
if (await userManager.IsInRoleAsync(user, roleString))
{
roleinfo.IsSelected = true;
}
else
{
roleinfo.IsSelected = false;
}
model.Roles.Add(roleinfo);
};
//**************************************************************************************************************************************************************
//IDENTITY CLAIM INFORMATION ------------------------------
var existingUserClaims = await userManager.GetClaimsAsync(user);
foreach (Claim claim in ClaimStore.AllClaims)
{
var userClaims = new EditUserViewModel.Claim
{
ClaimType = claim.Type
};
if (existingUserClaims.Any(c => c.Type == claim.Type && c.Value == "true"))
{
userClaims.IsSelected = true;
}
else
{
userClaims.IsSelected = false;
}
model.Claims.Add(userClaims);
}
ViewBag.UserModel = model;
return PartialView("~/Views/Modals/_EditUserModalPartial.cshtml", model);
}
Follow my example
Here is my DropDownListFor;
#Html.DropDownListFor(model => Model.SelectedDropDownValue, new SelectList(Model.DropDownListAutoPopulate), "Quarter - Year", new { #class = "form-control btn-primary form-control", #id = "QuarterYearConcat", #onchange = #"form.submit();" })
Model.SelectedDropDownValue is the selected value passed back from the controller
public List<string> DropDownListAutoPopulate { get; set; }
is the list that will populate the dropdown. Which is my viewModel model.
Here is my full model for the viewModel
namespace MoCApp.ViewModels
{
public class SLGAdminCreateViewModel
{
public SLGHeader SLGHeader;
[Range(-100.00, 100.00, ErrorMessage = "Value must be between -100 and 100")]
public decimal? TotalBudget { get; set; }
[Range(-100.00, 100.00, ErrorMessage = "Value must be between -100 and 100")]
public decimal? TotalLaborBudget { get; set; }
public List<QuarterWeekType> DropDownList { get; set; }
public SLGQuarterDetails SLGQuarterList { get; set; }
public QuarterWeekType Dropdown { get; set; }
public string SelectedDropDownValue { get; set; }
public List<string> DropDownListAutoPopulate { get; set; }
}
}
Here is my Get method in relation to the model and view.
// GET: SLG/CreateAdmin
[Authorize(Roles = "WFL_APP_MOCHUB-Admins,WFL_APP_SLG-Admins,Managers,WFL_ROLE_StoreManagmentTeams")]
public ActionResult CreateAdmin(SLGAdminCreateViewModel value)
{
// ViewModel for Both Forms
var viewModel = new SLGAdminCreateViewModel
{
SLGHeader = new SLGHeader(),
DropDownList = new List<QuarterWeekType>(),
DropDownListAutoPopulate = new List<string>(),
TotalBudget = null,
TotalLaborBudget = null
};
// Formating returned value for query to set values.
if (value.SelectedDropDownValue != null)
{
var QuarterYear = value.SelectedDropDownValue.Replace("Q", "").Replace(":", "").Replace(" ", "");
var Quarter = decimal.Parse(QuarterYear.Substring(0, 1), CultureInfo.InvariantCulture);
var Year = decimal.Parse(QuarterYear.Substring(1, 4), CultureInfo.InvariantCulture);
var TotalBudgetList = db.QuarterDetails.Where(x => x.Quarter == Quarter && x.Year == Year && x.Store == 1 && x.Department == "total")
.ToList();
foreach (var x in TotalBudgetList) { viewModel.TotalBudget = x.TotalBudget; viewModel.TotalLaborBudget = x.TotalLaborBudget; };
}
// Format dropdown list
viewModel.DropDownList = db.SLGHeaderTemplates.Where(x => x.Year > 2018 && x.Week == 1).Select(x => new QuarterWeekType { Year = x.Year, Quarter = x.Quarter, QuarterYearConcat = "" }).ToList();
foreach (var item in viewModel.DropDownList)
{
item.QuarterYearConcat = "Q" + Convert.ToInt32(item.Quarter) + " : " + Convert.ToInt32(item.Year);
}
foreach (var x in viewModel.DropDownList) { viewModel.DropDownListAutoPopulate.Add(x.QuarterYearConcat); };
return View(viewModel);
}
If you follow my example and have your model, view and controller in the same relations. You will be golden.
Don't mind my logic with me foreaching through one object and putting it into another list. Just know where your list goes in the DropDownListFor statement and how it is related to your viewModel and Controller.
I'm beginner in asp.net mvc.
I have a product model and I want implement user comments for any product.
I want to show comments as tree for each level.
I use a recursive method in my view to show comments and reply comment but
it cant show reply comments in third level .
The first level terms when replyId is empty displayed. Reply to first comment are displayed first. But the answer of Previous reply does not show in the third level.
Please help me. Thank you so much.
This is my model
namespace Mvc_Shop.Models
{
public class Comment
{
public Comment()
{
this.Children = new HashSet<Comment>();
}
public int Id { set; get; }
public string Body { set; get; }
public System.DateTime CommentDate { get; set; }
public int? ReplyId { get; set; }
public ICollection<Comment> Children { get; set; }
public virtual Comment Reply { set; get; }
public string User_Id { get; set; }
[ForeignKey("User_Id")]
public virtual User User { get; set; }
public int Product_Id { get; set; }
[ForeignKey("Product_Id")]
public virtual Product Product { get; set; }
}
}
This is my view
#helper TreeView(IEnumerable<Mvc_Shop.Models.Comment> Comments)
{
foreach (var item in Comments)
{
<div class="media">
<div class="media-body" id="Comment_#(item.Id)" style="padding: 3px;width: 100%;">
<h4 class="media-heading">
#item.User.UserName
<label class="badge pull-left" style="font-weight: normal">#item.CommentDate.ToString("dddd, dd MMMM yyyy - HH:mm")</label>
</h4>
<div class="clearfix">
#item.Body
</div>
<fieldset id="reply-cmnt-form_#(item.Id)" class="spr-form-review" style="display:none">
<div class="spr-form-review-body">
#Html.LabelFor(model => model.Comment.Body, new { #class = "spr-form-label" })
#Html.TextAreaFor(model => model.Comment.Body, new { #class = "spr-form-input spr-form-input-text", id = "commentbody" + #item.Id })
#Html.ValidationMessageFor(model => model.Comment.Body)
</div>
</fieldset>
<a id="btn-hide-div_#(item.Id)" class="btn btn-xs pull-left btn-primary" style="clear: both; display:none" onclick="opencmntdiv(#item.Id);"> بستن</a>
<a id="btn-send-div_#(item.Id)" class="btn btn-xs pull-left btn-primary" style="clear: both;float:right;display:none" onclick="ReplyComment(#item.Id);"> ارسال پاسخ</a>
<a id="btn-show-div_#(item.Id)" class="btn btn-xs pull-left btn-primary" style="clear: both" onclick="opencmntdiv(#item.Id);"> پاسخ</a>
</div>
</div>
<hr class="clearfix" />
if (item.Children.Any())
{
#TreeView(item.Children)
}
}
}
#TreeView(Model.Comments)
and this is my action
public ActionResult ShowProducts(string ProductName)
{
_dbContext = HttpContext.GetOwinContext().Get<ShopContext>();
var model = new UserCommentViewModel();
if (string.IsNullOrEmpty(ProductName))
{
return RedirectToAction("Index");
}
else
{
model.Products = blproduct.Where(p => p.Name.Trim() == ProductName.Trim()).ToList();
model.Comments = (from u1 in _dbContext.Users
join u2 in _dbContext.Comments
on u1.Id equals u2.User.Id
where u2.ReplyId == null
select new {
Id = u2.Id, Body = u2.Body, CommentDate = u2.CommentDate, User = u1,Children = u2.Children
}).ToList().Select(x => new Comment
{
Id = x.Id, Body = x.Body, CommentDate = x.CommentDate, User = x.User,Children = x.Children
}).ToList();
if (model != null)
{
return View(model);
}
else
{
return RedirectToAction("Index");
}
}
}
Thanks a lot.
I have this form in MVC Razor . The html is quite long so I am posting the area where I want to work
these are the checkboxes which are populated as service packages
The flow is the user will upload a photo and when proceeds to the next step it goes to a page where he will be selecting service for each photo if he has uploaded 3 photos the three photos will be having the same service
listing but different order IDS
I want is that when a user select services for a specific order means a specific order has multiple services . I want to map it so that Model List will be feteched in the Controller and I can easily insert in the database
this is the HTML:
#using (Html.BeginForm("PlaceOrder", "User", FormMethod.Post, new { id="ServiceForm",#class = "form-horizontal
white-clr", role = "form" }))
{
<!--If user has uploaded a single photo or multiple photo -->
<div class="window-for-choose-service">
#if (ViewBag.OrdersList != null)
{
int i= 1;
foreach (var d in ViewBag.OrdersList)
{
<div class="row">
<div class="col-sm-3 col-md-3 col-lg-3">
<img src="#d.ThumbnailPath" class="img-thumbnail img-responsive" width="250">
</div>
<div class="col-sm-9 col-md-9 col-lg-9">
<form class="white-clr" role="form">
<div class="form-group">
<label for="name">Description</label>
<textarea class="form-control" rows="4"></textarea>
</div>
</form>
</div>
<div class="col-sm-12 col-md-12 col-lg-12">
<div class="panel-group" id="accordion_#d.ID">
<div class="panel panel-primary">
#foreach (var Services in ViewBag.ServicePackages)
{
int cID = Services.ID + d.ID;
//int rndNumber = Convert.ToInt32(TimeSpan.FromSeconds(new Random().Next(0,
11221)).ToString("hmsf"));
if (Services.ServiceParentID == null)
{
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion_#d.ID"
href="#collapseOne_#cID">
#Services.ServiceName
</a>
</h4>
</div>
<div id="collapseOne_#cID" class="panel-collapse collapse in">
<div class="panel-body">
<div>
<div class="table-responsive">
#foreach (var child in Services.ft_service_packages1)
{
//string ness = "ServiceSelected[" + #d.ID + "]";
<div style="width:auto;min-width:250px;float:left; padding:4px; display:inline-block">
<div style="float:left;padding-right:5px;">
<label for="inlinecheckbox_#child.ID">
#Html.CheckBoxFor(m => m.ServiceSelect, new { id = "inlinecheckbox_" +
#child.ID, price_attr = "#child.ServicePrice"})
#Html.HiddenFor(m => m.UploadOrderID, new { Value = #d.ID })
</label>
</div>
<div style="padding-left:2px;">#child.ServiceName</div>
</div>
}
</div>
</div>
</div>
</div>
i++;
}
}
</div>
</div>
</div>
<div class="col-sm-12 col-md-12 col-lg-12"><p class="text-right font-blue"><b> Price $
0.0</b></p> </div>
</div>
}
}
The Html is genereting perfectly fine . But the thing is not getting anything in the controller regarding the model
Model is listed below
using System;
using System.Collections.Generic;
public partial class ft_order_itemized
{
public int ID { get; set; }
public int UploadOrderID { get; set; }
public int ServiceSelected { get; set; }
public decimal ServiceCharges { get; set; }
public System.DateTime ServiceSelectedDate { get; set; }
public Nullable<int> OrderID { get; set; }
public bool ServiceSelect { get; set; }
public virtual ft_orders ft_orders { get; set; }
public virtual ft_service_packages ft_service_packages { get; set; }
public virtual ft_uploads_orders ft_uploads_orders { get; set; }
}
My Controller :
[HttpPost]
public ActionResult PlaceOrder(ICollection<ft_order_itemized> Orders)
{
if (Orders.Count > 0)
{
}
// ICollection Allstrings = Orders["Service"].ToList();
return View();
}
I was trying to use Html Display For Template for looping through a Model data. Inside my Display template, I wanted to use an EditorFor template that would display a different set of data, In doing so, I was running into issues where my child model was empty. Upon playing around and getting guidance from David, I was able to make this to work. Below, please find my updated working solution.
UPDATE (Correct solution)
public class TargetingAreaViewModel
{
public int DealerId { get; set; }
public int OrderId { get; set; }
public List<TargetingAreaOrderItemViewModel> TargetingAreaOrderItems { get; set; }
public TargetingAreaViewModel()
{
this.TargetingAreaOrderItems = new List<TargetingAreaOrderItemViewModel>();
}
}
public class TargetingAreaOrderItemViewModel
{
public int OrderItemId { get; set; }
public int PackageMediaTypeId { get; set; }
public string PackageMediaTypeHeader { get; set; }
public string MediaTypeDesc { get; set; }
public string TargetingAdditonalInfo { get; set; }
public List<TargetingAreaItemViewModel> TargetingAreaItems { get; set; }
public TargetingAreaOrderItemViewModel()
{
this.TargetingAreaItems = new List<TargetingAreaItemViewModel>();
}
}
public class TargetingAreaItemViewModel
{
public int OrderItemId { get; set; }
public int PackageMediaTargetingFieldId { get; set; }
public string TargetingAreaFieldTitle { get; set; }
public string TargetingValue { get; set; }
public bool IsEnabled { get; set; }
public bool IsRequired { get; set; }
public string Comment { get; set; }
}
Parent View
#model Models.TargetingAreaViewModel
#{
ApplicationContext.Current.PageTitle = "Targeting Info";
Layout = "~/Views/Shared/MainLayout.cshtml";
}
#using (Html.BeginForm("OrderItemTargetingInfo", "Home", FormMethod.Post, new { #class = "form-horizontal" }))
{
#Html.DisplayFor(m => m.TargetingAreaOrderItems)
<div class="col-sm-12">
<div class="pull-right">
<input id="Submit" type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
}
DisplayFor Template View
#model Models.TargetingAreaOrderItemViewModel
<div class="row">
<div class="col-sm-12">
<div class="col-sm-12 btn-primary" style="margin-bottom: 10px; margin-top: 10px;">
#Html.Label(Model.MediaTypeDesc, new { #style = "font-weight: bold; padding-top: 10px; font-size: 18px;" })
#Html.HiddenFor(m => m.OrderItemId)
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
#Html.Raw(Model.PackageMediaTypeHeader)
</div>
</div>
<br />
<div class="row">
<div class="col-sm-12">
#Html.EditorFor(m => m.TargetingAreaItems)
</div>
</div>
<br />
<div class="row">
<div class="col-md-12">
<div class="form-group">
#Html.Label("Additional Info:", new { #class = "control-label col-md-2" })
<div class="col-md-6">
#Html.TextAreaFor(m => m.TargetingAdditonalInfo, new { #class = "form-control" })
</div>
</div>
</div>
</div>
Now, I am able to display the data, get the data out of my model on Post. Works great!!
In your parent views you are only passing in the TargetingAreaOrderItems of the model but the child view is expecting a TargetingAreaViewModel. Instead you should pass in the entire model:
#Html.DisplayFor(m => m)