Using A DateRange With DataTables
Using A DateRange With DataTables
Hello!
I am new to jQuery as well as ASP.Net MVC and have been attempting to implement a DataTable into my view. So far the DataTable has been performing wonderfully and I have the sorts, pagination, and search features working. I also added the various buttons offered by DataTables (PDF, Excel, Copy, Print) and those are also working. The problem I am having now is that I am trying to add a "date range" feature to the table and so far I have been unsuccessful. I have followed a few tutorials and have found numerous examples (including DataTables own https://www.datatables.net/examples/plug-ins/range_filtering.html), but have still not been able to get the feature to work. I have ran the debugger and am currently receiving two errors:
1) Uncaught TypeError: Cannot read property 'ext' of undefined
2) Uncaught TypeError: Cannot read property 'length' of undefined
The former error (from what I can find) is an issue with the order my scripts are initialized. I checked the order I am currently using with a few others and I thought that I had that figured out (obviously I was wrong). The second error seems to be a miscommunication with my database (probably mixed up some columns in my code). I can try to figure out that second error later, but my main concern is the date range. Are my scripts confusing each other somehow?
My HTML code is as follows:
@model IEnumerable<Grant_Tracker.Models.Old_Work>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Work Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<head>
@* Links for the style sheets*@
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/r/dt/jq-2.1.4,jszip-2.5.0,dt-1.10.9,b-1.0.3,b-flash-1.0.3,b-html5-1.0.3/datatables.min.css" />
<link rel="stylesheet" type="text/css" href="~/Content/dataTables.bootstrap.css" />
@* Links for the DataTable and various buttons (PDF, Excel, Copy, Print) *@
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.19/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.flash.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.html5.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.print.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
</head>
@* Text boxes used for user input *@
<table border="0" cellspacing="5" cellpadding="5">
<tbody>
<tr>
<td style="margin: 10px; padding: 5px;">Start Date:</td>
<td><input name="min" id="min" type="text"></td>
</tr>
<tr>
<td style="margin: 10px; padding: 5px;">End Date:</td>
<td><input name="max" id="max" type="text"></td>
</tr>
</tbody>
</table>
@* Sets the header names *@
<table class="table" id="reportTable">
<thead>
<tr>
<th width="150">
Date
</th>
<th width="150">
Name
</th>
<th width="150">
Description
</th>
<th width="150">
Location
</th>
<th width="150">
Work Hours
</th>
<th width="150">
District
</th>
<th width="150">
Category
</th>
<th></th>
</tr>
</thead>
@* Gathers the data from SQL database *@
<tbody>
@foreach (var item in Model)
{
<tr>
<td align="left">
@Html.DisplayFor(modelItem => item.Work_Date)
</td>
<td align="left">
@Html.DisplayFor(modelItem => item.User.User_Name)
</td>
<td align="left">
@Html.DisplayFor(modelItem => item.Work_Description)
</td>
<td align="left">
@Html.DisplayFor(modelItem => item.Work_Location)
</td>
<td align="center">
@Html.DisplayFor(modelItem => item.Work_Hours)
</td>
<td align="center">
@Html.DisplayFor(modelItem => item.District.District_Name)
</td>
<td align="left">
@Html.DisplayFor(modelItem => item.New_Work.Category_Name)
</td>
<td width="150">
@Html.ActionLink("Edit", "Edit", new { id = item.Work_ID }) |
@Html.ActionLink("Details", "Details", new { id = item.Work_ID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Work_ID })
</td>
</tr>
}
</tbody>
</table>
@* Calls the script that handles the button inputs *@
<script type="text/javascript" src="~/Scripts/buttons.js"></script>
@* Calls the script that handles the user inputs for the date range *@
<script type="text/javascript" src="~/Scripts/daterange.js"></script>
Here is my date range script:
$(document).ready(function(){
$.fn.dataTable.ext.search.push(
function (settings, data, dataIndex) {
var min = $('#min').datepicker("getDate");
var max = $('#max').datepicker("getDate");
var startDate = new Date(data[0]);
if (min == null && max == null) { return true; }
if (min == null && startDate <= max) { return true;}
if(max == null && startDate >= min) {return true;}
if (startDate <= max && startDate >= min) { return true; }
return false;
}
);
$("#min").datepicker({ onSelect: function () { table.draw(); }, changeMonth: true, changeYear: true });
$("#max").datepicker({ onSelect: function () { table.draw(); }, changeMonth: true, changeYear: true });
var table = $('#reportTable').DataTable();
// Event listener to the two range filtering inputs to redraw on input
$('#min, #max').change(function () {
table.draw();
});
});
Here is my buttons script:
// Initializes the DataTable and implements the buttons
$('#reportTable').DataTable(
{
dom: 'Blfrtip',
buttons:
[
{
extend: 'pdf',
className: 'green glyphicon glyphicon-file',
title: 'Report',
filename: 'Report',
exportOptions:
{
columns: [0, 1, 2, 3, 4, 5, 6]
}
},
{
extend: 'excel',
className: 'green glyphicon glyphicon-list-alt',
title: 'Report',
filename: 'Report',
exportOptions:
{
columns: [0, 1, 2, 3, 4, 5, 6]
}
},
{
extend: 'copy',
className: 'green glyphicon glyphicon-duplicate',
exportOptions:
{
columns: [0, 1, 2, 3, 4, 5, 6]
}
},
{
extend: 'print',
className: 'green glyphicon glyphicon-print',
title: 'Report',
text: 'Print',
exportOptions:
{
modifier:
{
page: 'current'
}
}
}
]
});
I have been beating my head against the wall for several days now and I can't figure out the problem with my code. Any insight would be greatly appreciated.
This question has an accepted answers - jump to answer
Answers
Are you loading jQuery a second time on the page? And what version of DataTables are you using?
It would be work running the debugger on your page and see what its tests say.
Allan
Thanks for the reply!
I ran the debugger again to check the version that I have installed, but it just has hyphens next to the latest version (1.10.19). Does that mean that I don't have DataTables actually installed? I thought it was installed via the CDN (line 22 on my first chunk of code).
You include the CDN download, which contains this comment:
Then you include some of those libraries individually as well. Remove those lines.
Good catch!
It looks like I can safely remove the lines:
If I remove any of the others, however, I lose some features (either the button goes missing or is no longer functional). This doesn't appear to fix the date range though.
It sounds increasingly likely that you are loading jQuery more than once. If the debugger can't find the DataTables version, then the instance of jQuery it has attached doesn't have access to DataTables.
To be able to provide much more help than that, I'd need a link to a page showing the issue.
Allan
Unfortunately, this is not a live website that I am currently working on it is still being locally hosted on my machine. >_<
I am a little bit confused, however, how jQuery would be loaded twice:
This is the line that actually loads jQuery, correct? This page is the only page that contains the line and it appears only once (at the top of my code). If this is the cause of my issue then where else is it being loaded and how can I correct this mistake?
Thank you very much for taking the time to respond. I have been struggling with this for longer than I care to admit and this is the last big hurdle for this project to be done.
I already showed you what is being loaded by your DT CDN link. It includes jQuery.
Yeah, it had the older version of jQuery running with it. I took that out along with those other doubles you found.
That is how things are looking right now. I actually have added another script (one to add up the work hours column), but that isn't working either. I've been trying to find a way to stop jQuery from loading multiple times. Still working on it.
So...you were absolutely right, Allan. I was so focused on the scripts and the view that I was working on that I completely forgot about the _Layout file.
That was the culprit right there. Once I removed that everything started working beautifully. Thank you both for your responses.