Create datamodule instance multiple times for same form - delphi

Good morning, I have an MDI application which I have a search form with a grid (frmCustomerSearch) and a view form (frmCustomerView), these are both child MDI forms.
The search form can only be opened once but the view form multiple times
Search is connected to dmCustomerSearch and view to dmCustomerView, I create an instance of the dmCustomerView on the create of frmCustomerView, filter the query by parameter and then open the query as below.
dmCustomerViewFrm := TdmCustomerViewFrm.create(self);
dmCustomerViewFrm.fdqCustView.ParamByName('REF').Value := fAccountRef;
dmCustomerViewFrm.fdqCustView.Open;
// Set dataModule to an empty string, prevents other forms using it.
dmCustomerViewFrm.Name := '';
The form opens on the correct record and I can edit the record without an issue.... my issue is when I open more than one record, I can edit the last record opened but anything prior I get the following error:
FDQCustView: Dataset not in edit or insert mode.
Is the new instance taking the original out of edit mode? or am I missing something?
Any advice greatly appreciated!

Related

How to share react-final-form between pages/screens

react-native
react-final-form
rect-navigation
I need to split up my form into subforms. The subforms will be rendered on separate screens in React-Native, but I need them to be part of the same form handling object. From each sub form I need access to the complete form state (for all fields), but each subform will only render some fields.
Is there a way to pass the form object to another screen/component and continue to use the state handling/validation from the main form?
Example:
MainForm
FieldX
FieldY
Button to open subform A
SubFormA
FieldA1
FieldA2
FieldX <- reused from main form, might be readonly in subform A
Button to go back to main form
Button to open subform B
SubFormB
FieldB1
Button to go back to main form
The actual submit of the form can only be preformed from the MainForm. I have this setup with an older form library, but I'm using Modals to show the subforms, which are inlined in the main form. But I'd like to stop using modals and instead push a separate screen (using react-navigation) with subform capabilities by somehow passing the form object.
You can use React Redux to have a Store to be able to share all the information.
Create your store and dispatch your actions, then you can get all the variables (fields) for the form from there.
I fiddled around some more and found a way. Thought I'd answer this for others to find.
The render property of the Form component actually gets the form instance as an argument.
The Form component also takes a form instance as a prop
These two features makes it possible to simply pass the form instance to another Form component. I tried this within the same screen and it works like a charm. I hope I won't get into trouble with the main Form getting unmounted when I push the next screen with react-navigation.
edit: It works perfectly between screens as well. I send the form instance to the subform via react-navigations params object.

delphi using dbgrid to view a record on a detail page

I have a form with a dbgrid and a second form with dbedits. My form with the dbgrid has a double click event(code below is the event) the dbedits on the second form has a data source that is connected to the first form's CDS and when I compile and run the program and open the form with db grid I can double click any record and it is display in the dbedits on the second form, but if I close the forms and reopen the form the only record that will display in the second form dbedits is the first record in the table. I have to open and close CDS and that is not working. what else would I need to do to correct this problem.
procedure TFRM_ADMIN.DBGrid1DblClick(Sender: TObject);
BEGIN
frm_LEADDETAILADMINLEAD := tfrm_LEADDETAILADMINLEAD.Create(FRM_ADMIN);
frm_LEADDETAILADMINLEAD.SHOW;
END;
The site will not allow me to add the dmf text. It is to large. I am using sqlconnection, sqlquery, data set provider, client data set, data source set up if this helps any.
This is a very wild quess, but I suspect the following at play:
You use the public variables for the forms that the IDE automatically has added to each unit.
You create FRM_ADMIN the way you create frm_LEADDETAILADMINLEAD, something like:
FRM_ADMIN := TFRM_ADMIN.Create(MainForm);
FRM_ADMIN.Show;
You don't close this form, but hide it (the default close action of a form).
The second time you create your second form, the designtime set DataSet property of the DataSource of your second form is automatically resolved to the ClientDataSet on the first instance of the first form.
So in the second run you are editing the record that was selected in the first run.
Solution and recommendations:
Destroy forms (set Action := caFree) in the OnClose event.
Do not use the public variables, remove them. Keep you form reference in a separate private field, unique to each instance.
Assign DataSource and/or DataSet properties at runtime explicitly.
Use DataModules.
Further reading:
Binding a second instance of a form to a second instance of a data module?
Will there be any detrimental effects if I accidentally remove something from a forms uses list which a control is referencing?
Separate DataSet instances using DataModules.
Show message when Tform2 is created?

A form that is able to be Modal after it is created

I have a PopForm that I want to stay over MainForm in any case.
The cases are:
PopForm.ShowModal and PopForm.Show.
Whilst ShowModal is completely works fine, the Show method is needed to interact with MainForm for doing 'drag-drop' things.
Main duty of the PopForm is to import data from some files to a dataset on the MainForm. There is two ways: drag-drop of the concrete data (selected rows while in Show-mode) and transfering all data from PopForm (while in ShowModal-mode). All data in the PopForm stored in something like ClientDataSet. I developed methods that are alike ClientDataSet's: First, Eof, FieldByName, Next, etc. and implemented them into PopForm.
After the PopForm is closed (after setting the ModalResult), the calling procedure uses a while not PopForm.eof do PopForm.Next... to import data into MainForm's dataset or whatever would be a user-programmers method.
For showing some progress I used to recreate PopForm with Show method and show a progress form above PopForm, while a cycle is being made in the calling procedure. After that - PopForm is closed.
This works fine, but the only problem is about a Show method - I need the PopForm to be over MainForm all the time. In most cases it is, but there are some applications, that somehow doesn't follow this rule. I've tried to use PopupParent & PopupMode properties, but they make popForm to recreate again on any assignment (and as I've just found - you need to assign a CustomForm on show and then - Nil it on close, because with common TForm.Close method it won't hide no way)
There would be no any problem about that, if there would be no need to Nil PopupParent on FormClose method. The other routine is to assign
...FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
...
end;
It would work if Assigned(PopForm) return false, but it returns true.
If there is any case to discover if the Form is Freed - that may help. What do you think?
If you set your form style to fsStayOnTop the form will always stay on top unles you there is another form with same property. In that case the active one of them will be on top.
As for moving data from your PopForm which you use for importing data you could folow similar approach as it is used in creating of custom Dialogs.
Custom dialogs are usually designed like so:
You have dialog class which contains fields for dialg settings (to change hoe the dialog woul look like), and even a field for dialog output (selected FileMame/s, etc.).
Within this class there is a dialog form class which esentially is a modal form. This dialog form uses its OnClose event to automatically feed necessary information into Dialog output field before closing.

Dynamic linking gets cleared when inserting new records

I have one form in AX 2012 from which i am calling another child form which shows records that are related to the selected record in Parent form(Dynamic linking).
Now, when I am trying to create a new record in a child form, the dynamic linking between this form and its parent form gets cleared and child form starts showing all data according to its datasource and not any filtered records which I don't want.
I want to know that, how to get stick with that dynamic linking while creating new Record in a child form.
Check that your grids really belongs to the correct datasources. If not, strange things happen.

How to keep only single form open in delphi

I have VCL application in delphi. One main form and many child forms.
How to ensure only one form opened at a time. In other words, If a form is opened, it will close previous form. Or, if user try to open form that same with previous, it will do nothing.
Code to open form in my main form:
procedure TFMainForm.OpenForm(const classname: string);
var
c: TPersistentClass;
f: TForm;
begin
c := GetClass(classname);
if c <> nil then
begin
f := TForm(TControlClass(c).Create(nil));
f.Parent := Self;
f.Show;
end;
end;
The child form is self-freed on close event.
If you make 'f' a variable in your mainform, instead of a local variable, you will have a reference to the currently open form. You can use that reference to close that form or to check its class.
Two notes:
You'll have to reset the variable if you close the form without opening another.
I wonder why you would want to do this. Isn't it more friendly to let your users decide whether they want to open multiple forms?
As an alternative, you could make the child forms modal (use ShowModal instead of Show), but that would block access to the main form when the child form is open.
Maybe not the same scenario but you could have a SubscriptionList, where every created form is Subscribed on create and unsubscribed on destroy. In that way you can check if your window is in the list, if it doesn't exist create, if already exist move focus to the form.
We use this approach to open the same form with diferent data (an invoice for example) and track them to not open the same invoice twice.
If you are doing for example a Dashboard and using a form for each piece of info you can track them all with the Subscription list instead of having a variable for each one.
Intercept "new form is getting active" event - http://docwiki.embarcadero.com/Libraries/en/Vcl.Forms.TScreen_Events
Enumerate the forms and ensure for all the other forms .Visible is false - http://docwiki.embarcadero.com/Libraries/en/Vcl.Forms.TScreen.CustomForms
Or, if user try to open form that same with previous, it will do nothing
What do you mean ? and how can user do it if other forms are hidden and he can no more see buttons/menus to open other forms?
Maybe all you need is TForm.ShowModal ?

Resources