My first bit of Mootools and centering a Google Map in a hidden div

Note: This post is over a year old and the content may no longer be accurate.

Started a new job last week for a really cool agency in a place I really want to work* – but they are Mootools users not jQuery folk, so I am been thrown headlong into (among other things) the world of Mootools. I’m used to just sitting down and being able to make things work quickly and painlessly with jQuery and it is funny being back to basics again. Today I wrote my first useful bit of Mootools code, which in the grand scheme of things is nothing – just a nice fading toggle to show and hide a Google Map – but it still felt good.

Along the way I had to ran into a problem with my map – when I showed it the centre-ing was gone – I tried all sorts of things… map.checkResize() didn’t work and map.setCenter() didn’t work.

Eventually I deduced that first you actually need to call both functions – reset, then centre e.g.

 
    map.checkResize();
    map.setCenter(new GLatLng(51.90568, -1.33214));

Along my way I have found a great article comparing jQuery and Mootools – which I would recommend to anyone going either way.

*But it is a kind of a personal philosophy not to ever say on my blog where I do work, just because. I’ve taken over a big project running on a Cloud server written by a load of other people, the sort of thing that is hard but very rewarding.
** I have no idea where those coordinates are. Maybe Up North somewhere?

Posting data from a popup back into TinyMCE

Note: This post is over a year old and the content may no longer be accurate.

Recently I’ve spent a long time playing around with WYMeditor a jQuery based text editor for websites. Its really interesting and I’m glad I was able to devote quite a lot of time to playing about with it, but unfortunately at the end of the day we decided it just wasn’t mature enough for our needs, so looking around I settled on TinyMCE and have been working with that.

In some ways the main problem with something like TinyMCE is the shear number of options available, but once you strip it back there is a great tool there. The trick is to find that balance between giving users the a useful feature set but stopping short of giving them the power to destroy that carefully crafted website design and throw any measure of accessibility out of the window in the process.

TinyMCE has got quite straightforward plugin architecture that seems to work well and and is fairly easy to trace through and debug and hack about and the inline popups plugin is a real winner Рpopups in windows are just so pass̩e.

Of course being in a terrible rush I decided at against writing (or hacking) a full blown plugin and instead decided to just load a window (containing our custom file / image manager) and then return data and insert it back. My quick and dirty solution works well, but it does contain what I can only really describe as a bit of brute force cheating (and if somebody can suggest an alternative I would really appreciate it).

My TinyMCE setup is straight forward, I am using TinyMCE on its recommended path (/js/tiny_mce/tiny_mce.js) and I am also using jQuery.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">
 
tinyMCE.init({
	mode : "textareas",
	theme : "advanced",
	editor_selector : "cms_editor",
	theme_advanced_toolbar_location : "top",
	plugins : "inlinepopups,safari",
	theme_advanced_buttons1 : "bold,italic,styleselect,formatselect,removeformat,link,unlink",
	theme_advanced_buttons2 : "",
	theme_advanced_buttons3 : "",
	theme_advanced_toolbar_align : "left",
	theme_advanced_statusbar_location : "bottom",
	content_css : "/css/editor.css",
	relative_urls : false,
	remove_script_host : true,
	document_base_url : "/",
});
 
 
</script>

Digging about I soon found the example of adding a custom button to the editor tool bar that inserts some HTML http://tinymce.moxiecode.com/examples/example_20.php and just modified this so my new init function now changes to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
<script type="text/javascript">
 
var my_editor = null;
 
 
tinyMCE.init({
	mode : "textareas",
	theme : "advanced",
	editor_selector : "cms_editor",
	theme_advanced_toolbar_location : "top",
	plugins : "inlinepopups,safari",
	theme_advanced_buttons1 : "bold,italic,styleselect,formatselect,removeformat,link,unlink,image_button", 
        // image_button is my new button
	theme_advanced_buttons2 : "",
	theme_advanced_buttons3 : "",
	theme_advanced_toolbar_align : "left",
	theme_advanced_statusbar_location : "bottom",
	content_css : "/css/editor.css",
	relative_urls : false,
	remove_script_host : true,
	document_base_url : "/",
 
 
 
    setup : function(ed) {
 
        my_editor = ed;
 
        // Add a custom button
        ed.addButton('image_button', {
            title : 'Insert an Image',
            image : '/img/mce_image.gif', // icon for the button link
            class : 'mce_image', // add a class to the button link
            onclick : function() {
 
            tinyMCE.activeEditor.windowManager.open(
            		{file: '/admin/uploads/image_browser', width : 920, height : 560, inline : true}
 
            	); 
            }
        });
 
    }
});
</script>

The above function just adds a button image_button to the toolbar and adds a click event to this button. The click event just loads a page into (containing my custom browser) into an inline popup.

In the example on the moxiecode website, if you look at the source you will see that the onclick just adds some content at the cursor, ed being a reference to the editor instance.

1
2
 
ed.selection.setContent('<strong>Hello world!</strong>');

In my modified function the first thing I do is save a reference to the instance in a global variable my_editor, this is so we can refer to it latter and insert the data back.

As this whole escapade is just a quick and dirty way of getting data back into the editor without going through the proper plugin route, the my image_browser can just be considered as a black box. The important thing is that it returns a string of HTML for example <img src=”/uploads/images/image.xgh46.jpg” width=”200″ height=”100″ title=”some image” alt=”some-image” class=”float-right” />

The only thing of importance in my Image Browser is the following piece of code:

1
2
3
4
5
6
7
8
 
$(document).ready(function(){ 
 
	$('#submit-button').click(function(){
 
		parent.insert_data(str);
	});		
});

Simply adding a click event to a submit button and then calling the function insert_data() in the parent window (containing the editor) and passing my string of HTML to it.

The final piece of the puzzle is this simple function:

1
2
3
4
5
6
7
8
9
10
11
12
 
function insert_data(data){
 
 
	$('.clearlooks2').remove();
	$('#mceModalBlocker').remove();
 
	my_editor.selection.setContent(data);
 
 
 
}

We have access to the editor instance via the my_editor variable we created when we added the button to the toolbar and with this we can insert the data at the selection.

I had one problem, I can’t for the life of me figure out how to close / destroy the overlay. In the end I had to resort to brute force and just zapped it with a bit of jQuery magic, .clearlooks2 and #mceModalBlocker being the popup and the overlay respectively. If anybody knows a more elegant solution, please let me know.

When Google Maps go bad…

Note: This post is over a year old and the content may no longer be accurate.

This week I noticed that a number of google maps had stopped working out of the blue, not dying in a spectacular javascript car crash, just a subdued failure and no map.

Looking in Firefox error console I see G_MAP_TYPE is not defined; – WTF? it was working…

Well looking into it, it is an easy fix. It seems that a lot of people (myself included) have been using depreceated constant names for the maps types, and that there will be quite a few Javascript Plugins (for things like jQuery) that may need updating.

The usual (i.e. correct) types we should now be using now are:

Old Constant name New Constant Name Description
G_MAP_TYPE G_NORMAL_MAP This map type (which is the default) displays a normal street map.
G_SATELLITE_TYPE G_SATELLITE_MAP This map type displays satellite images.
G_HYBRID_TYPE G_HYBRID_MAP This map type displays a transparent layer of major streets on satellite images.
  G_PHYSICAL_MAP

This map type displays maps with physical features such as terrain and vegetation. This map type is not displayed within map type controls by default. (Since 2.94)

See: http://code.google.com/apis/maps/documentation/reference.html#GMapType

For a bit of an actual explanation I found this post on Google Groups