Techblog

Tech Blog

Our latest geek adventures!

Archive for the ‘Javascript’ Category

6 November Drag’n'drop from HTML to Flash

Last week we released a new Floorplanner account, the Enterprise account. With it, companies can have an online Floorplanner solution completely branded to their wishes. It includes the Roomplanner module and a custom library of their own furniture elements.  Steelcase and Maxon are the first to have an active Enterprise account.

The interesting part of this release, from a tech point of view, is the new drag-and-drop functionality. The Roomplanner is running in the Flash Player. However, the library of furniture elements is in HTML. We chose to build the furniture library in the HTML sidebar for a couple of reasons. It’s not in the Roomplanner, so there is more space left to design. It gives us more freedom in the page layout. All items on the page are indexed and things like sorting and tags we’re easier to build in Ruby on Rails than in Flash.

Now we only needed a way to get the furniture from the sidebar to the Roomplanner. That’s where the drag’n'drop comes in, drag from HTML and drop in Flash. To drag an image of a furniture element in HTML we used the fantastic JavaScript script.aculo.us framework. The next step was to swap the image to an element in the Roomplanner and to update the position of the element while moving the cursor on the Flash content. For this we used ExternalInterface to communicate between JavaScript and ActionScript. That’s all there is to it. The theory is actually quite simple, but in practice it was very (I repeat, VERY) difficult to get it working in all the main browsers. All those nitty gritty browser details…

At this moment everything seems to work just fine, so please take a look at Steelcase and/or Maxon and let me know what you think!

2 Comments - Tags: , , , , , ,

16 July Using setInterval in a JavaScript class

Posted by Gert-Jan in Javascript

I just figured out how to use setInterval in a JavaScript class. This little snippet shows how I used setInterval in a recursive way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function MyClass() {}
 
MyClass.prototype.doNext = function( pArray ) {
	clearInterval( this.interval );
 
	if( pArray.length > 0 ) {
		// do something with the array record
		this.doSomething( pArray.pop() );
 
		// call this function again in a couple of milliseconds
		var scope = this;
		var milliseconds = 100;
		this.interval = setInterval( function(){ scope.doNext( pArray ) }, milliseconds );
	} 
} 
 
MyClass.prototype.doSomething = function( pRecord ) {
	// do something
}
 
var myObj = new MyClass();
myObj.doNext( myArray );

No Comments - Tags: ,

7 May Mousewheel events in Flash on OS X

The Flash Player on OS X currently lacks support for mousewheel events. This means that users cannot use their mousewheel on OS X, in the Floorplanner we use the mousewheel to easily zoom in to your Floorplan. After reading this post from pixelbreaker, I was inspired to implement this in the Floorplanner which was, in fact, very easy. I decided to only use the JavaScript class of pixelbreaker, which sends the mousewheel events to the Flash Player (on the Mac). In the Floorplanner ActionScript this event is handled by our own internal Event management system, which sends the Event to the reponsible part of the code. So thumbs up for pixelbreaker, for making this really easy to implement!

No Comments -

15 April JSON Validator

I’m currently working on a JSON export from the Floorplanner and I’m glad I found the excelent JSON Validator made by arc90 lab. They made the debugging process a lot easier. Thanks guys!

No Comments -

2 April Consume SOAP web service from Javascript

I wanted to get some data from a web service using Javascript. I looked at several Javascript classes (like this), but because the web service was running on another server it got a little troublesome. As a solution I tried to call the web service through a proxy, but that didn’t make it any easier.

Jaap suggested to take a look at NuSOAP, a -kinda old- SOAP toolkit for PHP. With an AJAX request I could call a PHP page that uses NuSOAP to consume the web service. It was actually easier then I thought it would be.

To make the AJAX call from Javascript I used Prototype and this script:

  function doRequest() {
    var url = "ajax/consume_webservice.php";
    var param1 = "value1";
    var param2 = "value2";
    var params = "param1="+ param1 +"&param2="+ param2;
 
    new Ajax.Request ( url, { method: 'POST', parameters: params,
      onComplete: onResult } );
  }
 
  function onResult( result ) {
    alert( result.responseText );
  }

The PHP file consume.php looks something like this:

< ?php
 
  $param1 = isset( $POST_['param1'] ) ? $POST_['param1'] : false;
  $param2 = isset( $POST_['param2'] ) ? $POST_['param2'] : false;
 
  // this is the only file I used from the NuSOAP project
  require_once( "nusoap.php" );
 
  $url = webserviceurl;
  $params = array( "param1" => $param1, "param2" => $param2 );
 
  $soap = new nusoap_client( $url, true, false, false, false, false, 0, 60 );
  $proxy = $soap->getProxy();
  $proxy->functionname( $params );
 
  echo $proxy->response;
 
?>

That’s all. Do a AJAX request from Javascript to a PHP page. Then the PHP page uses NuSOAP to consume the web service and returns the result. Back in Javascript you can do whatever you want with the given data.

No Comments - Tags: , , ,

28 March Rounding errors in practice

In college I followed a course in numerical analysis. The main point of the course was to be careful with floating point arithmetic, because it is vulnerable to rounding errors that can significantly influence the result of complex computations. Until yesterday I never had encountered such a problem. Now that I have lost my innocence in this matter, I would like to share my tale of nasty debugging and frustration.

After receiving some bug reports of Floorplanner designs that failed to save properly, we dove into the code to see what was going wrong. After some time, we found that the errors were caused by the script that loads the design after it has been saved with a unique name. This unique name is passed to the script to be able to find the design. We used the current timestamp as a unique name for the design. The current timestamp simply is the number of seconds passed since January 1, 1970 and looks something like this: 1206712028. As a design name, this number was passed to different scripts, both client-side and server-side. However, at some point in this chain of scripts, the number was changed slightly to 1206712030 and because of this the associated design could not be found, resulting in an error.

At first, we investigated the possibility that the stored timestamp was overwritten by a newer timestamp, as this could explain the slight increase in the number. However, we were not able to find this anywhere in the code and sometimes, the number was decreased a bit instead of being increased.

Finally, we monitored the data being sent between the different scripts, and we found that ActionScript automatically converted the numeric design name into a number in scientific notation. In our case, this would be 0.1206712028 x 10^10. Unfortunately, this number was rounded to 0.120671203 x 10^10 because computers use floating point arithmetic to store numbers in scientific notation. This number would eventually be converted back to normal notation, but it was now 1206712030 because of the rounding error.

We fixed it by putting an ‘a’ in front of the timestamp, preventing the automatic conversion to a number. Not very elegant, but it works!

No Comments -

25 March Encoding UTF-8 in Javascript

Posted by Gert-Jan in Javascript

I had to make a call from Javascript to a SOAP web service (more on that later). The data I had to send to the web service was in a XML format that contained non ASCII characters (for example: é). I tried to use the standard escape() function, but that one couldn’t handle the special characters.

Thanks to ecmanaut I found a very simple solution: encodeURIComponent() (with decodeURIComponent() as its counterpart).

No Comments -

14 February Javascript & XML

Posted by Gert-Jan in Javascript

Recently I’ve been working with Javascript in combination with XML and I found these methods quite usefull to switch between a string and a xml object.

function stringToXML( pString ){
	var lXML;
	// IE
	if( window.ActiveXObject ){
		lXML = new ActiveXObject( 'Microsoft.XMLDOM' );
		lXML.async = 'false';
		lXML.loadXML( pString );
	// no IE
	} else {
		var lParser = new DOMParser();
		lXML = lParser.parseFromString( pString, 'text/xml' );
	}
	return lXML;
}

function xmlToString( pXML ){
	// IE
	if( window.ActiveXObject ){
		return pXML.xml;
	// no IE
	} else {
		return ( new XMLSerializer() ).serializeToString( pXML );
	}
}

No Comments -

25 January Swfobject is only the messenger

In my previous post I thought that swfobject was causing the wmode=transparent problem in IE. However, I was wrong. Folkert told me that swfobject only passes the parameter to the Flash Player, swfobject is only the messenger.

Instead of wmode=transparent I also tried wmode=opaque as Jorrit suggested, but it didn’t make a difference. I set up three wmode sample pages to test the issue:

When you’re viewing the transparent and the opaque page in Internet Explorer you can see that editing the walls is quite difficult. You can also see that panning the design results in a strange elastic movement. I hope to find a solution soon….

Update
I’ve been reading this post and it looks like it’s something we have to live with…

SWFs using wmode actually perform slightly different from SWFs that have a default wmode. The difference is that when you are running as transparent or opaque, events are delayed until an onEnterFrame. If you are running at a slow frame rate and drive your movie with setInterval or use any number of other events, you are back to your slow frame rate. The real kicker is that SWFs in IE have this bug. SWFs in Firefox are just fine.

2 Comments -

17 January Flash trouble caused by SWFObject

Last week we accidentally introduced a nasty bug into the Floorplanner Flash app. Well, actually it wasn’t the Flash app that caused the problem. It appeared to be a weird issue in swfobject.

We wanted to layer some html content over the Flash app, so we added this line to the JavaScript:

swfObject.addParam( "wmode", "transparent" );

By doing that, the Flash app started acting really strange in Internet Explorer (6&7). I removed the line today and all seems fine again…

3 Comments -