Hi, I am spiking out a solution that can use web history to maintain back button support when user "transitions" between panels.
TL;DR
When adding history, the first "click" of the back button works as expected, but subsequent clicks require two clicks of the back button.
I have a web page that is composed of 4 Panels (Green, Red, Blue and Purple), an application object to manage the panel transitions and a PanelManager to deal with adding panels to a layout.
If you execute, MMSPanelPage, you can see the app in action. Clicking through the panels on the left transitions to each panel and the panel identifier is added to the URL via #SYS_WEB.History. Click through to the purple panel and then click your brower's back button. The first click works as expected, the blue panel is displayed. The second click does nothing (I would expect the red panel to be displayed), but the third click transitions to the red panel. Like wise for the previous green panel.
If you open your brower's dev tools, I have added some Console.Log statements to help track it down. I tried some crazy tricks like adding all the panel history to a collection and always getting the last one, nothing seems to work.
Attached is the export. Could use some advice or guidance on how to make this work.
Thanks,
Joe
Using Web History for Panel Navigation
Using Web History for Panel Navigation
- Attachments
-
- QuickExport20160222125540.zip
- (16.45 KiB) Downloaded 1293 times
- Stewart Marshall
- Posts: 417
- Joined: Thu Nov 05, 2015 5:25 pm
Re: Using Web History for Panel Navigation
Hi Joe
I found exactly the same issues when making the xDemoWebBackForward example. It's slightly simpler than yours, but the concepts are the same.
Your current processing is similar to this
Click green. Show green. Add green.
Click red. Show red. Add red.
Click blue. Show blue. Add blue.
Click back. Show red. Add red!!!!
Click back. Show red, but as it's already red, ignore.
Click back. Show green. Add green.
All processing has to go via the URLchanged event. This is a necessity for all back, forward and deep linking processing. However, not all navigations are equal. If a user clicks a button to do something, that should be added to the history, but use of Back/Forward should not. They just navigate through it.
I've made a couple of alterations to the code. The application object now has an AddToHistory method. This is called by each of the items in the list when they're used.
Regards
I found exactly the same issues when making the xDemoWebBackForward example. It's slightly simpler than yours, but the concepts are the same.
Your current processing is similar to this
Click green. Show green. Add green.
Click red. Show red. Add red.
Click blue. Show blue. Add blue.
Click back. Show red. Add red!!!!
Click back. Show red, but as it's already red, ignore.
Click back. Show green. Add green.
All processing has to go via the URLchanged event. This is a necessity for all back, forward and deep linking processing. However, not all navigations are equal. If a user clicks a button to do something, that should be added to the history, but use of Back/Forward should not. They just navigate through it.
I've made a couple of alterations to the code. The application object now has an AddToHistory method. This is called by each of the items in the list when they're used.
Regards
- Attachments
-
- QuickExport20160223112631.zip
- (15.91 KiB) Downloaded 1319 times
Re: Using Web History for Panel Navigation
Ok, I see what you did there.
I gotta remember about those demo apps, lots of good information in there if you remember to go look for it.
Thanks for the help.
I gotta remember about those demo apps, lots of good information in there if you remember to go look for it.
Thanks for the help.
Re: Using Web History for Panel Navigation
I realize this is an old topic, but I've encountered another issue related to the topic so I thought I would add it here.
While adding to the history works as expected regarding navigation, there seems to be an anomaly with other querystring parameters.
In essence what I am trying to do is add an entry to the history keeping the current querystring values and/or replacing certain values so that history would become
Subsequenent adds however seem to concat the values on the existing querystring whereas the initial add, replaced the entire querystring.
For example:
If the querystring is `?myvalue=123&trace=true` and I add `panel=ABC` then the querystring becomes `?panel=ABC`.
If I copy the the querystring parameters, add my panel parameter and then add all that to the history the querystring becomes `?myvalue=123&trace=true&mypanel=ABC`. If I copy the parameters, change the panel parameter add it to the history the querystring becomes `?myvalue=123&trace=true&mypanel=ABC&myvalue=123&trace=true&mypanel=DEF`.
It seems the first call to Add does a replace and subsequent calls to Add concatenate.
Has anyone else seen this behavior or know how to deal with it?
This is the code I am using, perhaps I am doing something wrong?
While adding to the history works as expected regarding navigation, there seems to be an anomaly with other querystring parameters.
In essence what I am trying to do is add an entry to the history keeping the current querystring values and/or replacing certain values so that history would become
- ?panel=ABC&Trace=True
- ?panel=DEF&Trace=True
- ?panel=GHI&Trace=True
Subsequenent adds however seem to concat the values on the existing querystring whereas the initial add, replaced the entire querystring.
For example:
If the querystring is `?myvalue=123&trace=true` and I add `panel=ABC` then the querystring becomes `?panel=ABC`.
If I copy the the querystring parameters, add my panel parameter and then add all that to the history the querystring becomes `?myvalue=123&trace=true&mypanel=ABC`. If I copy the parameters, change the panel parameter add it to the history the querystring becomes `?myvalue=123&trace=true&mypanel=ABC&myvalue=123&trace=true&mypanel=DEF`.
It seems the first call to Add does a replace and subsequent calls to Add concatenate.
Has anyone else seen this behavior or know how to deal with it?
This is the code I am using, perhaps I am doing something wrong?
Code: Select all
define_com class(#PRIM_ACOL<#PRIM_WEB.URLParameter>) name(#queryStringParameters)
mthroutine name(AddToPanelHistory) access(*PRIVATE)
define_map for(*INPUT) class(#STD_STRNG) name(#panelId)
define field(#queryString) type(*STRING)
#queryStringParameters.RemoveAll
for each(#urlParameter) in(#SYS_WEB.URLParameters)
* don't add a panel, we are going to add it later
continue if(#urlParameter.Name.Uppercase = PANEL)
#SYS_APPLN.TraceMessageText( ("Adding &1:&2 to parameters").Substitute( #urlParameter.Name #urlParameter.Value ) )
if (#queryStringParameters.Contains( #urlParameter ) = False)
#queryStringParameters.Insert( #urlParameter )
endif
endfor
* build up the querystring
for each(#queryStringParameter) in(#queryStringParameters)
if (#queryString.CurChars = 0)
#queryString += ("&1=&2").Substitute( #queryStringParameter.Name #queryStringParameter.Value )
else
#queryString += ("&1&2=&3").Substitute( '&' #queryStringParameter.Name #queryStringParameter.Value )
endif
endfor
* add the panel id and add it to the history
if (#queryString.CurChars = 0)
#queryString += ("&1=&2").Substitute( panel #panelId )
else
#queryString += ("&1&2=&3").Substitute( '&' panel #panelId )
endif
#SYS_WEB.History.Add( #queryString )
endroutine
- Stewart Marshall
- Posts: 417
- Joined: Thu Nov 05, 2015 5:25 pm
Re: Using Web History for Panel Navigation
Hi Joe
Here's a simple page showing history working as it should. Run it from the IDE to get additional parameters in the QueryString.
Every time a label is clicked, its caption is added to the history. As the sequence of the parameters in the QueryString isn't important, I ignore a "Panel" item if its there and then tack it on the end.
Regards
Here's a simple page showing history working as it should. Run it from the IDE to get additional parameters in the QueryString.
Every time a label is clicked, its caption is added to the history. As the sequence of the parameters in the QueryString isn't important, I ignore a "Panel" item if its there and then tack it on the end.
Code: Select all
Begin_Com Role(*EXTENDS #PRIM_WEB) Height(488) Width(769) Theme(#SYS_THEME<2015Blue>)
Define_Com Class(#prim_labl) Name(#Label1) Caption('Panel1') DisplayPosition(3) Left(32) Parent(#COM_OWNER) TabPosition(3) Top(64) TabStop(False) ThemeDrawStyle('LightTitle') Height(34) Width(209) Alignment(Center) VerticalAlignment(Center)
Define_Com Class(#prim_labl) Name(#Label2) Caption('Panel2') DisplayPosition(2) Left(32) Parent(#COM_OWNER) TabPosition(2) Top(104) TabStop(False) ThemeDrawStyle('LightTitle') Height(34) Width(209) Alignment(Center) VerticalAlignment(Center)
Define_Com Class(#prim_labl) Name(#Label3) Caption('Panel3') DisplayPosition(1) Left(32) Parent(#COM_OWNER) TabPosition(1) Top(144) TabStop(False) ThemeDrawStyle('LightTitle') Height(34) Width(209) Alignment(Center) VerticalAlignment(Center)
Define_Com Class(#prim_kcol<#prim_labl #xDemoCaption>) Name(#Labels) Style(Collection)
Evtroutine Handling(#Com_owner.CreateInstance)
For Each(#Member) In(#Com_owner.ComponentMembers) Operation(*Instance_of #prim_labl)
#Labels<#Member.Caption.UpperCase> <= #Member
Endfor
Endroutine
Evtroutine Handling(#Labels<>.Click) Com_Sender(#Sender)
#Com_owner.AddHistory( #Sender.Caption )
Endroutine
Mthroutine Name(AddHistory)
Define_Map For(*Input) Class(#Prim_Alph) Name(#Panel)
Define_Com Class(#Prim_alph) Name(#QueryString)
For Each(#Parameter) In(#sys_web.URLParameters)
Continue If(#Parameter.Name.UpperCase = Panel)
If (#QueryString <> "")
#QueryString += "&"
Endif
#QueryString += #Parameter.Name + "=" + #Parameter.Value
Endfor
#QueryString += "&Panel" + "=" + #Panel
#sys_web.History.Add( #QueryString )
Endroutine
Evtroutine Handling(#sys_web.URLChanged)
#Labels<>.ThemeDrawStyle := LightTitle
If (#sys_web.URLParameters<Panel> *IsNot *null)
#Labels<#sys_web.URLParameters<Panel>.Value.UpperCase>.ThemeDrawStyle := DarkTitle
Endif
Endroutine
End_Com