diff --git a/Data/SurveyContext.cs b/Data/SurveyContext.cs index e4933bb..7e1d741 100644 --- a/Data/SurveyContext.cs +++ b/Data/SurveyContext.cs @@ -51,7 +51,7 @@ namespace Data modelBuilder.Entity() - .HasKey(q => q.Id); + .HasKey(q => q.Id); modelBuilder.Entity() .HasMany(q => q.Questions) diff --git a/Services/Implemnetation/QuestionnaireRepository.cs b/Services/Implemnetation/QuestionnaireRepository.cs index a125349..e939124 100644 --- a/Services/Implemnetation/QuestionnaireRepository.cs +++ b/Services/Implemnetation/QuestionnaireRepository.cs @@ -58,6 +58,7 @@ namespace Services.Implemnetation public void Update(Questionnaire questionnaire) { _context.Questionnaires.Update(questionnaire); + } } } diff --git a/Web/Areas/Admin/Controllers/QuestionnaireController.cs b/Web/Areas/Admin/Controllers/QuestionnaireController.cs index 22fe76a..62be761 100644 --- a/Web/Areas/Admin/Controllers/QuestionnaireController.cs +++ b/Web/Areas/Admin/Controllers/QuestionnaireController.cs @@ -1,11 +1,13 @@ using Data; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Model; -using Services.Implemnetation; + using Services.Interaces; +using System.Security.Cryptography; using Web.ViewModel.QuestionnaireVM; -using Web.ViewModel.QuestionVM; + namespace Web.Areas.Admin.Controllers { @@ -135,11 +137,13 @@ namespace Web.Areas.Admin.Controllers } [HttpGet] - public IActionResult Edit(int id) + public IActionResult Edit(int? id) { - var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast(); - - ViewBag.QuestionTypes = new SelectList(questionTypes); + var questionTypes = Enum.GetValues(typeof(QuestionType)) + .Cast() + .Select(e => new SelectListItem { Value = e.ToString(), Text = e.ToString() }); + ViewBag.QuestionTypes = questionTypes; + var questionnaire = _questionnaire.GetQuestionnaireWithQuestionAndAnswer(id); if (questionnaire == null) @@ -147,21 +151,26 @@ namespace Web.Areas.Admin.Controllers return NotFound(); // Or handle not found case appropriately } - var viewModel = new QuestionnaireViewModel + var viewModel = new EditQuestionnaireViewModel { 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 + Text = a.Text, + Question=a.Question + }).ToList() }).ToList() }; @@ -170,12 +179,14 @@ namespace Web.Areas.Admin.Controllers } [HttpPost] - public async Task Edit(QuestionnaireViewModel viewModel) + public async Task Edit(EditQuestionnaireViewModel viewModel) { - var questionTypes = Enum.GetValues(typeof(QuestionType)).Cast(); + var questionTypes = Enum.GetValues(typeof(QuestionType)) + .Cast() + .Select(e => new SelectListItem { Value = e.ToString(), Text = e.ToString() }); + ViewBag.QuestionTypes = questionTypes; - ViewBag.QuestionTypes = new SelectList(questionTypes); if (ModelState.IsValid) { // Retrieve the existing questionnaire from the database @@ -190,77 +201,149 @@ namespace Web.Areas.Admin.Controllers existingQuestionnaire.Title = viewModel.Title; existingQuestionnaire.Description = viewModel.Description; - var Question = viewModel.Questions.ToList(); - - if(Question.Count()!=0) + // Update or add new questions + foreach (var questionViewModel in viewModel.Questions) { - foreach (var questionViewModel in viewModel.Questions) + var existingQuestion = existingQuestionnaire.Questions.SingleOrDefault(q => q.Id == questionViewModel.Id); + + + if (existingQuestion != null) { + existingQuestion.Text = questionViewModel.Text; + existingQuestion.Type = questionViewModel.Type; - var existingQuestion = existingQuestionnaire.Questions.FirstOrDefault(q => q.Id == questionViewModel.Id); + bool newAnswersAdded = false; // Flag to track if new answers were added - if (existingQuestion != null) - { - existingQuestion.Text = questionViewModel.Text; - existingQuestion.Type = questionViewModel.Type; - - // Update answers + // Check if the question has any answers + + // Loop through each answer in the view model foreach (var answerViewModel in questionViewModel.Answers) { + // Check if the answer already exists var existingAnswer = existingQuestion.Answers.FirstOrDefault(a => a.Id == answerViewModel.Id); + + if (answerViewModel.Id==0) + { - 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 if(existingAnswer !=null) + { + + existingAnswer.Text = answerViewModel.Text; } } - } + - } - } - else - { - foreach (var questionViewModel in viewModel.Questions) - { + //// Add newly answers that exist only in the view model + //foreach (var answerViewModel in questionViewModel.Answers.Where(av => existingQuestion.Answers.All(ea => ea.Id != av.Id))) + //{ + // existingQuestion.Answers.Add(new Answer { Text = answerViewModel.Text }); + // newAnswersAdded = true; // Set flag to true + //} - var existingQuestion = existingQuestionnaire.Questions.FirstOrDefault(q => q.Id == questionViewModel.Id); - - if (existingQuestion != null) + // If new answers were added, remove any null references + if (newAnswersAdded) { - 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 }); - } - } + existingQuestion.Answers.RemoveAll(a => a == null); } - } + else + { + // Add new question with its answers + var newQuestion = new Question + { + Text = questionViewModel.Text, + Type = questionViewModel.Type, + Answers = questionViewModel.Answers?.Select(a => new Answer { Text = a.Text }).ToList() ?? new List() + }; + + existingQuestionnaire.Questions.Add(newQuestion); + } + + //if (existingQuestion != null) + //{ + // existingQuestion.Text = questionViewModel.Text; + // existingQuestion.Type = questionViewModel.Type; + + // //var answerId = existingQuestion.Answers.Select(x => x.Id).ToList(); + // // Update or add new answers + // //foreach (var answerViewModel in questionViewModel.Answers) + // //{ + // // var existingAnswer = existingQuestion.Answers.FirstOrDefault(a => a.Id == answerViewModel.Id); + + // // if (existingAnswer != null) + // // { + // // existingAnswer.Text = answerViewModel.Text; + // // } + // // else + // // { + // // // Handle adding new answers if necessary + // // existingQuestion.Answers.Add(new Answer { Text = answerViewModel.Text }); + // // } + // //} + // if (questionViewModel.Answers != null) + // { + // // Update or add new answers + // foreach (var answerViewModel in questionViewModel.Answers) + // { + // var existingAnswer = existingQuestion.Answers.FirstOrDefault(a => a.Id == answerViewModel.Id); + + // if (existingAnswer != null) + // { + // // Update existing answer + // existingAnswer.Text = answerViewModel.Text; + // } + // else + // { + // foreach (var newanswers in questionViewModel.Answers) + // { + // existingQuestion.Answers.Add(new Answer { Text = newanswers.Text }); + // } + // // Check if the answer with the same text already exists + // //var answerWithSameText = existingQuestion.Answers.FirstOrDefault(a => a.Text == answerViewModel.Text); + + // //if (answerWithSameText == null) + // //{ + // // // Add new answer only if it doesn't exist with the same text + + // //} + // //else + // //{ + // // // Optionally handle the case where an answer with the same text already exists + // // // You can choose to do nothing, show a message, or take any other action + // //} + // } + // } + // } + + //} + //else + //{ + // // Add new question with its answers + // var newQuestion = new Question + // { + // Text = questionViewModel.Text, + // Type = questionViewModel.Type, + // Answers = questionViewModel.Answers.Select(a => new Answer { Text = a.Text }).ToList() + // }; + + // existingQuestionnaire.Questions.Add(newQuestion); + //} } - // Update questions - - - + // Remove any questions that are not in the view model + var questionIdsInViewModel = viewModel.Questions.Select(q => q.Id); + var questionsToRemove = existingQuestionnaire.Questions.Where(q => !questionIdsInViewModel.Contains(q.Id)).ToList(); + foreach (var questionToRemove in questionsToRemove) + { + existingQuestionnaire.Questions.Remove(questionToRemove); + } // Save changes to the database _questionnaire.Update(existingQuestionnaire); @@ -270,7 +353,7 @@ namespace Web.Areas.Admin.Controllers return RedirectToAction("Index"); } - // If the model state is not valid, return to the edit view with the existing model + // If ModelState is not valid, re-display the form with validation errors return View(viewModel); } @@ -318,7 +401,7 @@ namespace Web.Areas.Admin.Controllers _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 67b70be..a1fa742 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Create.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Create.cshtml @@ -63,7 +63,7 @@ - +
| Back to list @@ -119,7 +119,7 @@ newQuestionHtml += `
`; newQuestionHtml += `

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

`; + newQuestionHtml += `

`; newQuestionHtml += ``; newQuestionHtml += ``; newQuestionHtml += ``; @@ -130,7 +130,7 @@ // Add Remove Question button newQuestionHtml += ``; - newQuestionHtml += `
` + newQuestionHtml += `
` newQuestionHtml += `
`; $("#questions-container .form-group").append(newQuestionHtml); diff --git a/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml b/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml index 67d3930..d486fa2 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Delete.cshtml @@ -55,7 +55,7 @@
@@ -68,27 +68,7 @@
- @* *@ + @@ -108,60 +88,10 @@ CKEDITOR.replace("Description"); @{ - + } - @* *@ - + } \ No newline at end of file diff --git a/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml b/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml index b9e1074..2f68a27 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Edit.cshtml @@ -1,4 +1,4 @@ -@model QuestionnaireViewModel +@model EditQuestionnaireViewModel @{ ViewData["Title"] = "Edit"; @@ -7,288 +7,126 @@
-
Create Survey
+
Edit Survey
-
- +
+
+ +
+ + + +
+
+ + + +
- -
- -
- - - +
+ @for (int i = 0; i < Model.Questions.Count; i++) +{ +
+ +
+ + + +
+
+ + + +
+
+ @for (int j = 0; j < Model.Questions[i].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++) - { -
- - -
- } - - - -
- -
- } -
-
- - - -
- - | Back to list -
-
- - -
-
-
+ + + @section Scripts { - - + $(document).ready(function () { + // Function to add a new answer + $(document).on('click', '.addAnswer', function () { + var questionContainer = $(this).closest('.question'); + var newQuestionIndex = questionContainer.index(); - @{ - - } + // Correctly find the length of answers for the specific question + var newAnswerIndex = questionContainer.find('.answers .form-group').length; - + var answerHtml = ` +
+ + +
`; - @* *@ - @* - - *@ - + @* this script is working for adding mutiple answers for a question *@ - - - - - } + + *@ +} + diff --git a/Web/Areas/Admin/Views/Questionnaire/Index.cshtml b/Web/Areas/Admin/Views/Questionnaire/Index.cshtml index 8e4c1ac..8dfbdef 100644 --- a/Web/Areas/Admin/Views/Questionnaire/Index.cshtml +++ b/Web/Areas/Admin/Views/Questionnaire/Index.cshtml @@ -12,17 +12,18 @@

Questionnaire list

- Create New + Create New

- +
- + + @@ -33,24 +34,31 @@ - + diff --git a/Web/ViewModel/QuestionnaireVM/EditQuestionnaireViewModel.cs b/Web/ViewModel/QuestionnaireVM/EditQuestionnaireViewModel.cs new file mode 100644 index 0000000..c55e60a --- /dev/null +++ b/Web/ViewModel/QuestionnaireVM/EditQuestionnaireViewModel.cs @@ -0,0 +1,23 @@ +using Model; +using System.ComponentModel.DataAnnotations; + +namespace Web.ViewModel.QuestionnaireVM +{ + public class EditQuestionnaireViewModel + { + public EditQuestionnaireViewModel() + { + Questions = new List(); + } + public int Id { get; set; } + [Required] + + [Display(Name ="Questionnaire title")] + public string? Title { get; set; } + [Required] + public string? Description { get; set; } + + public List? Questions { get; set; } + + } +} diff --git a/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs b/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs index 6daac1b..80ce8c8 100644 --- a/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs +++ b/Web/ViewModel/QuestionnaireVM/QuestionnaireViewModel.cs @@ -10,7 +10,7 @@ namespace Web.ViewModel.QuestionnaireVM public QuestionnaireViewModel() { Questions = new List(); - + } public int Id { get; set; } diff --git a/Web/Views/Shared/_Layout.cshtml b/Web/Views/Shared/_Layout.cshtml index 0e6d527..f04f555 100644 --- a/Web/Views/Shared/_Layout.cshtml +++ b/Web/Views/Shared/_Layout.cshtml @@ -25,6 +25,9 @@ +
Id Title DescriptionNumber of questions Total Question Questions | Type | Answers Action
@item.Id @item.Title@item.Description@Html.Raw(item.Description) - Total Questions:@item.Questions?.Count() + @* *@ + + Questions @item.Questions?.Count() + - @foreach (var question in item.Questions) + @foreach (var question in item.Questions.Take(1)) { - - Question:@question.Text + + Question:@question.Text Type: @question.Type foreach (var answer in question.Answers) { Asnwer:@answer.Text + + } - + }