Jump to content
uniGUI Discussion Forums


uniGUI Subscriber
  • Content count

  • Joined

  • Last visited

Community Reputation

2 Neutral

About wprins

  • Rank
    Active Member

Profile Information

  • Gender

Recent Profile Visitors

55 profile views
  1. wprins

    Max Characters in Memo

    Thanks, apologies, I should've found that myself.
  2. wprins

    Max Characters in Memo

    Sherzod, thank you. Out of interest, can one do the same via beforeInit()? (I assume so?)
  3. wprins

    Call another web application

    I assume you meant to write it as the above (note I inserted [in]). What do you mean by "another web application" and what do you mean by "call" exactly? You can call other web services in the normal way you would from non uniGUI applications by whatever means suits your purpose. You can also "call" and frame another website inside a uniGUI frame, with some work and some co-operation from the site being called/framed. You could call a uniGUI application in various ways as well, though you'd need to arrange things to suit your purpose, which is to say you'll have to arrange for the required credentials/login to be somehow handled seamlessly/in the background. (We do something like this from an iSeries green screen system which publishes a clickable URL on the green screen and it directly "calls" our UniGUI application, taking the user to a specific page/form in the UniGUI application. If the user isn't already logged in then they're prompted to log in, after which of course the browser knows the user and further logins is seamlessly handled as required.)
  4. wprins

    Max Characters in Memo

    Today I needed this feature. It would be better if TUniMemo exposed MaxLength as a property to control this. But thanks for this solution. Edit: Also setting the maximum length doesn't actually prevent the entry of more than the maximum length. It does colour the memo frame red and display a hover warning about the maximum length however. Is it possible to actually stop entry once the memo reaches capacity?
  5. wprins

    UniGUI support, feedback in general and the future?

    For what it's worth, we generally employ the same policy -- avoid the use of closed source components whenever possible, UniGUI being essentially the only exception we've allowed in this policy for a very long time as it is such a good product. Still, I really continue to worry and dislike the level of risk we're carrying due to the size of FMSoft, e.g. if something happens to Farshad or FMSoft this will have quite serious consequences. It is entirely within the realm of possibilities to end up in a situation where FMSoft stops trading with no way to obtain the source code to UniGUI, and consequently that all the investment into a UniGUI based solution then ends up having to be abandoned and entirely rewritten due to lack of access to source and consequent inability to upgrade to newer versions of the Delphi and web ecosystems. (To add this is not just a purely hypothetical possibility either, I've actually worked with a company once where exactly this happened and a system had to be replaced at great cost and trauma to the business due to another business having gone under, so much so that they then negotiated special escrow agreements with a new provider to ensure they would have access to a product's source should that partner business cease trading etc... The whole issue is worrying enough that, as much as I like UniGUI, I do continue to consider the alternatives and will likely consider switching to eliminate this risk if something becomes available that is competitive with UniGUI.)
  6. Hi, I've today become aware of the new hyper-server functionality. Fantastic. It will solve some of the issues we've sort of just had to manage/deal with as mentioned in documentation. However, I have a question: It seems from the documentation however that Nodes (worker processes) that are managed by the hyper-server must reside on the same physical/virtual box? Is this corect? If so it's slightly unfortunate as it would seemingly be very useful if nodes could also be distributed over multiple servers rather than only being hosted on one single instance (for additional ability to scale and redundancy.) Or am I missing something or looking at this the wrong way? Thanks Walter
  7. For anyone finding this in future: The URL suggested by Gerhard (freegeoIP) is being retired as of July 2018. An alternative is www.ipify.org. Code as follows: procedure TLoginForm.UniLoginFormAjaxEvent(Sender: TComponent; EventName: string; Params: TUniStrings); begin if SameText(EventName, 'ClientIPAddr') then begin //Do what you want with the IP. As example we set the IP on a frame embedded in the login form (assumes there's a BrowserIP property.) LoginFrame.IPLabel.Caption := 'Your public IP is: '+Params.Values['ip']; LoginFrame.BrowserIP := Params.Values['ip']; end; end; procedure TLoginForm.UniLoginFormBeforeShow(Sender: TObject); begin //Reference: https://www.ipify.org/ UniSession.AddJS( '$(function() {'+ ' $.getJSON("https://api.ipify.org?format=jsonp&callback=?",'+ ' function(json) {'+ ' ajaxRequest(' + self.WebForm.JSName + ', "ClientIPAddr", ["ip="+json.ip]);'+ ' }'+ ' );'+ '});' ); end;
  8. Gerhard, sparkz thanks. I've not been on the forums much for the last 2 or so months. I eventually actually came up with a solution by myself about 2 months ago. It's not entirely unlike what you've (Gerhard) done, yours is a bit more succinct. I was planning on posting my solution at some point but have been either away or too busy. I'll still post it sometime as I avoid using AddJS which seems somehow slightly smelly to me and so may be of interest to others...(?) Edit: Gerhard, thanks again for your example. I did just have a quick look at what I did previously and I think your solution is perhaps preferable, nice and neat and to the point. Will try it out in due course. Nevertheless, for interest and in case anyone finds it useful or educational: Basically I used UniSession.CallbackURL() and UniSession.CallbackTarget() to generate a callback URL and target from within Delphi code. These are placed inside static HTML+JS page code placed a designtime (e.g. TUniHTMLFrame or TUniURLFrame content). At the bottom of the page I wrote some Javascript to retrieve the IP, after which I trigger a normal JS Form submit which fires the retrieved IP address off into the UniGui Session via UniFormAjaxEvent(). UniHTMLFrame1.HTML content: <div style="background-color:#ccc"> <br/><br/><br/><br/><br/> <form name="input" action="{URL_CALLBACK}" method="POST" target="{CALLBACK_TARGET}"> Username: <input type="text" name="user" value="Enter Text..."><br/> IP:<input type="text" name="ip" id="ip" value=""><br/> <input type="submit" value="Submit"> </form> <br/><br/><br/><br/><br/> </div> <script> var request = new XMLHttpRequest(); request.open('GET', 'https://jsonip.com', false); //synchronous request.send(null); if(request.status === 200) { data = JSON.parse(request.response); //console.log(data); //JQuery way: $("#ip").val(data.ip); document.forms["input"]["ip"].value = data.ip; //JQuery way: $("form#input").submit(); document.forms["input"].submit(); } </script> On Form create: procedure TMainForm.ReplaceTags; var S, Sc : string; begin S := UniSyntaxEdit1.Text; Sc := UniSession.CallbackUrl('mycallback', Self, []); S := StringReplace(S, '{URL_CALLBACK}', Sc, []); Sc := UniSession.CallbackTarget; S := StringReplace(S, '{CALLBACK_TARGET}', Sc, []); UniHTMLFrame1.HTML.Text := S; end; procedure TMainForm.UniFormCreate(Sender: TObject); begin UniSyntaxEdit1.Text:=UniHTMLFrame1.HTML.Text; ReplaceTags; end; Form Ajax event handler: procedure TMainForm.UniFormAjaxEvent(Sender: TComponent; EventName: string; Params: TUniStrings); begin if EventName = 'mycallback' then begin UniEdit1.Text := Params.Values['user']; UniEdit2.Text := Params.Values['ip']; UniMemo1.Text := Params.Text; end; end; (Again, this was based on and is a modified version of "HTTP Post Callback - HTMLFrame" demo project. I also similarly modified "HTTP Post Callback - URLFrame - Auto Target" which uses TUniURLFrame component instead of TUniHTMLFrame and does not require the "CALLBACK_TARGET" substitution.) Best regards.
  9. Hello, I've been away on holiday. Unfortunately I see no one's got any suggestions for my problem? So hence I post this additional response to bump it up a bit. As a reminder, my problem/question in short: What is the best way to call/run some Javascript in the browser and have something from it posted back to the corresponding UniGUI user session, and then from the UniGUI session update or set a cookie in the browser as a result? Walter
  10. Hello! Thanks for your response, but this does not help unfortunately. The properties you gave gives the "local network" IP address of the client machine on which the browser is running, which isn't usually the same as the apparent public IP address of that same machine. For example, if I run the uniGui server on my own machine and visit the server page with a browser, the above properties predictably return If I visit my machine from another machine on the LAN, these properties give the the other machine's LAN IP address. So far so good. But of course, if my machine or the other machine, were to visit some other website out on the internet, then both my machine, and the other machine will appear to be originating from a third different IP address, e.g the public IP address of the router and/or proxy server through which the traffic is being routed from the machines out to the site being visited. Now if you think back to what I'm doing: The client browser is simultaneously showing a (local network) uniGUI server, *and* framing another site (out on the internet in this case). Therefore, to the UniGUI server the browser machine appears to have a local LAN IP, but to the site on the internet the browser looks like it has the public IP address where the traffic is coming from. Now for the framing to work, the uniGUI server has to know what the browser's apparent IP address is, and generate an access token using this information (amongst other things.) E.g. it doesn't use the the local LAN IP that is directly visible to the UniGUI server and is obviously not known by the remote site, but it has to use the IP address seen by the third party site. As I mentioned before, this can in fact be easily retrieved from the context of the client browser with a bit of Javascript, but I'm not sure how to get this back to the uniGUI server. That is, my key question is what the best way is to essentially get the browser to do a request to the internet (to establish its "public" IP) and then pass this to the user's UniGUI session, so it can generate the token to place in a TUniURLFrame. Thanks in advance! Walter
  11. Hi, Problem: I'm trying to determine the client's apparent IP address (their public IP) so it is known inside the user's uniGUI session. Background: This is needed to enable us to generate an access token for integrating with an external party/site, where the originating browsers IP address is also used in the token signature/hash calculation/verification process. Obviously determining the user's IP is something that needs to happen inside the browser itself, in order to get the apparent public IP address of the browser running the application. Now it turns out that from a web browser/JS perspective this is quite easy. In fact there are multiple services that has API's that enable one to retrieve your apparent public IP. (See here, for example.) So the obvious idea is to somehow have the browser perform this IP capture itself just prior to, or as part of Login and then pass it and store it as part of the user's session (MainModule). Now I've had a look at the "HTTP POST callback" examples which would've provided, it would seem,a way to achieve this, if our login page was in fact a TUniURLFrame. I could then write some Javascript code to GET from the above URL (on document ready/loaded etc, say) and then update the browser document accordingly to finagle things so that on submit/POST the IP would effectively get passed together with the other form variables. However, we currently use a typical uniGUI login form with edit boxes and so on for login, not a uniURLFrame. So I'm a little at a loss as to where/how to sneak the required JS into the page to fetch the IP and ensure that it gets passed to the uniGUI server session either immediately or on login. Question: Given the above, what's the best way for me to effectively get the browser to get the user's IP address using e.g. https://api.ipify.org/?format=json, and pass this back with the other login details on login to the uniGUI server session? Alternatively do you have any better ideas or have I missed some obvious solution to this problem? (Maybe perhaps using UniSession.AddJS() which has just occurred to me while writing this...?) Thanks so much in advance for any pointers/suggestions, Walter
  12. wprins

    uniGUI: Verification failed

    Thanks for the feedback, it helps to at least know what the cause of the issue is. I'll avoid messing with the virtualisation settings and bear in mind that doing so may affect the uniGUI installation. (Actually the fact that it was off was as a result of a BIOS upgrade some time ago, which as is usual, reset the BIOS settings to defaults. It wasn't until today that I actually needed to use Hyper-V again and then noticed that virtualisation support was in fact off in the BIOS and turned it back on. Perhaps it's worth mentioning this somewhere in the documentation somewhere.) Thanks again and have a great day, Walter
  13. wprins

    uniGUI: Verification failed

    Just to confirm, I uninstalled, reinstalled, and it's working now. Not the end of the world.
  14. wprins

    uniGUI: Verification failed

    Hello, Today I rebooted my PC due to installing newer IBM iSeries drivers on my PC and having to do the usual reboot song-and-dance, and to enable virtualization as I sometimes use Hyper-V (nothing directly related to uniGUI.) However, I now get the following trying to start Delphi: Apparently one of these actions (installing drivers, enabling hyper-v, rebooting) has caused the above. (I've had this once before, and didn't at that time know what triggered it either. It necessitated uninstalling and reinstalling uniGUI to fix as I recall. I'm assuming it's going to be the same this time.) I just wanted to note that somewhere your validation is being overzealous, and politely voice my displeasure at having to deal with this and suggest you look into why this happened to try and prevent it from occurring in future. (This type of thing, though rare, is rather irritating when it happens and wastes time and distracts from actual work.) Best wishes, Walter
  15. wprins

    TUniURLFrame - how to AddJS or call a JS method

    Right, I've come up with a solution myself. Posting this for the benefit of others who may want to do something similar in future. (Basically I've taken a slightly different (and likely more straightforward) tack in dealing with the HTML in the frame and avoided depending on document.ready() as trying to submit from within the document.ready() seemed to be causing the problem even though this works directly in a browser): Anyway, the HTML.Text is now as follows: <!doctype html> <html> <head> <meta charset="utf-8" /> <title>Gateway page</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script> </head> <body> <div id="inputs" style="display: none"> <div id="lblreference">Reference to view:</div> <input type="text" name="reference" id="reference" value="" /> <form id="portal" method="post" name="portal"> <div id="lblgateway">Access token:</div><input type="text" name="gateway" id="gateway" value=""></input> <input type="submit" name="sub" id="sub" value="submit" /> </form> </div> </body> <script type="text/javascript"> var reference = "$reference$"; var token = "$token$"; //Set the above initial values into the form/fields with JQuery: $("#gateway").val(token); $("#reference").val(reference); //Setup a submit handler to check the values and abort if needed, //or modify the URL as required and then continue submission as normal: $("form#portal").submit( function (e) { if ($("#reference").val() == "") { alert("You must supply the reference to view."); $("#inputs").show(); return false; } if ($("#gateway").val() == "") { alert("You must supply the token to authorize viewing."); $("#inputs").show(); return false; } $("#portal").attr("action", "$portalurl$?$refparamname$="+$("#reference").val()); } ); //Try automatic submission at end of document load, here, now: $("form#portal").submit(); </script> </html> Then inside the Delphi code (just after TUniFrame construction, and during its subsequent setup) there is Delphi code like the following to substitute the parameter markers (delimited by $'s above) with their required values: UniURLFrame1.HTML.Text := StringReplace(UniURLFrame1.HTML.Text, '$reference$', IntToStr(LReference), [rfReplaceAll]); UniURLFrame1.HTML.Text := StringReplace(UniURLFrame1.HTML.Text, '$token$', LToken, [rfReplaceAll]); UniURLFrame1.HTML.Text := StringReplace(UniURLFrame1.HTML.Text, '$portalurl$', LPortalURL, [rfReplaceAll]); UniURLFrame1.HTML.Text := StringReplace(UniURLFrame1.HTML.Text, '$refparamname$', LRefURLParamName, [rfReplaceAll]); This has the desired result and immediately then posts the required values to the portal site and displays the results in the frame. I don't particularly like this string substitution based approach but it does work to accomplish the desired result. Comments/Improvements obviously welcome. Thanks Walter