I am able to query database to properly fill calendar with events. I can drag and drop and the dates successfully update in database. If I click on existing event, the popup modal shows the details I want and I have been able to customize that easily.
However, I can’t figure out how to create a new event from the fullCalendar view. I do not want to create it right there in a form in a modal, because I need to capture lots of extra selections from the user beyond the basics of start, end, id, color, etc. I just want to capture ‘start’ only and return a basic create view form.
When I track the breakpoint, everything looks like it is working. The ‘start’ value is passed to the controller method. That method calls to service to return a model. The breakpoint shows the view being rendered, but nothing actually changes on the screen. The js is below:
selectable: true, select: function (start) { selectedEvent = { eventID: 0, start: start, allDay: true, }; CreateFullCalEvent(start.toISOString()); $('#calendar').fullCalendar('unselect'); }, height: 'parent', events: function (start, end, timezone, callback) { $.ajax({ type: "GET", contentType: "application/json", url: "GetEventData", dataType: "JSON", success: function (data) { var events = []; $.each(data, function (i, data) { events.push( { title: data.title, start: moment(data.start), end: moment(data.end), allDay: true, backgroundColor: data.color, id: data.id, textColor: data.textColor } ); }); callback(events); } }) }, nextDayThreshold: '00:00:00', editable: true, droppable: true, nowIndicator: true, eventClick: function (info) { GetFullCalEventByID(info); }, eventDrop: function (info) { console.log(info); UpdateFullCalEvent(info.id, info.start.toISOString(), info.end.toISOString()); }, eventResize: function (info) { UpdateFullCalEvent(info.id, info.start.toISOString(), info.end.toISOString()); } }) } function CreateFullCalEvent(start) { var object = {}; object.start = start; $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", url: "CreateFullCalEvent/", dataType: "JSON", data: JSON.stringify(object) }); } function GetFullCalEventByID(eventinfo) {
The controller method is here:
//CREATE [HttpPost] public ActionResult CreateFullCalEvent(string start) { //return RedirectToAction("Create", "CalendarEvent"); var model = _calEventSvc.FullCalendarEventCreateView(DateTime.Parse(start)); return View(model); }
And the view:
@model CRM.Models.CalendarEvent.CalendarEventCreate @{ ViewBag.Title = "CreateFullCalEvent"; } <h2>CreateFullCalEvent</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Start, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Start, new { htmlAttributes = new { @class = "form-control", type = "date" } }) @Html.ValidationMessageFor(model => model.Start, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.End, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.End, new { htmlAttributes = new { @class = "form-control", type = "date" } }) @Html.ValidationMessageFor(model => model.End, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Location, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Location, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Location, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Details, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Details, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Details, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.TypeOfEvent, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EnumDropDownListFor(model => model.TypeOfEvent, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.TypeOfEvent, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" formaction="Create" class="btn btn-default" /> @*<input type="submit" value="Add Job info" formaction="Job" class="btn btn-default" />*@ </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
I am not getting an error in visual studio or in debug mode in the browser. It is just not showing my view as expected. This is a regular view, not a partial view, so I am expecting my layout view from my other pages to show here.
The page I am on when I click on a date does not use a layout page and is like this:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link href="~/Content/fullcalendar.min.css" rel="stylesheet" /> <link href="~/Content/bootstrap.css" rel="stylesheet" /> <script src="~/Scripts/jquery-3.4.1.js"></script> <script src="~/Scripts/bootstrap.min.js"></script> <script src="~/Scripts/moment.js"></script> <script src="~/Scripts/fullcalendar.js"></script> <script src="~/Scripts/calendar.js"></script> <script type="text/javascript"> $(document).ready(function () { GetEventsOnPageLoad(); }); </script> <style> .calendar-body { height: calc(100vh - 165px); width: 90%; padding-left: 130px; } .calendar-header { padding-left: 30%; margin-top: 5%; } body { zoom: 110%; background-image: url('../../Content/Assets/bgSubtle.jpg'); font-family: Consolas; } </style> </head> <body> <div class="calendar-header"> @Html.Partial("~/Views/Shared/NavBarLayout.cshtml") <div style="padding: 1%; margin-left: 71%;">@Html.ActionLink("List View", "Index", "CalendarEvent")</div> </div> <div class="calendar-body"> <div id="calendar"> </div> </div> <div id="MyPopup" class="modal fade modal-CreateEvent" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> @*Header*@ <div class="modal-header"> <h4 class="modal-title"></h4> </div> @*ModalBody*@ <div class="modal-body"> </div> @*modal footer*@ <div class="modal-footer"> <button type="button" class="btn" data-dismiss="modal"> OK </button> <button id="btnEdit" class="btn btn-default pull-right">Edit</button> </div> </div> </div> </div> </body> </html>
Advertisement
Answer
You’re calling CreateFullCalEvent
via AJAX. That won’t render your view unless you write some JavaScript to do so (and in that case you’d need a Partial View, not a full view, to go inside the existing page). Remember an AJAX request doesn’t refresh the page automatically, it simply sends a request and receives a response. The response data (in this case the HTML of the view) comes back to the JavaScript inside a variable – what happens to that response data is then up to you and the code you write to process it. At the moment, your code is ignoring the response it gets back from the AJAX request.
You said you didn’t want to put this Create form inside a modal, so I’ll assume that you actually wanted redirect the browser away from the calendar and onto the Create page. To do that, a simple redirect is all you need:
function CreateFullCalEvent(start) { window.location.href = "CreateFullCalEvent?start=" + encodeURIComponent(start); }
But to make that work with the server-side code you’ll also have to make the action method respond to GET instead of POST:
[HttpGet] public ActionResult CreateFullCalEvent(string start)
Optionally you could also try changing it to CreateFullCalEvent(DateTime start)
so you don’t need to call DateTime.Parse
later on.
P.S. Having said all that, it’s not really clear why you feel a form inside a modal (overlaid on top of the calendar) wouldn’t be suitable here – your “Create” view is only capturing a small number of fields. It seems to me it would work fine as a partial view. Just something to think about.