-
Posts
144 -
Joined
-
Last visited
-
Days Won
11
Content Type
Profiles
Forums
Events
Posts posted by Kattes
-
-
13 minutes ago, Sherzod said:
Hello,
What is the response code gets a PHP app?
The PHP App is fed with JSON strings in a normal case, which were triggered by the API calls coming from the PHP app. But sometimes it happens that an API call does not get any response. This status of not getting any responses can stay for some minutes up to an hour. But then its starting to work again, which is very strange.
-
Hello,
I am a bit clueless with a big problem I need to solve ASAP. The current situation is as followed. I am running on a Windows 2016 server two uniGui Applications. One works as a non visual DB server, which feeds an external PHP Shop Application with information like articles , prices, etc. The other one is a Backend Application, which handles all the articles from the shop. So this behaves more like the standard uniGui Application we all know, using all the nice uniGui visual components we all love.But my problem comes from the non visual application, which sometimes is not reachable, which means API calls from the PHP application do not get any response. Main part of this application is the Methode "UniGUIServerModuleHTTPCommand", which looks like this:
procedure TUniServerModule.UniGUIServerModuleHTTPCommand(ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; var Handled: Boolean); var sJSON, sParam, sRequest, s : string; i : integer; bValidRequest : boolean; begin // Examples of Supported APIs: // http://localhost:8077/v1/prom?ID=47 >> Get Details of selected event with the ID 47 // http://localhost:8077/v1/Prom/CheckAvail >> Check if server is online // http://localhost:8077/v1/Proms >> Get List of current events bValidRequest := false; if pos('/v1', ARequestInfo.URI) = 1 then // API Call found !! begin AResponseInfo.ResponseNo := 200; Handled := True; if ARequestInfo.AuthExists and (ARequestInfo.AuthPassword='wshgdaizuddsfrtG12') and (ARequestInfo.AuthUsername='XCloud') then begin sRequest := Uppercase(ARequestInfo.URI); if sRequest = Uppercase('/v1/Prom/CheckAvail') then // Checking the API accessibility during the purchase process begin bValidRequest := true; sJSON := '{"status": "online"}'; AResponseInfo.ContentText := sJSON; LogPayServer('HTTP Request "CheckAvail"', sJSON); end; if sRequest=Uppercase('/v1/Proms') then // Returns a list of all currently active proms in JSON format. begin bValidRequest := true; sJSON := GetEventsAsJSON; LogPayServer('HTTP Request "Proms"', sJSON); AResponseInfo.ContentText := sJSON; end; if sRequest=Uppercase('/v1/Prom/OrderConfirmed') then // Called after the sales process has been completed begin sJSON := ARequestInfo.RawHeaders.Values['OrderInfo']; // Process received order information LogPayServer('HTTP Request "OrderConfirmed"', sJSON); if AddJsonOrderInformationToDB2(sJSON) then begin LogPayServer('HTTP Request "OrderConfirmed"', 'bValidRequest=true'); bValidRequest := true; AResponseInfo.ContentText := '{"status": "processed"}'; // if everything is OK, than return follwing: end else LogPayServer('HTTP Request "OrderConfirmed"', 'bValidRequest=false'); end; if sRequest=Uppercase('/v1/Prom') then begin sParam := ARequestInfo.Params.Values['VoucherVal']; // Request to check the value of the given voucher if sParam <>'' then begin bValidRequest := true; // Get from DB the value of the given voucher and return it to JSON sJSON := '{"voucher value": '+GetVoucherValue(ZConnectionServerModule, sParam)+'}'; AResponseInfo.ContentText := sJSON; LogPayServer('HTTP Request "VoucherVal" ('+sParam+')', sJSON); end; sParam := ARequestInfo.Params.Values['Id']; // Returns information of the event, which was selected via its Id if sParam <>'' then begin bValidRequest := true; sJSON := GetEventDetailsJSON(sParam); AResponseInfo.ContentText := sJSON; LogPayServer('HTTP Request "Prom?Id=?"', sJSON); end; end; if not bValidRequest then begin AResponseInfo.ContentText := '<html>Not supported API-Call; Please check API documentation!</html>'; LogPayServer('HTTP Request "API ERROR"', ARequestInfo.URI); end; end else begin AResponseInfo.ContentText := '<html>Wrong or missing PW; Please use Basic Auth!</html>'; LogPayServer('HTTP Request "Invalid Caller"', 'PW / Auth wrong'); end; end; end;
The Internalisation Methode is also simple and straightforward:
procedure TUniServerModule.UniGUIServerModuleCreate(Sender: TObject); begin sHTML1 := tStringList.Create; sHTML2 := tStringList.Create; with ZConnectionServerModule do begin Connected := False; LibraryLocation := StartPath+'files\dll\libmysql.dll'; Protocol := 'mysql'; HostName := 'localhost'; Port := 3306; Database := 'xxxxx'; User := 'root'; Password := '-----'; Connected := true; end; LogPayServer('UniGUIServerModuleCreate','Server V'+FileVersionGet(StartPath+'AbiPaymentServer.dll')+' Created and running'); end;
I am mentioning it here because as you can see it also uses a Log-Call, which writes information to a log table within my MySQL database and I can find randomly entries in the log, which show me that the application was restarted.
At the moment the traffic handled by this Application is very low (less than 10 API calls per hour). Nevertheless I have the problem that the Application does not response and is not reachable sometimes. This is something I have not seen as long as I used it as standalone Application.
Any comments or help are more than welcome!
-
-
But don not waste too much of your time on it. I also found a different solution which is suitable for me .
unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUITypes, uniGUIAbstractClasses, uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniPanel, uniGUIBaseClasses, uniButton, Vcl.Imaging.jpeg, uniImage, uniEdit, uniSpinEdit; type TMainForm = class(TUniForm) UniButton1: TUniButton; UniPanel1: TUniPanel; UniImage1: TUniImage; UniEdit1: TUniEdit; UniEdit2: TUniEdit; UniSpinEdit1: TUniSpinEdit; procedure UniButton1Click(Sender: TObject); private { Private declarations } bToggle : boolean; public { Public declarations } end; function MainForm: TMainForm; implementation {$R *.dfm} uses uniGUIVars, MainModule, uniGUIApplication; procedure FadeInOut(xControl: TUniControl; bFadeOut: boolean; const Duration : integer = 300); begin if bFadeOut then xControl.JSInterface.JSCode(#1'.el.fadeOut({duration: '+IntToStr(Duration)+'});') else xControl.JSInterface.JSCode(#1'.el.fadeIn({duration: '+IntToStr(Duration)+'});') end; function MainForm: TMainForm; begin Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); end; procedure TMainForm.UniButton1Click(Sender: TObject); begin bToggle := not bToggle; FadeInOut(UniPanel1, bToggle, UniSpinEdit1.Value); FadeInOut(UniImage1, bToggle, UniSpinEdit1.Value); end; initialization RegisterAppFormClass(TMainForm); end.
-
Hi Sherzod,
Please find attached a little testcase.Thank you and kind regards,
Carsten -
Hi Sherzod,
Yes, I saw this older post and finally was inspired by it, but my goal is that whenever I change the "visible" property of any unigui control that this gets faded in or out (depending if visible is true or false). -
Hi,
I have a little problem to get a UniPanel "fadeOut" when changing its property "visible" from true to false - the other direction (fadeIn) works fine.Fade in is programmed as followed:
UniPanelStatus.ClientEvents.ExtEvents.Add('show=function show(sender, eOpts){'+ 'sender.el.setOpacity(0); '+ 'sender.el.fadeIn({duration: 500});'+ '}' );
How has a valid solution for "fadeOut" look like?
I tried the following without success:
UniPanelStatus.ClientEvents.ExtEvents.Add('hide=function hide(sender, eOpts){'+ 'sender.el.setOpacity(1); '+ 'sender.el.fadeOut({duration: 500});'+ '}' );
-
I don't know if somebody is using it. If yes I have an updated version which fixes a tiny bug and now allows nested message dialogs.
- 1
-
On 1/15/2020 at 10:50 AM, Freeman35 said:
Hello,
https://stackoverflow.com/questions/29292596/save-load-objects-as-blob-in-a-database
If I were you, I'm not save file to db. Make a folder, (I have not new version unigui) fileupload component saving file on server side. After saved this file move & rename it. then transfer file that from folder. Just save name and path to db. This is much better way.
regards.
I totally agree to Freeman35's post - Putting big files into a database makes everything slow and a backup of such a huge DB can become a nightmare!
As already recommended, please put only file references to the DB. -
BIngo ! 100 Points go to Sherzod !
This is perfect ! Thank you, again!
- 1
-
You can also do simply the following:
UniDBGrid1.DataSource.DataSet.Refresh;
-
Thank you Sherzod!
I slightly modified the solution you sent me, which I also want to share with the community.
procedure HideMenueItems(var MyTreeMenu: TUniTreeMenu; const sHide: string); var s,sH : string; i : integer; llist: string; begin llist := ''; sH := ','+sHide+','; for i := 0 to MyTreeMenu.Items.Count-1 do begin s := ','+MyTreeMenu.Items[i].AttachedMenuItem.Caption+','; if pos(s, sH)>0 then begin MyTreeMenu.Items[i].AttachedMenuItem.Visible := false; if llist='' then llist := '"'+MyTreeMenu.Items[I].AttachedMenuItem.Caption+'"' else llist := llist + ',"' + MyTreeMenu.Items[I].AttachedMenuItem.Caption+'"'; end; end; if llist<>'' then begin MyTreeMenu.JSInterface.JSAssign('_rtext', [MyTreeMenu.JSControl.JSArray(llist)]); MyTreeMenu.JSInterface.JSCode('var me='#1';'+ 'if(me._rtext) me.getStore().each(function(record) {'+ ' if (me._rtext.indexOf(record.get("text")) > -1) {'+ ' record.remove()'+ ' }'+ '});' ); end; end; procedure TMainForm.UniButtonHideClick(Sender: TObject); begin HideMenueItems(UniTreeMenu, 'Dashboard,Database,Management,Customers'); end;
- 1
-
Just another little cosmetic question. As you can see in the title of the grid, the "g" of the word "progress" is cut off. Can this be cured by a simple CSS statement, too?
-
Thanks Sherzod, your CSS trick also made sure that the widget fills the height of the grid cell better in addition to the vertical centering.
-
Sorry, I mean that the widget is currently located at the top of the grid cell, but I want to have it vertically centered.
-
Actually my approach is not relevant here, but I can of course tell you how I did it:
I simply created in my MySQL DB a table view, which contained a field:
Concat('<progress max="100" value="',Progr,'">',Progr,'%</progress>') as progress
This made the trick for me. But I am more interested in the widget approach, because it is using pre-defined themes and will look for browsers equal.
-
Sorry but I also have problems using your solutions.
I have the following uniTreeMenu structure:
.. and want to hide menu items "Management" and its children for "simple" users.
Therefor I am using the following code:
procedure TuDashboardFrame.UniPanelLoginClick(Sender: TObject); var s : string; i : integer; begin with MainForm do begin for i := 0 to UniTreeMenu1.Items.Count-1 do begin s := UniTreeMenu1.Items[i].AttachedMenuItem.Caption; if pos(s, 'Database Management Customers')>0 then UniTreeMenu1.Items[i].AttachedMenuItem.Visible := false; end; UpdateTreeMenu(UniTreeMenu1); end; end;
in combination with your slightly adapted solution:
procedure UpdateTreeMenu (myMenu : TUniTreeMenu); var I: Integer; _llist: string; begin with myMenu do begin SourceMenu.Items[0].Visible := False; _llist := ''; for I := 0 to SourceMenu.Items.Count-1 do if not SourceMenu.Items[I].Visible then if _llist='' then _llist := '"'+SourceMenu.Items[I].Caption+'"' else _llist := _llist + ',"' + SourceMenu.Items[I].Caption+'"'; if _llist<>'' then begin JSInterface.JSCall('getStore().clearFilter', []); JSInterface.JSCode(#1'.getStore().filterBy(function (record){ if (['+ _llist +'].indexOf(record.get("text"))>-1) return false; else return true;});'); end else JSInterface.JSCall('getStore().clearFilter', []); end; end;
Unfortunately this is not working
-
OK, I got it working, but the example (\FMSoft\Framework\uniGUI\Demos\Desktop\Grid - WidgetColumn2) is not really self explaining.
The screen shot below is using ProgressWidget (column Progr) and some HTML hard coded solution from me (column Progress).
Question: Is there a way to center the widget vertically? I tried it using margins, but that does not seem to work.
-
OK, I will give it a second try...
-
On 1/25/2020 at 11:21 AM, Sherzod said:
Works for me.
Can you please share your testcase with me?
-
Sorry, but this trick is not working anymore (at least for me using uniGUI_1.90.0.1514).
First you will think that everything is OK, but under real "usage" conditions it will make everything unstable.
So
DON'T USE THIS ! -
Sorry, but this trick is not working (at least for me using uniGUI_1.90.0.1514)
-
I know this is a really old topic, but I need to inform you that current solutions has problems. In one of my applications I am using a uniDBGrid to visualize different DB tables. Based on the above examples I tried to assign different page sizes based on the selected table.
Therefore I used this modified routine:
procedure TuDBFrame.SetPageSize(PageSize : integer); var DBGridJSName: string; RecordCount: Integer; JSCode: string; st : TDataSetState; begin DBGridJSName := UniDBGrid.JSName; st := UniDBGrid.DataSource.DataSet.State; if st in [dsInactive] then UniDBGrid.DataSource.DataSet.Open; RecordCount := UniDBGrid.DataSource.DataSet.RecordCount; UniDBGrid.WebOptions.PageSize := PageSize; JSCode := DBGridJSName + '.getStore().pageSize=' + IntToStr(PageSize) + ';'; if RecordCount > PageSize then JSCode := JSCode + DBGridJSName + '.pagingBar.show();' else JSCode := JSCode + DBGridJSName + '.pagingBar.hide();'; JSCode := JSCode + DBGridJSName + '.getStore().load();'; UniSession.AddJS(JSCode); end;
If I call this routine the first time for e.g. table A with a PageSize of 50 records and later for a different table B with a PageSize of 100 only the first 50 records of table B are listed in the dbgrid on the first page, i.e. 50 records are lost on the first page! When switching to the second page, this starts with record number 101 (which is in line with the changed page size).
I guess that the first call changes also some unknown but important JS variable, which later will not get changed anymore and leads to this unwanted effect.
-
Great - Thank you for the fast reply!
This is really fantastic and makes my life much easier. So far I wasn't aware of that in case of using IIS with ISAPI no PEM files are needed - probably I have simply overseen it.
Best regards,
Carsten- 1
Problem With ISAPI
in General
Posted
Hi Jean-Marc,
So you would suggest to keep the DB connection in the state "connected := false" as long as I do not enter UniGUIServerModuleHTTPCommand routine - so changing its state here on entry to true and before leaving to false again?