how to retrieve parent data and child data in the same view - c#

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 :

Related

Good practices and use of DateTime in List of ViewModels

I am making a system for the client, and he did not use fullcalendar, which would be practical. With that, I created in a table with the fields AgendaId (int), and DateAgendar (DateTime) years forward (some 20000 lines).
With that I set up the following ViewModel:
public class AgendaAgendamentoVM
{
public int Id { get; set; }
public int? AgendamentoId { get; set; }
public DateTime Date { get; set; }
public int? ClienteId { get; set; }
public string ClienteNome { get; set; }
}
And I have a second table called Reserva with the fields:
public class Reserva
{
public int ReservaId { get; set; }
public int AgendaId { get; set; }
[Required]
public int ClienteId { get; set; }
public string Servico { get; set; }
public virtual Cliente Cliente { get; set; }
}
and Clients:
public class Cliente
{
public int ClienteId { get; set; }
[Column(TypeName = "varchar(50)")]
public string Nome { get; set; }
[Column(TypeName = "varchar(50)")]
public string Telefone { get; set; }
[Column(TypeName = "varchar(50)")]
public string Endereco { get; set; }
[Column(TypeName = "varchar(50)")]
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}
The ViewModel code below returns every day from 6 am until 10 pm:
IList<AgendaAgendamentoVM> _listaAgendaVM = new List<AgendaAgendamentoVM>();
if (!String.IsNullOrEmpty(mes))
{
var data = DateTime.Parse(mes);
ViewBag.Data = data;
ViewBag.Ontem = data.AddDays(-1);
ViewBag.Amanha = data.AddDays(1);
var dias = await _context.Agenda
.Where(x => x.DataAgenda >= data.AddHours(6))
.Where(x => x.DataAgenda <= data.AddHours(22))
.ToListAsync();
foreach (var item in dias)
{
AgendaAgendamentoVM li = new AgendaAgendamentoVM();
li.Id = item.AgendaId;
li.Date = DateTime.Parse(item.DataAgenda.ToString());
_listaAgendaVM.Add(li);
}
ViewData["ListaAgenda"] = _listaAgendaVM;
return View();
The View:
#{
ViewBag.Title = "Agenda";
}
<form>
<input type="date" name="mes" required /> <input type="submit" value="Enviar" />
</form>
<div class="row m-1 p-2 bg-success rounded">
<div class="col-4">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Ontem)"><</a>
</div>
<div class="col-4 text-center text-white font-weight-bolder">
#String.Format("{0:d}", ViewBag.Data)
</div>
<div class="col-4 text-right">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Amanha)">></a>
</div></div>
<ul class="list-group m-1">
#foreach (var item in ViewData["ListaAgenda"] as
List<Camarim.Core.ViewModels.AgendaAgendamentoVM>)
{
<li class="list-group-item"><a href="#?agendaid=#item.Id">#String.Format("{0:HH:mm}",
item.Date) - #item.ClienteNome</a></li>
}
Only with the Agenda table, I can display in a view a "navigable" calendar as shown in the image:
Still in the Reservation table, I have a ClienteId field, where I return a specific customer. In the List I make of the ViewModel, I use a foreach calling the Reservation and Customers table, as shown in the photo:
The problem with this is, when doing this, the view stops showing the entire list from 6 am to 10 pm, it only shows the fields where clients are scheduled. My goal was to leave it at least this way:
How can I do to achieve this goal: and / OR another: Is there any other way to do this without using the database for popular dates?
It seems that you want to display the ClientNome.
Firstly,from your expected result image,it should be one-to-many relationship between Agenda and Reserva.Then you could get the multiple ClientNome to display it in your razor view.Change your model like below:
public class Agenda
{
public int AgendaId { get; set; }
public DateTime DataAgenda { get; set; }
public List<Reserva> Reserva { get; set; }
}
public class Reserva
{
public int ReservaId { get; set; }
public int AgendaId { get; set; }
[Required]
public int ClienteId { get; set; }
public string Servico { get; set; }
public virtual Cliente Cliente { get; set; }
}
public class Cliente
{
public int ClienteId { get; set; }
[Column(TypeName = "varchar(50)")]
public string Nome { get; set; }
[Column(TypeName = "varchar(50)")]
public string Telefone { get; set; }
[Column(TypeName = "varchar(50)")]
public string Endereco { get; set; }
[Column(TypeName = "varchar(50)")]
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}
public class AgendaAgendamentoVM
{
public int Id { get; set; }
public int? AgendamentoId { get; set; }
public DateTime Date { get; set; }
public int? ClienteId { get; set; }
public List<string> ClienteNome { get; set; }
}
View:
<form>
<input type="date" name="mes" required /> <input type="submit" value="Enviar" />
</form>
<div class="row m-1 p-2 bg-success rounded">
<div class="col-4">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Ontem)"><</a>
</div>
<div class="col-4 text-center text-white font-weight-bolder">
#String.Format("{0:d}", ViewBag.Data)
</div>
<div class="col-4 text-right">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Amanha)">></a>
</div>
</div>
<ul class="list-group m-1">
#foreach (var item in ViewData["ListaAgenda"] as List<AgendaAgendamentoVM>)
{
<li class="list-group-item">
<a href="#?agendaid=#item.Id">
#String.Format("{0:HH:mm}",
item.Date) - #foreach (var i in item.ClienteNome)
{
#i #string.Format(" ") #*change this*#
}
</a>
</li>
}
</ul>
Controller:
public async Task<IActionResult> Index(string mes)
{
IList<AgendaAgendamentoVM> _listaAgendaVM = new List<AgendaAgendamentoVM>();
if (!String.IsNullOrEmpty(mes))
{
var data = DateTime.Parse(mes);
ViewBag.Data = data;
ViewBag.Ontem = data.AddDays(-1);
ViewBag.Amanha = data.AddDays(1);
var dias = await _context.Agenda
.Where(x => x.DataAgenda >= data.AddHours(6))
.Where(x => x.DataAgenda <= data.AddHours(22))
.ToListAsync();
foreach (var item in dias)
{
var reservas = (from p in _context.Reservas
join c in _context.Clientes on p.ClienteId equals c.ClienteId
where p.AgendaId == item.AgendaId
select c).ToList();
AgendaAgendamentoVM li = new AgendaAgendamentoVM();
li.Id = item.AgendaId;
li.Date = DateTime.Parse(item.DataAgenda.ToString());
li.ClienteNome = reservas.Select(a => a.Nome).ToList();
_listaAgendaVM.Add(li);
}
ViewData["ListaAgenda"] = _listaAgendaVM;
return View();
}
return View();
}
Result:

How to pass List model to controller from view http post

I have a CategoryModel that contains a list item for the ItemModel as well as some other strings etc.
I'm trying to pass the list from the view to the controller. The model on the view is the ABCModel which contains a list of 'Categories' of type CategoryModel. On the view I'm only looking to post the 'active' Category back to be saved.
When I do this the active category is passed with details added from the form but the list of items is null.
.cs Models
namespace Company.Models
{
public class ABCModel
{
public IList<CategoryModel> Categories;
public SummaryModel Summary;
}
}
namespace Company.Models
{
public class CategoryModel
{
public string Label { get; set; }
public bool Active { get; set; }
public decimal Amount { get; set; }
public string Frequency { get; set; }
public string Type { get; set; }
public List<ItemModel> Items;
}
)
namespace Company.Models
{
public class ItemModel
{
public string Label { get; set; }
public string Explanation { get; set; }
public string Amount { get; set; }
public string Frequency { get; set; }
public bool Flag { get; set; }
public string Note { get; set; }
}
}
Controller
[HttpPost]
public ActionResult SaveItems([FromForm] CategoryModel activeCategoryModel, [FromForm] List<ItemModel> items, [FromQuery] string activecategory, [FromQuery] string nextcategory)
{
...
}
View
#model ABCModel
#{ CategoryModel nextCategory = null; }
#{ CategoryModel activeCategoryModel = null; }
#if (Model.Categories.Any())
{
#for (var i = 0; i < Model.Categories.Count; i++)
{
Company.Models.CategoryModel category = Model.Categories[i];
#if (category.Active)
{
activeCategoryModel = category;
if ((i + 1 < Model.Categories.Count) && (Model.Categories[i + 1] != null))
{
nextCategory = Model.Categories[i + 1];
}
}
}
}
<form id="ABC-form" class="needs-validation" novalidate="" asp-action="SaveItems" asp-controller="Home" method="post">
#if (activeCategoryModel != null)
{
<input asp-for="#activeCategoryModel.Label" type="hidden" />
<input asp-for="#activeCategoryModel.Active" type="hidden" />
<input asp-for="#activeCategoryModel.Amount" type="hidden" />
<input asp-for="#activeCategoryModel.Frequency" type="hidden" />
<input asp-for="#activeCategoryModel.Type" type="hidden" />
#if (activeCategoryModel.Items.Any())
{
#for (var i = 0; i < activeCategoryModel.Items.Count; i++)
{
#Html.HiddenFor(x => activeCategoryModel.Items[i].Label)
#Html.HiddenFor(x => activeCategoryModel.Items[i].Explanation)
#Html.TextBoxFor(x => items[i].Amount, new { #class = "form-control" })
}
}
}
<button id="continue" type="submit" asp-action="SaveItems" asp-route-activecategory="#activeCategoryModel.Label" asp-route-nextcategory="#(nextCategory != null ? nextCategory?.Label : null)">Continue</button>
</form>
I had been including IFormCollection as a parameter within the SaveItems on the controller and this showed that the items are being passed in the format I was thinking would work but the model only shows the values entered and the list of items is null.
How can I populate the list of items on the active category model from the view?
Items in CategoryModel should be a property not a filed,so your CategoryModel should be like below:
public class CategoryModel
{
public string Label { get; set; }
public bool Active { get; set; }
public decimal Amount { get; set; }
public string Frequency { get; set; }
public string Type { get; set; }
public List<ItemModel> Items { get; set; }
}

How to show dynamic category in razor page?

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>

MVC Multiple Models in One View

I want to reach multiple models in one view. I have DAL folder and DbContext.
class CvContext : DbContext
{
public CvContext() : base("CvContext")
{
}
public DbSet<LinkModel> Links { get; set; }
public DbSet<AboutModel> Abouts { get; set; }
public DbSet<PortfolioModel> Portfolios { get; set; }
public DbSet<SkillModel> Skills { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
And HomeController
public class HomeController : Controller
{
private CvContext db = new CvContext();
public ActionResult Index()
{
return View(db.Links.ToList());
}
}
Index.cshtml
#model IEnumerable<MvcCv.Models.LinkModel>
<ul>
#foreach (var item in Model)
{
<li>
<a href="#Html.DisplayFor(modelItem => item.LinkUrl)">
#Html.DisplayFor(modelItem => item.LinkName)
<span class="icon"></span>
<span class="menu-icon">
<img src="#Url.Content(item.LinkImage)" alt="" />
</span>
</a>
</li>
}
</ul>
How can i reach all models? I will use foreach for item in Model like Links. Thanks.
You should create a view model as follows:
public class FooViewModel
{
public IEnumerable<LinkModel> Links { get; set; }
public IEnumerable<AboutModel> Abouts { get; set; }
public IEnumerable<PortfolioModel> Portfolios { get; set; }
public IEnumerable<SkillModel> Skills { get; set; }
}
Then from your controller populate them as to your requirements, as an example:
public ActionResult Index()
{
var model = new FooViewModel();
model.Links = db.Links.ToList();
model.Abouts = db.Abouts.ToList();
model.Portfolios = db.Portfolios.ToList();
model.Skills = db.Skills.ToList();
return View(model);
}
Then change the model in your view to FooViewModel and all your properties will be available in there.
#model FooViewModel
<ul>
#foreach (var item in Model.Links)
{
<li>
#item
</li>
}
</ul>
<ul>
#foreach (var item in Model.Links)
{
<li>
#item
</li>
}
</ul>
// ....etc, obviously change the outputs as needed.
//suppose you have two Models
public class student
{
public int Id
public string Name{get;set;}
}
public class class
{
public int Id
public string Name{get;set;}
}
// Now combine these two class Model in single Model for example:
public class Mixmodel
{
public Student student {get;set;}
public Class class {get;set;}
}
//here is the Home controller of the Index view
#model projectName.MixModel
#foreach(var item in Model.class)
{
#html.displayfor(item.class.Name)
}
#foreach(var item in Model.student)
{
#html.displayfor(item.student.Name)
}

How to display create form in an existing MVC 4 view and C#

I have view to display Restaurant. In this view at the bottom of the page, I want to display Comments form to add comments about that Restaurant.
Can someone please help me to do this using MVC 4 & C#.
My Models has the followign two tables:
/Classifieds TABLE
public class Classifieds
{
[Key]
public string C_Unique_Id { get; set; }
public string AdType { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
//ClassifiedsComments TABLE
public class ClassifiedsComments
{
[Key]
public string CCommentsUniqueId { get; set; }
public string CommentAuthor { get; set; }
public string Comment { get; set; }
[ForeignKey("Classifieds")]
public string C_Unique_Id { get; set; } //this is the foreign key of Classified record
public virtual Classifieds Classifieds { get; set; }
}
Classifieds Details view:
#model SomeIndianShit.Models.Classifieds
#{
ViewBag.Title = "Details";
}
<table class="recordDetailsDisplayTableStype">
<tr>
<td colspan="2" align="left">
#Html.DisplayFor(model => model.Description)
<br /><br />
</td>
</tr>
<tr>
<td>
Ad Type
</td>
<td align="left"> :
#Html.DisplayFor(model => model.AdType)
</td>
</tr>
SOME OTHER FIELDS DISPLAY HERE
</table>
//Here I want to display "ClassifiedsComments" form to add comments to above Classified.
//HOW can I display the ClassifiedsComments create.cshtml code here??
Try this:
With View:
#using (Html.BeginForm("Classifieds", "ClassifiedsDetails", FormMethod.Post))
and
#using (Html.BeginForm("ClassifiedsComments", "ClassifiedsDetails", FormMethod.Post))
And use 1 Model for this:
public class ClassifiedsDetails
{
public Classifieds Model1{ get; set; }
public ClassifiedsComments Model2{ get; set; }
}
Update:
public class ClassifiedsDetails
{
public ClassifiedsDetails()
{
Model1 = new Classifieds();
Model2 = new ClassifiedsComments();
}
public Classifieds Model1{ get; set; }
public ClassifiedsComments Model2{ get; set; }
}
public class Classifieds
{
public Classifieds()
{
C_Unique_Id = String.Emty;
AdType = String.Emty;
//---- Add default setting here------
}
[Key]
public string C_Unique_Id { get; set; }
public string AdType { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
Or display list of comments in View with Model:
public class ClassifiedsDetails
{
public ClassifiedsDetails()
{
Model1 = new Classifieds();
Model2 = new List<ClassifiedsComments>();
}
public Classifieds Model1{ get; set; }
public List<ClassifiedsComments> Model2{ get; set; }
}
View:
#model ClassifiedsDetails
#Html.LabelFor(model => model.Model1.Title)
#foreach (var items in Model.Model2)
{
#item. //fields
}
To display data in view create view model, but to post comment, dont use model:
public class ClassifiedsViewModel
{
public ClassifiedsViewModel()
{
Comments = new List<ClassifiedsComments>();
}
public Classifieds Classifieds { get; set; }
public List<ClassifiedsComments> Comments { get; set; }
}
Fill this view model, use in view to display details and comments like above you write.
if(Model != null && Model.Classifieds != null)
{
<table> ...display details.. </table>
}
if(Model != null && Model.Comments != null)
{
<table> ...display comments with foreach loop.. </table>
}
And at bottom, create comment post form
#using (Html.BeginForm("SaveComment", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//set to which Classifieds will this comment posted
#Html.Hidden("C_Unique_Id", Model.Classifieds.C_Unique_Id)
<fieldset>
#Html.TextBox("Comment")
//other fields ....
<input type="submit" value="Save" />
</fieldset>
}
Edit2: View model creating:
public ActionResult Details(int id)
{
//add breakpoint here and follow any step.
ClassifiedsViewModel viewModel = new ClassifiedsViewModel();
viewModel.Classifieds = db.Classifieds.Find(id);
viewModel.Comments = db.LoadCommentsByClassifiedsId(id); //create db method
// or instead of this line use:
viewModel.Comments = db.ClassifiedsComments.Where(e => e.C_Unique_Id == id).ToList();
return(viewModel);
}
You can then add a ViewModel like this
public class ClassifiedsDetailViewModel
{
public ClassifiedsDetailViewModel()
{
ClassifiedsComments = new ClassifiedsComments();
}
public Classifieds Classifieds { get; set; }
public ClassifiedsComments ClassifiedsComments { get; set; }
}
Pass this view model to your view and then add #Html.Partial("_CreateClassifiedsCommentsFormPartial", Model.ClassifiedComments) below the table. And in your partial view, you can use Html.BeginForm or the Ajax.BeginForm.
See sample here

Categories

Resources