smart-mobile-studio

Prevent Dialog form from closing in Smart Mobile Studio application


I have a modalDialog with a W3EditBox where the user enters a string that ultimately gets added to a W3ListBox on the main form

I am trying to prevent the modalDialog from closing if one of these conditions exist

1.) W3EditBox text is nil

2.) if W3EditBox text already exists in the W3ListBox list

Here is the code for calling the dialog form (has just a label, edit box, and ok and cancel buttons)

procedure TfrmMain.HandleAddClick(Sender: TObject);
begin
  Application.ShowModal('frmGoal', 'W3Panel1', 'edtTitle', InitDialog, OkResponse, nil);
end;

Here is the code for handling the OK response

procedure TfrmMain.OkResponse(AForm: TW3CustomForm);
begin
 //code here to prevent if title is nil or already exists in listbox
 W3Listbox1.Add(TfrmGoal(AForm).Title);
end;

On another note, I don’t understand how the W3ListBox’s IndexOf method works. I am use to search for a string – and it looks like it wants a control

Thanks

Shane


Solution

  • Let's say we have a visual project with main form MainForm and dialog AddDialog. The main form contains a listbox lbItems and the dialog contains a wrapper panel W3Panel1 with three child objects - an edit box inpItem and two buttons - btnOK and btnCancel. The AddDialog dialog is registered with a name AddDialog.

    FAddDialog := TAddDialog.Create(Display.View);
    FAddDialog.Name := 'AddDialog';
    RegisterFormInstance(FAddDialog, False);
    

    The dialog is then displayed with a simple ShowModal call.

    btnAdd.OnClick := lambda
      Application.ShowModal('AddDialog', 'W3Panel1', 'inpItem', InitDialog, OkResponse);
    end;
    

    The simplest way to access the main form's listbox from the dialog is to provide the dialog with the reference to the main form's component. To do so, add a property to the dialog

    property Items: TW3ListBox;
    

    and then assign its value in the InitDialog.

    procedure TMainForm.InitDialog(dialog: TW3CustomForm);
    begin
      (dialog as TAddDialog).Items := lbItems;
    end;
    

    In the dialog itself you can then set up button click handlers.

    btnCancel.OnClick := lambda Application.HideModal(mrCancel); end;
    btnOK.OnClick := lambda CloseDialog; end;
    

    The CloseDialog method will check whether the edit box is empty or equal to an already existing item in the listbox. You are correct that the IndexOf method is of no use in this case so just use a for loop to check all listbox items.

    procedure TAddDialog.CloseDialog;
    begin
      if inpItem.Text = '' then
        Exit;
      for var i := 0 to Items.Count - 1 do
        if Items.Text[i] = inpItem.Text then
          Exit;
      Application.HideModal(mrOK);
    end;
    

    BTW, the best way to access the dialog edit box from the main form is to expose it via a property in the dialog object:

    property ItemText: string read (inpItem.Text) write (inpItem.Text);
    

    The code in the main program can then access this property.

    procedure TMainForm.OkResponse(dialog: TW3CustomForm);
    begin
      lbItems.Add((dialog as TAddDialog).ItemText);
    end;