i have create dynamic category with subcategory ...
i can't show on my razor page i used foreach but foreach for 2 step category or 3 step my category have unlimited step
plz help me
public class vmCategoryForSearch
{
public int CategoryId { get; set; }
public string titleEn { get; set; }
public bool isDelete { get; set; }
public List<vmCategoryForSearch> Children { get; set; }
}
how to call this code
public List<vmCategoryForSearch> GetAllCategoryForSearchClients()
{
return catsearchList.Where(mm => mm.ParentId == 0).Select(m => new vmCategoryForSearch
{
titleEn = m.titleEn,
titleFa = m.titleFa,
Children = GetAllCategoryForSearchClients(m.SubId)
}).ToList();
}
private List<vmCategoryForSearch> GetAllCategoryForSearchClients(int id)
{
return catsearchList.Where(sm => sm.ParentId == id).Select(vm => new vmCategoryForSearch
{
titleEn = vm.titleEn,
titleFa = vm.titleFa,
Children = GetAllCategoryForSearchClients(vm.SubId)
}).ToList();
}
my razor page
Here is a simple worked example , you could refer to :
Category model
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
}
vmCategoryForSearch
public class vmCategoryForSearch
{
public int CategoryId { get; set; }
public string Name { get; set; }
public List<vmCategoryForSearch> Children { get; set; }
}
PageModel
private readonly RazorPages2_1Project.Data.RazorPagesDbContext _context;
private readonly List<Category> list;
public CreateModel(RazorPages2_1Project.Data.RazorPagesDbContext context)
{
_context = context;
list = _context.Category.ToList();
}
public IActionResult OnGet()
{
CategoryList = GetAllCategoryForSearchClients();
return Page();
}
[BindProperty]
public List<vmCategoryForSearch> CategoryList { get; set; }
public List<vmCategoryForSearch> GetAllCategoryForSearchClients()
{
var result= list.Where(mm => mm.ParentId == 0).Select(m => new vmCategoryForSearch
{
Name = m.Name,
Children = GetAllCategoryForSearchClients(m.Id)
}).ToList();
return result;
}
private List<vmCategoryForSearch> GetAllCategoryForSearchClients(int id)
{
var result1 = list.Where(sm => sm.ParentId == id).Select(vm => new vmCategoryForSearch
{
Name = vm.Name,
Children = GetAllCategoryForSearchClients(vm.Id)
}).ToList();
return result1;
}
}
Razor Pages
<div class="c-box_item">
#foreach(var item in Model.CategoryList)
{
<ul >
<li>
<span> #item.Name</span>
<div>
#foreach(var subitem in item.Children)
{
<ul>
<li>
<span> #subitem.Name</span>
<div>
#if (subitem.Children.Count > 0)
{
#foreach (var subitems in subitem.Children)
{}
}
</div>
</li>
</ul>
}
</div>
</li>
</ul>
}
</div>
Related
I want to retrieve the data of parent and child in the same view mvc5 c#
<ul class="circle2">
<li style=" border:0px">
<div class="text">#Html.DisplayFor(model => model.Name)</div>
</li>
<ul class="circle3">
#foreach (var item1 in Model)
{
<li>
<div class="text">#Html.Display(modelItem => item1.Name)</div>
</li>
}
<li>
<div class="text" data-toggle="tooltip" data-placement="left" title="add family member">#Html.ActionLink("+", "Create")</div>
</li>
Your model must look like this:
public class newtree
{
public string User_ID { get; set; }
public string Name { get; set; }
public string perantID { get; set; }
List<Child> Children { get; set; }
}
You need to fill up the Children-list with the correct data, then iterate it with #foreach (var item1 in Model.Children)
Model
public class EmployeeViewModel {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public EmployeeDepartment employeeDepartment { get; set; }
}
public class EmployeeDepartment {
public int Id { get; set; }
public string DepartmentName { get; set; }
}
Controller
public ActionResult EmployeeData() {
EmployeeViewModel model = new EmployeeViewModel();
EmployeeDepartment ed = new EmployeeDepartment();
model.Id = 1;
model.Name = "Muhammmad Ashraf Faheem";
model.Email = "it.ashraffaheem#gmail.com";
ed.Id = 1;
ed.DepartmentName = "Development";
model.employeeDepartment = ed;
return View(model);
}
View
#model UploadFileDemo.Models.EmployeeViewModel
#{ViewBag.Title = "EmployeeData";}
<label>#Model.Id</label><br />
<label>#Model.Name</label><br />
<label>#Model.Email</label><br />
<label>#Model.employeeDepartment.Id</label><br />
<label>#Model.employeeDepartment.DepartmentName</label>
with this way we can use parent and child model in same view :
I just followed this guide to install and set up AutoMapper, and I think I got it correctly set up. But when I try to map from IEnumerable<ProductCategory> to IEnumerable<ViewModelProductCategory>, like this:
var categories = _context.ProductCategories.Include(e => e.Children).ToList();
var topLevelCategories = categories.Where(e => e.ParentId == null);
var VMCategory = _mapper
.Map<IEnumerable<ProductCategory>,
IEnumerable<ViewModelProductCategory>>(topLevelCategories);
return View(VMCategory);
(Thank you to #Anton Gorbunov, for pointing out that I had my objects swapped!)
... my view complains about receiving the wrong model. I'm pretty sure it's because of the children categories not being mapped to a sub-list, so in the view, item.Children is not properly set up as a viewmodel.
How can I map a list of lists?
This is my Index-view:
#model IEnumerable<MyStore.Models.ViewModels.ViewModelProductCategory>
<ul>
#Html.Partial("_CategoryRecursive", Model)
</ul>
... and this is _CategoryRecursive.cshtml:
#model IEnumerable<MyStore.Models.ViewModels.ViewModelProductCategory>
<ul style="list-style:none;padding-left:0px;">
#if (Model != null)
{
foreach (var item in Model)
{
<li style="margin:8px 0px 0px 0px;">
<ul>
#Html.Partial("_CategoryRecursive.cshtml", item.Children)
</ul>
</li>
}
}
</ul>
Mapping profile:
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<ProductCategory, ViewModelProductCategory>();
CreateMap<ViewModelProductCategory, ProductCategory>();
CreateMap<Product, ViewModelProduct>();
CreateMap<ViewModelProduct, Product>();
}
}
Entity model:
public class ProductCategory
{
public int Id { get; set; }
public int SortOrder { get; set; }
public string Title { get; set; }
[ForeignKey(nameof(ParentCategory))]
public int? ParentId { get; set; }
public ProductCategory ParentCategory { get; set; } //nav.prop to parent
public ICollection<ProductCategory> Children { get; set; } //nav. prop to children
public List<ProductInCategory> ProductInCategory { get; set; }
}
Viewmodel:
public class ViewModelProductCategory
{
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public int SortOrder { get; set; }
public string ProductCountInfo
{
get
{
return Products != null && Products.Any() ? Products.Count().ToString() : "0";
}
}
public ProductCategory ParentCategory { get; set; } // Nav.prop. to parent
public IEnumerable<ProductCategory> Children { get; set; } // Nav.prop. to children
public List<ViewModelProduct> Products { get; set; } // Products in this category
public List<ViewModelProduct> OrphanProducts { get; set; } // Products with no references in ProductInCategory
}
Problem here:
var VMCategory = _mapper.Map<IEnumerable<ViewModelProductCategory>, IEnumerable<ProductCategory>>(topLevelCategories);
you should change code to
var VMCategory = _mapper.Map<IEnumerable<ProductCategory>, IEnumerable<ViewModelProductCategory>>(topLevelCategories);
Description:
TDestination = Map<TSource,TDestination>(TSource sourceObject), but you swapped the types TSource and TDestination inside brackets <,>
I'm having trouble understanding how to add my CustId and selected DevId values from the CheckBoxList to my CustomerDevice table in my database.
My Index Action Method for the CustomerDeviceController displays a list of Customers from my Customers table. I have a link labeled "Add Device(s)" that passes the CustId value to the CustomerDeviceController [HttpGet] Create Action Method which displays my CheckBoxListItem values from the Devices table which works fine.
The part that I'm having trouble understanding and figuring out, is how can I add the selected DevId values from the CheckBoxList along with the CustId value to my CustomerDevice Table on the [HttpPost] Create Action Method.
Please see the following code below that I have so far.
CheckBoxListItem Model
public class CheckBoxListItem
{
public int ID { get; set; }
public string Display { get; set; }
public bool IsChecked { get; set; }
}
Customer Model
public class Customer
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public string CustFirstName { get; set; }
public string CustLastName { get; set; }
public string CustCompanyName { get; set; }
public string CustAddress { get; set; }
public string CustPhoneNumber { get; set; }
public string CustMobileNumber { get; set; }
public string CustEmailAddress { get; set; }
}
Device Model
public class Device
{
public int DevId { get; set; }
public string DevType { get; set; }
}
CustomerDevice Model
public class CustomerDevice
{
public int CustId { get; set; }
public int DevId { get; set; }
public Customer Customer { get; set; }
public Device Device { get; set; }
}
Shared/EditorTemplates/CheckBoxListItem.cshtml
<div class="checkbox">
<label>
#Html.HiddenFor(x => x.ID)
#Html.CheckBoxFor(x => x.IsChecked)
#Html.LabelFor(x => x.IsChecked, Model.Display)
</label>
<br />
CustomerDeviceFormViewModel
public class CustomerDeviceFormViewModel
{
public int CustId { get; set; }
public string CustDisplayName { get; set; }
public List<CheckBoxListItem> Devices { get; set; }
}
CustomerDeviceController
public class CustomerDeviceController : Controller
{
private CheckBoxAppContext db;
public CustomerDeviceController(CheckBoxAppContext context)
{
db = context;
}
// GET: /<controller>/
public IActionResult Index()
{
return View(db.Customers.ToList());
}
public ActionResult Create(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerDeviceFormViewModel();
{
Customer customer = db.Customers.SingleOrDefault(c => c.CustId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustId = customer.CustId;
// Retrieves list of Devices for CheckBoxList
var deviceList = db.Devices.ToList();
var checkBoxListItems = new List<CheckBoxListItem>();
foreach (var device in deviceList)
{
checkBoxListItems.Add(new CheckBoxListItem()
{
ID = device.DevId,
Display = device.DevType,
IsChecked = false //On the create view, no devices are selected by default
});
}
customervm.Devices = checkBoxListItems;
return View(customervm);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerDeviceFormViewModel vm)
{
if (ModelState.IsValid)
{
var customerDevices = new CustomerDevice();
{
customerDevices.CustId = vm.CustId;
var deviceList = db.Devices.ToList();
var checkBoxListItems = new List<CheckBoxListItem>();
foreach (var deviceId in deviceList)
{
}
}
db.CustomerDevices.Add(customerDevices);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return View(vm);
}
}
}
Index View
<table class="table">
<tr>
<th>Id</th>
<th>Display Name</th>
<th>Actions</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CustId)
</td>
<td>
#Html.DisplayFor(modelItem => item.CustDisplayName)
</td>
<td>
#Html.ActionLink("Add Device(s)", "Create", new { id = item.CustId })
</td>
</tr>
}
Create View
<div class="form-group">
#Html.EditorFor(x => x.Devices)
</div>
#Html.HiddenFor(c => c.CustId)
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
Assuming that your CustomerDevice is the join table for a M:N relation between Customer and Device entities, I think you need something like this in your POST action:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerDeviceFormViewModel vm)
{
if (ModelState.IsValid)
{
foreach (var deviceId in vm.Devices.Where(x => x.IsChecked).Select(x => x.ID))
{
var customerDevices = new CustomerDevice
{
CustId = vm.CustId,
DevId = deviceId
};
db.CustomerDevices.Add(customerDevices);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
}
You create an entity of the join table and add it to the context. EF will associate the records when you call SaveChanges.
Hope this helps!
So I have an Html.DropDownList that I want to use on an edit page to allow users to edit the categories of different recipe ingredients. So for example if a user wants to edit the chili recipe they are shown all the different properties for the recipe including a list of all the ingredients which they should be able to add to or delete from or edit the quantity, name and category of. And I only want to have a drop down list to edit the category because I only want them to be able to choose from a preselected list of categories. Here is what I have.
<table>
<tr>
<th></th>
</tr>
#for (int i = 0; i < #Model.Recipe.RecipeIngredients.Count; i++)
{
<tr>
<td>#Html.EditorFor(model => model.Recipe.RecipeIngredients[i].Quantity)</td>
<td>#Html.EditorFor(model => model.Recipe.RecipeIngredients[i].IngredientName)</td>
<td>#Html.DropDownList("AvailableCategories")</td>
</tr>
}
</table>
//// GET: /Recipe/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
EditViewModel vm = new EditViewModel();
vm.Recipe = Db.Recipes.Find(id);
if (vm.Recipe == null)
{
return HttpNotFound();
}
List<SelectListItem> items = new List<SelectListItem>();
foreach (var item in Db.Categories)
{
items.Add(new SelectListItem { Text = item.CategoryName, Value = item.CategoryId.ToString() });
}
vm.AvailableCategories = items;
return View(vm);
}
public class EditViewModel
{
public Recipe Recipe { get; set; }
public List<SelectListItem> AvailableCategories { get; set; }
public EditViewModel()
{
AvailableCategories = new List<SelectListItem>();
}
}
public class RecipeIngredient
{
public int IngredientId { get; set; }
public int RecipeId { get; set; }
public int CategoryId { get; set; }
public string IngredientName { get; set; }
public string Quantity { get; set; }
public int IsOnMenu { get; set; }
public bool IsOnTheDamnMenu
{
get
{
return IsOnMenu == 1;
}
set
{
IsOnMenu = value ? 1 : 0;
}
}
public virtual Recipe Recipe { get; set; }
public virtual Category Category { get; set; }
}
I actually just found that I can pass more properties into this. So something like
#Html.DropDownListFor(model => model.Recipe.RecipeIngredients[i].CategoryId, new SelectList(Model.AvailableCategories, "Value", "Text", Model.Recipe.RecipeIngredients[i].CategoryId), "-Select-")
Shows the correct category now.
I currently have a navigation bar which is dynamically created from a MS SQL Database, but I would like to add a second sub layer. Below is what I have so far for the current working single level navigation bar.
Navigation
public partial class Navigation
{
public int Id { get; set; }
public string Title { get; set; }
public Nullable<int> Position { get; set; }
public bool Main { get; set; }
public string Action { get; set; }
public string Controller { get; set; }
}
HomeController
[ChildActionOnly]
public ActionResult Navigation()
{
var navigationModel = (from m in db.Navigations where (m.Main == true) orderby m.Position select m);
return View(navigationModel);
}
Navigation
#{ Layout = null; }
#model IEnumerable<WebApplication1.Models.Navigation>
<ul class="nav sf-menu clearfix">
#foreach (var item in Model)
{
#Html.MenuLink(item.Title, item.Action, item.Controller)
}
</ul>
The second tier needs to link to the Contents table, the relationship is db.Navigations.Id = db.Contents.NavigationId.
Content
public partial class Content
{
public int Id { get; set; }
public Nullable<int> NavigationId { get; set; }
public string Title { get; set; }
public string Content1 { get; set; }
public Nullable<int> Position { get; set; }
public string Image { get; set; }
public string Sub { get; set; }
public Nullable<bool> Active { get; set; }
public string Url { get; set; }
public string Summary { get; set; }
}
Could someone please provide a tutorial or example code of how I can bind child data to the parent dataset and then in the View, how to check if a parent holds child records and if so loop through them.
Any help would be much appreciated :-)
I added a new class called NavigationViewModel to declare the tables I wish to use and modified the HomeController to use NavigationViewModel for querying the respective tables.
NavigationViewModel
namespace WebApplication1.Models
{
public class NavigationViewModel
{
public List<Navigation> Navigation { get; set; }
public List<Content> Content { get; set; }
}
}
HomeController
[ChildActionOnly]
public ActionResult Navigation()
{
var navigationModel = new NavigationViewModel();
navigationModel.Navigation = (from m in db.Navigations where (m.Main == true) orderby m.Position select m).ToList();
navigationModel.Content = (from n in db.Contents where (n.Active == true) orderby n.Position select n).ToList();
return View(navigationModel);
}
Navigation
#model WebApplication1.Models.NavigationViewModel
<ul class="nav sf-menu clearfix">
#foreach (var navigation in Model.Navigation)
{
int records = Model.Content.Count(c => c.NavigationId == navigation.Id);
if (records > 0)
{
#Html.SubMenuLink(navigation.Title, navigation.Action, navigation.Controller)
#Html.Raw("<ul>")
foreach (var content in Model.Content.Where(c => c.NavigationId == navigation.Id))
{
if (string.IsNullOrEmpty(content.Url))
{
if (string.IsNullOrEmpty(content.Content1))
{
}
else
{
#Html.MenuLink(content.Title, "Home/Article/" + content.Id + "/" + ToFriendlyUrl(content.Title), "Home");
}
}
else
{
#Html.MenuLink(content.Title, content.Url, "Home");
}
}
#Html.Raw("</ul>")
#Html.Raw("</li>")
}
else
{
#Html.MenuLink(navigation.Title, navigation.Action, navigation.Controller)
}
}
</ul>
I'm not sure this is the most elegant or efficient way to achieve the end goal, any suggestions to make the code more efficient I am happy to listen.