From f83d5c492b765285d38a5d740ee781151a32a4e9 Mon Sep 17 00:00:00 2001 From: Qais Yousuf Date: Tue, 12 Mar 2024 16:57:42 +0100 Subject: [PATCH] the questionnaire mode CURD complete --- Services/Implemnetation/QuestionRepository.cs | 6 + .../Implemnetation/QuestionnaireRepository.cs | 7 +- Services/Interaces/IQuestionRepository.cs | 2 + .../Interaces/IQuestionnaireRepository.cs | 1 + .../Controllers/QuestionnaireController.cs | 233 ++++++++++-- .../Admin/Views/Questionnaire/Create.cshtml | 355 ++++-------------- .../Admin/Views/Questionnaire/Delete.cshtml | 270 +++++++++++++ .../Admin/Views/Questionnaire/Edit.cshtml | 294 +++++++++++++++ .../Admin/Views/Questionnaire/Index.cshtml | 26 +- .../Admin/Views/Shared/_AdminLayout.cshtml | 4 +- 10 files changed, 881 insertions(+), 317 deletions(-) create mode 100644 Web/Areas/Admin/Views/Questionnaire/Delete.cshtml create mode 100644 Web/Areas/Admin/Views/Questionnaire/Edit.cshtml diff --git a/Services/Implemnetation/QuestionRepository.cs b/Services/Implemnetation/QuestionRepository.cs index 85761b7..dbded3a 100644 --- a/Services/Implemnetation/QuestionRepository.cs +++ b/Services/Implemnetation/QuestionRepository.cs @@ -1,4 +1,5 @@ using Data; +using Microsoft.EntityFrameworkCore; using Model; using Services.Interaces; using System; @@ -36,5 +37,10 @@ namespace Services.Implemnetation { throw new NotImplementedException(); } + + public List GetQuestionsWithAnswers() + { + return _context.Questions.AsNoTracking().Include(x=>x.Answers).ToList(); + } } } diff --git a/Services/Implemnetation/QuestionnaireRepository.cs b/Services/Implemnetation/QuestionnaireRepository.cs index 97ff2e2..a125349 100644 --- a/Services/Implemnetation/QuestionnaireRepository.cs +++ b/Services/Implemnetation/QuestionnaireRepository.cs @@ -47,7 +47,12 @@ namespace Services.Implemnetation public List GetQuestionnairesWithQuestion() { - return _context.Questionnaires.AsNoTracking().Include(x=>x.Questions).ToList(); + return _context.Questionnaires.AsNoTracking().Include(x=>x.Questions).ThenInclude(x=>x.Answers).ToList(); + } + + public Questionnaire GetQuestionnaireWithQuestionAndAnswer(int? id) + { + return _context.Questionnaires.AsNoTracking().Include(x => x.Questions).ThenInclude(x => x.Answers).FirstOrDefault(x=>x.Id==id); } public void Update(Questionnaire questionnaire) diff --git a/Services/Interaces/IQuestionRepository.cs b/Services/Interaces/IQuestionRepository.cs index cc23652..4c597d7 100644 --- a/Services/Interaces/IQuestionRepository.cs +++ b/Services/Interaces/IQuestionRepository.cs @@ -11,6 +11,8 @@ namespace Services.Interaces { List GetAllQuestions(); + List GetQuestionsWithAnswers(); + Question GetQuestionById(int id); void Add(Question question); diff --git a/Services/Interaces/IQuestionnaireRepository.cs b/Services/Interaces/IQuestionnaireRepository.cs index dd06918..762c594 100644 --- a/Services/Interaces/IQuestionnaireRepository.cs +++ b/Services/Interaces/IQuestionnaireRepository.cs @@ -12,6 +12,7 @@ namespace Services.Interaces List GetAllQuestions(); List GetQuestionnairesWithQuestion(); Questionnaire GetQuesById(int? id); + Questionnaire GetQuestionnaireWithQuestionAndAnswer(int? id); void Add(Questionnaire questionnaire); void Update(Questionnaire questionnaire); diff --git a/Web/Areas/Admin/Controllers/QuestionnaireController.cs b/Web/Areas/Admin/Controllers/QuestionnaireController.cs index b7f967c..22fe76a 100644 --- a/Web/Areas/Admin/Controllers/QuestionnaireController.cs +++ b/Web/Areas/Admin/Controllers/QuestionnaireController.cs @@ -2,8 +2,10 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Model; +using Services.Implemnetation; using Services.Interaces; using Web.ViewModel.QuestionnaireVM; +using Web.ViewModel.QuestionVM; namespace Web.Areas.Admin.Controllers { @@ -24,6 +26,10 @@ namespace Web.Areas.Admin.Controllers var questionnaire = _questionnaire.GetQuestionnairesWithQuestion(); + var question = _question.GetQuestionsWithAnswers(); + + + List viewmodel = new List(); @@ -34,7 +40,10 @@ namespace Web.Areas.Admin.Controllers Id = item.Id, Description = item.Description, Title = item.Title, - Questions = item.Questions + Questions = item.Questions, + + + }); } @@ -91,7 +100,7 @@ namespace Web.Areas.Admin.Controllers QuestionnaireId=questionViewModel.QuestionnaireId, Text = questionViewModel.Text, Type = questionViewModel.Type, - Answers = new List() // Initialize the list of answers for each question + Answers = new List() }; foreach (var answerViewModel in questionViewModel.Answers) @@ -103,41 +112,16 @@ namespace Web.Areas.Admin.Controllers }; - // Add the answer to the list of answers for the current question + question.Answers.Add(answer); } - // Add the question to the list of questions for the questionnaire + questionnaire.Questions.Add(question); } - //var answers = questions.Where(x => x.Answers == viewmodel.Answers); - - - //foreach (var question in questions) - //{ - - // questionnaire.Questions.Add(new Question - // { - // Id = question.Id, - // Text=question.Text, - // Type=question.Type, - // QuestionnaireId=questionnaire.Id, - - - // }); - - // //foreach(var answer in answers) - // //{ - // // question.Answers.Add(new Answer - // // { - // // Id=answer - // // }); - // //} - - - //} + _questionnaire.Add(questionnaire); await _questionnaire.commitAsync(); @@ -149,6 +133,193 @@ namespace Web.Areas.Admin.Controllers } return View(viewmodel); } - + + [HttpGet] + public IActionResult Edit(int id) + { + var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast(); + + ViewBag.QuestionTypes = new SelectList(questionTypes); + var questionnaire = _questionnaire.GetQuestionnaireWithQuestionAndAnswer(id); + + if (questionnaire == null) + { + return NotFound(); // Or handle not found case appropriately + } + + var viewModel = new QuestionnaireViewModel + { + Id = questionnaire.Id, + Title = questionnaire.Title, + Description = questionnaire.Description, + Questions = questionnaire.Questions + .Select(q => new Question + { + Id = q.Id, + Text = q.Text, + Type = q.Type, + Answers = q.Answers.Select(a => new Answer + { + Id = a.Id, + Text = a.Text + }).ToList() + }).ToList() + }; + + return View(viewModel); + } + + [HttpPost] + public async Task Edit(QuestionnaireViewModel viewModel) + { + + var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast(); + + ViewBag.QuestionTypes = new SelectList(questionTypes); + if (ModelState.IsValid) + { + // Retrieve the existing questionnaire from the database + var existingQuestionnaire = _questionnaire.GetQuestionnaireWithQuestionAndAnswer(viewModel.Id); + + if (existingQuestionnaire == null) + { + return NotFound(); // Or handle not found case appropriately + } + + // Update the existing questionnaire with the data from the view model + existingQuestionnaire.Title = viewModel.Title; + existingQuestionnaire.Description = viewModel.Description; + + var Question = viewModel.Questions.ToList(); + + if(Question.Count()!=0) + { + foreach (var questionViewModel in viewModel.Questions) + { + + var existingQuestion = existingQuestionnaire.Questions.FirstOrDefault(q => q.Id == questionViewModel.Id); + + if (existingQuestion != null) + { + existingQuestion.Text = questionViewModel.Text; + existingQuestion.Type = questionViewModel.Type; + + // Update answers + foreach (var answerViewModel in questionViewModel.Answers) + { + var existingAnswer = existingQuestion.Answers.FirstOrDefault(a => a.Id == answerViewModel.Id); + + if (existingAnswer != null) + { + existingAnswer.Text = answerViewModel.Text; + existingAnswer.QuestionId = answerViewModel.QuestionId; + } + else + { + // Handle adding new answers if necessary + existingQuestion.Answers.Add(new Answer { Text = answerViewModel.Text }); + } + } + } + + } + } + else + { + foreach (var questionViewModel in viewModel.Questions) + { + + var existingQuestion = existingQuestionnaire.Questions.FirstOrDefault(q => q.Id == questionViewModel.Id); + + if (existingQuestion != null) + { + existingQuestion.Text = questionViewModel.Text; + existingQuestion.Type = questionViewModel.Type; + + // Update answers + foreach (var answerViewModel in questionViewModel.Answers) + { + var existingAnswer = existingQuestion.Answers.FirstOrDefault(a => a.Id == answerViewModel.Id); + + if (existingAnswer != null) + { + existingAnswer.Text = answerViewModel.Text; + existingAnswer.QuestionId = answerViewModel.QuestionId; + } + else + { + // Handle adding new answers if necessary + existingQuestion.Answers.Add(new Answer { Text = answerViewModel.Text }); + } + } + } + + } + } + + // Update questions + + + + + // Save changes to the database + _questionnaire.Update(existingQuestionnaire); + TempData["Success"] = "Questionnaire updated successfully"; + await _questionnaire.commitAsync(); + + return RedirectToAction("Index"); + } + + // If the model state is not valid, return to the edit view with the existing model + return View(viewModel); + } + + [HttpGet] + public IActionResult Delete(int id) + { + + var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast(); + + ViewBag.QuestionTypes = new SelectList(questionTypes); + var questionnaire = _questionnaire.GetQuestionnaireWithQuestionAndAnswer(id); + + if (questionnaire == null) + { + return NotFound(); // Or handle not found case appropriately + } + + var viewModel = new QuestionnaireViewModel + { + Id = questionnaire.Id, + Title = questionnaire.Title, + Description = questionnaire.Description, + Questions = questionnaire.Questions + .Select(q => new Question + { + Id = q.Id, + Text = q.Text, + Type = q.Type, + Answers = q.Answers.Select(a => new Answer + { + Id = a.Id, + Text = a.Text + }).ToList() + }).ToList() + }; + + return View(viewModel); + } + + [HttpPost] + [ActionName("Delete")] + public IActionResult DeleteConfirm(int id) + { + _questionnaire.Delete(id); + _questionnaire.commitAsync(); + + return Json(new { success = true, message = "Item deleted successfully" }); + TempData["Success"] = "Questionnaire deleted successfully"; + } + } } diff --git a/Web/Areas/Admin/Views/Questionnaire/Create.cshtml b/Web/Areas/Admin/Views/Questionnaire/Create.cshtml index 9e92226..67b70be 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Create.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Create.cshtml @@ -6,9 +6,9 @@ }
-
+
-
Create Survey
+
Create questionnaire
@@ -23,82 +23,54 @@
- +
-
-

Create Questions

-
- @for (int i = 0; i < Model.Questions?.Count; i++) - { -
- - - -
-
- - @for (int j = 0; j < Model.Answers?.Count; j++) - { -
- - -
- } - - - -
- } -
-
- - - @*
+
+
+

Create Questions

-
+
@for (int i = 0; i < Model.Questions?.Count; i++) { -
+
- + + +
+ + @for (int j = 0; j < Model.Questions?[i].Answers?.Count; j++) + { +
+ + +
+ } + + + +
+
-
- - @for (int j = 1; j < Model.Questions?[i].Answers?.Count; j++) - { -
- - -
- } - - - -
- - - }
- - -
- - -
*@ - - - | Back to list + + +
+ + | Back to list +
+
+ +
@@ -111,8 +83,13 @@ @section Scripts { + + + @{ - + } @@ -122,32 +99,40 @@ $("#add-question-btn").click(function () { var newQuestionHtml = ` -
- - - +
+ + `; // Add answers input fields - newQuestionHtml += `
`; - newQuestionHtml += ``; - newQuestionHtml += `
`; - newQuestionHtml += ``; - newQuestionHtml += ``; - newQuestionHtml += ``; - newQuestionHtml += `
`; - newQuestionHtml += `
`; + newQuestionHtml += `
`; + newQuestionHtml += `

`; + newQuestionHtml += ``; + newQuestionHtml += `

`; + newQuestionHtml += ``; + newQuestionHtml += ``; + newQuestionHtml += ``; + newQuestionHtml += `

`; + newQuestionHtml += `
`; newQuestionHtml += `
`; - + newQuestionHtml += `
`; + + // Add Remove Question button + newQuestionHtml += ``; + newQuestionHtml += `
` + newQuestionHtml += `
`; + $("#questions-container .form-group").append(newQuestionHtml); questionIndex++; }); @@ -158,9 +143,12 @@ var answerIndex = $(this).closest('.answers-container').find('.answer-group').length; var answerGroup = $(this).closest('.answers-container').find('.answer-group:first').clone(); answerGroup.find('input').val(''); // Clear input values + answerGroup.find('.add-answer').hide(); // Hide the "Add Answer" button answerGroup.find('.remove-answer').show(); // Show the "Remove Answer" button + answerGroup.data('answer-index', answerIndex); + answerGroup.find('label').text(`Answer ${answerIndex + 1}`); answerGroup.find('input').attr('name', `Questions[${questionIndex}].Answers[${answerIndex}].Text`); $(this).closest('.answers-container').append(answerGroup); }); @@ -169,204 +157,21 @@ $("#questions-container").on("click", ".remove-answer", function () { $(this).closest('.answer-group').remove(); }); + + // Remove question dynamically + $("#questions-container").on("click", ".remove-question", function () { + $(this).closest('.question-group').remove(); + }); }); - @* *@ + - - - - - - @* *@ - - @* *@ - - - - - + + - @* *@ + } \ No newline at end of file diff --git a/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml b/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml new file mode 100644 index 0000000..67d3930 --- /dev/null +++ b/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml @@ -0,0 +1,270 @@ +@model QuestionnaireViewModel + +@{ + ViewData["Title"] = "Delete"; +} +
+
+
+
Delete questionnaire
+
Are you sure you want to delete this questionnaire: @Model.Title
+ +
+ + +
+
+ +
+ + + +
+
+ + + +
+
+ Total Number of questions: @Model.Questions.Count
+ @* Total Number of answer: @Model.Questions.Select(x=>x.Answers.Select(x=>x.Id)).Count() *@ +
+ + + + +
+
+ + + +
+
+
+
+
+ + + + + + @* *@ + + + + +@section Scripts { + + + + + + + + + + + + @{ + + } + + + @* *@ + + +} \ No newline at end of file diff --git a/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml b/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml new file mode 100644 index 0000000..b9e1074 --- /dev/null +++ b/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml @@ -0,0 +1,294 @@ +@model QuestionnaireViewModel + +@{ + ViewData["Title"] = "Edit"; +} + +
+
+
+
Create Survey
+ +
+ + +
+
+ +
+ + + +
+
+ + + +
+
+ +
+ +

Create Questions

+
+ @for (int i = 0; i < Model.Questions?.Count; i++) + { +
+ + + + +
+ + @for (int j = 0; j < Model.Questions?[i].Answers?.Count; j++) + { +
+ + +
+ } + + + +
+ +
+ } +
+
+ + + +
+ + | Back to list +
+
+ + +
+
+
+
+
+
+
+ +@section Scripts { + + + + + @{ + + } + + + + @* *@ + @* *@ + + + + + + + } + + diff --git a/Web/Areas/Admin/Views/Questionnaire/Index.cshtml b/Web/Areas/Admin/Views/Questionnaire/Index.cshtml index a0179ab..8e4c1ac 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Index.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Index.cshtml @@ -3,26 +3,26 @@ @{ ViewData["Title"] = "Questionnaire"; } -
+
-
+
Questionnaire

Questionnaire list

Create New

- - +
- + + @@ -34,14 +34,23 @@ - + + @@ -63,3 +72,4 @@ + diff --git a/Web/Areas/Admin/Views/Shared/_AdminLayout.cshtml b/Web/Areas/Admin/Views/Shared/_AdminLayout.cshtml index 684a230..e4e00e7 100644 --- a/Web/Areas/Admin/Views/Shared/_AdminLayout.cshtml +++ b/Web/Areas/Admin/Views/Shared/_AdminLayout.cshtml @@ -45,7 +45,7 @@ -
+
-
+
@RenderBody()
Id Title DescriptionQaustion & Questions TypeNumber of questionsTotal Question Action
@item.Id @item.Title @item.Description + Total Questions:@item.Questions?.Count() + + @foreach (var question in item.Questions) { - Question:@question.Text - Type: @question.Type + Question:@question.Text + Type: @question.Type + foreach (var answer in question.Answers) + { + Asnwer:@answer.Text + } + }