Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC5 and DataTables for a beginner: what goes where?

I've asked this question on the DataTables forum, but in the interest of getting quick feedback, I'm willing to endure some abuse, so I'm cross-posting here.


I'm just starting an adventure into ASP.NET MVC5, armed with web development skills firmly rooted in 1995. After some effort, the basic CRUD application is working, and I'm proceeding to dress it up some. The functionality that DataTables delivers seems to be a perfect fit.

What I understand about JavaScript could fit in a small comment block, but I can follow well formed instructions. So when I found the documentation that said, "just add these three include lines and this one line of JS, and you're off and running," I thought it would be straightforward. I did what I thought the instructions said, and nothing changed. Doing more research, I found someone's project that creates bindings for MVC5 and DataTables 1.10, but the instructions are sparse ("easy" is only easy if you understand what they're telling you to do).

Beginning with the DataTables instructions ("just add these three lines..."), here's what I have:

<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.5/css/jquery.dataTables.css">

<!-- jQuery -->
<script type="text/javascript" charset="utf8" src="//code.jquery.com/jquery-1.10.2.min.js"></script>

<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="//cdn.datatables.net/1.10.5/js/jquery.dataTables.js">
</script>

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table" id="products" >
    <tr>
        <th> @Html.DisplayName("Code")</th>
        <th>@Html.DisplayNameFor(model => model.Name)</th>
        <th>@Html.DisplayNameFor(model => model.Category)</th>
        <th>@Html.DisplayName("Active")</th>
        <th>@Html.DisplayName("Published")</th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>@Html.DisplayFor(modelItem => item.ProductCode)</td>
        <td>@Html.DisplayFor(modelItem => item.Name)</td>
        <td>@Html.DisplayFor(modelItem => item.Category)</td>
        <td>@Html.DisplayFor(modelItem => item.Active.Value)</td>
        <td>@Html.DisplayFor(modelItem => item.Published.Value)</td>
        <td>@Html.ActionLink("Details", "Details", new { id=item.ID })</td>
    </tr>
}
</table>

Theoretically, all I need to add is one line:

$(document).ready( function () {
    $('#products').DataTable();
} );

What's missing (here's where my rudimentary understanding comes in) is WHERE to add it. I've tried several places, and no change to the table is made. The first place I tried was within the script tag for the third block:

<script type="text/javascript" charset="utf8" src="//cdn.datatables.net/1.10.5/js/jquery.dataTables.js">
$(document).ready( function () {
    $('#products').DataTable();
} );</script>

Is that the right place? Am I identifying the target table correctly? Do I need to figure out how to implement the code found at https://github.com/ALMMa/datatables.mvc ? Should I abandon all hope until I've mastered JavaScript?

Thanks for whatever help you can give me.

Cheers.

JD

like image 713
J.D. Ray Avatar asked Feb 10 '15 22:02

J.D. Ray


People also ask

What are DataTables used for?

Data tables are used in Excel to display a range of outputs given a range of different inputs. They are commonly used in financial modeling and analysis to assess a range of different possibilities for a company, given uncertainty about what will happen in the future.

What is better than DataTables?

The best alternative is jQuery Dynatable. It's not free, so if you're looking for a free alternative, you could try List. js or Webix DataTable. Other great apps like DataTables are Frappe DataTable, Dash DataTable, wpDataTables and Essential JS 2 for JavaScript by Syncfusion.

What is DataTable in asp net?

A DataTable represents one table of in-memory relational data; the data is local to the . NET-based application in which it resides, but can be populated from a data source such as Microsoft SQL Server using a DataAdapter For more information, see Populating a DataSet from a DataAdapter.

How much data can DataTables handle?

The maximum number of rows that a DataTable can store is 16,777,216.


2 Answers

I too had a difficult time getting DataTables operational in MVC5. I was attempting to use it in the standard Index View that Scaffolding generates against a view model. I was able to build a small prototype but not against the FOREACH generator for the table.
I entered many different JS and CSS code lines from suggested examples and also patched the BundleConfig. Still no joy.
The Index would present properly but not the features such as sortable columns.
Eventually that was resolved by exactly matching the count of columns in the header to the count of columns in the displayed table body. Notice that the Id column is not counted in the displayed columns. In my example there are 6 displayed columns and six headers. But seven in the model with the Id column hidden. The Action Column also has a header.

By now there are JavaScript and css fragments all over the place. I wanted to clean it up for reuse.

I was able to partially correct the bundle. Then a skilled associate showed me how to properly deploy the bundle references solely in the Index Page not on the _Layout Page where it would be unnecessarily loaded on every page.

You will also see that there are no Version numbers in any of the paths. This is purposeful to allow JS, CSS and DataTable updates without changing the source code.

Make sure your Table Id specified in the <table> line exactly matches the value in the Javascript at the bottom with a # in front in the JS. When I was finished with this task there were no remaining JS of CSS lines in my pages. Try the following.

  1. Download the Latest Bootstrap and DataTables from NuGet
  2. Modify the RegisterBundles Code in the AppStart folder by adding

    //
        //  These are the DataTables bundles
        //  Be sure to activate them on the Page where they are needed or on _Layout 
        //
        bundles.Add(new ScriptBundle("~/bundles/dataTables").Include(
                  "~/Scripts/DataTables/jquery.dataTables.js",
                  "~/Scripts/DataTables/dataTables.bootstrap.js"));
    
        bundles.Add(new StyleBundle("~/Content/dataTables").Include(
                  "~/Content/DataTables/css/jquery.dataTables.css",
                  "~/Content/DataTables/css/jquery.dataTables.min.css"));
    
  3. Then add references to the bundles at the Top and Bottom of the Index page.

At the head section of the Index Page

 @model IEnumerable<"Your Own Model">.PriceList>

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    @Styles.Render("~/Content/dataTables")


<h2>Price List</h2>
        <table id="table_id" class="table table table-striped table-hover">
            <thead>
                <tr>                        
                    <th>
                        Product Ptr
                    </th>                        
                    <th>
                        Product Class
                    </th>
                    <th>
                        Ver
                    </th>
                    <th>
                        Year
                    </th>
                    <th>
                        Description
                    </th>
                    <th>
                        Action
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model)
                {
                    <tr>  
                            @Html.HiddenFor(modelItem => item.PriceList_Id)

                        <td>
                            @Html.DisplayFor(modelItem => item.Product_Pt)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.ProductClass_Pt)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Version)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Year)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.ProductDesc)
                        </td>

                        <td>
                            @Html.ActionLink("Edit", "Edit", new { id=item.PriceList_Id }) |
                            @Html.ActionLink("Details", "Details", new { id = item.PriceList_Id }) |
                            @Html.ActionLink("Delete", "Delete", new { id = item.PriceList_Id })
                        </td>

                    </tr>
                }
            </tbody>
        </table>
@section scripts {

@Scripts.Render("~/bundles/dataTables")

<script type="text/javascript">

    $(document).ready(function () {
        $('#table_id').DataTable();
    });

</script>
}
like image 145
user3594395 Avatar answered Oct 17 '22 23:10

user3594395


It's working!!

So, here's what I had to do:

In _Layout.cshtml I added the following to the head tag:

<link href="~/Content/jquery.dataTables.css" rel="stylesheet" type="text/css"/>
<link href="~/Content/jquery.dataTables_themeroller.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" charset="utf8" src="~/Scripts/jquery.dataTables.js"></script>

In BundleConfig.cs I added the following lines:

        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-1.10.2.min.js"));

        bundles.Add(new ScriptBundle("~/bundles/datatables").Include(
                    "~/Scripts/jquery.dataTables.js"));

Finally, at the bottom of Index.cshtml is the call to the script:

<script type="text/javascript" charset="utf8">
    $(document).ready( function () {
        $('#products').DataTable();
    } );
</script>

I suspect that the BundleConfig.cs bits are redundant, but it's working, so I don't want to fool with trying to optimize it right now.

Cheers.

JD

like image 3
J.D. Ray Avatar answered Oct 17 '22 22:10

J.D. Ray