RBS
asked on
MVC - Data-driven FAQs with nested Questions
Hi:
I have an MVC app that uses bootstrap that creates accordion panels of questions that are driven from the database. All works fine. However, I'd like to be able to create data-driven sub-questions (1 level deep) and am having difficulty.
I have a data repository that appears as follows:
To initiate my view, I have the following:
Finally, my view is as follows:
Problem is, in the line: @foreach (var subItem in Model.SubFaqDtos(myItem.Id )) in the View, I'm getting the error that a method, delegate or event is required. I'm not sure how to handle this. Any help greatly appreciated.
RBS
I have an MVC app that uses bootstrap that creates accordion panels of questions that are driven from the database. All works fine. However, I'd like to be able to create data-driven sub-questions (1 level deep) and am having difficulty.
I have a data repository that appears as follows:
public class FaqsRepository : BaseRepository<Faq>, IFaqsRepository
{
public FaqsRepository(ScormLinkDbContext context)
: base(context)
{
}
public IEnumerable<FaqDto> GetFaqsSorted()
{
return DbSet.OrderBy(e => e.SortOrder)
.Select(f => new FaqDto
{
Id = f.Id,
Question =f.Question,
Answer=f.Answer,
SortOrder=f.SortOrder,
AnswerLink= "#" + f.SortOrder ,
AnswerId = f.SortOrder
}
);
}
public IEnumerable<FaqDto> GetSubFaqsSorted(int parentId)
{
return DbSet.OrderBy(e => e.SortOrder)
.Where(e => e.ParentId == parentId)
.Select(f => new FaqDto
{
Id = f.Id,
Question = f.Question,
Answer = f.Answer,
SortOrder = f.SortOrder,
AnswerLink = "#" + f.SortOrder,
AnswerId = f.SortOrder
}
);
}
}
To initiate my view, I have the following:
public ActionResult Scorm()
{
var viewModel = new MyViewModel
{
FaqBriefs = _faqsRepository.GetFaqsSorted(),
SubFaqDtos = _faqsRepository.GetSubFaqsSorted(0)
};
return View(viewModel);
}
Finally, my view is as follows:
@model ScormLink.Models.MyViewModel
<div class="container pageWrap">
<h2>SCORM - Asked and Answered</h2>
<div id="accordion" class="panel-group">
@foreach (var item in Model.FaqBriefs)
{
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href=@Html.DisplayFor(modelItem => item.AnswerLink)>@Html.Raw(item.Question)</a>
</div>
</div>
<div id=@Html.DisplayFor(modelItem => item.AnswerId) class="panel-collapse collapse ">
<div class="panel-body">
@Html.Raw(item.Answer)
var myItem = item;
@foreach (var subItem in Model.SubFaqDtos(myItem.Id))
{
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href=@Html.DisplayFor(modelItem => subItem.AnswerLink)>@Html.Raw(subItem.Question)</a>
</div>
</div>
<div id=@Html.DisplayFor(modelItem => subItem.AnswerId) class="panel-collapse collapse ">
<div class="panel-body">
@Html.Raw(item.Answer)
</div>
</div>
</div>
}
</div>
</div>
</div>
}
</div>
</div>
Problem is, in the line: @foreach (var subItem in Model.SubFaqDtos(myItem.Id
RBS
ASKER
I'm sorry, I don't know what you mean. I put it in MyViewModel from my controller just as I put FaqDtos in MyViewModel.
for Model I mean to say but SubFaqDtos in ScormLink.Models.MyViewMod el, I think this is what you did.
Now its working?
Now its working?
ASKER
I do not understand what you mean - could you explain by changing the code you are talking about?
can you send me code for ScormLink.Models.MyViewMod el and SubFaqDtos?
ASKER
Sure:
using System.Collections.Generic;
using ScormLink.Model;
namespace ScormLink.Models
{
public class MyViewModel
{
public virtual IEnumerable<FaqDto> FaqBriefs { get; set; }
public virtual IEnumerable<FaqDto> SubFaqDtos { get; set; }
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Great - thanks! I didn't realize that ViewModels could include methods. Here's the main change I made - and it works!
using System.Collections.Generic ;
using ScormLink.Data;
using ScormLink.Model;
namespace ScormLink.Models
{
public class SCORMViewModel
{
private readonly FaqsRepository _faqsRepository;
private readonly ScormLinkDbContext _db = new ScormLinkDbContext();
public SCORMViewModel()
{
_faqsRepository = new FaqsRepository(_db);
}
public virtual IEnumerable<FaqDto> FaqBriefs { get; set; }
public virtual IEnumerable<FaqDto> SubFaqDtos(int parentId)
{
return _faqsRepository.GetSubFaqs Sorted(par entId);
}
}
}
Thanks again VjSoft - I didn't think I would get this going today.
RBS
using System.Collections.Generic
using ScormLink.Data;
using ScormLink.Model;
namespace ScormLink.Models
{
public class SCORMViewModel
{
private readonly FaqsRepository _faqsRepository;
private readonly ScormLinkDbContext _db = new ScormLinkDbContext();
public SCORMViewModel()
{
_faqsRepository = new FaqsRepository(_db);
}
public virtual IEnumerable<FaqDto> FaqBriefs { get; set; }
public virtual IEnumerable<FaqDto> SubFaqDtos(int parentId)
{
return _faqsRepository.GetSubFaqs
}
}
}
Thanks again VjSoft - I didn't think I would get this going today.
RBS
SubFaqDtos method should be your model, not in controller.