views:

819

answers:

2

I have been trying to wrap my head around this one, and a lot of tutorials and sites have been suggesting the creation of a separate event object, which seems to be a bit of overkill for just implementing one function to happen at some point in the object.

Basically I want to have a custom "onComplete" event to fire when certain methods are called within the object being used. I have an GMaps control object that is toggled on or off. When on it allows manipulation of polylines on the map, but when turned off it disables the manipulation, at which point I would like the polyline data to be stored. What I am attempting to do is allow users of the object to create their own event to listen for the turned off event, and allow them to access the polyline data from that object. How can I do that?

This is my code thus far:

function ToggleLineDrawControl() {}

ToggleLineDrawControl.prototype = new GControl();

ToggleLineDrawControl.prototype._on = false;

ToggleLineDrawControl.prototype._button = false;

ToggleLineDrawControl.prototype._map = false;

ToggleLineDrawControl.prototype._overlay = false;

ToggleLineDrawControl.prototype._plots = [];

ToggleLineDrawControl.prototype._line = false;

ToggleLineDrawControl.prototype._addPlotListener = false;

ToggleLineDrawControl.prototype._onComplete = false;

ToggleLineDrawControl.prototype.initialize = function(map) {
this._map = map;

var me = this;

var container = document.createElement('div');

var buttonDiv = document.createElement('div');
this._button = buttonDiv;
this.setButtonStyle_();
container.appendChild(this._button);
this._button.appendChild(document.createTextNode('Plot'));

GEvent.addDomListener(this._button, 'click', function() {
 if(!this._on) {
  this.style.backgroundColor = '#333333';
  this.style.color = 'white';
  this.firstChild.nodeValue = 'Done';

  me.startPlotting();

  this._on = true;
 } else {
  this.style.backgroundColor = 'white';
  this.style.color = '#333333';
  this.firstChild.nodeValue = 'Plot'

  me.stopPlotting();

  this._on = false;
 }
});

this._map.getContainer().appendChild(container);

return container;
 };

 ToggleLineDrawControl.prototype.getDefaultPosition = function() {
     return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 57));
 };

 ToggleLineDrawControl.prototype.setButtonStyle_ = function() {
     this._button.style.textDecoration = 'none';
     this._button.style.color = '#333333';
     this._button.style.backgroundColor = 'white';
     this._button.style.font = 'small Arial';
     this._button.style.border = '1px solid black';
     this._button.style.padding = '2px';
     this._button.style.marginBottom = '3px';
     this._button.style.textAlign = 'center';
     this._button.style.width = '5em';
     this._button.style.cursor = 'pointer';
 };

 ToggleLineDrawControl.prototype.setPlot = function(latlng) {
     var wicon = new GIcon();
    wicon.image = 'http://www.site.com/images/waypoint2.png';
    wicon.iconSize = new GSize(32, 32);
    wicon.iconAnchor = new GPoint(8, 28);

    var marker = new GMarker(latlng, {icon: wicon});

    this._map.addOverlay(marker);

    this._plots.push(latlng);

    this.drawLines();
 };

 ToggleLineDrawControl.prototype.drawLines = function() {
     var numPlots = this._plots.length;

     if(this._line != false) {
           this._map.removeOverlay(this._line);
     }

     if(numPlots > 1) {
      this._line = new GPolyline(this._plots, '#cc0000', 2, 0.75);

      this._map.addOverlay(this._line);
     }
 }

 ToggleLineDrawControl.prototype.startPlotting = function() {
     var me = this;

     this._addPlotListener = GEvent.addListener(this._map, 'click', function(o, l, ol) {
      me.setPlot(l);
     });
 };

 ToggleLineDrawControl.prototype.stopPlotting = function() {
     GEvent.removeListener(this._addPlotListener);
 };

 ToggleLineDrawControl.prototype.onComplete = function(callback) {
     this._onComplete = callback // get this to somehow be listener event method
 };
A: 

You may want to move your onComplete function near the top as that is what you seem to be asking about.

But, I don't understand the flow.

If I use your library, and I want to pass in a function, as the event handler, for onComplete, you store it in a prototype variable (this._onComplete), so each object only has one callback function.

Where is this ever being called?

Once you finish you should be calling the callback, passing in the object as a parameter: if (this._onComplete != false this._onComplete(this);

James Black
James,Thanks for your response. Sorry, to confuse things, but that onComplete() method and its use in the object I lazily left unfinished, because I didn't know where to take it. IN the usage of this object, I want to declare it, then assign a custom method to use the scope of the object, in order to be used at a time that another one of the object's methods are being used. My initial thought was running the custom method once a method like stopPlotting() was run.
qualsh
A: 

Ok solved it with a bit of help from a former colleague. Sometimes you just need to step out of your own head, and ask the right person. Anyhow, James was right in that I was not even calling the method in the first place. So, a colleague of mine suggested creating a reference to the custom function in the main object function as an option:

function ToggleLineDrawControl(options) {
     this._onComplete = options.onComplete;
}

... and in the stopPlotting() method, where I want this method to get called:

ToggleLineDrawControl.prototype.stopPlotting = function() {
     ...
     this._onComplete(this);
};

Works like a charm

qualsh