Basic Table with Search/Export/Sort
User Request Date Hours Is Approved
HTML
<table class="table table-hover" data-fd="table" id="SIMPLE_TABLE">
	<thead>
		<tr>
			<th fd-for="UserID" fd-for-name></th>
			<th fd-for="RequestDate" fd-for-name></th>
			<th fd-for="Hours" fd-for-name></th>
			<th fd-for="IsApproved" fd-for-name></th>
		</tr>
	</thead>
</table>
JavaScript
(function initializeDataTable() {
	simpleDataTable = $("#SIMPLE_TABLE").DataTable({
		ajax: {
			url: baseUrl + "GetItemList",
			dataSrc: function (result) {
				return result;
			}
		},
		responsive: false,
		searching: true,
		deferRender: true,
		order: [[1, "desc"], [0, "asc"]],
		columns: [
			{ data: "userName" },
			{
				data: "requestDate",
				render: function (data) {
					return moment(data).format('MMMM Do, YYYY');
				}
			},
			{ data: "hours" },
			{
				data: "isApproved",
				type: "boolean",
				render: function (data, type, row) {
					if (type === "sort" || type === "type") {
						return data;
					}
					return '<input type="checkbox" data-fd-control="checkbox"' + (data ? ' checked' : '') + ' disabled /></div>';
				}
			}
		],
		createdRow: function (row, data) {
			const $row = $(row).attr("data-fd-parentid", data.userId + '_' + data.requestDate);
		},
		drawCallback: function () {
			$("[data-fd='table']").enableControls();
		}
	});
}());
Advanced Table with Ajax Params/Column Filter/Scroll
User Request Date Hours Is Approved
HTML

<select name="IsApproved" class="form-control" data-fd-control="select" data-fd-allowsearch="false" data-fd-allowclear="true" data-fd-callback="reloadTable">
	<option value="">All</option>
	<option value="true">True</option>
	<option value="false">False</option>
</select>
<table class="table table-hover" data-fd="table" id="SIMPLE_TABLE_2">
	<thead>
		<tr>
			<th fd-for="UserID" fd-for-name></th>
			<th fd-for="RequestDate" fd-for-name></th>
			<th fd-for="Hours" fd-for-name></th>
			<th fd-for="IsApproved" fd-for-name></th>
		</tr>
	</thead>
	<tfoot>
		<tr>
			<th><input asp-for="Item.UserName" data-fd-control="text" class="form-control" /></th>
			<th><input asp-for="Item.RequestDate" data-fd-control="datepicker" class="form-control" /></th>
			<th><input asp-for="Item.Hours" data-fd-control="text" class="form-control" /></th>
			<th></th>
		</tr>
	</tfoot>
</table>
JavaScript
$dataTable = $("#SIMPLE_TABLE_2").DataTable({
    ajax: {
        url: baseUrl + "GetItemList",
        cache: false,
        data: (d) => {
            d.isApproved = $('[name=IsApproved]').val()
        },
        dataSrc: result => result
    },
    scrollY: "150px",
    responsive: false,
    searching: true,
    deferRender: true,
    dom: 'lrt',
    order: [[1, "desc"], [0, "asc"]],
    columns: [
        { data: "userName" },
        {
            data: "requestDate",
            render: function (data) {
                return moment(data).format('MMMM Do, YYYY');
            }
        },
        { data: "hours" },
        {
            data: "isApproved",
            type: "boolean",
            render: function (data, type) {
                if (type === "sort" || type === "type") {
                    return data;
                }
                return '<input type="checkbox" data-fd-control="checkbox"' + (data ? ' checked' : '') + ' disabled /></div>';
            }
        }
    ],
    createdRow: function (row, data) {
        $(row).attr("data-fd-parentid", data.userId + '_' + data.requestDate);
    },
    drawCallback: function () {
        $("[data-fd='table']").enableControls();
    },

    initComplete: function () {
        this.api().columns().every(function (ind) {
            var column = this;
            $(column.footer()).find('input')
                .attr('placeholder', 'Filter by ' + $(column.header()).text())
                .on('keyup change clear', function () {
                    if (column.search() !== this.value) {
                        column.search(this.value).draw();
                    }
                });
        });
    }
});

reloadTable: function () {
    $dataTable.ajax.params().isApproved = this.element.val();
    $dataTable.ajax.reload();
}
Advanced Table with Edit Controls
Add Item
User Request Date Hours Is Approved
HTML
<form asp-action="CreatePtoRequest" fd-ajax-complete="FD.Page.UpdatePtoRequest" id="ADD_FORM">
	<div class="card">
		<div class="card-header bg-light">
			Add Item
		</div>
		<div class="card-body row no-gutters">
			
		</div>
		<div class="pb-3 pr-4 row no-gutters justify-content-end">
			<button class="btn btn-outline-primary" type="submit">Add</button>
		</div>
	</div>
</form>

<table class="table table-hover" data-fd="table" id="COMPLEX_TABLE">
	<thead>
		<tr>
			<th fd-for="UserId" fd-for-name></th>
			<th fd-for="RequestDate" fd-for-name></th>
			<th fd-for="Hours" fd-for-name></th>
			<th fd-for="IsApproved" fd-for-name></th>
		</tr>
	</thead>
</table>

<div id="ButtonTemplate" class="d-none">
	<i class="far fa-edit mr-1 btn btn-outline-secondary" data-fd-control="button" data-fd-callback="editRecord"></i>
	<i class="far fa-trash-alt mr-1 btn btn-outline-secondary" data-fd-control="confirmationpopover" data-fd-confirmcallback="removeRecord" data-fd-confirmclass="btn-danger" data-fd-message="Are you sure you want to remove this request?"></i>
</div>
JavaScript
FD.Page.removeRecord = function (data) {
	const $row = $("tr[data-fd-parentid='" + data.parentid + "']").addClass("d-none");

	$row.find("[data-fd-confirmcallback=removeRecord]").data().fdControl_confirmationpopover.element.popover("hide"); // force the popover to hide

	$.fdAjax({
		url: baseUrl + "DeletePtoRequest",
		params: complexDataTable.row($row).data(),
		callback: function (result) {
			if (!result.data) {
				$row.removeClass("d-none");
			} else {
				child.dismiss();
			}
		}
	});
};

FD.Page.editRecord = function (data) {
	const $row = $("tr[data-fd-parentid='" + data.parentid + "']").addClass("active");

	$.fdAjax({
		url: baseUrl + "GetPtoRequest",
		params: complexDataTable.row($row).data(),
		ishtml: true,
		callback: function (result) {
			if (result.data) {
				addForm.hide();
				addForm.next('form').remove();
				addForm.after(result.data);
				addForm.next('form').enableControls();
			}
		}
	});
}

FD.Page.UpdatePtoRequest = function () {
	addForm[0].reset();
	child.dismiss();
	complexDataTable.ajax.reload();
}

FD.Page.dismiss = function (data) {
	addForm.show();
	addForm.next('form').remove();
}


(function initializeDataTable() {
	complexDataTable = $("#COMPLEX_TABLE").DataTable({
		ajax: {
			url: baseUrl + "GetItemList",
			dataSrc: function (result) {
				return result;
			}
		},
		responsive: false,
		searching: true,
		deferRender: true,
		order: [[1, "desc"], [0, "asc"]],
		columns: [
			{ data: "userName" },
			{
				data: "requestDate",
				render: function (data) {
					return moment(data).format('MMMM Do, YYYY');
				}
			},
			{ data: "hours" },
			{
				data: "isApproved",
				type: "boolean",
				render: function (data, type, row) {
					if (type === "sort" || type === "type") {
						return data;
					}
					return '<input type="checkbox" data-fd-control="checkbox"' + (data ? ' checked' : '') + ' disabled /></div>';
				}
			},
			{
				data: null,
				defaultContent: buttonTemplate,
				orderable: false,
				searchable: false
			}
		],
		createdRow: function (row, data) {
			const $row = $(row).attr("data-fd-parentid", data.userId + '_' + data.requestDate);
			if (data.isApproved === true) {
				$("[data-fd-callback=editRecord]", $row).addClass("d-none");
			}
		},
		drawCallback: function () {
			$("[data-fd='table']").enableControls();
		}
	});
}());