We need to create the blog.js file in the Admin folder and to define the following variables:

  • jsonPage (the module name; in our case is Blog)
  • aoColumns (the posts table column names)

We also need to setup the function loadData(aoData) that returns the filters values for our entity:

  • length (set by the datatables iDisplayLength var)
  • start (set by the datatables iDisplayStart var)
  • secho (set by the datatables sEcho var)
  • filters (set by us using the inputs from the data table header row)
    • If we have a normal input then we will get it's value if the value is not empty
    • If we have a select then we will get it's value if the value is different than -1 (we use -1 value as any value, like the simple input with no value)
    • If we have a combobox then we will get it's autocomplete data like the following code:
      if($(element).data('ui-autocomplete') && $(element).data('ui-autocomplete').hasOwnProperty('selectedItem') && $(element).data('ui-autocomplete').selectedItem) filters.filters[FILTERNAME] = $(element).data('ui-autocomplete').selectedItem.id;

      Replace $(element) with the jquery element selector and FILTERNAME with the column name

Because our entity has a html content editor (we use CKEditor for this type of editor) and a combobox for admins (the authors of posts) we need to instantiate them when the document is loaded.

The content of blog.js file

var jsonPage = 'Blog',
	aoColumns = [
		{ "mData": "id" },
		{ "mData": "title" },
		{ "mData": function(e) {
			//Return column "name" from table "admins"; this is loaded automatically because we added a foreign key to "admin" column in "posts" table
			return e.admins.name;
		} },
		{ "mData": "date_updated" },
		{ "mData": function (e) {
			return $('#statusf').find('option[value="' + e.status + '"]').text();
		} },
		{ "mData": function(e) {
			return "<span class=\"actions btn fa fa-edit\"></span><span class=\"actions btn btn-outline-danger fas fa-trash\" title=\"" + jsstrings.delete + "\" data-actid=\"" + e.id + "\" data-toggle=\"modal\" data-target=\"#confirm_delete\"></span>";
		} }
	delAction = 'delete_post';
$(function() {
	//Replace the simple textarea with a CKEditor
	CKEDITOR.replace('edcontent', {
		allowedContent: true,
		extraPlugins: 'justify'
	//Set the inputs with the "autocomplete-author" css class as comboboxes and load their values from Administrators module
		source: function(request, response) {
			var data = {};
			data.filters = {};
			data.filters.name = request.term;
				type: 'POST',
				url: 'json/Administrators',
				data: data,
				jsonp: "callback",
				dataType: "jsonp",
				success: function(data) {
					response($.map(data, function(el, index) {
						var iddata = index.substring(1);
						return {
							value: el,
							id: iddata
		minLength: 3
//Function to set filters when loading data for the table of posts
function loadData(aoData) {
	var filters = {};
	$(aoData).each(function(i, val) {
		if(val.name == 'sEcho') filters.secho = val.value;
		else if(val.name == 'iDisplayStart') filters.start = val.value;
		else if(val.name == 'iDisplayLength') filters.length = val.value;
	filters.filters = {};
	if($("#idf").val()!='') filters.filters['id'] = $("#idf").val();
	if($("#titlef").val()!='') filters.filters['title'] = $("#titlef").val();
	if($("#authorf").data('ui-autocomplete') && $("#authorf").data('ui-autocomplete').hasOwnProperty('selectedItem') && $("#authorf").data('ui-autocomplete').selectedItem) filters.filters['admin'] = $("#authorf").data('ui-autocomplete').selectedItem.id;
	if($("#statusf").val()!='-1') filters.filters['status'] = $("#statusf").val();
	return filters;