Page 1 of 1

ComboBoxGadget and #PB_EventType_Change

Posted: Wed Feb 01, 2023 8:05 am
by itzybitzyspider
I have an issue where #PB_EventType_Change gets triggered even when user is not selecting anything due to changes caused by the code.

So I have several combo box, then when user selects a value in one of the boxes, it makes a websocket call and receives back the drill down values in a List for all the combo boxes. I then go and ClearGadget() and then rebuild the combo boxes with AddGadgetItem()

This triggers another #PB_EventType_Change and then it goes and gets everything again.

Runs in a loop and then browser gets unresponsive.

How do I ignore #PB_EventType_Change with the code manipulations and only when real user clicks and selects?

Being trying to use some True False variable to ignore but because Websocket is also event triggered, I can't specifically catch it. Any pointers?

Re: ComboBoxGadget and #PB_EventType_Change

Posted: Thu Feb 02, 2023 10:15 am
by bembulak
Any chance to provide us with a minimal working example that shows the situation/problem?

Thank you.

Re: ComboBoxGadget and #PB_EventType_Change

Posted: Thu Feb 02, 2023 12:13 pm
by Peter
I don't understand exactly what the problem is yet, but here's some code as a basis for discussion:

Code: Select all

EnableExplicit

Enumeration
  #Window
  #Combo1
  #Combo2
  #Combo3
EndEnumeration

Procedure Combo1Callback()
  
  Protected Counter
  
  Debug "Combo1Callback"

  ClearGadgetItems(#Combo2)
  
  For Counter = 0 To 9
    AddGadgetItem(#Combo2, Counter, GetGadgetText(#Combo1) + "#Combo2Entry" + Counter)
  Next
  
  SetGadgetState(#Combo2, 0)

EndProcedure

Procedure Combo2Callback()
  
  Protected Counter

  Debug "Combo2Callback"

  ClearGadgetItems(#Combo3)
  
  For Counter = 0 To 9
    AddGadgetItem(#Combo3, Counter, GetGadgetText(#Combo2) + "#Combo3Entry" + Counter)
  Next
  
  SetGadgetState(#Combo3, 0)
    
EndProcedure

Procedure Combo3Callback()
  Debug "Combo3Callback"
EndProcedure

If OpenWindow(#Window, 0, 0, 350, 125, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ComboBoxGadget(#Combo1, 10, 10, 320, 25)
  ComboBoxGadget(#Combo2, 10, 50, 320, 25)
  ComboBoxGadget(#Combo3, 10, 90, 320, 25)
EndIf

BindGadgetEvent(#Combo1, @Combo1Callback(), #PB_EventType_Change)
BindGadgetEvent(#Combo2, @Combo2Callback(), #PB_EventType_Change)
BindGadgetEvent(#Combo3, @Combo3Callback(), #PB_EventType_Change)

Define Counter

For Counter = 0 To 9
  AddGadgetItem(#Combo1, Counter, "Combo1Entry" + Counter)
Next
SetGadgetState(#Combo1, 0)

Re: ComboBoxGadget and #PB_EventType_Change

Posted: Thu Feb 02, 2023 10:31 pm
by itzybitzyspider
Hi, apologies for the late reply.

I've changed your code to reflect what I'm doing. As you can see, if user selects something in Combo 1 for example or any combo for that matter, I am then getting all the data for all the combos again based on the selection of the combo. I will use that set and just update all of them again. As you can see, it triggers the change event 2 times due to I guess I am changing the contents of the original selected combo. It stops at 2 because I am not setting the selected item in the code again after the update. If I do, then I probably will trigger event change again. Hope you understand my explanation.

Code: Select all

EnableExplicit

Enumeration
  #Window
EndEnumeration

Global BaseComboID.l = 1
Global BaseY = 10

Procedure AddRandomData(whichCombo.l)
  Define i.l
  For i = 0 To 10
    AddGadgetItem(whichCombo, i, "Combo" + i + Random(1000))
  Next
EndProcedure

Procedure ComboAllCallBack()
  Define i.l
  Debug "Clear and Set All. EventType=" + EventType()
  ; Assume data from some API connection
  For i = 0 To 5
    ;Clearing
    Debug "Clearing " + i
    ClearGadgetItems(BaseComboID + i)
  Next
  ;Handle Data
  For i = 0 To 5
    AddRandomData(BaseComboID + i)
  Next
  ;Assume I will then set the selected item with the correct combo to show what I already selected
  
EndProcedure


If OpenWindow(#Window, 0, 0, 350, 125, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Define i.l
  For i = 0 To 5 ;5 combos
    ComboBoxGadget(BaseComboID + i, 10, BaseY + (40 * i), 320, 25)
    AddRandomData(BaseComboID + i)
    BindGadgetEvent(BaseComboID + i, @ComboAllCallBack(), #PB_EventType_Change)
  Next
EndIf
So what I did instead was to first check whether focused is one of the combos or not. If not, I will ignore and assume this as code causing the change event. So once the user selects something, I move the focus away first to the main window. This way, the code does not again trigger an update.

I know it may be easier to not touch the original selected combo and just update the rest. However, in reality... I am using the combo to show what the user has selected. And therefore, should be just 1 record only.