Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 5 of 5 total
Thread Handling the web browsers back button and leaving the app
Fri, Aug 28 2020 3:45 AMPermanent Link

Paul Coshott

Avatar

Hi All,

I have done a heap of searching on this, but couldn't find anything that really helped. I am currently writing a webshop and just want to trap the back button press or leaving the app.

Maybe show the "This page is asking you to confirm that you want to leave - data you have entered may not be saved." message.

Any help would be appreciated.

Cheers,
Paul
Fri, Aug 28 2020 9:22 AMPermanent Link

Raul

Team Elevate Team Elevate

On 8/28/2020 3:45 AM, Paul Coshott wrote:
> I have done a heap of searching on this, but couldn't find anything that really helped. I am currently writing a webshop and just want to trap the back button press or leaving the app.
>
> Maybe show the "This page is asking you to confirm that you want to leave - data you have entered may not be saved." message.
>
> Any help would be appreciated.

Paul

Search for anchors (hash # on URL) - one idea is to redirect app to new
anchor and then back button would go back an previous anchor (and you
can trap anchor change event)

Quick search in forums resulted in this that has good info

https://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb_general&page=1&msg=11606#11606

No doubt other posts also

Raul
Fri, Aug 28 2020 9:26 AMPermanent Link

Matthew Jones

Paul Coshott wrote:

> I have done a heap of searching on this, but couldn't find anything that really helped. I am currently writing a webshop and just want to trap the back button press or leaving the app.
>
> Maybe show the "This page is asking you to confirm that you want to leave - data you have entered may not be saved." message.

You can do both, but the latter is less good because the browser will stop you having total control.

The key you need to look for is "hashchange", and there isn't much about it hereabouts. I'll post the code I wrote to test this below, but it might be for version 1, so it may not work as is. But it should give you a clue I hope.

--

Matthew Jones


unit fURLChanger;

interface

uses WebCore, WebForms, WebCtrls, WebDom;

type


 TWindowHash = class
 private
   fList: TStringList;
   function GetText: string;
   function GetCount: integer;
   function GetName(I: integer): string;
   function GetValue(I: integer): string;
 public
   constructor Create; override;
   destructor Destroy; override;
   procedure Clear;
   procedure SendToBrowser(const ANewTab: boolean = False);
   procedure ReadFromBrowser;
   procedure AddPair(const AName: string; const AValue: string);
   property Count: integer read GetCount;
   property Names[I: integer]: string read GetName;
   property Values[I: integer]: string read GetValue;   
   property Text: string read GetText;
 end;



TForm1 = class(TForm)
     Edit1: TEdit;
     Button1: TButton;
     Button2: TButton;
     editReport: TMemo;
     procedure Button2Click(Sender: TObject);
  procedure Button1Click(Sender: TObject);
  private
   m_xWindowHash : TWindowHash;
     { Private declarations }
   function TrapWindowHashChange(event: TEvent): boolean;
public
     { Public declarations }
   procedure Report(szMessage : String);
  end;

var
  Form1: TForm1;

implementation

procedure TForm1.Button2Click(Sender: TObject);
begin            
   if not assigned(m_xWindowHash) then
       m_xWindowHash := TWindowHash.Create;
   SetWindowEventHandler('hashchange',TrapWindowHashChange);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   m_xWindowHash.AddPair('Hello', 'Mum');
   m_xWindowHash.SendToBrowser(false);
end;

procedure TForm1.Report(szMessage : String);
begin
   editReport.Lines.Add(szMessage);
end;

function TForm1.TrapWindowHashChange(event: TEvent): boolean;
begin
 Result := True;


 m_xWindowHash.ReadFromBrowser;

 Report(m_xWindowHash.Names[0]);

//    if fWindowHash.Names[0] = 'View' then
//    begin
//    if fWindowHash.Values[0] = 'Home' then
//        DoShowForm(frmHome)
//    else if fWindowHash.Values[0] = 'Welcome' then
//        DoShowForm(frmWelcome)
//
//    else if fWindowHash.Values[0] = 'Item' then
//    DoShowForm(frmItem)
//
//    else if fWindowHash.Values[0] = 'Preview' then
//    DoShowForm(frmPreview)
//
//    else if fWindowHash.Values[0] = 'Folder' then
//    DoShowForm(frmFolder)
//
//    else if fWindowHash.Values[0] = 'Notifications' then
//    DoShowForm(frmNotifications)
//
//    else if fWindowHash.Values[0] = 'Discussions' then
//    DoShowForm(frmDiscussions)
//
//    else if fWindowHash.Values[0] = 'Subscribed' then
//    DoShowForm(frmSubscribed)
//
//    else if fWindowHash.Values[0] = 'Upload' then
//    DoShowForm(frmUpload)
//
//    else if fWindowHash.Values[0] = 'Settings' then
//    DoShowForm(frmSettings)
//
//    else if fWindowHash.Values[0] = 'Search' then
//    DoShowForm(frmSearch)
//
//    else if fWindowHash.Values[0] = 'Discussion' then
//    DoShowForm(frmDiscussion)
//    end;
end;
   

constructor TWindowHash.Create;
begin
 inherited Create;
 fList := TStringList.Create;
 fList.LineSeparator := '&';
end;

destructor TWindowhash.Destroy;
begin
 fList.Free;
 inherited Destroy;
end;

procedure TWindowHash.SendToBrowser(const ANewTab: boolean = False);
var
 S: string;
 I: integer;
begin

 if fList.Count = 0 then
   S := ''
 else
   begin
     S := '#';
     for I := 0 to fList.Count - 1 do
       begin
         S := S + Names[I];
         S := S + '=';
         S := S + Values[I];
         if I < fList.Count - 1 then
           S := S + '&';
       end;
   end;

 if ANewTab then
   Window.Open(StrReplace(Window.Location.HRef,Window.Location.Hash,S),'_blank','',False)
 else
   Window.Location.Hash := S;                          {+ '&_dc=' + IntToStr(MSecondOf(Now) + (SecondOf(Now) * 1000) + (MinuteOf(Now) * 60 * 1000))}
end;

procedure TWindowHash.ReadFromBrowser;
var
 S: string;
 I: integer;
begin
 fList.Clear;
 S := Window.Location.Hash;
 if S[1] <> '#' then
   exit;
 S := Copy(S,2,Length(S) - 1);
Form1.Report(S);
 if S = '' then
   raise EError.Create('TWindowHash.ReadFromBrowser: Empty hash encountered');
 fList.Text := S;
 for I := 0 to fList.Count - 1 do
   if Pos('=',fList[I]) = 0 then
     raise EError.Create('TWindowHash.ReadFromBrowser: Pair format is invalid');
 {if Pos('_dc=',fList[fList.Count - 1]) <> 0 then
   fList.Remove(fList.Count - 1);}
end;

procedure TWindowHash.Clear;
begin
 fList.Clear;
end;

procedure TWindowHash.AddPair(const AName: string; const AValue: string);
begin
 if Trim(AName) = '' then
   raise EError.Create('TWindowHash.AddPair: Empty name');
 if Trim(AValue) = '' then
   raise EError.Create('TWindowHash.AddPair: Empty value');
 fList.Add(Trim(AName) + '=' + Trim(AValue));
end;

function TWindowHash.GetText: string;
begin
 Result := fList.Text;
end;

function TWindowHash.GetCount: integer;
begin
 Result := fList.Count;
end;

function TWindowHash.GetName(I: integer): string;
var
 S: string;
 P: integer;
begin
 if (I < 0) or (I > fList.Count - 1) then
   raise EError.Create('TWindowHash.GetName: Invalid index');
 S := fList[I];
 P := Pos('=',S);
 if P = 0 then
   raise EError.Create('TWindowHash.GetName: Pair format is invalid');
 Result := Copy(S,1,P - 1);
 if Result = '' then
   raise EError.Create('TWindowHash.GetName: Empty name');
end;

function TWindowHash.GetValue(I: integer): string;
var
 S: string;
 P: integer;
begin
 if (I < 0) or (I > fList.Count - 1) then
   raise EError.Create('TWindowHash.GetValue: Invalid index');
 S := fList[I];
 P := Pos('=',S);
 if P = 0 then
   raise EError.Create('TWindowHash.GetValue: Pair format is invalid');
 Result := Copy(S,P + 1,Length(S) - P);
 if Result = '' then
   raise EError.Create('TWindowHash.GetValue: Empty value');
end;

end.
Fri, Aug 28 2020 9:28 AMPermanent Link

Matthew Jones

Matthew Jones wrote:

> old code

Go with Raul's answer - the anchor replaces my hack. I knew there was something better!


--

Matthew Jones
Mon, Aug 31 2020 5:29 PMPermanent Link

Paul Coshott

Avatar

I modified my app to use the Address.Anchor mechanism to do the loading and unloading of my forms. And now the back button behaves as you would expect in a static html website. Just brilliant!

Thanks to Raul and Matthew for their help. Thanks to Uli for the sample application showing how to use the Address.Anchor and once again, thanks to Tim for providing us with the solutions to make our lives so much easier.

Cheers,
Paul
Image