Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » Elevate Web Builder Technical Support » Support Forums » Elevate Web Builder General » View Thread |
Messages 1 to 6 of 6 total |
Problem calling a module |
Wed, Jul 19 2017 7:08 AM | Permanent Link |
Paul Coshott | Hi All,
I am currently trying to write a module that will accept a field name and then using that field return the next ID for use in my EWB app. For example, if I'm adding a new client, before saving the new client, I'll make a call to the module using 'ClientId' as the field name. The (delphi) module itself is fine, but I am not even able to call it, as I'm doing something wrong in my EWB app. I have a form that is never shown, it is just used for common functions and procedures to be called from anywhere in the app. The following is the form's code. I have indicated in the code below where it fails, and the error is: Object expected Line: 1 Any ideas what I'm doing wrong? Thanks, Paul -------------------------------------------------------------------------------------------------------------------------- unit AppProcedures; interface uses WebCore, WebUI, WebForms, WebCtrls, WebHTTP; type TNextSystemId = class(TPersistent) private FNextId: integer; published property NextId: integer read FNextId write FNextId; end; TfrmAppProcedures = class(TForm) srNextId: TServerRequest; procedure srNextIdComplete(Request: TServerRequest); private { Private declarations } Reader: TReader; public { Public declarations } NextSystemId : TNextSystemId; end; var frmAppProcedures: TfrmAppProcedures; //functions function GetNextSystemId(sIdField : string) : integer; implementation uses Main; function GetNextSystemId(sIdField : string) : integer; begin Result := -1; <----------- THIS IS OK with frmAppProcedures do begin <----------- FAILS ON THIS LINE with srNextId do begin Method := rmPost; URL := '/modules/rs_sysids'; RequestHeaders.Clear; RequestHeaders.Values['Content-Type'] := 'text/plain'; RequestContent.Clear; RequestContent.Values['IdField'] := sIdField; Execute; end; end; end; procedure TfrmAppProcedures.srNextIdComplete(Request: TServerRequest); begin Reader := TReader.Create; NextSystemId := TNextSystemId.Create; try if (Request.StatusCode <> HTTP_OK) then begin //an error occured, so set global next id to -1 gblNextId := -1; end else begin Reader.Initialize(Request.ResponseContent.Text); NextSystemId.Load(Reader); gblNextId := NextSystemId.NextId; end; finally Reader.Free; NextSystemId.Free; end; end; end. |
Wed, Jul 19 2017 8:51 AM | Permanent Link |
Raul Team Elevate | On 7/19/2017 7:08 AM, Paul Coshott wrote:
> I am currently trying to write a module that will accept a field name and then using that field return the next ID for use in my EWB app. > For example, if I'm adding a new client, before saving the new client, I'll make a call to the module using 'ClientId' as the field name. The (delphi) module itself is fine, but I am not even able to call it, as I'm doing something wrong in my EWB app. > I have a form that is never shown, it is just used for common functions and procedures to be called from anywhere in the app. The following is the form's code. I have indicated in the code below where it fails, and the error is: Is the actual form created either by you or IDE ? In project options is the frmAppProcedures listed under "Auto-create Forms and Databases" (Forms and Databases Tab). If not then you need to either add it there or create it in your code on app startup (i.e. frmAppProcedures := TfrmAppProcedures.Create... ). easiest way to do latter would be to create it dynamically if needed. function GetNextSystemId(sIdField : string) : integer; begin Result := -1; if not assigned(frmAppProcedures ) then frmAppProcedures := TfrmAppProcedures.Create(Application); with frmAppProcedures do begin with srNextId do begin Method := rmPost; ... Raul |
Wed, Jul 19 2017 9:18 AM | Permanent Link |
Paul Coshott | Raul wrote:
> Is the actual form created either by you or IDE ? Hi Raul, Got it in one! Thanks so much for the help. I added it to the Auto Create list and worked like a charm. Now I know it's working, I have one other question. I want to call a function that returns the next id. But the function itself doesn't ever actually know the result. That happens in the OnComplete event of the TServerRequest. Is there a way to handle this. So the calling form can get the result returned to it? Hope this makes sense, Thanks, Paul |
Wed, Jul 19 2017 10:08 AM | Permanent Link |
Matthew Jones | Paul Coshott wrote:
> So the calling form can get the result returned to it? The OnComplete is usually a procedure on the form that wants it. -- Matthew Jones |
Wed, Jul 19 2017 10:59 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Paul,
<< Is there a way to handle this. So the calling form can get the result returned to it? >> You can do this by assigning an OnComplete event handler defined on the calling form directly to the TServerRequest.OnComplete event property, or you can chain the event handlers by adding a new OnComplete property to your TfrmAppProcedures form, like this: TfrmAppProcedures = class(TForm) srNextId: TServerRequest; procedure srNextIdComplete(Request: TServerRequest); private { Private declarations } Reader: TReader; FOnComplete: TServerRequestEvent; <<<<<<<<<<<<< public { Public declarations } NextSystemId : TNextSystemId; OnComplete: TServerRequestEvent read FOnComplete write FOnComplete; <<<<<<<<<<<<< end; You need to fix your calling method, though. It should look like this: procedure GetNextSystemId(sIdField : string) ; begin with frmAppProcedures do begin <----------- FAILS ON THIS LINE with srNextId do begin Method := rmPost; URL := '/modules/rs_sysids'; RequestHeaders.Clear; RequestHeaders.Values['Content-Type'] := 'text/plain'; RequestContent.Clear; RequestContent.Values['IdField'] := sIdField; Execute; end; end; end; You can't return a result from this method yet because there isn't a result yet (it's returned in the OnComplete event handler). procedure TfrmAppProcedures.srNextIdComplete(Request: TServerRequest); begin Reader := TReader.Create; NextSystemId := TNextSystemId.Create; try if (Request.StatusCode <> HTTP_OK) then begin //an error occured, so set global next id to -1 gblNextId := -1; end else begin Reader.Initialize(Request.ResponseContent.Text); NextSystemId.Load(Reader); gblNextId := NextSystemId.NextId; end; finally Reader.Free; NextSystemId.Free; if Assigned(FOnComplete) then <<<<<<<<<<<<< FOnComplete(Request); <<<<<<<<<<<<< end; end; And then you would call it like this: frmAppProcedures.OnComplete:=MyFormOnCompleteEventHandler; frmAppProcedures.GetNextSystemId('MyField'); The MyFormOnCompleteEventHandler event handler needs to be defined manually as a method of the calling form, and it needs to match the signature of the OnComplete event: procedure MyFormOnCompleteEventHandler(Request: TServerRequest); begin ShowMessage('The next ID is: '+IntToStr(gblNextId)); end; Of course, the *best* way to deal with all of this is to just make your frmAppProcedures form into a component instead of a form and install it on the component palette. Then you won't need to mess around with chaining event handlers for the forms and can just drop the component directly on the form where you're using it. There *is* a little more work required on the component creation side, but it's balanced by less work required on the usage side. You can also defined your own event handler type that returns the next ID in the event handler instead of using a global variable, and use event handler type instead of the same TServerRequestEvent event type. Please note that this technique works for *any* type of event handler chaining that is required due to async event triggering: server requests, form/dialog close events, timers, etc. Tim Young Elevate Software www.elevatesoft.com |
Thu, Jul 20 2017 9:25 AM | Permanent Link |
Paul Coshott | Tim Young [Elevate Software] wrote:
>> You can do this by assigning an OnComplete event handler defined on the calling form directly to the >> TServerRequest.OnComplete event property, or you can chain the event handlers by adding a new OnComplete >> property to your TfrmAppProcedures form, like this: Hi Tim, Thanks so much for the detailed help. I implemented your suggestions and it's all working great now. Thanks heaps. Cheers, Paul |
This web page was last updated on Thursday, December 5, 2024 at 09:15 PM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |