voyent
how to: dynamic includes + back button  XML
Forum Index -> General Help
Author Message
jmind

Joined: 07/Jul/2008 00:00:00
Messages: 54
Offline


i'm using dynamic includes with facelets so my navigation doesn't pass through the jsf navigation handler, i just change the include. I found in the jira archive a solution based on the navigation handler - google rsh combo. How can i achieve the same result with dynamic includes?

italian coder
humppa


Joined: 18/Mar/2008 00:00:00
Messages: 137
Offline


Hi,

I'm using SWFAddress for that functionality.

http://www.asual.com/swfaddress/

jmind

Joined: 07/Jul/2008 00:00:00
Messages: 54
Offline


from the site i didn't understand how it works. Can you post some sample code?

Thanks

italian coder
humppa


Joined: 18/Mar/2008 00:00:00
Messages: 137
Offline


jmind wrote:
from the site i didn't understand how it works. Can you post some sample code?

Thanks 


Hi!

I will try to explain it, but it has been a while since I implemented it...

(sorry for my goofy english)

General Explanation:
the main problem is that it's generally not possible to change the browser url using javascript without reloading the page.
So Swfaddress can not change the url from www.icefaces.com to icefaces.com?humppa=1.
But it is possible to use the browser build in "jumping label" (I don't know the english word for that) technique to append text at the end of the url.
So it is possible to change a url from www.icefaces.com to www.icefaces.com#?humppa=1.
the problem now is that when the browser processes the address in the addressbar it will only send everything in front of the #-character to the webserver (if the page has not already been loaded). everything coming after the #-char will be processed locally after the page has been loaded.
So what I'm doing now is, I use the swfaddress-event system to recognize when the string after the #-char has been changed and submitted. in the event handler i send the new url back to the appserver using icefaces. then my backingbean processes the new url and changes for example the facelet dynamic include path according to the new url.

So with that technique your page is fully bookmarkable and the browser back button will work.

Notice: all this will not work for robots, because as far as i know they are not using javascript and also they ignore everything after the #-character in the url.


some code:

In your jspx put following lines in the <head> tag:

Code:
 <head>
          <script type="text/javascript" src="./swfaddress/swfaddress-optimizer.js"></script>
          <script type="text/javascript" src="./swfaddress/swfaddress.js?html=false;strict=true;"></script>
          <script type="text/javascript" src="./main.js"></script>
 </head>
 
 <body>
 				<ice:form partialSubmit="true" id="backchannelform">
 					<ice:inputHidden id="backchannelparamvalue" value="#{navi.backChannelParamValue}"></ice:inputHidden>
 				</ice:form>
 </body>
 


the first script loads the swfaddress library,
the second script does some swfaddress configuration (as far as I remember), you can read more info about it in the swfaddress documentation.
the third script is a javascript file with my swfaddress implementation.


here is the intressting part of my backingbean:
Code:
 
 	private String BackChannelParamValue;
 	public void setBackChannelParamValue(String backChannelParamValue)
 	{...}
 
 
 	public void setBrowserAddressBar(String params)
 	{
 		this.lastSentURL = params;
 		//function setAddressBar(url)
 		JavaScript.InvokeJavaScriptFunction("setAddressBar", new Object[]{params});
 	}
 
 


main.js:
Code:
 function setAddressBar(url) 
 {
 	SWFAddress.setValue("?"+url);
 }
 
 function Init()
 {
 	SWFAddress.setHistory(true);
 }
 Init();
 
 function SendURLParameters(params) 
 {
 	//parameter name
 	document.getElementById("backchannelform:backchannelparamvalue").value = params;
 	iceSubmitPartial(document.getElementById("backchannelform"), document.getElementById("backchannelform:backchannelparamvalue"));//MouseEvent.CLICK); 
 }
 
 function handleChange(event) 
 {
 	SendURLParameters(event.value);
 }
 SWFAddress.addEventListener(SWFAddressEvent.CHANGE, handleChange);
 


first the init() function gets called, it will enable the browser back button.

the handleChange() function gets called when the addressbar has been manipulated (for example when the user changes the url, or hits the back button). it calls then the SendURLParameters() function, which sends the new url back to my appserver, using a hiddeninput field.
the url will then be processed by the backing bean which results for example in a change of a facelets dynamic include path.

the setAddressBar() function gets called by my backingbean. it manipulates the addressbar ;-)
for example setAddressBar("humppa"); would add "#?humppa" at the end of the url.



cheers!
michelle2

Joined: 14/Nov/2007 00:00:00
Messages: 449
Offline


humppa wrote:

jmind wrote:
from the site i didn't understand how it works. Can you post some sample code?

Thanks 


Hi!

I will try to explain it, but it has been a while since I implemented it...

(sorry for my goofy english)

General Explanation:
the main problem is that it's generally not possible to change the browser url using javascript without reloading the page.
So Swfaddress can not change the url from www.icefaces.com to icefaces.com?humppa=1.
But it is possible to use the browser build in "jumping label" (I don't know the english word for that) technique to append text at the end of the url.
So it is possible to change a url from www.icefaces.com to www.icefaces.com#?humppa=1.
the problem now is that when the browser processes the address in the addressbar it will only send everything in front of the #-character to the webserver (if the page has not already been loaded). everything coming after the #-char will be processed locally after the page has been loaded.
So what I'm doing now is, I use the swfaddress-event system to recognize when the string after the #-char has been changed and submitted. in the event handler i send the new url back to the appserver using icefaces. then my backingbean processes the new url and changes for example the facelet dynamic include path according to the new url.

So with that technique your page is fully bookmarkable and the browser back button will work.

Notice: all this will not work for robots, because as far as i know they are not using javascript and also they ignore everything after the #-character in the url.


some code:

In your jspx put following lines in the <head> tag:

Code:
 <head>
          <script type="text/javascript" src="./swfaddress/swfaddress-optimizer.js"></script>
          <script type="text/javascript" src="./swfaddress/swfaddress.js?html=false;strict=true;"></script>
          <script type="text/javascript" src="./main.js"></script>
 </head>
 
 <body>
 				<ice:form partialSubmit="true" id="backchannelform">
 					<ice:inputHidden id="backchannelparamvalue" value="#{navi.backChannelParamValue}"></ice:inputHidden>
 				</ice:form>
 </body>
 


the first script loads the swfaddress library,
the second script does some swfaddress configuration (as far as I remember), you can read more info about it in the swfaddress documentation.
the third script is a javascript file with my swfaddress implementation.


here is the intressting part of my backingbean:
Code:
 
 	private String BackChannelParamValue;
 	public void setBackChannelParamValue(String backChannelParamValue)
 	{...}
 
 
 	public void setBrowserAddressBar(String params)
 	{
 		this.lastSentURL = params;
 		//function setAddressBar(url)
 		JavaScript.InvokeJavaScriptFunction("setAddressBar", new Object[]{params});
 	}
 
 


main.js:
Code:
 function setAddressBar(url) 
 {
 	SWFAddress.setValue("?"+url);
 }
 
 function Init()
 {
 	SWFAddress.setHistory(true);
 }
 Init();
 
 function SendURLParameters(params) 
 {
 	//parameter name
 	document.getElementById("backchannelform:backchannelparamvalue").value = params;
 	iceSubmitPartial(document.getElementById("backchannelform"), document.getElementById("backchannelform:backchannelparamvalue"));//MouseEvent.CLICK); 
 }
 
 function handleChange(event) 
 {
 	SendURLParameters(event.value);
 }
 SWFAddress.addEventListener(SWFAddressEvent.CHANGE, handleChange);
 


first the init() function gets called, it will enable the browser back button.

the handleChange() function gets called when the addressbar has been manipulated (for example when the user changes the url, or hits the back button). it calls then the SendURLParameters() function, which sends the new url back to my appserver, using a hiddeninput field.
the url will then be processed by the backing bean which results for example in a change of a facelets dynamic include path.

the setAddressBar() function gets called by my backingbean. it manipulates the addressbar ;-)
for example setAddressBar("humppa"); would add "#?humppa" at the end of the url.



cheers! 


We use spring webflow so It may make it easier. But even without swf

couldn't you do an icePartialSubmit in javascript on a hidden button that is tied to a navigation rule in your facesConfig.

Alternatively, couldn't you get the HttpRequestContext in your backing bean, build an http request, execute it via a javascriptCall, and force a refresh of the view.
[Email]
jmind

Joined: 07/Jul/2008 00:00:00
Messages: 54
Offline


many thanks! i'll work on that

italian coder
michelle2

Joined: 14/Nov/2007 00:00:00
Messages: 449
Offline


jmind wrote:
many thanks! i'll work on that 


function invoketest(argument)
{
document.getElementById("myForm:hiddenData").value = argument;
iceSubmitPartial(document.getElementById("myForm"),document.getElementById("Form:HiddenButton"),MouseEvent.CLICK);
}
</script>
[Email]
 
Forum Index -> General Help
Go to:   
Powered by JForum 2.1.7ice © JForum Team