Javascript – Dump đối tượng dưới dạng HTML table

Thông thường để xem một đối tượng có kiểu phức tạp trong javascript, ta thường dùng FireBug hoặc một addon tương tự. Tuy nhiên cách hiển thị các thông tin đối tượng của chúng có thể không theo ý bạn.  Trong bài viết này, tôi sẽ tạo hướng dẫn cách để hiển thị một đối tượng javascript dưới dạng các table lồng nhau tùy theo độ phức tạp của chúng. Phương pháp rất đơn giản, bạn chỉ cần sử dụng đệ quy để kiểm tra kiểu đối tượng, lặp và tạo một table tương tự như công cụ LindPad thực hiện.

Để thực hiện ví dụ, tôi sẽ tạo một đối tượng, bao gồm các property đơn giản, phức tạp và cả kiểu mảng. Phương thức tạo ra đối tượng này như sau:

function createSampleObject(){

var school = new Object();

school.Name = "ABC University";
school.Address = {
Country : "Vietnam",
City : "HCM"
};

var student1 = {
Name : "Nguyen A To",
Age : 13,
Address: {
Country : "Vietnam",
City : "Bien Hoa"
}
};
var student2 = {
Name : "Le Thi La",
Age : 14
};

school.students = [ student1 , student2 ]; // array

return school;
}

Đối tượng trả về của phương thức trên khi xem trong FireBug:

FireBug Console Log Object

Tiếp đến, tôi viết một phương thức tên là dumpTable() dùng để tạo một table của đối tượng. Phương thức này sẽ phân ra hai trường hợp:

– Nếu đối tượng là mảng, nó sẽ duyệt qua từng phần tử của mảng. Với mỗi phần tử, nó sẽ tạo một dòng mới với cột đầu tiên là chỉ số của phần tử trong mảng. Cột thứ hai chính là giá trị của phần tử được tạo ra bằng cách gọi lại phương thức dumpTable() để chèn một bảng con (nested table) vào bên trong cột vừa tạo.

– Ngược lại, gọi một phương thức khác để tạo ra các dòng cho table.

function dumpTable(obj)
{
	var output = "<table><thead><tr><th>Property</th><th>Value</th></tr></thead><tbody>";

	if(obj.length)
	{
		for(var i=0 ; i<obj.length; i++)
		{
			output+="<tr><td>"+i+"</td><td>";
			output+=dumpTable(obj[i]);
			output+="</td></tr>";
		}
	}else
	{
		output+=dumpRows(obj);
	}
	return output+"</tbody></table>";;
}

Phương thức dumpRows() dùng để duyệt qua từng property của đối tượng. Với mỗi property, tôi sẽ tạo một dòng với cột đầu là tên của property và cột thứ hai là giá trị của property.

Để kiểu tra kiểu của property, tôi dùng toán tử typeof. Nếu nó là “object” (kiểu phức tạp), tôi sẽ gọi phương thức dumpTable() để chứa nó trong một table con mới. Ngược lại, chỉ cần thêm nó vào dưới dạng chuỗi:

function dumpRows(obj)
{
	var output = "";
	for (property in obj) {

		var row="<tr><td>"+property+"</td><td>";

		if(typeof obj[property]=="object")
			row+=dumpTable(obj[property]); //  nested table
		else
			row+=obj[property]; // text

		output+=row;
	}
	return output;
}

Rất đơn giản, phần còn lại chỉ việc thêm một vài mã HTML và CSS để trang trí. Như minh họa sau:

Javascript Dump Object Table

Và mã nguồn hoàn chỉnh:

<html>
	<head>
	<title></title>

	<style>
	table, td, th {
		border:1px solid #336699;
	}
	th {
		background-color: #336699;
		color:white;
	}
	</style>
	<script type="text/javascript">

	function createSampleObject(){

		var school = new Object();

		school.Name = "ABC University";
		school.Address = {
			Country : "Vietnam",
			City : "HCM"
		};

		var student1 = {
			Name : "Nguyen A To",
			Age : 13,
			Address: {
				Country : "Vietnam",
				City : "Bien Hoa"
			}
		};
		var student2 = {
			Name : "Le Thi La",
			Age : 14
		};

		school.students = [ student1 , student2 ]; // array

		return school;
	}

		function dumpObject(){
			var obj = createSampleObject();
			console.log(obj);
			var output=dumpTable(obj);
			document.getElementById("output").innerHTML = output;
		}
		// return a table
		function dumpTable(obj)
		{
			var output = "<table><thead><tr><th>Property</th><th>Value</th></tr></thead><tbody>";

			if(obj.length)
			{
				for(var i=0 ; i<obj.length; i++)
				{
					output+="<tr><td>"+i+"</td><td>";
					output+=dumpTable(obj[i]);
					output+="</td></tr>";
				}
			}else
			{
				output+=dumpRows(obj);
			}
			return output+"</tbody></table>";;
		}
				// return rows
		function dumpRows(obj)
		{
			var output = "";
			for (property in obj) {

				var row="<tr><td>"+property+"</td><td>";

				if(typeof obj[property]=="object")
					row+=dumpTable(obj[property]); //  nested table
				else
					row+=obj[property]; // text

				output+=row;
			}
			return output;
		}
	</script>
</head>
	<body>
		<button id="button1" onclick="dumpObject();">Dump</button>
		<div id="output"></div>
	</body>
</html>