4. show dialogs
Now let's show the dialogs.
The db_dialog will be used when the user taps on the Add button or on a customlistview item.
The cat_dialog is used in the Category page to add, change or delete records from the category table.
Click on the B4XMainPage tab and open the designer window. Open the db_dialog file en generate the members (Tools / Generate Members).
Click on the CategoryPage tab in the IDE.
Open the file cat_dialog and generate the members for that layout.
Back in the B4XMainPage we need to initialize the variables.
Add a declaration (in Class_Globals subroutine) for the db_dialog:
Public dbdialog As B4XDialog
In the B4XPage_Created add these lines:
dbdialog.Initialize(Root)
dbdialog.PutAtTop = True
dbdialog.BackgroundColor = Colors.LightGray
dbdialog.BodyTextColor = Colors.Blue
Now write the code to show the dialog.
Do you remember how? You can find examples in the tutorial
B4A-lists
Here is the code sofar (it will change later):
Private Sub show_add_dialog(title As String,title_color As Int)
pnl1 = setup_dialog("db_dialog"," Add " & title,title_color)
lbldate.Text = ""
ftf1.HintText = "Amount (" & strcurrency & ")"
ftf1.update
ftf2.HintText = "Description (optional)"
ftf2.update
ftf1.text = ""
ftf2.Text = ""
Dim rsub1 As ResumableSub = dbdialog.ShowCustom(pnl1, "OK", "", "CANCEL")
Wait For (rsub1) Complete (Result As Int)
If Result = xui.dialogResponse_Positive Then
Log(lbldate.Text)
Log(ftf1.Text)
If ftf1.Text <> "" And lbldate.Text <> "" Then
add_record(strtablename, Array As String(lbldate.Text,"1",ftf2.Text,ftf1.Text))
Else
xui.MsgboxAsync("Date and amount cannot be empty!","Add " & strtablename)
End If
End If
End Sub
private Sub setup_dialog(strlayout As String,lbltext As String,lblcolor As Int) As Panel
Dim pnl As B4XView = xui.CreatePanel("")
pnl.SetLayoutAnimated(0dip, 0dip, 0dip, 340dip, 200dip)
pnl.LoadLayout(strlayout)
Dim lbl As Label
lbl.Initialize("")
lbl.Text = lbltext
lbl.TextSize = 18
lbl.TextColor = Colors.Black
lbl.Color = lblcolor
pnl.AddView(lbl,0dip,0dip,340dip,30dip)
Return pnl
End Sub
To call the subroutine add these lines to the sbtn1_Click subroutine:
strtablename = "expenses"
show_add_dialog("Expense",Colors.ARGB(100,249,177,241))
You can change the existing lines by putting them in comments (select the lines, Edit / Block Comment).
If you run the app now the db_dialog will be displayed.
When you tap on the date icon in the db_dialog the datepicker_dialog will appear on top of the db_dialog.
That is O.K. and after you selected a date (displayed in the label between the 2 buttons) the datepicker_dialog is closed.
But now the code continues and returns to the main thread and not to the db_dialog.
We change the code from the datepicker_dialog. Add after the line that sets the lbldate.text the following code:
lbldate.Text = DateTime.Date(cal.lblticks)
' resume the db_dialog
Dim rsub1 As ResumableSub = dbdialog.ShowCustom(pnl1, "OK", "", "CANCEL")
Wait For (rsub1) Complete (Result As Int)
If Result = xui.dialogResponse_Positive Then
Log(lbldate.Text)
Log(ftf1.Text)
add_record(strtablename, Array As String(lbldate.Text,"1",ftf2.Text,ftf1.Text))
End If
This code shows the datepicker_dialog again because we use the pnl1 variable from the datepicker to show the db_dialog.
After we change the pnl1 in the datepicker_dialog to pnlcal the db_dialog will be displayed.
Declaration in Class_Globals:
Private pnlcal As Panel
Initialization in B4XPage_Created:
pnlcal.Initialize("")
Changes in the datepicker_dialog subroutine:
Sub datepicker_dialog
lblseldate.Text = ""
pnlcal.Color = Colors.White
pnlcal.SetLayoutAnimated(0dip, 0dip, 0dip, 278dip, 368dip)
pnlcal = cal.set_date_picker(displaymonth,displayyear)
Dim rsub1 As ResumableSub = caldialog.ShowCustom(pnlcal, "OK", "", "CANCEL")
...
This should fix that issue.
The cbx1 combobox will be filled in the next section.
Now insert the show_change_dialog subroutine into the B4XMainPage code before the datepicker_dialog subroutine.
Private Sub show_change_dialog(rowid As Int, title As String, title_color As Int)
Dim pnl1 As Panel = setup_dialog("db_dialog"," Edit/Delete " & title, title_color)
ftf1.HintText = "Amount (" & strcurrency & ")"
ftf1.update
ftf2.HintText = "Description (optional)"
ftf2.update
Dim rsub1 As ResumableSub = dbdialog.ShowCustom(pnl1, "SAVE", "DELETE", "CANCEL")
Wait For (rsub1) Complete (Result As Int)
If Result = xui.dialogResponse_Positive Then
If ftf1.Text <> "" And lbldate.Text <> "" Then
change_record(strtablename, Array As String(lbldate.Text,"1",ftf2.Text,ftf1.Text),rowid)
B4XPage_Appear
Else
xui.MsgboxAsync("Date and amount cannot be empty!","Change " & strtablename)
End If
else if Result = xui.dialogResponse_Negative Then
remove_record(strtablename,rowid)
B4XPage_Appear
End If
End Sub
To show the dialog add code to the clv1_ItemClick event subroutine:
strtablename = "expenses"
show_change_dialog(1,"Expense",Colors.ARGB(100,249,177,241))
When you run the app now it appears that everything is working. But, after a date selection in the datepicker_dialog the db_dialog is set to the add version (OK and CANCEL buttons) and not to the change version (SAVE, DELETE and CANCEL buttons).
Let's insert a test in the datepicker_dialog subroutine.
We use a public variable called old_amount and set it to empty in the show_add_dialog. In the show_change_dialog this variable will be set to the value from the database field of the expenses or earnings table.
In Class_Globals:
Public old_amount As String
In show_add_dialog below the setup_dialog(...) statement:
old_amount = ""
In show_change_dialog below the setup_dialog(...) statement:
old_amount = "100"
In the datepicker_dialog above and below the Wait For statement:
If Result = xui.dialogResponse_Positive Then
DateTime.DateFormat = "yyyy-MM-dd"
lbldate.Text = DateTime.Date(cal.lblticks)
' resume the db_dialog
If old_amount = "" Then
Dim rsub1 As ResumableSub = dbdialog.ShowCustom(pnl1, "OK", "", "CANCEL")
Else
Dim rsub1 As ResumableSub = dbdialog.ShowCustom(pnl1, "SAVE", "DELETE", "CANCEL")
End If
Wait For (rsub1) Complete (Result As Int)
If Result = xui.dialogResponse_Positive Then
Log(lbldate.Text)
Log(ftf1.Text)
If old_amount = "" Then
add_record(strtablename, Array As String(lbldate.Text,"1",ftf2.Text,ftf1.Text))
Else
change_record(strtablename, Array As String(lbldate.Text,"1",ftf2.Text,ftf1.Text),1)
End If
End If
End If
Now the show_change_dialog will be displayed if the old_amount is not empty.