I have a database table of some courses. I am trying to add new course to this db and then display it on calendar but I see alert error3.
function SaveCourse(data) {
$.ajax({
type: "POST",
url: '/home/SaveCourse',
data: data,
success: function (data) {
if (data.any) {
//Refresh the calender
FetchCourseAndRenderCalendar();
$('#myModalSave').modal('hide');
}
},
error: function () {
alert('Failed3');
}
});
}
I have a calendar and I need to add a new course. I click add, a form appears ... I fill it out and I see an error (Failed3)
at the same time, when I debug I see data in the controller (SaveCourse (Course c))
here is my index
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="calender"></div>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><span id="courseTitle"></span></h4>
</div>
<div class="modal-body">
<button id="btnDelete" class="btn btn-default btn-sm pull-right">
<span class="glyphicon glyphicon-remove"></span> Remove
</button>
<button id="btnEdit" class="btn btn-default btn-sm pull-right" style="margin-right:5px;">
<span class="glyphicon glyphicon-pencil"></span> Edit
</button>
<p id="pDetails"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="myModalSave" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Save Course</h4>
</div>
<div class="modal-body">
<form class="col-md-12 form-horizontal">
<input type="hidden" id="hdCourseID" value="0" />
<div class="form-group">
<label>Subject</label>
<input type="text" id="txtSubject" class="form-control" />
</div>
<div class="form-group">
<label>Start</label>
<div class="input-group date" id="dtp1">
<input type="text" id="txtStart" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group" id="divEndDate" style="display:none">
<label>End</label>
<div class="input-group date" id="dtp2">
<input type="text" id="txtEnd" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea id="txtDescription" rows="3" class="form-control"></textarea>
</div>
<div class="form-group">
<label>Column Color</label>
<select id="ddColumnColor" class="form-control">
<option value="green">Default</option>
<option value="blue">Blue</option>
</select>
</div>
<button type="button" id="btnSave" class="btn btn-success">Save</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
</div>
</div>
</div>
</div>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.css" rel="stylesheet" />
<link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.print.css" rel="stylesheet" media="print" />
#section Scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js"></script>
<script>
$(document).ready(function () {
var courses = [];
var selectedCourse = null;
FetchCourseAndRenderCalendar();
function FetchCourseAndRenderCalendar() {
courses = [];
$.ajax({
type: "GET",
url: "/home/GetCourseJsonResults",
success: function (data) {
$.each(data, function (i, v) {
courses.push({
courseID: v.CourseID,
title: v.Subject,
description: v.Description,
start:v.Start,
end: v.End,
color: v.ColumnColor
});
});
GenerateCalender(courses);
},
error: function () {
alert('failed1');
}
});
}
function GenerateCalender(courses) {
$('#calender').fullCalendar('delete');
$('#calender').fullCalendar({
contentHeight: 400,
defaultDate: new Date(),
timeFormat: 'h(:mm)a',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay,agenda'
},
courseLimit: true,
courseColor: '#378006',
courses: courses,
courseClick: function (calCourse, jsEvent, view) {
selectedCourse = calCourse;
$('#myModal #courseTitle').text(calCourse.title);
var $description = $('<div/>');
$description.append($('<p/>').html('<b>Start:</b>' + calCourse.start.format("DD-MMM-YYYY HH:mm a")));
if (calCourse.end != null) {
$description.append($('<p/>').html('<b>End:</b>' + calCourse.end.format("DD-MMM-YYYY HH:mm a")));
}
$description.append($('<p/>').html('<b>Description:</b>' + calCourse.description));
$('#myModal #pDetails').empty().html($description);
$('#myModal').modal();
},
selectable: true,
select: function (start, end) {
selectedCourse = {
courseId: 0,
title: '',
description: '',
start: start,
end: end,
color: ''
};
openAddEditForm();
$('#calendar').fullCalendar('unselect');
},
editable: true,
courseDrop: function (course) {
var data = {
CourseID: course.courseId,
Subject: course.title,
Start: course.start.format('DD/MM/YYYY HH:mm A'),
End: course.end != null ? course.end.format('DD/MM/YYYY HH:mm A') : null,
Description: course.description,
ColumnColor: course.color
};
SaveCourse(data);
}
});
}
$('#btnEdit').click(function () {
//Open modal dialog for edit course
openAddEditForm();
});
$('#btnDelete').click(function () {
if (selectedCourse != null && confirm('Are you sure?')) {
$.ajax({
type: "POST",
url: '/home/DeleteCourse',
data: { 'courseId': selectedCourse.courseId },
success: function (data) {
data.status = true;
//Refresh the calender
FetchCourseAndRenderCalendar();
$('#myModal').modal('hide');
},
error: function () {
alert('Failed2');
}
});
}
});
//$('#dtp1,#dtp2').datetimepicker({
// format: 'DD/MM/YYYY HH:mm A'
//});
function openAddEditForm() {
if (selectedCourse != null) {
$('#hdCourseID').val(selectedCourse.courseId);
$('#txtSubject').val(selectedCourse.title);
$('#txtStart').val(selectedCourse.start.format('DD/MM/YYYY HH:mm A'));
$('#txtEnd').val(selectedCourse.end != null ? selectedCourse.end.format('DD/MM/YYYY HH:mm A') : '');
$('#txtDescription').val(selectedCourse.description);
$('#ddColumnColor').val(selectedCourse.color);
}
$('#myModal').modal('hide');
$('#myModalSave').modal();
}
$('#btnSave').click(function () {
//Validation/
if ($('#txtSubject').val().trim() == "") {
alert('Subject required');
return;
}
if ($('#txtStart').val().trim() == "") {
alert('Start date required');
return;
}
else {
var startDate = moment($('#txtStart').val(), "DD/MM/YYYY HH:mm A").toDate();
var endDate = moment($('#txtEnd').val(), "DD/MM/YYYY HH:mm A").toDate();
if (startDate > endDate) {
alert('Invalid end date');
return;
}
}
var data = {
CourseID: $('#hdCourseID').val(),
Subject: $('#txtSubject').val().trim(),
Description: $('#txtDescription').val(),
DateStart: $('#txtStart').val().trim(),
DateEnd: $('#chkIsFullDay').is(':checked') ? null : $('#txtEnd').val().trim(),
ColumnColor: $('#ddColumnColor').val()
};
SaveCourse(data);
// call function for submit data to the server
});
function SaveCourse(data) {
$.ajax({
type: "POST",
url: '/home/SaveCourse',
data: data,
success: function (data) {
if (data.any) {
//Refresh the calender
FetchCourseAndRenderCalendar();
$('#myModalSave').modal('hide');
}
},
error: function () {
alert('Failed3');
}
});
}
})
</script>
}
my controller
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using UberDrive.Data;
using UberDrive.Models;
namespace My.Controllers
{
public class HomeController : Controller
{
private readonly AppDbContext _context;
public HomeController(AppDbContext context)
{
_context = context;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
//todo
public async Task<JsonResult> GetCourseJsonResults()
{
var res = await _context.Сourses.AsNoTracking().ToListAsync();
return new JsonResult(res);
}
[HttpPost]
public JsonResult SaveCourse(Сourse c)
{
// >0
if (c.СourseId != 0)
{
var course = _context.Сourses.FirstOrDefault(x => x.СourseId == c.СourseId);
// update find course
if (course != null)
{
course.Subject = c.Subject;
course.Description = c.Description;
course.DateStart = c.DateStart;
course.DateEnd = c.DateEnd;
course.ColumnColor = c.ColumnColor;
}
}
else
{
_context.Сourses.Add(c);
}
_context.SaveChanges();
return new JsonResult (_context.Сourses.AsNoTracking().ToListAsync());
}
[HttpPost]
public JsonResult DeleteCourse(int courseId)
{
var c = _context.Сourses.FirstOrDefault(x => x.СourseId == courseId);
if (c != null)
{
_context.Сourses.Remove(c);
_context.SaveChanges();
}
return new JsonResult(_context.Сourses.AsNoTracking().ToListAsync());
}
}
}
and Сourse class
public class Сourse
{
public int СourseId { get; set; }
[Required, StringLength(120)]
public string Subject { get; set; }
public string Description { get; set; }
public DateTime DateStart { get; set; }
public DateTime DateEnd { get; set; }
[Required, StringLength(20)]
public string ColumnColor { get; set; }
}
tell me what is the problem
Wild guess, but not supplying content type or using [FromBody] might be it.
function SaveCourse(data) {
$.ajax({
type: "POST",
url: '/home/SaveCourse',
contentType: "application/json",
data: data,
success: function (data) {
if (data.any) {
//Refresh the calender
}
},
error: function () {
alert('Failed3');
}
});
}
And decorate your controller action with [FromBody] =>
[HttpPost]
public JsonResult SaveCourse([FromBody]Сourse c)
{
// Code ommitted
}
Related
I want to create a Quiz, add questions to the quiz, and add answers to the question. I bound all items with asp-for, serialize my form, and send it to the controller, but they don't bind.
My classes:
public class Answer
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Content { get; set; }
public Guid QuestionId { get; set; }
}
public class Question
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Content { get; set; }
public Guid QuizId { get; set; }
public ICollection<Answer> Answers { get; set; } = new List<Answer>() {
new Answer() { Content = "Answeeeer" },
new Answer() { Content = "Answeeeer2" },
new Answer() { Content = "Answeeeer3" }
};
}
public class Quiz
{
[Key]
public Guid Id { get; } = Guid.NewGuid();
public string Name { get; set; }
public ICollection<Question> Questions { get; set; } = new List<Question>() { };
}
Quiz view:
#model QuizIt_Tests.Entities.Quiz
#{
ViewData\["Title"\] = "Create";
}
\<h1\>Create\</h1\>
\<h4\>Quiz\</h4\>
\<hr /\>
\<div class="row"\>
\<div class="w-75"\>
\<form id="myform" asp-action="Create" method="post" class="p-3"\>
<div class="form-group">
<label asp-for="Name" class="control-label">Quiz Name</label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div id="questionRows" class="form-group w-100">
#Html.EditorFor(model => model.Questions)
<button type="button" id="AddQuestion" class="btn btn-primary mt-2">Add Question</button>
</div>
<div class="form-group mt-2">
input id="submitbutton" type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
\</div\>
\<div\>
\<a asp-action="Index"\>Back to List\</a\>
\</div\>
#section Scripts {
#{
await Html.RenderPartialAsync("\_ValidationScriptsPartial");
}
<script>
$("#submitbutton").click(function (e) {
e.preventDefault();
console.log("Serialized Data: ");
console.log($('#myform').serialize())
$.ajax({
async: true,
data: $('#myform').serialize(),
method: 'post',
url: "Quizes/AddQuestion",
success: function () {
}
});
});
$("#AddQuestion").click(function () {
console.log("Serialized Data: ");
console.log($('#myform').serialize())
console.log($('#questionRows').serialize())
$.ajax({
url: '#Url.Action("AddBlankQuestion", "Quizes")',
cache: false,
success: function (html) { $("#questionRows").append(html); },
error: function (xhr, status, error) {
console.log(xhr.responseText);
}
});
return false;
});
$("a.deleteRow").on("click", function () {
$(this).parents("div.editorRow:first").remove();
return false;
});
</script>
}
Question partial view:
#model QuizIt_Tests.Entities.Question
\<hr style="height: 4px; color: black;" /\>
\<div class="w-100 p-3 px-5 my-3"\>
<div class="form-group">
<label asp-for="Content" class="control-label">Question</label>
<input asp-for="Content" class="form-control" value="#Model.Content" />
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<input type="hidden" asp-for="Id" class="form-control" value="#Model.Id" />
#{
var answerrowid = "answerRows" + #Model.Id;
var addanswerbtnid = "addAnswer" + #Model.Id;
}
<div id="#answerrowid" class="w-75">
#Html.EditorFor(model => model.Answers)
</div>
<button type="button" class="btn btn-primary" id="#addanswerbtnid">Add Answer</button>
\</div\>
<script>
console.log("##addanswerbtnid");
$("##addanswerbtnid").click(function () {
console.log("Add Answer clicked");
$.ajax({
url: '#Url.Action("AddBlankAnswer", "Quizes")',
cache: false,
success: function (html) {
$("##answerrowid").append(html);
},
error: function (xhr, status, error) {
console.log(xhr.responseText);
}
});
return false;
});
</script>
Answer partial view:
#model QuizIt_Tests.Entities.Answer
\<div class="row" style="margin: 20px;"\>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Content" class="control-label">Answer Content</label>
<input asp-for="Content" class="form-control" value="#Model.Content" />
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<input type="hidden" asp-for="Id" class="form-control" value="#Model.Id" />
\</div\>
This is my controller:
public class QuizesController : Controller
{
private readonly ApplicationDBContext _context;
public QuizesController(ApplicationDBContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
return View(await _context.Quizzes.ToListAsync());
}
public IActionResult Create()
{
var newquiz = new Quiz();
return View(newquiz);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Quiz quiz)
{
if (ModelState.IsValid)
{
_context.Add(quiz);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(quiz);
}
public IActionResult AddBlankQuestion(Quiz model)
{
Question question = new Question();
//question.Answers.Add(new Answer() { QuestionId = question.Id, Content = "Salaaam Necesem" });
return PartialView("EditorTemplates/Question", question);
}
public IActionResult AddBlankAnswer(Question model)
{
var newanswer = new Answer() { QuestionId = model.Id, Content = String.Empty };
return PartialView("EditorTemplates/Answer", newanswer);
}
}
I want to create a Quiz, add questions to the quiz, and add answers to the question. I bound all items with asp-for, serialize my form, and send it to the controller, but they don't bind.
public ICollection Questions { get; set; }
You don't bind Content to your list ICollection<Question> Questions , so the Questions list is null.
You need to set name like name="Questions[0].Content" and name="Questions[1].Content".
The problem:
I am trying to save events in a calendar by passing the content in ajax to my controller function. But I keep on getting null values being passed to my database. I have checked the console.log under Network tools in browsers and all of the data is null except EventId .
I know inserting the events into the database is working but it seems like the data being inserted is not being read by either Ajax or there's something wrong with my controller. Why do I keep on getting null values?
What the data in my database looks like after I saved the events
Here's my controller
[HttpPost]
public IActionResult SaveEvent(Event data)
{
var userId = _userManager.GetUserId(User);
var status = false;
if (string.IsNullOrEmpty(userId))
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(new { Data = false, ErrorMessage = "no User Id!" });
}
if (data.EventId > 0)
{
//Update the event
var v = db.Events.Where(a => a.EventId == data.EventId).FirstOrDefault();
if (v != null)
{
userId = data.UserId;
v.EventId = data.EventId;
v.Title = data.Title;
v.Counselor = data.Counselor;
v.Description = data.Description;
v.EventStart = data.EventStart;
v.EventEnd = data.EventEnd;
v.AllDay = data.AllDay;
v.ThemeColor = data.ThemeColor;
}
}
else
{
db.Events.Add(data);
}
db.SaveChanges();
status = true;
return Json(new { Data = data, status});
}
This is my Event class:
public class Event {
public string UserId { get; set; }
public int? EventId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string EventStart { get; set; }
public string EventEnd { get; set; }
public string Counselor { get; set; }
public string ThemeColor { get; set; }
public bool AllDay { get; set; }
}
and my Ajax function
function GenerateCalender(events) {
jq341('#calender').fullCalendar('destroy');
jq341('#calender').fullCalendar({
contentHeight: 400,
defaultDate: new Date(),
timeFormat: 'h(:mm)a',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay,agenda'
},
eventLimit: true,
eventColor: '#378006',
events: events,
eventClick: function (calEvent, jsEvent, view) {
selectedEvent = calEvent;
jq341('#myModal #eventTitle').text(calEvent.title);
var description = jq341('<div />');
description.append(jq341('<p />').html('<b>Start:</b>' + calEvent.start.format("DD-MMM-YYYY HH:mm a")));
if (calEvent.end != null) {
description.append(jq341('<p/>').html('<b>End:</b>' + calEvent.end.format("DD-MMM-YYYY HH:mm a")));
}
description.append(jq341('<p />').html('<b>Description:</b>' + calEvent.description));
jq341('#myModal #pDetails').empty().html(description);
jq341('#myModal').modal();
},
selectable: true,
select: function (start, end) {
selectedEvent = {
userID: '',
eventID: 0,
title: '',
counselor: '',
start: start,
end: end,
description: '',
allDay: false,
color: ''
};
openAddEditForm();
jq341('#calendar').fullCalendar('unselect');
},
editable: true,
eventDrop: function (event) {
var data = {
UserId: event.userID,
EventId: event.eventID,
Title: event.title,
Counselor: event.counselor,
EventStart: event.start.format('DD/MM/YYYY HH:mm A'),
EventEnd: event.end != null ? event.end.format('DD/MM/YYYY HH:mm A') : null,
Description: event.description,
AllDay: event.allDay,
ThemeColor: event.color,
};
SaveEvent(data);
}
})
}
function openAddEditForm() {
if (selectedEvent != null) {
jq341('#hdEventID').val(selectedEvent.eventID);
jq341('#hdUserID').val(selectedEvent.userID);
jq341('#txtSubject').val(selectedEvent.title);
jq341('#ddCounselor').val(selectedEvent.counselor);
jq341('#txtStart').val(selectedEvent.start.format('DD/MM/YYYY HH:mm A'));
jq341('#chkIsFullDay').prop("checked", selectedEvent.allDay || false);
jq341('#chkIsFullDay').change();
jq341('#txtEnd').val(selectedEvent.end != null ? selectedEvent.end.format('DD/MM/YYYY HH:mm A') : '');
jq341('#txtDescription').val(selectedEvent.description);
jq341('#ddThemeColor').val(selectedEvent.color);
}
jq341('#myModal').modal('hide');
jq341('#myModalSave').modal();
}
jq341('#btnSave').click(function () {
//Validation
if (jq341('#txtSubject').val().trim() == "") {
alert('Title required');
return;
}
if (jq341('#txtStart').val().trim() == "") {
alert('Start date required');
return;
}
if (jq341('#chkIsFullDay').is(':checked') == false && jq341('#txtEnd').val().trim() == "") {
alert('End date required');
return;
}
else {
var format_start = jq341('#txtStart').val().replace(' ', '-').split('-');
var nowy_start = format_start[1] + '-' + format_start[0] + '-' + format_start[2] + ' ' + format_start[3];
var format_end = jq341('#txtEnd').val().replace(' ', '-').split('-');
var nowy_end = format_end[1] + '-' + format_end[0] + '-' + format_end[2] + ' ' + format_end[3];
}
//edited
var data = {
UserId: jq341('#hdUserID').val(),
EventId: jq341('#hdEventID').val(),
Title: jq341('#txtSubject').val().trim(),
Counselor: jq341('#ddCounselor').val(),
EventStart: jq341('#txtStart').val().trim(),
EventEnd: jq341('#chkIsFullDay').is(':checked') ? null : jq341('#txtEnd').val().trim(),
Description: jq341('#txtDescription').val(),
ThemeColor: jq341('#ddThemeColor').val(),
AllDay: jq341('#chkIsFullDay').is(':checked')
}
alert(data);
SaveEvent(data);
// call function for submit data to the server
})
function SaveEvent(data) {
jq341.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "JSON",
url: '/Calendar/SaveEvent',
data: JSON.stringify(data),
success: function (data) {
console.log(data)
if (data.status) {
//Refresh the calender
FetchEventAndRenderCalendar();
jq341('#myModalSave').modal('hide');
}
},
error: function () {
alert('Failed', ErrorMessage);
}
})
}
my cshtml
<div id="myModalSave" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Appointments</h4>
</div>
<div class="modal-body">
<form class="col-md-12 form-horizontal">
<input type="text" id="hdEventID" value="0" />
<input type="hidden" id="hdUserID">
<div class="form-group">
<label>Subject</label>
<input type="text" id="txtSubject" class="form-control" />
</div>
<div class="form-group">
<label>Counselor</label>
<select id="ddCounselor" class="form-control">
<option value="0">Choose your counselor</option>
<option value="DrSalwa">Dr Salwa</option>
<option value="DrNorzaiham">Dr Norzaiham</option>
<option value="Nasri">Sir Nasri</option>
<option value="Adibah">Ms. Adibah</option>
</select>
</div>
<div class="form-group">
<label>Start</label>
<div class="input-group date" id="dtp1">
<input type="text" id="txtStart" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<label><input type="checkbox" id="chkIsFullDay" checked="checked" /> Is Full Day event</label>
</div>
</div>
<div class="form-group" id="divEndDate" style="display:none">
<label>End</label>
<div class="input-group date" id="dtp2">
<input type="text" id="txtEnd" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<label>Description</label>
<textarea id="txtDescription" rows="3" class="form-control"></textarea>
</div>
<div class="form-group">
<label>Theme Color</label>
<select id="ddThemeColor" class="form-control">
<option value="">Default</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="black">Black</option>
<option value="green">Green</option>
</select>
</div>
<button type="button" id="btnSave" class="btn btn-success">Save</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</form>
</div>
</div>
</div>
</div>
Below are screenshots of the Network tool
Using [FormBody] but getting that null exception in if(data.eventId >0) in controller
Below is [FormBody] is omitted from the controller but still getting null values except EventId
First, you should add the [FromBody] attribute, otherwise the data will not be successfully obtained.
You can add a breakpoint in your action to observe whether the binding is successful.
Then, modify your db.Add() method, because your data contains EventId, and in your database I see EventId as the primary key, and your primary key is auto-incremented. If you add a New entity of EventId, then an exception will be thrown.
You can try change your action like below:
[HttpPost]
public IActionResult SaveEvent([FromBody]Event data)
{
var userId = _userManager.GetUserId(User);
var status = false;
if (string.IsNullOrEmpty(userId))
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(new { Data = false, ErrorMessage = "no User Id!" });
}
if (data.EventId > 0)
{
//Update the event
var v = db.Events.Where(a => a.EventId == data.EventId).FirstOrDefault();
if (v != null)
{
userId = data.UserId;
v.EventId = data.EventId;
v.Title = data.Title;
v.Counselor = data.Counselor;
v.Description = data.Description;
v.EventStart = data.EventStart;
v.EventEnd = data.EventEnd;
v.AllDay = data.AllDay;
v.ThemeColor = data.ThemeColor;
}
}
else
{
var data1 = new Event
{
UserId=data.UserId,
Title = data.Title,
Counselor = data.Counselor,
Description = data.Description,
EventStart = data.EventStart,
EventEnd = data.EventEnd,
AllDay = data.AllDay,
ThemeColor = data.ThemeColor,
};
db.Events.Add(data1);
}
db.SaveChanges();
status = true;
return Json(new { Data = data, status});
}
I want to display dropdownlist in Bootstrap Modal When I click on button add it displays this error ( Server Error in '/' Application. There is no ViewData item of type 'IEnumerable' that has the key 'DepartmentId'.)
it returns the NULL value someone help me to solve this problem
In Controller:
Database1Entities db = new Database1Entities();
public ActionResult Index()
{
List<Department> DeptList = db.Departments.ToList();
ViewBag.ListOfDepartment = new SelectList(DeptList, "DepartmentId", "DepartmentName");
return View();
}
public ActionResult GetStudent()
{
List<StudentViewModel> data = db.Students.Select(x => new StudentViewModel
{
StudentId =x.StudentId,
FirstName = x.FirstName,
LastName = x.LastName,
DepartmentName = x.Department.DepartmentName,
}).ToList();
return Json(new { data = data }, JsonRequestBehavior.AllowGet);
}
public ActionResult GetStudentPartial(int? id)
{
var student = db.Students.Find(id) ?? new Student();
return PartialView("_CreateOrUpdateStudentPartial", student);
}
public ActionResult CreateOrUpdateStudent(Student student)
{
if (ModelState.IsValid)
{
if (student.StudentId > 0)
{
db.Entry(student).State = System.Data.Entity.EntityState.Modified;
}
else
{
db.Students.Add(student);
}
db.SaveChanges();
return Json(true, JsonRequestBehavior.AllowGet);
}
return Json(false, JsonRequestBehavior.AllowGet);
}
public ActionResult Delete(int id)
{
try
{
var student = db.Students.Find(id);
db.Students.Remove(student);
db.SaveChanges();
return Json(true, JsonRequestBehavior.AllowGet);
}
catch (Exception)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
}
Partial View:
#model Example1.Models.Student
<form name="studentForm">
<div class="modal-header">
<h5 class="modal-title">
Modal title
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</h5>
</div>
<div class="modal-body">
#Html.HiddenFor(x => x.StudentId)
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label>First Name</label>
#Html.EditorFor(x => x.FirstName, new { htmlAttributes = new { #class = "form-control", #placeholder = "First Name*", Required = true } })
#Html.ValidationMessageFor(x => x.FirstName, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Last Name</label>
#Html.EditorFor(x => x.LastName, new { htmlAttributes = new { #class = "form-control", #placeholder = "Last Name*", Required = true } })
#Html.ValidationMessageFor(x => x.LastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Department Name</label>
#Html.DropDownListFor(m => m.DepartmentId, ViewBag.ListOfDepartment as SelectList, "--Select Dept--", new { #id = "DropDwn", #class = "form-control" })
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm pull-left" data-dismiss="modal">Cancel</button>
<button type="button" onclick="createOrUpdate()" class="btn btn-success pull-left">Save</button>
</div>
</form>
View:
<div style="width:90%; margin:0 auto" class="tablecontainer">
<p><button type="button" class="btn btn-sm btn-success" onclick="getStudent()">Add New Student</button></p>
<table id="myDatatable" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>DepartmentName</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
</table>
</div>
<div class="modal fade" role="dialog" id="studentModal" aria-labelledby="studentModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content" id="studentmodalBody">
</div>
</div>
</div>
Script:
<script>
var datatable;
$(document).ready(function () {
datatable = $('#myDatatable').DataTable({
"ajax": {
"url": '/home/GetStudent',
"type": "get",
"datatype": "json"
},
"columns": [
{ "data": "FirstName", "autoWidth": true },
{ "data": "LastName", "autoWidth": true },
{
"data": "DepartmentName", "render": function (data) {
return data;
}
},
{
"data": "StudentId", "width": "50px", "render": function (data) {
return '<button class="btn btn-success" onclick="getStudent(' + data + ')">Edit</button>';
}
},
{
"data": "StudentId", "width": "50px", "render": function (data) {
return '<button class="btn btn-danger" onclick="Delete(' + data + ')">Delete</button>';
}
},
]
})
})
function getStudent(id) {
$.get("/Home/GetStudentPartial", { id: id }, function (res) {
$("#studentmodalBody").html(res);
$("#studentModal").modal('show');
})
}
function createOrUpdate() {
var modal = $("#studentModal");
var form = $('form[name= "studentForm"]');
form.validate();
if (!form.valid()) {
return;
} else {
var data = form.serialize();
$.post("/home/CreateOrUpdateStudent", data, function (res) {
if (res) {
modal.modal('hide');
datatable.ajax.reload();
}
})
}
}
function Delete(id) {
if (confirm("Are you sure ? ") == true) {
$.get("/Home/Delete", { id: id }, function (res) {
if (res) {
datatable().ajax.reload();
}
})
}
}
</script>
If your DeptList is not null, try change code below :
#Html.DropDownListFor(m => m.DepartmentId, ViewBag.ListOfDepartment as SelectList, "--Select Dept--", new { #id = "DropDwn", #class = "form-control" })
to:
#Html.DropDownListFor(m => m.DepartmentId, ViewBag.ListOfDepartment as IEnumerable<SelectListItem>, "--Select Dept--", new { #id = "DropDwn", #class = "form-control" })
EDIT: I've just realized that you are filling your ViewBag in the Index() method but your are calling it in _CreateOrUpdateStudentPartial and you can't do that. ViewBag is not tranffering data between views.
public ActionResult GetStudentPartial(int? id)
{
var student = db.Students.Find(id) ?? new Student();
// you need to add here
List<Department> DeptList = db.Departments.ToList();
ViewBag.ListOfDepartment = new SelectList(DeptList,"DepartmentId","DepartmentName");
return PartialView("_CreateOrUpdateStudentPartial", student);
}
I'm having a basic form with few text fields and a file upload controller on a bootstrap modal dialog (Bootstrap 4). below is my code:
Model:
public class DemoContent
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[RegularExpression("([0-9]+)",ErrorMessage = "Age must be numbers only")]
public int Age { get; set; }
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Upload)]
[Display(Name = "Image")]
public HttpPostedFileBase ImageUrl { get; set; }
}
JavaScript
$(function() {
$("a[data-modal=demoPopup]").on("click", function () {
$("#demoModalContent").load(this.href, function () {
$("#demoModal").modal({ keyboard: true }, "show");
$("#demoForm").submit(function () {
if ($("#demoForm").valid()) {
var files = $("ImageUrl").get(0).files;
var data = $(this).serialize();
data.append("ImageUrl", files[0]);
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$("#demoModal").modal("hide");
location.reload();
} else {
$("#MessageToClient").text(result.message);
}
},
error: function () {
$("#MessageToClient").text("The web server had an error.");
}
});
return false;
}
});
});
return false;
});
Controller:
[HttpPost]
public ActionResult Create(DemoContent model)
{
if (model.Age > 55)
{
var file = model.ImageUrl;
return Json(new { success = true });
}
else
{
return Json(new { success = false,message="Invalid Data" });
}
}
Now when i open the popup it works also when i submit the form it goes to the controller along with the file. but the problem is once the server returns the success message the popup shows that message in a blank page instead of capturing it and refreshing the current page or showing the messages. any idea why is this happening.
link to source files : https://drive.google.com/open?id=1W3H3kFEpHJWfaf7_UnJI3O5I900GxyC7
May be you wrote your javascripts function in document.ready() function,That is why it again refreshing.
Write your JavaScript code as follows:
$(function() {
$("a[data-modal=demoPopup]").on("click", function () {
$("#demoModalContent").load(this.href, function () {
$("#demoModal").modal({ keyboard: true }, "show");
$("#demoForm").submit(function (event) { // Pass the event as parameter to the function.
event.preventDefault(); // I have added these two lines
event.stopImmediatePropagation();
if ($("#demoForm").valid()) {
var files = $("ImageUrl").get(0).files;
var data = $(this).serialize();
data.append("ImageUrl", files[0]);
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$("#demoModal").modal("hide");
location.reload();
} else {
$("#MessageToClient").text(result.message);
}
},
error: function () {
$("#MessageToClient").text("The web server had an error.");
}
});
return false;
}
});
});
return false;
});
I think you should install and use Microsoft.Unobtrusive.Validation and *.Ajax, if you want your modal to be updated (I get your question like that...). With this, you can use code like the following example, which can update your modal (used this in a project a few days ago):
Modal:
#using (Ajax.BeginForm("Login", new { Controller = "Home", area = "" }, new AjaxOptions() { OnSuccess = "onSuccessLogin", HttpMethod = "POST", UpdateTargetId = "loginmodalbody"}, new { id = "loginForm" }))
{
<div class="modal-body" id="loginmodalbody">
<div class="text-danger loginfailed"></div>
<div class="container">
<div class="card border-primary mb-3" style="margin: 0 auto;">
<div class="card-body">
#Html.Partial("~/Views/Shared/Modals/LoginModalBody.cshtml")
</div>
</div>
<div class="container">
<span><a onclick="alert('Leads to pw info')" href="#">Forgot password?</a></span>
</div>
<br />
<button class="btn btn-primary btn-block buttonlogin">Login</button>
</div>
<br />
</div>
}
Modal Body:
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-lg-12 col-12">
#Html.EditorFor(model => model.EMail, new { htmlAttributes = new { #class = "form-control", placeholder = "EMail", #id = "inputemail" } })
#Html.ValidationMessageFor(model => model.EMail, "", new { #class = "text-danger", #id = "dangeremail" })
</div>
</div>
<div class="form-group">
<div class="col-lg-12 col-12">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control", placeholder = "Passwort", #id = "inputpassword" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger", #id = "dangerpassword" })
</div>
</div>
</div>
Thus, it updates your modal body after getting data from the posting of the form - you define the id to be updated within the AjaxOptions, as shown in the above snippet.
I am currently working on an accounting project and I am experiencing a stupid problem.
I enter the values in text boxes and I click on Add Person button, the values get added but when I click Save to Database button the multiple added values get pushed into database. I am able to insert multiple values in the database but unable to call the multiple entries from the SQL server back again onto my UI.
I have multiple same first names in my table of SQL server and I want to pick up all the values which have the same first name and populate them in $scope.arr I defined in angular code.
When I pass an integer value in my $scope.GetPerson() method, I get the desired result and my array ($scope.arr) gets populated with all the values having the same CustomerCode but when I pass a string value i.e, FirstName in GetPerson method, my array($scope.arr) doesn't get populated with the same First Name values that were placed into the database.
I want the experts to look into this problems and guide me where am I actually doing the mistake.`
My Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestProj.Models
{
public class TestModel
{
public int ID { get; set; }
public int CustomerCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal Debit { get; set; }
public decimal Credit { get; set; }
}
}
My Angular JS script:
var app = angular.module("TestApp", []);
app.controller("TestCtrl", function ($scope, TestService) {
$scope.arr = [];
GetAllPers();
function GetAllPers() {
var getPersData = TestService.getPersons();
getPersData.then(function (Persons) {
$scope.persons = Persons.data;
}, function () {
alert('Error in getting Person records');
});
}
$scope.addPerson = function () {
var obj = {
CustomerCode: $scope.customercode,
FirstName: $scope.firstname,
LastName: $scope.lastname,
Debit: $scope.debit,
Credit: $scope.credit,
};
$scope.arr.push(obj);
};
$scope.savePerson = function () {
var TestData = TestService.AddPer($scope.arr);
TestData.then(function (msg) {
$scope.customercode = "";
$scope.firstname = "";
$scope.lastname = "";
$scope.debit = "";
$scope.credit = "";
GetAllPers();
alert(msg.data);
for (var i = 0; i < $scope.arr.length; i++) {
$scope.arr.pop();
}
}, function () {
alert('Error In Adding Person');
});
};
$scope.GetPerson = function (test) {
var getTestData = TestService.getPers(test.FirstName);
getTestData.then(function (_test) {
$scope.arr = _test.data;
}, function () {
alert('Error in getting person records');
});
}
});
app.service("TestService", function ($http) {
this.getPersons = function () {
return $http.get("/Test/GetAllPers");
}
this.AddPer = function (person) {
var response = $http({
method: "post",
url: "/Test/AddPerson",
data: JSON.stringify(person),
dataType: "json",
});
console.log(response);
return response;
}
this.getPers = function (persname) {
var response = $http({
method: "post",
url: "/Test/GetPersonByFName",
params: {
firstname: JSON.stringify(persname)
}
});
return response;
}
});
My C# controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestProj.Models;
namespace TestProj.Controllers
{
public class TestController : Controller
{
TestContext dc = new TestContext();
// GET: Test
public ActionResult Index()
{
return View();
}
public JsonResult GetAllPers()
{
var personList = dc.TestModels.ToList();
return Json(personList, JsonRequestBehavior.AllowGet);
}
public JsonResult GetPersonByFName(string firstname)
{
var q = (from ab in dc.TestModels.Where(b => b.FirstName == firstname) select ab);
return Json(q, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public string AddPerson(List<TestModel> test)
{
bool val = false;
foreach (var t in test)
{
if (t != null)
{
dc.TestModels.Add(t);
val = true;
}
else
{
val = false;
}
}
dc.SaveChanges(); //save context at the end, when no error occurs
if (val == true)
{
return "Success";
}
else
{
return "Failed";
}
}
}
}
My HTML:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div ng-controller="TestCtrl">
<form>
<button class="btn" data-toggle="modal" data-target="#myModal">Show records</button><br />
Customer Code: <input class="form-control" ng-model="customercode" /><br />
FirstName: <input class="form-control" ng-model="firstname" /><br />
LastName: <input class="form-control" ng-model="lastname" /><br />
Debit: <input class="form-control" ng-model="debit" /><br />
Credit: <input class="form-control" ng-model="credit" /><br />
<button class="btn btn-success" ng-click="addPerson()">Add Person</button>
<button class="btn btn-success" ng-click="savePerson()">Save To DB</button>
#*Table for showing pushed values*#
<table class="table table-bordered">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Debit</th>
<th>Credit</th>
</tr>
<tr ng-repeat="a in arr">
<td>{{a.CustomerCode}}</td>
<td>{{a.FirstName}}</td>
<td>{{a.LastName}}</td>
<td>{{a.Debit}}</td>
<td>{{a.Credit}}</td>
</tr>
</table>
#*Modal popup*#
<div class="modal fade" role="dialog" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4>Persons</h4>
</div>
<div class="modal-body">
<label class="control-label col-md-2" style="width: auto">Search:</label>
<div class="col-md-8">
<input class="form-control" ng-model="searchfor" />
</div><br />
<table class="table table-hover">
<tr>
<td><b>First Name</b></td>
<td><b>Last Name</b></td>
<td><b>Debit</b></td>
<td><b>Credit</b></td>
<td><b>Select</b></td>
</tr>
<tr ng-repeat="b in persons | filter:searchfor ">
<td>{{b.CustomerCode}}</td>
<td>{{b.FirstName}}</td>
<td>{{b.LastName}}</td>
<td>{{b.Debit}}</td>
<td>{{b.Credit}}</td>
<td>
<button type="button" class="btn btn-success" ng-click="GetPerson(b)" data-dismiss="modal">Select</button>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#myModal">Okay</button>
</div>
</div>
</div>
</div><br />
</form>
</div>
<script src="~/Scripts/MyAngular/Module.js"></script>
The issue is with your getPers(). Adding JSON.stringfy() adds " to your string.
It should be used like this :
this.getPers = function (persname) {
var response = $http({
method: "post",
url: "/Test/GetPersonByFName",
params: {
firstname: persname
}
});
return response;
}