As some of you may know I am the creator of the Dropdown Module. Link to original devpost: DropDown Module! V.3. Now, there were some issues with the previous one, like you could only use this module once for creating a dropdown, so I made a new one! Introducing DropDown Module Pro+, it grants you access to so many new functions, but first we must explain how to basically install it.
Step By Step On How To Use It:
Step 1: Get the module off of the link provided.
Step 2: Put the module into the game. Place in any location you would like!
Step 3: Create two folders, one will be used to store your dropdown buttons, and one will be used to store the contents of the dropdown frame.
Step 4: Create all of the dropdown buttons. Then, inside of the DropDown contents folder, make a Folder for each DropDown button and name it THE SAME as the DropDown button it is paired with! Now, make your DropDown contents buttons, make sure to put them inside of the correct Folder. Name each of these dropdown content buttons with 1 NUMBER in the name, also ensure that each buttons number is numerical. Example: Content1, Content2, .. ect. Unacceptable: djwuidj239dwj23dj, has more than one set of numbers, and is not numerical and does not have a reasonable number!
Step 5: Position the buttons inside of the content folder at the same Y.Scale value as the dropdown button. Make sure that these buttons are hidden, so if needed, change the ZIndex of the dropdown button.
For confustion, you can paste this in your command tab!
local dropDownFolder = -- Put the location of the folder here
local dropDownContentFolder = -- Put location of the folder here
local zInD = 0
for _, x: TextButton in ipairs(dropDownFolder:GetChildren()) do
for _, y: TextButton in ipairs(dropDownContentFolder:FindFirstChild(x.Name):GetChildren()) do
if y.ZIndex > zInD then
zInD = y.ZIndex
end
y.Position = UDim2.new(y.Position.X.Scale, 0, x.Position.Y.Scale, 0)
end
x.ZIndex = zInD + 1
end
Step 6: First, require the module. Second, get both the dropDown folder and the DropDown Content folder. The first parameter is the DropDown folder, and the second is the DropDown contents folder. Then we have three other parameters: autoClose, moveOthers, and advancedSettings. Later we will get into what moveOthers and advancedSettings are, but for now keep them as empty tables: {}. moveOthers is the third parameter which if set to true will close the previous button when another one is opened.
Sorry for the yap, but now we will get into requiring. Now this code is going to look a bit weird, so letâs break it down. The .New() function is so you can create a new Dropdown Instance. You can read more about the .New() function down below. We set this new Instance to a variable, like we would any other, so we can use our other functions on it. Now we use the :AnimateMenu() function, to connect all the buttons to actually open their contents, you can read more about that down below as well! Now time for the code!
Example of LocalScript Code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(
dropDownButtons, -- Holds all the buttons
dropdownContents, -- Button Contents
true, -- Auto Close
{}, -- moveOthers
{} -- advancedSettings
)
dropDown:AnimateMenu()
Functions
Here are all of the modules functions:
.New()
Q - How does this function work?
A - Think of it as Instance.new(), but with the new instance being a Instance of a dropdown menu! When we create a new instance, it is important to save it as a variable, so we can other functions with it! So, make sure to save it under like âdropDownâ or something to that nature. Then you can pass the 5 arguments through it, where you can see the full explanation of what each parameter is down below!
Sample code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(
dropDownButtons, -- Holds all the buttons
dropdownContents, -- Button Contents
true, -- Auto Close
{}, -- moveOthers
{} -- advancedSettings
)
:AnimateMenu()
Q - What does this function do?
A - It allows the buttons to actually be animated! So if you want them to work, it is important you use them after the .New() event!
Sample code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(
dropDownButtons, -- Holds all the buttons
dropdownContents, -- Button Contents
true, -- Auto Close
{}, -- moveOthers
{} -- advancedSettings
)
dropDown:AnimateMenu()
:DisconnectAll()
Q - What does the function do?
A - This disconnects all the buttons connections, so they will not animate or open anymore!
Sample Code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(dropDownButtons, dropdownContents, true, {}, {})
dropDown:AnimateMenu()
-- This dropdown no longer serves use, so you disconnect it
dropDown:DisconnectAll()
:PauseConnections()
Q - What does the function do?
A - It stops the buttons from working for a given amount of time, but not a permanent thing! It can either be done by passing an number value, so it can be paused during a cutscene. Or, it can be paused while a player does not have access to the menu for whatever reason, and can be reaccessed by using :ResumeConnections() function!
Passing a number value through the function:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(dropDownButtons, dropdownContents, true, {}, {})
dropDown:AnimateMenu()
-- random code here
loadCutscene()
dropDown:PauseConnections(60) -- pauses for 60 seconds while cutscene runs
Example of using the :ResumeConnections() function:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(dropDownButtons, dropdownContents, true, {}, {})
dropDown:AnimateMenu()
RemovePlayerAccessToMenu.OnClientEvent:Connect(function()
dropDown:PauseConnections()
end)
GiveBackPlayerAccessToMenu.OnClientEvent:Connect(function()
dropDown:ResumeConnections()
end)
:ResumeConnections()
Q - What does the function do?
A - It connects the buttons to work again from using the :PauseConnections() function!
Tip: Use this when the time base is unsure. For example, if you have a fixed time for a cutscene, just pass an amount of seconds through `:PauseConnections()â function, but if you are unsure, then you can use this function!
Sample code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(dropDownButtons, dropdownContents, true, {}, {})
dropDown:AnimateMenu()
RemovePlayerAccessToMenu.OnClientEvent:Connect(function()
dropDown:PauseConnections()
end)
GiveBackPlayerAccessToMenu.OnClientEvent:Connect(function()
dropDown:ResumeConnections()
end)
:LockButton()
Q - What does this function do?
A - It stops the player from opening a certain button! This can be reversed by using the :UnlockButton() function!
Security: LOW | So, do not keep any sensitive data inside of this, or you will have to create a more secure way for sensitive data that a player should not be able to access
USE CASE: Why would you even need a :LockButton() function? Letâs say you were creating a dropdown menu that showed the specific powers a player unlocks with each level, but you donât want them to see what they have until they reach that certain level. Then you can use this to keep the buttons locked from them!
Sample Code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(dropDownButtons, dropdownContents, true, {}, {})
dropDown:AnimateMenu()
for _, x in ipairs(dropdownContents:GetChildren()) do
dropDown:LockButton(x)
end
local player = game.Players.LocalPlayer
local leaderstats = player.leaderstats
local level = leaderstats.level
level:GetPropertyChangedSignal("Value"):Connect(function()
local value = level.Value
local buttonToUnlock = dropDownButtons:FindFirstChild("Level-"..value.."-Powers")
dropDown:UnlockButton(buttonToUnlock)
end)
:UnlockButton()
Q - What does this function do?
A - It unlocks the button from its locked state from the :LockButton() function.
Sample Code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(dropDownButtons, dropdownContents, true, {}, {})
dropDown:AnimateMenu()
for _, x in ipairs(dropdownContents:GetChildren()) do
dropDown:LockButton(x)
end
local player = game.Players.LocalPlayer
local leaderstats = player.leaderstats
local level = leaderstats.level
level:GetPropertyChangedSignal("Value"):Connect(function()
local value = level.Value
local buttonToUnlock = dropDownButtons:FindFirstChild("Level-"..value.."-Powers")
dropDown:UnlockButton(buttonToUnlock)
end)
:CloseButton()
Q - What does this function do?
A - I feel this is very self explanatory, but it overrides the players choice and force closes a button. (No animation shown when force closed!)
Sample Code:
dropDown:CloseButton(dropDownButtons.button1)
:OpenButton()
Q - What does this function do?
A - I feel this is very self explanatory, but it overrides the players choice and force opens a button. (No animation shown when force opened!)
Sample Code:
dropDown:OpenButton(dropDownButtons.button1)
:UpdateSettings()
Q - What is this function used for?
A - Letâs say you want the player to be able to customize their own settings you can use this function to change their settings!
Sample Game: Dropdown Module Function Usecases - Roblox
Sample Code:
-- Services ---
local rs = game:GetService("ReplicatedStorage")
-- Replicated Server ----
local moduleFolder = rs:WaitForChild("Modules")
-- Modules -----
local dropdownMod = require(moduleFolder.DropDownHandler)
local sliderMod = require(moduleFolder.SliderModule)
local UI = script.Parent
local otherDrop = UI.OtherDropDown
local settingsFrame = UI["Settings frame"]
local otherDropDown = dropdownMod.New(
otherDrop.DropdownFolder,
otherDrop.Content,
true,
{},
{
["DropDownSpace"] = 0.005
}
)
local sampleDrop = settingsFrame.SampleDropDown
local sampleDropDown = dropdownMod.New(
sampleDrop.DropdownFolder,
sampleDrop.Content,
true,
{},
{
["DropDownSpace"] = 0.005
}
)
otherDropDown:AnimateMenu()
sampleDropDown:AnimateMenu()
print(dropdownMod)
local previousValue = 0.005
function spaceUpdateFunction(value)
if value == previousValue then
return
end
sampleDropDown:OpenButton(sampleDrop.DropdownFolder.Bob)
sampleDropDown:PauseConnections()
otherDropDown:UpdateSettings({["DropDownSpace"] = value})
sampleDropDown:UpdateSettings({["DropDownSpace"] = value})
print(sampleDropDown["spaceInBetween"])
sampleDropDown:ResumeConnections()
end
local timeValue = 0
function timeUpdateFunction(value)
if value == timeValue then
return
end
sampleDropDown:ResumeConnections()
otherDropDown:UpdateSettings({["TweenTime"] = value})
sampleDropDown:UpdateSettings({["TweenTime"] = value})
end
sliderMod.new(settingsFrame.Spacing, settingsFrame.Spacing.TextLabel, spaceUpdateFunction, 0.05, 0.005, 3)
sliderMod.new(settingsFrame.Time, settingsFrame.Time.TextLabel, timeUpdateFunction, 3, 0, 2)
local trueBtn = settingsFrame.True
local falseBtn = settingsFrame.False
trueBtn.MouseButton1Click:Connect(function()
trueBtn.UIStroke.Enabled = true
falseBtn.UIStroke.Enabled = false
otherDropDown:UpdateSettings({["autoClose"] = true})
sampleDropDown:UpdateSettings({["autoClose"] = true})
end)
falseBtn.MouseButton1Click:Connect(function()
trueBtn.UIStroke.Enabled = false
falseBtn.UIStroke.Enabled = true
otherDropDown:UpdateSettings({["autoClose"] = false})
sampleDropDown:UpdateSettings({["autoClose"] = false})
end)
local easingStyleInt = 1
local EasingStlyeTable = {
[1] = Enum.EasingStyle.Linear,
[2] = Enum.EasingStyle.Sine,
[3] = Enum.EasingStyle.Back,
[4] = Enum.EasingStyle.Quad,
[5] = Enum.EasingStyle.Quart,
[6] = Enum.EasingStyle.Quint,
[7] = Enum.EasingStyle.Bounce,
[8] = Enum.EasingStyle.Elastic,
[9] = Enum.EasingStyle.Exponential,
[10] = Enum.EasingStyle.Circular,
[11] = Enum.EasingStyle.Cubic
}
local easingDirectInt = 1
local EasingDirectTable = {
[1] = Enum.EasingDirection.In,
[2] = Enum.EasingDirection.Out,
[3] = Enum.EasingDirection.InOut,
}
local styleDebounceTime = 1
local styleDebounceId = 0
local selectedStyle
settingsFrame.EasingStyle.MouseButton1Click:Connect(function()
easingStyleInt += 1
if easingStyleInt > 11 then
easingStyleInt = 1
end
selectedStyle = EasingStlyeTable[easingStyleInt]
local styleName = string.split(tostring(selectedStyle), ".")[3]
settingsFrame.EasingStyle.Text = "Easing Style: "..styleName
styleDebounceId += 1
local currentId = styleDebounceId
task.delay(styleDebounceTime, function()
if currentId == styleDebounceId then
-- Only apply after no clicks for 5 seconds
otherDropDown:UpdateSettings({["EasingStyle"] = selectedStyle})
sampleDropDown:UpdateSettings({["EasingStyle"] = selectedStyle})
sampleDropDown:ResumeConnections()
print("Applied easing style:", styleName)
end
end)
end)
local directionDebounceTime = 1
local directionDebounceId = 0
local selectedDirection
settingsFrame.EasingDirection.MouseButton1Click:Connect(function()
easingDirectInt += 1
if easingDirectInt > 3 then
easingDirectInt = 1
end
selectedDirection = EasingDirectTable[easingDirectInt]
local directionName = string.split(tostring(selectedDirection), ".")[3]
settingsFrame.EasingDirection.Text = "Easing Direction: "..directionName
directionDebounceId += 1
local currentId = directionDebounceId
task.delay(directionDebounceTime, function()
if currentId == directionDebounceId then
-- Only apply after no clicks for 5 seconds
otherDropDown:UpdateSettings({["EasingDirection"] = selectedDirection})
sampleDropDown:UpdateSettings({["EasingDirection"] = selectedDirection})
sampleDropDown:ResumeConnections()
print("Applied easing direction:", directionName)
end
end)
end)
local openSize = settingsFrame.Size
local closeSize = UDim2.new(0,0,0,0)
settingsFrame.Close.MouseButton1Click:Connect(function()
settingsFrame:TweenSize(closeSize, EasingDirectTable[1], EasingStlyeTable[1], 0.5)
task.wait(0.5)
settingsFrame.Visible = false
UI.OpenSettings.Visible = true
end)
UI.OpenSettings.MouseButton1Click:Connect(function()
settingsFrame.Visible = true
settingsFrame:TweenSize(openSize, EasingDirectTable[1], EasingStlyeTable[1], 0.5)
UI.OpenSettings.Visible = false
end)
local lockButton = settingsFrame.LockButton
local lock = false
lockButton.MouseButton1Click:Connect(function()
if lock then
sampleDropDown:UnlockButton(sampleDrop.DropdownFolder.Amelia)
otherDropDown:UnlockButton(otherDrop.DropdownFolder.Amelia)
lockButton.Text = "Lock Grace"
else
sampleDropDown:LockButton(sampleDrop.DropdownFolder.Amelia)
otherDropDown:LockButton(otherDrop.DropdownFolder.Amelia)
lockButton.Text = "Unlock Grace"
end
lock = not lock
end)
:ResetSettings()
Q - What does this function do?
A - It resets all of the settings to what you set at the very beginning of the code, when you used the .New() function!
Sample Code:
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local dropDown = dropDownModule.New(
dropDownButtons, -- Holds all the buttons
dropdownContents, -- Button Contents
true, -- Auto Close
{}, -- moveOthers
{
["DropDownSpace"] = 0.005
} -- advancedSettings
)
dropDown:AnimateMenu()
ResetSettingsButton.MouseButton1Click:Connect(function()
dropDown:ResetSettings() -- This will reset the DropDownSpace to 0.005 no matter what you changed it to!
end)
:RefreshPositions()
Q - What does this function do?
A - If you believe the function had a glitch with a miscalculation, you can always use the refresh function! Or letâs say something happened and the buttons are positioned all weird, you can just reset them, then boom, this does not close any buttons, but simply recalculated!
dropDown:RefreshPositions()
:ResetDropdownStates()
Q - What does this function do?
A - It closes all of the buttons and unlocks every single button!
Sample code
dropDown:ResetDropdownStates()
:ConnectChildedAddedConnectionWithDropdownFolder()
Q - What does this function do?
A - I know the name is intimidating, but all it does it makes sure if you add a button, it still works with the new addition!
Sample Code (Iâll write a better one later sorry!)
dropDown:ConnectChildedAddedConnectionWithDropdownFolder()
:DisconnectChildAdded()
Q - What does this function do?
A - It disconnects the previous function. This is useful when the player is not needing to check if anything is added, so it saves processing power!
Sample Code:
dropDown:DisconnectChildAdded()
Wow, that is a lot of functions! I will add more if I can think of them, or you can give me ideas below!
Parameters
The parameter moveOthers is a table, where you will store other elements to be moved with the drop down effect, ensuring they will be moved out of the way! You can use two sets of Folders, it will loop through the first folder and find GuiObjects there and will search through a second table for GuiObjects, but no third table will work!. You can also use a specific type of 1 GuiObject! You could even use the collection service and add it to a table and have it work like that!
CollectionService Code Example With Requiring
local dropDownModule = require(game:GetService("ReplicatedStorage").Modules.HandleDropDownMenu)
local moveOthers= {}
local cs = game:GetService("CollectionService")
local tag = "ToMove"
for _, x in ipairs(cs:GetTagged(tag)) do
if x:IsA("GuiObject") then
table.insert(moveOthers, x)
end
end
local dropDown = dropDownModule.New(
dropDownButtons, -- Holds all the buttons
dropdownContents, -- Button Contents
true, -- Auto Close
moveOthers,
{} -- advancedSettings
)
dropDown:AnimateMenu()
There is a 5th parameter! This parameters name is ADVANCED_SETTINGS, in this parameter, you can change the TweenTime, DropDownSpace, EasingDirection, and EasingStyle. More could be added, recommend any if you want them to be added.
- Why is there the
TweenTimeandDropDownSpaceagain, isnât it already at the top, used before?
Yes, it is, you would use this in case of creating MULTIPLE dropdowns, and wanting them to be spaced differently or be tweened faster.
Now, for EasingDirection and EasingStyle allows YOU to change the way it is animated!
- So, how do I use this?
Well first you create a table, and inside of the table, you need to have [âTweenTimeâ] = to your value, not all are needed in there, you can only change one if you would like! All the other ones have the same capitals, and spelling as the matching ones.
- Can I see this in code, so it all makes sense?
Yes, of course! (This table is what you would put inside of the required portion!
local advancedSettings = {
["TweenTime"] = 0.1,
["DropDownSpace"] = 0,
["EasingDirection"] = Enum.EasingDirection.In,
["EasingStyle"] = Enum.EasingStyle.Quad
}
Without using this, here are the defult values:
TweenTimeis equal whatever the number value is childed to the moduleDropDownSpaceis equal whatever the number value is childed to the moduleEasingDirection= Enum.EasingDirection.InEasingStyle= Enum.EasingStyle.Linear
Now, that is all of the basics. I will let this module be out for free for 24 hours!! Please go test and let me know of any errors you encounter!
Module: https://create.roblox.com/store/asset/119281570862694/DropDown-Module-Pro
Someone also pointed out about an example game, yes I do have one that is uncopylocked, check out here: Dropdown Module Function Usecases - Roblox!


