Solved

MVC - Data-driven FAQs with nested Questions

Posted on 2013-11-30
8
223 Views
Last Modified: 2013-12-01
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:

 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
                }

            );
        }
    }

Open in new window


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);

        }

Open in new window


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>

Open in new window


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
0
Comment
Question by:RBS
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
8 Comments
 
LVL 8

Expert Comment

by:Mohit Vijay
ID: 39687826
Hello

SubFaqDtos method should be your model, not in controller.
0
 

Author Comment

by:RBS
ID: 39688216
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.
0
 
LVL 8

Expert Comment

by:Mohit Vijay
ID: 39688233
for Model I mean to say but SubFaqDtos in ScormLink.Models.MyViewModel, I think this is what you did.

Now its working?
0
How To Install Bash on Windows 10

Windows’ budding partnership with Canonical has certainly led to some great improvements. One of them being the ability to use Bash on your Windows machine without third party applications! This might be one of the greatest things a cloud engineer in a Windows environment can do!

 

Author Comment

by:RBS
ID: 39688278
I do not understand what you mean - could  you explain by changing the code you are talking about?
0
 
LVL 8

Expert Comment

by:Mohit Vijay
ID: 39688298
can you send me code for ScormLink.Models.MyViewModel and SubFaqDtos?
0
 

Author Comment

by:RBS
ID: 39688305
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; }
    }
}

Open in new window

0
 
LVL 8

Accepted Solution

by:
Mohit Vijay earned 500 total points
ID: 39688313
So You are having SubFaqDtos as property, but in your view you are using it as method.

So You have to opt one of below changes

1
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 ()
{
//some code that return IEnumerable<FaqDto>
}
    }
}

Open in new window


2. in your view, you change that line as

@foreach (var subItem in Model.SubFaqDtos)
                        {

Open in new window

0
 

Author Closing Comment

by:RBS
ID: 39688336
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.GetSubFaqsSorted(parentId);
        }
    }
}

Thanks again VjSoft - I didn't think I would get this going today.

RBS
0

Featured Post

Is Your Team Achieving Their Full Potential?

74% of employees feel they are not achieving their full potential. With Linux Academy, not only will you strengthen your team's core competencies but also their knowledge of of the newest IT topics.

With new material every week, we'll make sure that you stay ahead of the game.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

635 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question