Archive for the ‘Web Development’ Category

Javascript Video Lessons

Thursday, April 9th, 2009

If you’re looking for some good videos to learn javascript I suggest Douglas Crockford’s videos on YUI Theatre. Doug Crockford is the guy who ‘discovered’ JSON(whatever that means) and is the technical lead for YUI. I’ve mentioned him before…

How to change size of infoWindow in Google Map with API

Friday, March 27th, 2009

I ran into a problem the other day when trying to resize the ‘infoWindow’ on a Google Map. The infoWindow is the bubble that appears on the map, usually above a pin-marker when you click on it. Google’s own map has this behavior.

As usual, my solution requires some YUI components. I think you’ll just need the selector module and the core.

The problem I was running into, was that Google provides no way for the infoWindow to be resized. The easiest thing would have been for google to add CSS classes onto all the divs that make up the infoWindow but for some reason, they haven’t provided this and you need to jump through hoops if you really want to resize it. Typically, it seems that people would like to shrink the height because, for some reason, google will not resize it any lower than about 60px, even if the content is much small. In my case, I had only two lines in the infoWindow and a bunch of ugly whitespace below.

You can use the infoWindow.reset method, but the first three parameters are actually required despite what the API seems to imply.

“Resets the state of the info window. Each argument may be null and then
its value will not be changed from the current value.”

This is WRONG. Only the last two arguments are options, which you can tell by the ‘?’ in the method signature on the left.

“reset(latlng:GLatLng, tabs:GInfoWindowTab[], size:GSize, offset?:GSize, selectedTab?:Number)”

If you got this far, then perhaps you might have tried showing the infoWindow and then resetting it to the size you wanted, however, this will only work if you put your call to the reset method into the onOpenFn of the infoWindowOptions. It seems that when the info window is shown it is animated and then resized itself, so if you call the reset method directly after calling openInfoWindow it will animate and then resize AFTER your reset has already done your resizing… However, even this will not let you make the infoWindow’s height any smaller than about 60 px as I mentioned above, don’t worry though, we’ll get there!

Code to resize the infoWindow TALLER than 60px:

var infoWindow = map.getInfoWindow();
var point = new GLatLng(0,0);
var marker = new GMarker(point);
GEvent.bind(marker,”click”,marker,function() {
map.openInfoWindowHtml(this.getPoint(),this.address,{onOpenFn:function(){
infoWindow.reset(this.getPoint(),infoWindow.getTabs(),new GSize(200,200),null,null);
}});
});

If you want ot make the infoWindow SMALLER, then the reset method will not work! Why? No one knows… There’s probably a hard-coded minimum height somewhere in google’s code but their documentation doesn’t seem to mention it anywhere.

The infoWindow is made from a handful of divs that are absolutely positioned in the appropriate places. These divs are for the 4 corners and the top, bottom and middle, sorta like a tic-tac-toe board but with one div for the middle row. By manipulating all these div’s style.top appropriately and the height of the middle div, we can actually shrink the infoWindow despite Google API’s best effort to get in our way!

Code to resize infoWindow with a small height:

var infoWindow = map.getInfoWindow();
var point = new GLatLng(0,0);
var marker = new GMarker(point);
GEvent.bind(marker,”click”,{marker:marker,address:address},function() {
map.openInfoWindowHtml(this.marker.getPoint(),this.address,{onOpenFn:function(){
/* Google Maps API does not support any way to resize the infoWindow, this is my hack.
* There is no CSS class to manipulate these divs and the infoWindow.reset method
* CAN be used to increase the size but not to make it smaller.(min height is about 60px).
*/
var infoWindowBlocks = YAHOO.util.Selector.query(’#area-map-tool div div div div’);
for(var c = 0; c < infoWindowBlocks.length; c++){
if(infoWindowBlocks[c].style.height === "40px" && infoWindowBlocks[c].style.top === "25px"){
infoWindowBlocks[c].style.height = "10px";
}
if(infoWindowBlocks[c].style.top === "65px"){
infoWindowBlocks[c].style.top = "35px"
}
}
}});
});

Be sure to change the css selector to the appropriate id of the div that contains your map! mine was area-map-tool!

I have not tested this EXACT code but will hopefully get a demo working here soon. Please let me know if you find any problems!
Cheers!

“this compilation unit is not on the build path of a java project”

Friday, March 13th, 2009

This was an error i got with intellisense/autocompletion in Eclipse. The project needs to be a “Java Project” and not a “Project”, this can be done by doing a new checkout of the code from the “SVN Repositories” view and selecting the project “Wizard” when prompted. I could not find any other way from within Eclipse to create a Java Project and also retrieve the code from SVN/CVS. I suppose you could create a new project and then copy over the appropriate files, but I don’t know if eclipse-svn is smart enough to handle this.

How to add comments to Wordpress homepage

Tuesday, December 30th, 2008

So, I use Wordpress.  I don’t like Wordpress at all, but I used it at my last job so I got some experience with it and that means that it was easier to just use it and deal with the consequences later.  I wouldn’t recommend it to another developer though, the codebase is truly hideous.

I recently wanted to add comments to my homepage.  I only like to make changes to my template and not to change any Wordpress “core code”, since then I’ll have to make all those changes everytime I update Wordpress.  I didn’t think this policy would be a problem for me this time since all I was trying to do was add the ‘comments template’ to the homepage and I thought that I should be able to just copy the appropriate line from my ’single.php’ into my ‘homepage.php’…  Wrong!   How any ‘non-technical’ person manages to use wordpress is beyond me…

Anyhow, I did some digging and found the problem.  The function comments_template in comment-template.php has these lines:

if ( ! (is_single() || is_page() || $withcomments) )
return;

I’m not going to go into the reason why these lines are harmful but I’ll just say that my argument might be summed up as “hard coded configuration”.  Anyway, these lines in homepage.php will get you what you want:

$withcomments = true;
comments_template();

Or, if you want to be a smartass like myself, this will work too:

$withcomments = “I hate wordpress”;
comments_template();

Cheers!

Stylizing text input elements with background images

Saturday, October 11th, 2008

I often like to add background images to my text input elements, it’s a great way to stylize them and adds a nice little pop to small forms. The search box in the upper right corner of this blog is an example of this. I recently wrote this nice little javascript function to help me get this done quickly and easily.

Feel free to use this code wherever you please, it requires the prototype javascript library.  There’s an example of the usage at the bottom.

crabenda.global.giveTextInputBackground = (function(){
handleFocus = function(e){
elem = Event.element(e);
elem.setStyle({’background’: ‘none’});
}
handleBlur = function(e){
elem = Event.element(e);
if(elem.value === ”){
elem.setStyle({’background’: ‘url(’+elem.backgroundImgSrc+’) no-repeat’});
}
}
return function(formElem,imgSrc){
formElem = $(formElem);
if(formElem){
formElem.backgroundImgSrc = imgSrc;
Event.observe(formElem,’focus’,handleFocus);
Event.observe(formElem,’blur’,handleBlur);
if(formElem.value === ”){
formElem.setStyle({’background’: ‘url(’+formElem.backgroundImgSrc+’) no-repeat’});
}
}
}
})();

Sample usage:

document.observe(”dom:loaded”,function(){
Event.observe(’submitbutton’,'click’,crabenda.header.submitButtonClickHandler);/search3.gif’)
});

If any of the code looks odd(like maybe the parentheses before and after the function) then you need to watch more Douglas Crockford!
Cheers!

How to initialize a remote Git repository

Wednesday, September 24th, 2008

Well, since it took me all day to figure this out again, I figured I might as well write it down somewhere so that at least I’ll be able to remember it the next time I want to create a new repo with Git.

The one thing that irks me is that I always try to create a bare repo on the server and then clone it to my client.  For some reason git doesn’t want to work this way even though that’s what my intuition tells me.

Anyway, the way to do it is to first create your working copy.  I’m making a little website so I have some code in /www/my-working-copy.  After you have some code that you want in the repo, you need to initialize a git repository and add your code to it like so:

git init
git add .

After that’s done, you want to go your git-daemon’s base path and clone this repo there with a bare copy:

cd /my-git-daemon-base-path && git clone –bare /www/my-working-copy my-remote-repo

You should get a message like “Initialized empty Git repository in /my-git-daemon-base-path/my-remote-repo/” after which you may need to run update-server-info and you’ll also want to add a ‘git-daemon-export-ok’ file to the repo so that the daemon knows that it is okay to export it:

git update-server-info
cd /my-git-daemon-base-path/my-remote-repo && touch git-daemon-export-ok

At this point you also will most likely want to add a ‘tracked repository’ named ‘origin’ to your working copy so that git will know where you want to push and pull from:

cd /www/my-working-copy && git remote add origin /my-git-daemon-base-path/my-remote-repo

That’s it!  To test it out simply try a commit:

git commit -a

You should receive a message “nothing to commit (working directory clean)”.

At this point you probably want to push your changes to the repo.  Although the repo is created, it won’t be very useful until there’s something in it:

git push origin master

Cheers!

Form Validation using Prototype(no return false): How to cancel an event

Saturday, September 13th, 2008

I remember getting lost a few times back when I first started using Prototype. I was trying to implement some form validation, which is pretty easy with prototype, but ‘old habits’ were getting in my way. Coming from ‘plain old javascript’, I was accustomed to using ‘return false;’ to cancel a form submission, but when you’re trying to separate form from function(and thats really the whole point of events), you don’t necessarily want to put javascript into your html. e.g.:

<form onsubmit=’return myValidator();’>

First of all, it’s ugly. More importantly though, it mixes your javascript and your html, if you want to rename your validator function you now have to dip into the HTML code(which should probably live in a different file)… ew, divs. Since you’re using prototype you should be using prototype’s event management. Here’s a sample:

<form id=”myForm”…>

$(’myForm’).observe(’submit’, doValidation);
function doValidation(event) {
//do validation here
}

And, in order to stop the form from submitting you would use Prototype’s Event library again:

myEvent.stop();

This stops the submission event from ‘bubbling up(or down)’ to the Document Object and being submitted. This is our ‘return false;’

Putting it all together we get something like this:

<form id=”myForm”…>
<input id=”email”

$(’myForm’).observe(’submit’, doValidation);
function doValidation(submissionEvent) {
if($(’email’) && !(/^.+@.+\..+/.exec($(’email’).value))){
//not valid, let the user know.
submissionEvent.stop();
}
//do more validation here
}

..and there was much rejoicing. Our HTML and and javascript are separate, our lives are easier. Our new code also makes it clear that form submissions are actually events and that our validation function is a handler for that event.
Cheers!

Apparenly Ryan Campbell wrote on the same subject back in 2006, he claimed that Event.stop() didn’t work in Safari but as far as I know that’s no longer true.
Prototype’s api entry for event.stop.