Login Register

Trying to create Menus in my own Widget

I created my own widget which is a panel with a button that activates a menu.

dojo.widget.defineWidget("myapp.widget.Colleator", dojo.widget.HtmlWidget, {
    widgetsInTemplate: true,
    templatePath: "path_to_file_and_contents_below"
...

And the template looks like this:

<div dojoType="ContentPane">
    <div dojoType="Button">Actions...</div>
    <div dojoType="PopupMenu2" widgetId="refreshMenu">
        <div dojoType="MenuItem2" caption="Refresh"></div>
        <div dojoType="MenuItem2" caption="Stop"></div>
        <div dojoType="MenuItem2" caption="Advanced" submenuId="refreshAdvancedMenu"></div>
    </div>
    <div dojoType="PopupMenu2" widgetId="refreshAdvancedMenu">
        <div dojoType="MenuItem2" caption="Force Stop"></div>
        <div dojoType="MenuItem2" caption="Send Error Report"></div>
    </div>
</div>

And I have some code to make the button open "refreshMenu". But then it occured to me, if someone uses my widget more than once. i.e.,

<div dojoType="Colleator">test</div>
<div dojoType="Colleator">test2</div>

Then it won't work because I used the same widgetId for the menus, and widgetIds are the only way of linking a submenu with a menu. How can I fix this? Because I don't think it's possible to set the widgetId randomly inside my template file, right?

You could try using

You could try using ${this.widgetId} in your template... Dojo assigns unique values if you dont specify a widgetId... Not sure how that will work for the subWidgets though since I dont think the current widget Object has a way of returning their widgetId like that...

-Karl

Thanks, Karl. At first I

Thanks, Karl. At first I didn't understand what you were saying and thought you misunderstood my question, so I started looking for another solution. Then as I was looking through the DomWidget.js code, I noticed the string substitution thing and then thought I could generate a unique id on initialization and assign it to "this.string['uid']=Math.random()" and then in the templates use an "id='${uid}_refreshMenu'" attribute to give it a unique id. Then I started looking around for a function which would be run before the string substitution so that I could override it. Then I thought, wait my widget will get a unique id generated for it on startup anyways so I could do "id='${this.widgetId}_refreshMenu'" then I tried it out and it worked! Then I thought, hey wait, didn't I get exactly the same suggestion in the forum the other day? So I came back here and sure enough you were suggesting the exact same solution!

Here is my final code:

<div dojoType="DropDownButton" menuId="${this.widgetId}_refreshMenu">Actions...</div>
<div dojoType="PopupMenu2" widgetId="${this.widgetId}_refreshMenu">
<div dojoType="MenuItem2" caption="Advanced" submenuId="${this.widgetId}_refreshAdvancedMenu"></div>
</div>
<div dojoType="PopupMenu2" widgetId="${this.widgetId}_refreshAdvancedMenu">
<div dojoType="MenuItem2" caption="Force Stop"></div>
</div>

Cool, glad it worked

Cool, glad it worked out!

-Karl

Please explain how the ${this.widgetId} works

I am trying to use this to let the HTML template assign the id (as you showed above). THEN, I want to retrieve this generated id in javascript.
I create a form with an HTML template like this:

Then in java script, in dojo.addOnLoad(), I write:

itemForm = document.getElementsByTagName('form');
alert("itemForm.id is : " + itemForm[0].id);

It displays in the alert window --> itemForm.id is ${this.widgetId}

I'm confused

When dojo parses template

When dojo parses template files, it replaces ${this.varname} with the value of yourWidget.varname.... so ${this.widgetId} inserts the widgetId assigned to that widget into the template where that is put in...

-Karl

Please see my editted comment

I added a code example. I try to see the value of the widgetId, in an alert, but all I see is ${this.widgetId}

Well yah...

This is not a template file... this is a skeleton, ie. Markup used to create a widget... if you do templateString="" and inserted a serialized version of the template in there and used ${this.widgetId} then you would see a result...

-Karl

Here is a form sample - how best to use templateString?

It would be a great help if you could indicate the best way to incorporate the templateString into my form sample below. I actually include this form in a ContentPane with the ContentPane.setUrl() function. I tried using the createWidget() function to create the form, and included the entire form's HTML in the templateString, but then the other dojo widgets within the form do not behave correctly.


Item Form


        var djConfig = {isDebug: true};
        //djConfig.debugAtAllCosts = true;




 dojo.require("dojo.widget.*");
 dojo.require("dojo.widget.Form");
 dojo.require("dojo.widget.LayoutContainer");
 dojo.require("dojo.widget.ContentPane");
 dojo.require("dojo.widget.ComboBox");
 dojo.require("dojo.widget.Checkbox");
 dojo.require("dojo.widget.DropdownDatePicker");
 //dojo.hostenv.writeIncludes();
 var obj = null;
 var bo;
 var itemForm;
 var itemType;
 var inventoriedcb;
 var boOrig = null;
 
 dojo.addOnLoad(function(){
 	itemForm = document.getElementsByTagName('form');
 	alert("this form is : " + itemForm[0]);
 	alert("this.id is : " + itemForm[0].id);
 });




Item Maintenance - Test

Item Descriptiontext Item Type Manufactured Purchased Service Date Added Inventoried Safety Stock

Thank for your help, and for taking a look at this example.

Randy

writing vs. using dojo widgets

Rdennisj,
${this.widgetId}, and for that matter any form of string substitution using the ${} syntax, will only work if and only if you are writing your own widgets. This is distinct from just using dojo widgets somewhere on your webpage. A telltale sign that you are writing a widget is that you have written the following class-construction code:

dojo.declare("my.widget.Colleator", null, {
    templateString: "<div>This is an instance of Colleator</div>",
    initialize: function() {}
});

The way dojo works is that when you use a widget (i.e., initialize a new instance of my.widget.Colleator()) using the markup:

<div dojoType="my:Colleator"></div>

dojo will take the text inside the "templateString" variable of your class-construction code, deserialize it into a DOM node, and insert it into your markup. That is what happens behind the scenes when you use any widget.

In addition to deserializing the string, dojo will also perform a string substitution step, which is just a search and replace on the "templateString" for /\$\{([^}]+)\}/ prior to insertion into the markup. What I did was take advantage of this step to insert a unique string into the serialized form of my HTML before it got deserialized.

None of this pertains to

None of this pertains to TemplateString... thats your PAGE... Template's are under widget/templates/*.html... thats where you would get the contents for your template string if you want to override the widget template. OR you can just edit the html file and "make your own" template out of it...

By the way... thread hi-jacking is not really acceptable...

-Karl

Apologies for the unintended thread 'hi-jacking'

I did try to ask these questions in the Dijit forum on 5/25 at 12:51, but got no responses. It was not my intent to divert the above discussion. I saw references to this.widgetId, and was just trying to move forward.

Thanks again