Solved

MVC - Data-driven FAQs with nested Questions

Posted on 2013-11-30
8
222 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
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

759 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