B4J Question [SOLVED] Refresh B4XPreferenceDialog Options from Updated List

aeric

Expert
Licensed User
Longtime User
The options work very well in project without database. When I wanted to refresh the options from updated database, the option is not updated.
In attached project, go to "Page 3" from MainPage and click on button "Show Options", the options show 3 items.
Click on button "Add Option" then click on button "Show Options" again.

B4X:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private PrefDialog3 As PreferencesDialog
    Private FruitList3 As List
End Sub

Public Sub Initialize As Object
    Return Me
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("Page3")
    CreateDialog
End Sub

Private Sub CreateDialog
    PrefDialog3.Initialize(Root, "Dialog", 300dip, 300dip)
    PrefDialog3.LoadFromJson(File.ReadString(File.DirAssets, "template_fruit.json"))
    RefreshList
End Sub

Private Sub ShowDialog (Fruits As Map)
    Dim sf As Object = PrefDialog3.ShowDialog(Fruits, "OK", "CANCEL")
    Wait For (sf) Complete (Result As Int)
    If Result = xui.DialogResponse_Positive Then
        xui.MsgboxAsync("You have chosen " & Fruits.Get("Favourite"), "Favourite Fruit")
        Main.MyFavourite = Fruits.Get("Favourite")
    End If
End Sub

Private Sub BtnShowOptions_Click
    Dim Fruits As Map = CreateMap("Favourite": Main.MyFavourite)
    ShowDialog(Fruits)
End Sub

Private Sub BtnAddOption_Click
    Dim BlnFound As Boolean
    Dim RS As ResultSet = Main.DB.ExecQuery2($"SELECT Fruit FROM Fruits WHERE Fruit = ?"$, Array As String("Durian"))
    Do While RS.NextRow
        BlnFound = True
    Loop
    RS.Close
    If BlnFound Then
        xui.MsgboxAsync("Durian is already in list", "Duplicate Option")
    Else
        Main.DB.ExecNonQuery2($"INSERT INTO Fruits (Fruit) SELECT ?"$, Array As String("Durian"))
        xui.MsgboxAsync("You have added Durian", "New Option")
        RefreshList
    End If
End Sub

Private Sub BtnRemoveOption_Click
    Dim BlnFound As Boolean
    Dim RS As ResultSet = Main.DB.ExecQuery2($"SELECT Fruit FROM Fruits WHERE Fruit = ?"$, Array As String("Durian"))
    Do While RS.NextRow
        BlnFound = True
    Loop
    RS.Close
    If BlnFound Then
        Main.DB.ExecNonQuery2($"DELETE FROM Fruits WHERE Fruit = ?"$, Array As String("Durian"))
        xui.MsgboxAsync("You have removed Durian", "Removed Option")
        RefreshList
    Else
        xui.MsgboxAsync("Durian not found in database", "Missing Option")
    End If
End Sub

Private Sub BtnClosePage_Click
    B4XPages.ClosePage(Me)
End Sub

Private Sub RefreshList
    FruitList3.Initialize
    Dim RS As ResultSet = Main.DB.ExecQuery($"SELECT Fruit FROM Fruits"$)
    Do While RS.NextRow
        FruitList3.Add(RS.GetString("Fruit"))
    Loop
    RS.Close
    If PrefDialog3.IsInitialized Then
        PrefDialog3.SetOptions("Favourite", FruitList3)
    End If
End Sub
 

Attachments

  • RefreshData.zip
    13.3 KB · Views: 147

Magma

Expert
Licensed User
Longtime User
B4X:
Private Sub RefreshList
    FruitList3.Initialize
    FruitList3.Clear '<-------------------- add this
    Dim RS As ResultSet = Main.DB.ExecQuery($"SELECT Fruit FROM Fruits"$)
    Do While RS.NextRow
        FruitList3.Add(RS.GetString("Fruit"))
    Loop
    RS.Close
    If PrefDialog3.IsInitialized Then
        PrefDialog3.SetOptions("Favourite", FruitList3)
    End If
End Sub

FruitList3.Clear
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Upvote 0

aeric

Expert
Licensed User
Longtime User
...i only edited the bxpage3... i am sure you will understand.. how...
Thanks @Magma
Your solution works.

It seems I have to refresh the list every time before showing the dialog. I wish I only need to do it once or force refresh the list when necessary (there is an update to the database).

B4X:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private PrefDialog3 As PreferencesDialog
    Private FruitList3 As List
    Private AvailableFruit As List = Array("Apple", "Banana", "Citrus", "Durian")
End Sub

Public Sub Initialize As Object
    Return Me
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("Page3")
    FruitList3.Initialize   
End Sub

Private Sub B4XPage_Resize(Width As Int, Height As Int)
    If PrefDialog3.IsInitialized And PrefDialog3.Dialog.Visible Then PrefDialog3.Dialog.Resize(Width, Height)
End Sub

Private Sub PrefDialog3_BeforeDialogDisplayed (Template As Object)
    RefreshList
    If FruitList3.Size > 0 Then PrefDialog3.SetOptions("Favourite", FruitList3)
End Sub

Private Sub ShowDialog (Fruits As Map)
    PrefDialog3.Initialize(Root, "Dialog", 300dip, 300dip)
    PrefDialog3.LoadFromJson(File.ReadString(File.DirAssets, "template_fruit.json"))
    PrefDialog3.SetEventsListener(Me, "PrefDialog3")
    Dim sf As Object = PrefDialog3.ShowDialog(Fruits, "OK", "CANCEL")
    Wait For (sf) Complete (Result As Int)
    If Result = xui.DialogResponse_Positive Then
        xui.MsgboxAsync("You have chosen " & Fruits.Get("Favourite"), "Favourite Fruit")
        Main.MyFavourite = Fruits.Get("Favourite")
    End If
End Sub

Private Sub RefreshList
    FruitList3.Clear
    Dim RS As ResultSet = Main.DB.ExecQuery($"SELECT Fruit FROM Fruits"$)
    Do While RS.NextRow
        FruitList3.Add(RS.GetString("Fruit"))
    Loop
    RS.Close
End Sub

Private Sub BtnShowOptions_Click
    RefreshList
    If FruitList3.Size > 0 Then
        Dim Fruits As Map = CreateMap("Favourite": Main.MyFavourite)
        ShowDialog(Fruits)
    Else
        xui.MsgboxAsync($"No fruits to choose"$, "Empty Options")
    End If
End Sub

Private Sub BtnAddOption_Click
    For Each f As String In AvailableFruit
        Dim BlnFound As Boolean
        Dim RS As ResultSet = Main.DB.ExecQuery2($"SELECT Fruit FROM Fruits WHERE Fruit = ?"$, Array As String(f))
        Do While RS.NextRow
            BlnFound = True
        Loop
        RS.Close
        If Not(BlnFound) Then
            Main.DB.ExecNonQuery2($"INSERT INTO Fruits (Fruit) SELECT ?"$, Array As String(f))
            xui.MsgboxAsync($"You have added ${f}"$, "New Option")
            Return
        End If
    Next
    xui.MsgboxAsync($"No more fruits to add"$, "Full Options")
End Sub

Private Sub BtnRemoveOption_Click
    Dim BlnFound As Boolean
    Dim LastFruit As String
    Dim RS As ResultSet = Main.DB.ExecQuery($"SELECT Fruit FROM Fruits ORDER BY id DESC LIMIT 1"$)
    Do While RS.NextRow
        BlnFound = True
        LastFruit = RS.GetString("Fruit")
    Loop
    RS.Close
    If BlnFound Then
        Main.DB.ExecNonQuery($"DELETE FROM Fruits WHERE id = (SELECT MAX(id) FROM Fruits)"$)
        xui.MsgboxAsync($"You have removed ${LastFruit}"$, "Removed Option")
    Else
        xui.MsgboxAsync("No more fruit in database", "Empty Options")
    End If
End Sub
 

Attachments

  • RefreshData3.zip
    13.3 KB · Views: 118
Upvote 0

Magma

Expert
Licensed User
Longtime User
The "secret" here is the "prefdialog_BeforeDialogDisplayed", options, short-options must preset in this sub... all the others can set by using "put" at map before showing the dialog at the same sub... also the default options-pre-selected-value set at the same sub (of creation-showing prefdialog)

Well it is a little strange... but it works...
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
I have found another solution.
B4X:
PrefDialog.GetPrefItem("Favourite").Extra.Put("options", FruitList)

I don't need to requery the database every time to show the dialog.
 

Attachments

  • RefreshData4.zip
    13.4 KB · Views: 119
Upvote 0

swamisantosh

Member
Licensed User
Longtime User
Is it possible to display more than one field in option. FruitList3.Add(RS.GetString("Fruit")+ ' '+FruitList3.Add(RS.GetString("id"))
 
Upvote 0
Top