I am trying to fetch events from my LocalDB server and have them display on my calendar, but they aren't appearing.
I am using the following method to fetch the events.
public JsonResult GetEvents(double start, double end)
{
var fromDate = ConvertFromUnixTimestamp(start);
var toDate = ConvertFromUnixTimestamp(end);
var eventList = from e in db.Events
select new
{
ID = e.ID,
Title = e.Title,
StartDate = e.StartDate.ToString("s"),
EndDate = e.EndDate.ToString("s"),
EventType = e.EventType,
Hours = e.Hours,
AllDay = true
};
var rows = eventList.ToArray();
return Json(rows, JsonRequestBehavior.AllowGet);
}
private static DateTime ConvertFromUnixTimestamp(double timestamp)
{
var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}
My calendar is rendered as follows:
#Styles.Render("~/Content/fullcalendar")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/fullcalendar")
<br />
<div id="calendar"></div>
<br />
<script type="text/javascript">
$(document).ready(function () {
$('#calendar').fullCalendar({
header: {
left: 'title',
center: '',
right: 'prev,next today' },
defaultView: 'month',
weekends: false,
editable: false,
events: "/Home/GetEvents/" });
});
</script>
Any help is greatly appreciated.
EDIT:
This is in my web console:
no element found abort:1:1
Use of getPreventDefault() is deprecated. Use defaultPrevented instead. browserLink:37:40278
no element found send:1:1
no element found send:1:1
no element found send:1:1
no element found
GET http://localhost:54802/Home/GetEvents/ [HTTP/1.1 500 Internal Server Error 10ms]
Your response is not conform to fullCalendar expected output. If you see the doc, you understand that each events needs to have at least these parameters:
title
start
In your case the code should be like this:
public JsonResult GetEvents(double start, double end)
{
var fromDate = ConvertFromUnixTimestamp(start);
var toDate = ConvertFromUnixTimestamp(end);
var eventList = from e in db.Events
select new
{
id = e.ID,
title = e.Title,
start = e.StartDate.ToString("s"),
end = e.EndDate.ToString("s"),
eventType = e.EventType,
hours = e.Hours,
allDay = true
};
var rows = eventList.ToArray();
return Json(rows, JsonRequestBehavior.AllowGet);
}
The first problem is, as I think, the name of variables for each event. This not match what fullCalendar is expecting.
With this new one GetEvents method fullCalendar should understand and print your output.
Related
I'm using Fullcalendar to render a calendar.
Everything is working fine, but I have a specific request that I've been trying to solve, which is: show two months, but have some kind of visual separation (i.e. empty row) between them.
I have my custom view set-up, but have no idea where to even begin on inserting a row between months. (My initial thoughts are: it's probably easier to insert a 'row' into the calendar after it renders, as opposed to getting too deep).
I was thinking about looping through the calendar's HTML on the fc-day-top CSS class and use Moment.js to match the date and then break the row by inserting html into the DOM; but I'm not sure if that's the right approach. (please see the code below and fiddle)
I am able to select the last day of the respective month, but am now trying to figure out the best way to insert HTML into the table with correct offsets before and after the split.
Any help would be much appreciated!
var calendarEl = document.getElementById('my-calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'interaction', 'dayGrid','timeGrid', 'list' ],
header: {
left: 'prev,next today',
center: 'title',
right: 'listDay,dayGridMonth,monthView2'
},
views: {
monthView2: {
type: 'dayGrid',
duration: {
months: 2
},
buttonText: '2-Month View',
showNonCurrentDates: false,
},
dayGridMonth: {
buttonText: 'Month View',
showNonCurrentDates: false,
},
listDay: { buttonText: 'Day List' },
},
defaultView: 'monthView2',
// With the code below: my initial though is: find the last day of the month, and insert <td>s and a row to split it
datesRender: function( info ){
$('.fc-row.fc-week').each(function() {
var thisWeek = $(this);
var $d_i = 0;
var htmlCellStringBefore = htmlCellStringAfter = '';
$(thisWeek).find('.fc-day-top').each(function() {
$d_i++;
var thisDay = $(this).data('date');
var thisDateYear = moment(thisDay).year();
var thisDateMonth = moment(thisDay).month();
var lastDay = new Date(thisDateYear, thisDateMonth + 1, 0);
var lastDayMoment = moment(lastDay).format('YYYY-MM-DD');
// Match the last day, if matches, cut the table and insert HTML
if(thisDay == lastDayMoment){
var cellIteratorBefore = 7 - $d_i;
var cellIteratorAfter = 7 - cellIteratorBefore;
// Looping to create number of offset cells before break for insertion
for (i = 0; i < cellIteratorBefore; i++) {
htmlCellStringBefore += '<td class="cellBefore"></td>';
}
// Looping to create number of offset cells after break for insertion
for (i = 0; i < cellIteratorAfter; i++) {
htmlCellStringAfter+= '<td class="cellAfter"></td>';
}
var returnHtmlHead = htmlCellStringBefore + '</tr></thead>'; // inserting empty cells after date to break into head
var returnHtmlBody = htmlCellStringBefore + '</tr></tbody></table>'; // inserting empty cells after date to break into table body
var thisTableFcBG = $(thisWeek).find('.fc-bg tbody td');
var thisTableFcSkeleton = $(thisWeek).find('.fc-content-skeleton tbody td');
var thisTableFcBGNthTableCell = $(thisTableFcBG)[cellIteratorBefore];
var thisTableFcSkeletonNthTableCell = $(thisTableFcSkeleton)[cellIteratorBefore];
var MonthName = moment(lastDayMoment).add(1, 'days').format("MMMM");
$('<div class="break-month-title">'+ MonthName+ '</div>').insertAfter(thisWeek);
// This part is messy and i'm trying figure out the best way to split up the tables
$(returnHtmlHead).insertAfter(thisDay);
$(returnHtmlBody + '<div class="fc-row fc-week fc-widget-content"><div class="break-month">BREAK MONTH</div><div class="fc-bg"><table><thead><tr>'+ htmlCellStringAfter).insertAfter(thisTableFcBGNthTableCell);
$(returnHtmlBody + '<div class="fc-content-skeleton"><table><thead><tr>' + htmlCellStringAfter).insertAfter(thisTableFcSkeletonNthTableCell);
}
});
});
}
});
calendar.render();
.break-month {
background:#f10000;
}
.break-month-title {
text-align:center;
padding:3rem;
font-size:2rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/core/main.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/core/main.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/interaction/main.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/daygrid/main.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/4.2.0/timegrid/main.min.js"></script>
<div id="my-calendar"></div>
I also have a fiddle: https://jsfiddle.net/zjr73m41/
I want to load an action result with javascript. I found some solution on stackoverflow, but they aint working.
I have this piece of code that when its friday it should load this view. It looks like this:
var from = jQuery('#orderForDate').datepicker().val().split("-");
var f = new Date(from[2], from[1] - 1, from[0]);
var n = f.getDay();
orderForDate = jQuery('#orderForDate').datepicker({ dateFormat: "dd-mm-yy" }).val();
if (n == 5) {
console.log('friday baby!');
var url = '#Html.Raw(Url.Action("Bestellen", "Cart", new { orderForDate=orderForDate}))';
window.location = url;
}
This is the controller is should load:
public ActionResult Bestellen(string orderForDate)
{
ViewBag.date = string.IsNullOrEmpty(orderForDate) ? DateTime.Now.Date : DateTime.ParseExact(orderForDate, "dd-MM-yyyy", CultureInfo.GetCultureInfo("nl-NL"));
User user = _db.Users.Find(_db.GetCurrentUserId());
var vm = new BestellenViewModel { ShowFavoritesAsDefault = user.ShowFavoritesAsDefault };
return PartialView(vm);
}
The problem is, when I click on a date that is friday in my datepicker, the browsers loads this url/page
http://localhost:54408/Cart/#Html.Raw(Url.Action(%22Bestellen%22,%20%22Cart%22,%20new%20%7B%20orderForDate=orderForDate%7D))
And I obviously don't get the desired page.
What am I missing here?
Read your url link. http://localhost:54408/Cart/#Html.Raw(Url.Action(%22Bestellen%22,%20%22Cart%22,%20new%20%7B%20orderForDate=orderForDate%7D)). It is not what you want. Try: window.location = '/Cart/Bestellen?orderForDate=' + orderForDate
I'm using JQuery datatables to sort some table with data.
I'm using custom items to sort, in my case I have a select element which sorts one of the columns. And this works.
I also have 2 inputs that serve as datepickers.
These pickers have data formatted as same as on the table, so filtering works well, but my question is:
Is possible to filter column based on the range of pickers? So for example:
from 1 sep 2017 to 10 sep 2017?
I'm was looking for some custom function in datatables docs but I found nothing so it's why I'm asking StackOverflow community.
I think I need to check when second date one was selected and then get data of first datepicker and filter column based on this. But to make things easier, when the first picker is selected I will just show the second picker, so the user may know that selecting the first picker will trigger need of selecting the second one also....
$(document).ready(function() {
var table = $('#scroll-wrc-changes-table table').DataTable({
"paging": false,
});
var picker1 = $('#datetimepicker1').datetimepicker({
format: 'DD MMM YYYY',
defaultDate: new Date(),
});
var picker2 = $('#datetimepicker2').datetimepicker({
format: 'DD MMM YYYY',
defaultDate: new Date(),
});
picker1.on('dp.change',function() {
table.columns([3] ).search( this.value ).draw();
});
picker2.on('dp.change',function() {
table.columns([3] ).search( this.value ).draw();
});
// This is just select element
$('#table-select').change(function() {
table.columns([2] ).search( this.value ).draw();
})
});
Maybe this link can help you.
Range Filtering
The idea is to make function for custom filtering.
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var date1 = new Date( $('#datetimepicker1').val() );
var date2 = new Date( $('#datetimepicker2').val() );
var dateData = new Date( data[3] ); // use data from the date column
if ( dateData >= date1 && dateData <= date2 )
{
return true;
}
return false;
});
Hope this help..
Asuming you are using ajax datatable . If not draw idea from this example
Add a row where you can set range for filter as:
<div class="col-md-3"> <label>From:</label> <input readonly="readonly" type="text" id="mindate" class="srchdp"> <i class="fa fa-times-circle-o" id="clear-mindate"></i></div>
<div class="col-md-3"> <label>To:</label> <input readonly="readonly" type="text" id="maxdate" class="srchdp"> <i class="fa fa-times-circle-o" id="clear-maxdate" ></i></div>
<div class="col-md-2"><button class="btn btn-primary" id="filter-record">Filter</button></div>
//initialize datepicker as
$("input:text.srchdp").datetimepicker({
changeMonth: true,
changeYear: true,
yearRange: "-100:+0",
dateFormat: 'mm/dd/yy',
controlType: 'select',
timeFormat: 'hh:mm:ss TT',
})
// now keep a event on filter button click
$(document).on("click", "#filter-record", function () {
assetListVM.search("").draw();
});
// now on ajax request
public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel, string mindate,string maxdate, string searchbase)
{
DataBaseEntities db = new DataBaseEntities();
IQueryable<Wishlist> query = db.Wishlists;
var totalCount = query.Count();
#region Filtering
// Apply filters for searching
var value = requestModel.Search.Value.Trim();
if (!string.IsNullOrEmpty(searchbase))
{
if (!string.IsNullOrEmpty(mindate) && !string.IsNullOrEmpty(maxdate))
{
DateTime datevaluemin;
DateTime datevaluemax;
var mindateval = DateTime.TryParse(mindate, out datevaluemin);
var maxdateval = DateTime.TryParse(mindate, out datevaluemax);
if (mindateval && maxdateval)
{
var minvalue = Convert.ToDateTime(mindate);
var maxvalue = Convert.ToDateTime(maxdate);
if (searchbase == "CreatedDate")
{
query = query.Where(p =>
p.CreatedDate >= minvalue
&& p.CreatedDate <= maxvalue);
}
}
}
else if (!string.IsNullOrEmpty(mindate))
{
DateTime datevalue;
var mindateval = DateTime.TryParse(mindate, out datevalue);
if (mindateval)
{
var minvalue = Convert.ToDateTime(mindate);
if (searchbase == "CreatedDate")
{
query = query.Where(p =>
p.CreatedDate >= minvalue
);
}
}
}
}
if (requestModel.Search.Value != string.Empty)
{
query = query.Where(p => p.Id.ToString().Equals(value) ||
p.ProductId.ToString().Equals(value) ||
p.MemberId.ToString().Contains(value)
);
}
var filteredCount = query.Count();
#endregion Filtering
#region Sorting
// Sorting
var sortedColumns = requestModel.Columns.GetSortedColumns();
var orderByString = String.Empty;
foreach (var column in sortedColumns)
{
orderByString += orderByString != String.Empty ? "," : "";
orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc");
}
query = query.OrderBy(orderByString == string.Empty ? " asc" : orderByString);
#endregion Sorting
// Paging
query = query.Skip(requestModel.Start).Take(requestModel.Length);
var data = query.Select(asset => new
{
Id = asset.Id,
ProductId = asset.ProductId,
ProductName = asset.Product.ProductName,
MemberId=asset.MemberId,
CreatedDate = asset.CreatedDate.ToString(),
}).ToList();
return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}
}
}
this code is not complete hence it doesn't work alone.
I want to get a range of items between dates from two JQuery calendars and then update the view when I press a submit button so that I only see the items between the selected dates. I'm not sure I'm going about things the best way.
My plan was to:
Get the user to select the dates in the calendars.
Use Javascript to return the dates as variables.
Send the variables to a controller which would then return a new view.
My code is below and my question is really in two parts.
Is there a better way to do this?
If this is ok, how can I get the javascript variables into the ActionLink to pass back to the controller?
Thanks in advance!
Controller:
// GET: Home
public ActionResult IndexDateRange(string sortOrder, DateTime startDateFromJS, DateTime endDateFromJS)
{
var sortedByDates = from pay in db.DailyPayments
select pay;
sortedByDates = sortedByDates.OrderByDescending(pay => pay.Date);
var first = sortedByDates.Select(pay => pay.Date).First();
var lastDate = sortedByDates.Select(pay => pay.Date).Last();
if (startDateFromJS > first.Date || (endDateFromJS < lastDate))
{
var dateRange = sortedByDates.Where(pay => pay.Date >= startDateFromJS && pay.Date <= endDateFromJS);
return View(dateRange.ToList());
}
return View(sortedByDates.ToList());
}
Javascript in the Index:
#Html.ActionLink("Get Dates", "IndexDateRange", routeValues: new { startDateFromJS = startDate, endDateFromJS = endDate })
<script>
$(function () {
var startDate = getStartDate();
var endDate = getEndDate();
function getStartDate() {
$('#startDate').datepicker();
$('#calendarSubmitButton').click(function () {
//var startDate = $('#startDate').datepicker('getDate');
var startDate = $('#startDate').datepicker('getDate');
console.log(startDate);
return startDate;
})
};
function getEndDate() {
$('#endDate').datepicker();
$('#calendarSubmitButton').click(function () {
var endDate = $('#endDate').datepicker('getDate');
console.log(endDate);
return endDate;
})
};
Temporary Test JS to try and wire up the href. When I click on it, it just adds the pound symbol to the home/index Url and in the browser developer tools it says illegal character.
Get Dates
<script type="text/javascript">
$('#calendarSubmitButton').click(function() {
var tempStartDate = #DateTime.Now.AddMonths(-1).ToString("yyyyMMdd");
var tempEndDate = #DateTime.Now.ToString("yyyyMMdd");
location.href='#Url.Action("IndexDateRange")+'?startDateFromJS='+$('tempStartDate')+'&endDateFromJS='+$('tempEndDate')';
});
</script>
Screen Grab:
Screenshot of the setup
Try this
Get Dates
<script type="text/javascript">
$('#calendarSubmitButton').click(function() {
var tempStartDate = '#DateTime.Now.AddMonths(-1).ToString("yyyyMMdd")';
var tempEndDate = '#DateTime.Now.ToString("yyyyMMdd")';
location.href='#Url.Action("IndexDateRange")?startDateFromJS='+tempStartDate +'&endDateFromJS='+tempEndDate;
});
</script>
Thanks to the help of #StephenMuecke and #Tanmay, I was finally able to get this to work. I'm posting the functioning code here.
Controller
// GET: Home
public ActionResult Index(string sortOrder, string startDate, string endDateFromJS)
{
var sortedByDates = from pay in db.DailyPayments
select pay;
sortedByDates = sortedByDates.OrderByDescending(pay => pay.Date);
if (startDate != null && endDateFromJS != null)
{
DateTime convertedStartDateFromJS = DateTime.ParseExact(startDate, "yyyyMMdd", new CultureInfo("en-US"));
DateTime convertedEndDateFromJS = DateTime.ParseExact(endDateFromJS, "yyyyMMdd", new CultureInfo("en-US"));
var dateRange = sortedByDates.Where(pay => pay.Date >= convertedStartDateFromJS && pay.Date <= convertedEndDateFromJS);
return View(dateRange.ToList());
}
return View(sortedByDates.ToList());
}
Javascript and HTML in the index.cshtml
<div class="form-group">
#Html.Label("Total payment:", new { id = "totalTextbox" }) <br />
#Html.TextBox("Total", Math.Floor(totalPayment) + " yen" , new { #class = "alert alert-danger", #readonly = "readonly" })
</div>
<div class="form-group">
#Html.Label("Starting Date:")
#Html.TextBox("Starting Date:", "", new { #class = "date-picker", id = "startDate" })
#Html.Label("Ending Date:")
#Html.TextBox("Ending Date:", "", new { #class = "date-picker", id = "endDate" })
#*<input type="submit" href="#" id="calendarSubmitButton" class="btn btn-primary" />*#
Get Dates
<script type="text/javascript">
$(document).ready(function () {
$('#calendarSubmitButton').click(function () {
//TODO: Figure this out.
var tempStartDate = $("#startDate").val($.datepicker.formatDate('yymmdd', new Date($('#startDate').datepicker('getDate'))));
var tempEndDate = $("#endDate").val($.datepicker.formatDate('yymmdd', new Date($('#startDate').datepicker('getDate'))));
location.href = '#Url.Action("Index")?startDate=' + tempStartDate.val() + '&endDateFromJS=' + tempEndDate.val();
})
});
</script>
</div>
I have a list of dates that I want to disable in my bootstrap date picker. I cannot get the datesDisabled function to work with the array of dates returned from JSON. It does work with a hard coded array of dates.
Is there something that I need to do format the dates returned from JSON in order to get it to work?
Query:
var DatesBooked= JsonConvert.SerializeObject(db.Calendar.Where(x => x.CalLocation != "OFF")).Select(x => x.CalDate).Distinct().ToList());
In my view:
#Html.TextBox("AddedDates", null, new { #class = "form-control small", #Value = ViewBag.SelDate, autocomplete = "off" })
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.timepicker.js"></script>
<script src="~/Scripts/bootstrap-datepicker.min.js"></script>
<script>
var unavailableDates= #Html.Raw(Json.Encode(Model.DatesBooked));
$input = $("#AddedDates");
$input.datepicker({
multidate: true,
multidateSeparator: ',',
datesDisabled: unavailableDates,
});
</script>
unavailableDates value
var unavailableDates = "[\"2016-05-01T00:00:00\",\"2016-05-02T00:00:00\",\"2016-05-03T00:00:00\",\"2016-06-24T00:00:00\",\"2016-06-25T00:00:00\"]"
If I hardcode thisfor unavailableDates, everything works fine.
var unavailableDates = ["05/25/2016", "05/26/2016"]
How do I need to format the dates in order to get this to work?
TIA!
Well after many attempts and more research, I was able to solve this by doing the following:
I reformatted the date using C#:
var checkdates = db.Calendar.Where(x => x.CalLocation != "OFF")).Select(x => x.CalDate).Distinct().ToList()
var DatesBooked= JsonConvert.SerializeObject(checkdates, Formatting.None, new IsoDateTimeConverter() { DateTimeFormat = "MM/dd/yyyy" });
Then in the view, I stripped the "\" characters returned by JSON and created an array:
var unavailableDates = #Html.Raw(Json.Encode(Model.DatesBooked));
var formatDates = unavailableDates.replace(/\\/g, "");
var trimDate = formatDates.slice(1, -1); // to remove " at beginning and end
var finalDates = JSON.parse("[" + trimDate + "]");
$input = $("#AddedDates");
$input.datepicker({
multidate: true,
multidateSeparator: ',',
datesDisabled: finalDates,
todayHighlight: true
});