Pages

Sunday, December 20, 2009

Tapestry 5 and Javascript

Ok, I'm not a web designer. The only web framework that I've ever learn was tapestry. So when i try to make something and that something is related to web scripting, javascript or css, I'm lost. But i can't let that happened all the time, that is a necessary skill for me to complete my side project. Because of that reasone I'm spending this long weekend to know javascript in Tapestry 5 a little better.

Since my side project is building something with google maps, i find that there are 3 kind of javascript that i need to handel in my page. First external javascript, my google maps library that reside in another webserver. Second my javascript library, javascript code that will be used in many pages. And the third is the javascript for my current page.

Isn't the first and second type can be consider as one ? Unfortunately no, from the perspective of the page they both are external javascript. But currently there are no way to treat the external javascript from google like javascript library in Tapestry 5.

My Story


Okay, since I'm a bit slow picking up new things. So I created my page the old way. I put everything in the template (.tml) file. Luckily it worked, the map from google shows and I've managed to create some polygon above it. Doing this required me to have :

a link to google maps javascript library
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=xxxxx" type="text/javascript"></script>

my own link
<script type="text/javascript" src="${asset:context:js/mapeditor.js}" charset="utf-8"></script>

and my own javascript for current page
<script type="text/javascript">
// tapestry aware vars
var latLng = ${getArea()};
<!-- //
// used for only initialization and invoke method in js lib,
// while other js lib will be added using addScript command in the java file
// lets keep the template clean
var map = null;
var gmarkers = [];
var other_polygon = [];

function initialize() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(-2.1088986592431254, 117.158203125), 5);
showPolygon(latLng);
}
}

// -->
</script>

This worked !

The Other way
Now I'm trying to do it the right way, in this case the Tapestry 5 way. As i understand you can add external library so it will render in the top of your page by using renderSupport addScriptLink method. But unfortunately this method cannot add the external Javascript from google, so i leave the google javascript library in the template file.

While i've managed to move my library to the java file, so the template would look clean. I understand moving the current page to the render support is also possible, but composing the javascript into a string using StringBuffer is a pain :(. And i don't see the real benefit anyway. Because as long as you keep the page javascript clean, only for initialization, its okay to leave it on the template page.

Anyway one of tapestry strong point is to separate coding and UI design. And sometimes the UI designer uncomfortable when they doesn't know the behaviour of the page. If you move all of the script to the java class. And that would break their design tool WYSWYG and also force them to understand the java class.

PS : I understand one more things writing this blog. Writing code in blogger is pain, because you need to < , > sign to the appropriate mark-up your self.

2 comments:

Ángel said...

Hi!
I´m working with GMaps, javascript adn tapestry5, but I can´t view my page because there is an error. The problem is when I put my own javascript for current page in the template (.tml) file.
Do you have any additional code in *java?
Thanks

B said...

Hi angel,

I'm having a few problem my self inserting javascript in the .tml file, but i guess that's my skill limitation.

My suggestion is you should try to show it in ordinary html page first. See if it works, just initialize it using dummy data.

Another thing, i'm facing a problem when the javascript in the .tml file contains less than and more than character, like for looping. My solution was to separate the method that use it itu a .js file then include it as a library in the original .tml file.