Lee
Lee

Reputation: 5936

Javascript - Dojo - Object reference to itself

I am using the Dojo JS framework 1.6 to declare and track custom classes. I want to use these classes to create reusable functionality such as user edit dialogue box and so on..

The problem is however when using a method inside the class to create a dojo html type button for example. If that button then needs to call a method back within the class, it doesn't know the instantiated variable to call..

How would i get stage2 to reference this instance of the class without hard coding the object name?

Example Class:

dojo.provide('edit.contacts');
dojo._hasResource["edit.contacts"] = true;

dojo.declare("edit.contacts", null,
{
   /*
   *     Init
   */
   init   : function(customer_id)
   {
      var out = ''
      +'<button dojoType="dijit.form.Button" onClick="stage2();" />Edit</button>'
      +'';

      // Create the dlg box
      var edit_contacts_dlg = new dijit.Dialog(
      {
         title    : 'New Diag',
         style    : 'width:550px; height:600px;background:#FFFFFF;',
         id       : 'edit_contacts_dlg',
         content  : out
      }).show();
   },

   /*
   *     Stage 2
   */
   stage2   :  function()
   {
      alert('halllo');
   }
}

Example Usage:

Upvotes: 1

Views: 869

Answers (2)

phusick
phusick

Reputation: 7352

It's a problem of scope. You will always face this kind of problem when mixing JS and HTML to create nodes or widgets. You need a reference to the instance of the button widget in the moment you're calling init() method, which you don't have because you used HTML and dojo.parser to create the button. Basically, you have three ways out:

  1. Create the button programmatically and give it the onClick either directly or via a dojo.connect. This is very flexible since you can literally pass any function, using any variables in scope, to the onclick.

    var out = new dijit.form.Button({
        label: 'Edit',
        onClick: dojo.hitch(this, 'stage2')
    });
    var edit_contacts_dlg = new dijit.Dialog({
        title    : 'New Diag',
        style    : 'width:550px; height:600px;background:#FFFFFF;',
        id       : 'edit_contacts_dlg_' + uniqueId,
        content  : out
    }).show();
    
  2. Generate unique id for each instance of edit.contants class and insert it into your html string. Then obtain the instance of the button via dijit.byId() and do the above mentioned connect:

    var out = '<button dojoType="dijit.form.Button" id="' + uniqueId + '">Edit</button>';
    var edit_contacts_dlg = new dijit.Dialog({
        title    : 'New Diag',
        style    : 'width:550px; height:600px;background:#FFFFFF;',
        id       : 'edit_contacts_dlg_' + uniqueId,
        content  : out
    }).show();
    var btn = dijit.byId(uniqueId);
    dojo.connect(btn, "onClick", this, "stage2");
    
  3. Create class based on dijit._Widget and dijit._Templated, i.e. widget, and use its data-dojo-attach-point feature to obtain button instance (see it in action at jsFiddle):

    dojo.require("dijit._Widget");
    dojo.require("dijit._Templated");
    dojo.require("dijit.Dialog");
    dojo.require("dijit.form.Button");
    
    dojo.ready(function() {
    
        dojo.declare("edit.ContactTemplate", [dijit._Widget, dijit._Templated], {
            templateString: '<div><button data-dojo-type="dijit.form.Button" data-dojo-attach-point="editBtn">Edit</button></div>',
            widgetsInTemplate: true    
        }) 
    
        dojo.declare("edit.contacts", null, {
    
            init: function(customerId) {
                this.customerId = customerId;
    
                var widget = new edit.ContactTemplate();
                dojo.connect(widget.editBtn, "onClick", this, "stage2");
    
                this.editContactDlg = new dijit.Dialog({
                    title    : "Dialog: " + customerId,
                    style    : "width:200px;height:80px;background:#FFFFFF;",
                    id       : "edit_contacts_dlg_" + customerId,
                    content  : widget
                });
    
                this.editContactDlg.show();
                return this;
            },
    
            stage2:  function() {
                alert(this.customerId);
            }
        });
    
        var c1 = new edit.contacts().init("customer #1");
        var c2 = new edit.contacts().init("customer #2");
    });
    

This is useful when you need a reference to many widgets/nodes.

Upvotes: 5

Ian Link
Ian Link

Reputation: 686

I don't really use Dojo, but I tried out a few things. It looks like you can use This just as you would normally. Try out this demo: http://jsfiddle.net/dSpsr/11/

Upvotes: 1

Related Questions