WoWInterface (
-   Lua/XML Help (
-   -   Table inside of a table getting a value (

Walkerbo 03-10-21 05:07 PM

Table inside of a table getting a value
Hi all

I have a table within a table where I need to access a value to build a button.

So far I can build the buttons successfully and they display their value, however, when click the button to use that value to print a message only the top button prints the expected string, the second prints nothing, and each subsequent button prints nil.

Here is my chunk;
Lua Code:
  1. DeathKnightChatScrollFrame.buttons = {}
  2. for index = 1, NumberList.scrollButtonNumber do
  3.     DeathKnightChatScrollFrame.buttons[index] =
  4.         CreateFrame("Button", "btn" .. index, DeathKnightChatScrollParent, "OptionsListButtonTemplate")
  5.     button = DeathKnightChatScrollFrame.buttons[index]
  6.     button:SetSize(NumberList.scrollSpellFrameWidth, NumberList.phraseTextButtonHeight)
  7.     button:SetPoint("TOPLEFT", 8, -(index - 1) * NumberList.phraseTextButtonHeight - 8)
  8.     button:SetScript(
  9.         "OnClick",
  10.         function(self)
  11.             print("Test Print -  ", DeathKnightSpellList[self.index].spellChatList[index], index) -- debug --
  12.         end
  13.     )
  14. end

This is the table layout;

These are the print results;

My questions are why can I not grab the string values using the following syntax,
Lua Code:
  1. DeathKnightSpellList.spellChatList[self.index]

And what is the proper syntax to correctly use the string value in the second table?

Kanegasi 03-10-21 05:35 PM

A few issues:

1. The second argument of CreateFrame is the global name of the frame. You do not want to create global objects named "btn1" etc. Choose a unique name.

2. Line 5, you're missing "local" in front of "button".

3. Your thread's issue is because you're attempting to index the parent DeathKnightSpellList table at the same time you're trying to index the spellChatList child table.

The first button: DeathKnightSpellList[1].spellChatList[1]
The second button: DeathKnightSpellList[2].spellChatList[2]

And so on. I also don't see where the index key in the button's table is getting its value in the code you shared, so self.index should be nil.

Fizzlemizz 03-10-21 07:39 PM

Alternatively for button names you could use

"$parentbtn" .. index

$parent will be replaced with the name of the buttons parent frame. It's the same as:
Lua Code:
  1. DeathKnightChatScrollFrame.buttons[index] = CreateFrame("Button", DeathKnightChatScrollParent:GetName() .. "btn" .. index, DeathKnightChatScrollParent, "OptionsListButtonTemplate")

It assumes the parent frame has a name which seems likely given you're naming the buttons.

Walkerbo 03-10-21 08:51 PM

Thanks for the replys.

I thought that any items built within a function are local to that function, so setting them as local was redundant, is this the case for variables within a function as well? (I have now made the button local).

Thanks for showing me the "$parentbtn" .. index thing, this will be very helpful for me.

It also makes sense the point made of,
The first button: DeathKnightSpellList[1].spellChatList[1]
The second button: DeathKnightSpellList[2].spellChatList[2]

How do I change it to make it,
The first button: DeathKnightSpellList.spellChatList[1]
The second button: DeathKnightSpellList.spellChatList[2]

The syntax I thought would work, DeathKnightSpellList.spellChatList[index], does not work and I have not yet been able to find a way to solve this.

Fizzlemizz 03-10-21 10:05 PM

Assuming this is for a ScrollList, when you update each button information during OnVerticalScroll is when you set each button .index to the corresponding entry in SpellList

Incomplete and rough as example for OnVerticalScroll
Lua Code:
  1. self.ScrollBar:SetValue(offset)
  2. self.offset = math.floor(offset / itemHeight)
  3. local newOffset = self.offset or 0
  4. for i = 1, #DeathKnightChatScrollFrame.buttons do
  5.     local index = newOffset + i
  6.     if not DeathKnightSpellList[index] then
  7.         break
  8.     end
  9.     local button = DeathKnightChatScrollFrame.buttons[i]
  10.     button.Text:SetText(DeathKnightSpellList[index].spelllink)
  11.     button.index = index -- self.index used to get the spell entry in OnClick
  12. end

Kanegasi 03-10-21 10:14 PM

Creating objects makes them global by default. The only exceptions are objects passed into a function and loop objects.

For example, say you have function(self,event), the objects "self" and "event" are automatically local to that function.

In loops, for i=1,10 do makes "i" local and for k,v in pairs(t) do makes "k" and "v" local.

There's also setenv but that's advanced and rarely has uses within WoW's addon environment. WeakAuras makes use of this to keep all objects inside an aura's custom code local.

Walkerbo 03-11-21 12:14 AM

Hi guys

@ Fizzlemizz
Based on your post I changed the way my update worked.
I built a templist that from the DKChatlist so I was updating that instead.
Lua Code:
  1. local function updateDeathKnightSpellChatList()
  2.     currentSpellList = {}
  3.     for k, v in pairs(DeathKnightSpellList) do
  4.         if v.spellID == VariableList.currentSpellID then
  5.             currentSpellList = v.spellChatList
  6.         end
  7.     end
  8.     FauxScrollFrame_Update(
  9.         DeathKnightChatScrollFrame,
  10.         #currentSpellList,
  11.         NumberList.scrollButtonNumber,
  12.         NumberList.scrollButtonHeight
  13.     )
  14.     for index = 1, NumberList.scrollButtonNumber do
  15.         offset = index + FauxScrollFrame_GetOffset(DeathKnightChatScrollFrame)
  16.         button = DeathKnightChatScrollFrame.buttons[index]
  17.         button.index = offset
  18.         if offset <= #currentSpellList then
  19.             button:SetText(currentSpellList[offset])
  20.             button:Show()
  21.         else
  22.             button:Hide()
  23.         end
  24.     end
  25. end

That allowed me to use the following syntax;
Lua Code:
  1. print("Test Print 1 - ", currentSpellList[self.index]) -- debug --

After I re-reading your first post again I realized you had already given me the answer when you said
The second button: DeathKnightSpellList[2].spellChatList[2]

So I changed the syntax to
Lua Code:
  1. print("Test Print 2 -  ", DeathKnightSpellList[1].spellChatList[self.index]) -- debug --

Both of these syntaxes now work.

Thanks for all of your help.

All times are GMT -6. The time now is 02:41 PM.

vBulletin © 2021, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI