Need help for hierarchical table based menu

I want to make a hierarchical table based menu, i made a picture to kinda explain.


So i want to make multiple tables (represented by A and B here), that each have their own buttons, and inside those buttons are subbuttons, again and again. The goal of this is to make it more simple than making hundreds of uis by hand.

I have one done right now, but many problems have showed up, such as the back button not working. Ive thought about using string.split to make it, however i dont know how to use that. The script is too messy and making a new one would be rather better at that point.

Also, I do not know how to make the last buttons of the tree show a different UI, or do something different than all the others.

My discord is EdouardLeBeau, if you want to VC or talk about it



1 Like

Ok well this took be almost an hour which im not proud to admit but i got it to work, i tested it and I dont see any bugs

local masterTable = {
	["General1"] = {
		["Sub1"] = {
			"Even more sub1 11",
			"Even more sub1 21",
			"Even more sub1 31",
		},
		["Sub2"] = {
			"Even more sub2 11",
			"Even more sub2 21",
			"Even more sub2 31"
		},
		["Sub3"] = {
			"Even more sub2 11",
			"Even more sub2 21",
			"Even more sub2 31"
		},
	},

	["General2"] = {
		["General 2 sub 1"] = {
			"Even more sub1 12",
			"Even more sub1 22",
			"Even more sub1 32",
		},
		["General 2 sub Sub2"] = {
			"Even more sub2 12",
			"Even more sub2 22",
			"Test"
		},
		["General 2 sub Sub3"] = {
			"Even more sub2 12",
			"Even more sub2 22",
			"Even more sub2 32"
		},
	},

	["General3"] = {
		["General 3 sub 1"] = {
			"Even more sub1 13",
			"Even more sub1 23",
			"Even more sub1 33",
		},
		["General 3 sub Sub2"] = {
			"Even more sub2 13",
			"Even more sub2 23",
			"Even more sub2 33"
		},
		["General 3 sub Sub3"] = {
			"Hen",
			"Dog",
			"Cat"
		},
	},
}

local currentTable = masterTable
local tableHistory = {}

function assignButtonTexts(desiredTable)
	local keyTable = {}
	
	local index = 1
	
	print(desiredTable)
	
	for i, v in pairs(desiredTable) do
		if type(v) == "table" then
			script.Parent:FindFirstChild(index).Text = i
			index += 1
		else
			script.Parent:FindFirstChild(index).Text = v
			index += 1
		end
		
	end
end

assignButtonTexts(currentTable)

script.Parent:FindFirstChild("1").MouseButton1Click:Connect(function()
	table.insert(tableHistory, currentTable)
	local searchTable = {}
	
	for i, v in pairs(currentTable) do
		table.insert(searchTable, i)
	end

	currentTable = currentTable[searchTable[1]]
	task.wait(0.1)
	assignButtonTexts(currentTable)
end)

script.Parent:FindFirstChild("2").MouseButton1Click:Connect(function()
	table.insert(tableHistory, currentTable)
	local searchTable = {}

	for i, v in pairs(currentTable) do
		table.insert(searchTable, i)
	end
	
	currentTable = currentTable[searchTable[2]]
	task.wait(0.1)
	assignButtonTexts(currentTable)
end)

script.Parent:FindFirstChild("3").MouseButton1Click:Connect(function()
	table.insert(tableHistory, currentTable)
	local searchTable = {}

	for i, v in pairs(currentTable) do
		table.insert(searchTable, i)
	end
	
	currentTable = currentTable[searchTable[3]]
	task.wait(0.1)
	assignButtonTexts(currentTable)
end)

script.Parent.Back.MouseButton1Click:Connect(function()
	if #tableHistory > 0 then
		if #tableHistory > 0 then
			currentTable = table.remove(tableHistory)  
			task.wait(0.1)
			assignButtonTexts(currentTable)
		end
	end
end)

1 Like

There’s a problem with it, the numbers are not where they should be for some reason, and clicking the sub 2 doesnt show sub 2-1. Also, the unused buttons stay visible

image
image
image

I didnt have the issue where clicking sub 2 gave the wrong entries. Unused one stay visible because you clearly showed in your image it would always be a 3-3-3-3 layout. And if you want behavior different from what you showed you can modify the code

That’s the major trouble. Effectively you need a dictionary, but dictionary ordering is not ensured. So you have to find some way to fill it out. This means your data structure could get annoyingly verbose.

Examples
local data = {
	{
		["text"] = "The First Button",
		["children"] = {
			{
				["text"] = "The first sub menu",
				['children'] = {
					
				}
			}
		}
	},
	
	{
		["text"] = "The Second button",
		["children"] = {}
	}
}




local data = {
	["The first button"] = {
		priority = 1,
		children = {
			
		}
	},
	
	["The second button"] = {
		priority = 1,
		children = {
			["Other button"] = {
				priority = 1,
				children = {

				}
			}
		}
	}
}

There are just too many requirements per item. Honestly it would be easier to just build the structure in explorer and just have your code format it when the menu gets selected. That way you can actually fill out this data in a more intuitive way.

Actually i found my way out of it. Heres what i used

function assignButtonTexts(desiredTable)
	local keyTable = {}
	local index = 1
	
	for key in pairs(desiredTable) do
		table.insert(keyTable, key)
	end
	
	table.sort(keyTable)
	print(keyTable)
	
	for _, v in pairs(keyTable) do
		script.Parent:FindFirstChild(index).Text = v
		index += 1
	end
end