Solved

MVC - Data-driven FAQs with nested Questions

Posted on 2013-11-30
8
220 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
  • 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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

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

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
I need help making a collection from a class in VB.Net 3 33
VB: Convert 2 dates to specific format 24 48
Modal Popup Extender control 1 20
.NET 2008 VB and C# 6 28
The object model of .Net can be overwhelming at times – so overwhelming that quite trivial tasks often take hours of research. In this case, the task at hand was to populate the datagrid from SQL Server database in Visual Studio 2008 Windows applica…
This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

810 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