Datatable Row Reorder with Checkboxes and Radio Buttons

Datatable row recorders feature is used in tables using it’s add-on plugin named (dataTables.rowReorder.js). Using this addon we can drag and drop rows in any order we want in the table. This works only if the table is having some unique serial number or ID. Let’s work on the implementation of datatable with row reorder feature.

See Demo Here

Datatable Row Reorder with Checkboxes and Radio Buttons

Following are basic steps to use jQuery Datatable.

Step 1) Include Javascript and CSS liberaries required.

//Css Style for Datatables
<link href="jquery.dataTables.css" rel="stylesheet"/>

<script type='text/javascript' src='jquery.min.js'></script>

<!--Datatable library-->
<script type='text/javascript' src='jquery.dataTables.js'></script>

<!--Datatable Row Reorder Addon-->
<script type='text/javascript' src='dataTables.rowReorder.js'></script>

 

Step 2) Now we need to call Javascript code to initiate Datatables. I have already inline comments in the code below and will also explain it below. We have added a dummy data object.

<script>

$(document).ready(function(){

//Test Data to Build Datatable
var dataArray = [{
		"profile_id": 2522,
		"positionName": "Proposal Manager",
		"NumberOfProjects": 2,
		"profile_intro": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s",
		"flgSelect": false,
		"RowPosition": 1,
		"checked": false
	}, {
		"profile_id": 2624,
		"positionName": "Mission Assurance Volume Writer",
		"NumberOfProjects": 0,
		"profile_intro": "gfgg",
		"flgSelect": true,
		"RowPosition": 2,
		"checked": true
	}, {
		"profile_id": 2629,
		"positionName": "Software Engineer",
		"NumberOfProjects": 0,
		"profile_intro": "cxcxcxc",
		"flgSelect": false,
		"RowPosition": 3,
		"checked": false
	}, {
		"profile_id": 2638,
		"positionName": "Software Engineer",
		"NumberOfProjects": 0,
		"profile_intro": "wwww",
		"flgSelect": false,
		"RowPosition": 4,
		"checked": true
	}, {
		"profile_id": 2696,
		"positionName": "Mission Assurance Volume Writer",
		"NumberOfProjects": 0,
		"profile_intro": "okkok",
		"flgSelect": false,
		"RowPosition": 5,
		"checked": true
	}, {
		"profile_id": 2697,
		"positionName": "Mission Assurance Volume Writer",
		"NumberOfProjects": 0,
		"profile_intro": ",mm,m",
		"flgSelect": false,
		"RowPosition": 6,
		"checked": true
	}, {
		"profile_id": 2698,
		"positionName": "Mission Assurance Volume Writer",
		"NumberOfProjects": 0,
		"profile_intro": "kmkmkmkm",
		"flgSelect": false,
		"RowPosition": 7,
		"checked": false
	}, {
		"profile_id": 2699,
		"positionName": "Basis of Estimate Specialist",
		"NumberOfProjects": 0,
		"profile_intro": "trt",
		"flgSelect": false,
		"RowPosition": 8,
		"checked": false
	}, {
		"profile_id": 2700,
		"positionName": "Systems Engineer",
		"NumberOfProjects": 0,
		"profile_intro": "f",
		"flgSelect": false,
		"RowPosition": 9,
		"checked": false
	}, {
		"profile_id": 2309,
		"positionName": "Basis of Estimate Specialist",
		"NumberOfProjects": 0,
		"profile_intro": "dfdfdfdfdfdf",
		"flgSelect": false,
		"RowPosition": 10,
		"checked": false
	}
];

var radioCheckedID = "";
var checkBoxChecked = [];

////Set Checked Radio Value
$(document).on("change", "input:radio", function () {
	radioCheckedID = $(this).attr("id");
});

//Set Checked Checboxed Values
$(document).on("change", "input:checkbox", function () {
	checkBoxChecked = [];
	$.each(dataArray, function (key, value) {
		if (value.checked)
			checkBoxChecked.push("chk" + value.profile_id);
	});
});

var roleTable = $('#tblTest').dataTable({
		//"order": [1, "desc"],
		"filter": false,
		"lengthChange": false,
		"paginate": false,
		"sort": true,
		"info": false,
		"data": dataArray,
		"destroy": true,
		"sScrollX": "100%",
		"responsive": true,
		"drawCallback": function (settings) {

			//Retain Checked Radio After Drag
			if (radioCheckedID.length)
				$("#" + radioCheckedID).prop("checked", true);

			//Retain Checked Checkbox After Drag
			$.each(checkBoxChecked, function (key, value) {
				$("#" + value).prop("checked", true);
			});
		},
		"columnDefs": [{
				"targets": [0],
				"visible": true,
				"width": "4%",
				"class": "sorting_disabled",
				"orderable": false,
				"render": function (data, type, full, meta) {
					return '<span class="icon-drag"><span class="hide-id-drop">' + data + '</span></span>';
				}
			}, {
				"targets": [1],
				"visible": true,
				"width": "10%",
				"orderable": false
			}, {
				"targets": [2],
				"visible": true,
				"width": "25%",
				"orderable": false
			}, {
				"targets": [3],
				"visible": true,
				"width": "40%",
				"orderable": false
			}, {
				"targets": [4],
				"width": "10%",
				"class": "noShow",
				"orderable": false,
				"render": function (data, type, full, meta) {
					if (full.flgSelect)
						return '<input id="rd' + full.profile_id + '" type="radio" checked name="defaultRole" >';
					else
						return '<input id="rd' + full.profile_id + '" type="radio" name="defaultRole" >';
				}
			}, {
				"targets": [5],
				"width": "10%",
				"class": "noShow",
				"orderable": false,
				"render": function (data, type, full, meta) {
					if (full.checked)
						return '<input id="chk' + full.profile_id + '" checked type="checkbox"/>';
					else
						return '<input id="chk' + full.profile_id + '" type="checkbox"/>';
				}
			}

		],
		"columns": [{
				"data": "RowPosition"
			}, {
				"data": "NumberOfProjects"
			}, {
				"data": "positionName"
			}, {
				"data": "profile_intro"
			}, {
				"data": "profile_id"
			}, {
				"data": "profile_id"
			}
		],
		rowReorder: {
			dataSrc: 'RowPosition'
		},
		"initComplete": function () {

			if ($(this).find('input[type=checkbox]:checked').length > 0) {
				$(this).parents('.content-wrapper:eq(0)').find('.switch-btn:eq(0) input[type=checkbox]').prop("checked", true);
			}
		}
	});

});

</script>

 

 

Step 3) Add HTML part for a table in which we are binding Data.

	<table id="tblTest" class="table" width="100%">
		<thead>
			<tr>
				<th style="width:2%">Drag Here</th>
				<th style="width:23%">ID</th>
				<th style="width:15%">Name</th>
				<th style="width:15%">Position</th>
				<th style="width:15%">Incharge</th>
				<th style="width:15%" >Manger</th>
			</tr>
		</thead>
	</table>

 

 

As there is Radio and Checkboxes control in data tables. We are using row reorder in datatables. So normally what happens is whenever we drag and drop a row radio and check boxes, control reset to default dataset. Here we are adding jQuery functions to save radio and checkbox values in an array which will reflect after data is redrawn.

var radioCheckedID = "";
var checkBoxChecked = [];

////Set Checked Radio Value
$(document).on("change", "input:radio", function () {
	radioCheckedID = $(this).attr("id");
});

//Set Checked Checboxed Values
$(document).on("change", "input:checkbox", function () {
	checkBoxChecked = [];
	$.each(dataArray, function (key, value) {
		if (value.checked)
			checkBoxChecked.push("chk" + value.profile_id);
	});
});

 

Step 4) Also add this additional CSS for adding drag effect on Rows when reordering.

table.dt-rowReorder-float {
    position: absolute !important;
    opacity: 0.8;
    table-layout: fixed;
    outline: 2px solid #888;
    outline-offset: -2px;
    z-index: 2001
}

tr.dt-rowReorder-moving {
    outline: 2px solid #555;
    outline-offset: -2px
}

body.dt-rowReorder-noOverflow {
    overflow-x: hidden
}

table.dataTable td.reorder {
    text-align: center;
    cursor: move
}

 

We are using following operations to check saved radio and checkbox in “drawCallback” event.

"drawCallback": function (settings) {

			//Retain Checked Radio After Drag
			if (radioCheckedID.length)
				$("#" + radioCheckedID).prop("checked", true);

			//Retain Checked Checkbox After Drag
			$.each(checkBoxChecked, function (key, value) {
				$("#" + value).prop("checked", true);
			});
		},

 

You can see the working code example here.

Let me know if you have any challenges during implementation of datatables. 😁😋

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments