English 中文(简体)
Dojo Tabs as Custom Widgets
原标题:
  • 时间:2009-11-11 21:37:27
  •  标签:
  • dojo
  • widget

I ve created a number of widgets that are loaded as tab panes in a tabcontainer. Everything seems to work well, except I m getting different results when using my custom widgets vs. creating everything in markup (tab content isn t taking up the whole page, 3rd party widgets aren t behaving properly, etc). This all leads me to think that I might not be creating my widgets correctly. The trick seems to be that they are not interpreted as contentpanes.

I am using dojo 1.3.2.

The following markup, for example, works great:

<body class="soria" style="overflow-y: hidden;">
    <!-- Container for whole page -->
    <div dojoType="dijit.layout.BorderContainer" design="headline" id="borderContainer" style="height:100%;width:100%;">
        <!-- Header container -->
        <div dojoType="dijit.layout.ContentPane" region="top">
            Title
        </div>
        <!-- Left side -->
        <!--<div dojoType="dijit.layout.ContentPane" region="left" id="addressContainer" splitter="true" style="width:100%; background-color: #F0F8FF;">-->
        <div dojoType="dijit.layout.ContentPane" region="left" id="addressContainer" splitter="true">
            <div style="text-align: center;">
                <!-- address -->
                <span id="addressInstructions">Address Contents</span>
            </div>
        </div>
        <!-- Tabs -->
        <div dojoType="dijit.layout.TabContainer" id="tabs" region="center" tabPosition="top">
            <div dojoType="dijit.layout.ContentPane" id="tab1" title="map">
                <p>Change map to:</p>
                <div id="divMapList"></div>
                <div style="padding: 10px 10px 10px 10px;">
                    <div id="divMap" dojoAttachPoint="divMap" style="width:300px;height:300px;border:1px solid #000;display:block;margin-left:auto;margin-right:auto;"></div>
                </div>
            </div>
            <div dojoType="dijit.layout.ContentPane" id="tab2" title="other">
                Some text in here.
            </div>
        </div>
    </div>
</body>

Looking at the resulting HTML code, I can see that the tab itself has the following class: "dijitContentPane dijitTabPane dijitTabContainerTop-child dijitTabContainerTop-dijitContentPane dijitVisible".

Below is the HTML of one of my custom widgets:

<div>
    <div style="text-align: center; padding: 5px 5px 5px 5px;">
        <div>${i18nStrings.mapChangeMap}:</div>
        <div dojoAttachPoint="divMapSelection"></div>
        <div style="padding: 10px 10px 10px 10px;">
            <div id="divMap" dojoAttachPoint="divMap" style="width:300px;height:300px;border:1px solid #000;display:block;margin-left:auto;margin-right:auto;"></div>
        </div>
    </div>

And here is part of the custom widget JS (I can provide more code if necessary):

dojo.declare("xxxx.Widget.Map", [dijit._Widget, dijit._Templated],
{
    //Specify the path of the HTML file that sets the look of the widget
    templatePath: dojo.moduleUrl("xxxx", "widget/templates/Map.html"),

    //The strings used to populate standard text. Populated in postMixInProperties
    i18nStrings: null,

    //The widget s root div identifier. Value overwritten in postMixInProperties
    id:"tabMap",

    //The tab s title. Value overwritten in postMixInProperties
    title: "",

    //True to activate the tab. False otherwise.
    activate: false,

    //The map & current layer
    map: null,
    currentLayer: null,

    //Sets up some basic properties
    postMixInProperties: function() {
        this.inherited(arguments);
        var _1 = dojo.i18n.getLocalization("dijit", "loading", this.lang);
        this.loadingMessage = dojo.string.substitute(this.loadingMessage, _1);
        this.errorMessage = dojo.string.substitute(this.errorMessage, _1);
        if (!this.href && this.srcNodeRef && this.srcNodeRef.innerHTML) {
            this.isLoaded = true;
        }
        this.i18nStrings = dojo.i18n.getLocalization("IndyVIP","applicationStrings");
        this.title = this.i18nStrings.mapTabTitle;
    },
</div>

I am adding the widget to the container by creating the widget, then adding it as a child to the tabcontainer.

This results in the following class assigned to my tab: "dijitTabPane dijitTabContainerTop-child dijitVisible".

Does anyone know what I am doing wrong?

Thank you!

Emmster

UPDATE: I have decided to try inheriting from dijit.layout.ContentPane & dijit._Templated. I am still having problems with that though, the main one being that if I add my widget to a TabContainer, I get the error "node is null" on line 4467 of dojo.js.uncompressed.js, but the tab seems to work just fine IF it s the active tab starting out. If I add the widget to a page that only contains the widget, it works fine without errors.

See the code below that gives me the expected results, but causes that one "node is null" error. HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Test</title>
    <script type="text/javascript">
        var djConfig = {
            parseOnLoad: true,
            useXDomain: true,
            debugAtAllCosts: true,
            baseUrl:  ./ ,
            modulePaths: {IndyVIP:  js }
        };
    </script>
    <link rel="Stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/1.5/js/dojo/dijit/themes/soria/soria.css" />
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=1.5"></script>
    <script type="text/javascript">
        dojo.require("dojo.parser");
        dojo.require("dijit.layout.BorderContainer");
        dojo.require("dijit.layout.ContentPane");
        dojo.require("dijit.layout.TabContainer");
        dojo.require("IndyVIP.Widget.Map");
        dojo.addOnLoad(init);
        function init() {
            var tab = new IndyVIP.Widget.Map({title:  Map });
            var tabContainer = dijit.byId( tabs );
            tabContainer.addChild(tab);
        }
    </script>
</head>
<body class="soria" style="overflow-y: hidden;">
    <!-- Container for whole page -->
    <div dojoType="dijit.layout.BorderContainer" design="headline" id="borderContainer" style="height:100%;width:100%;">
        <!-- Header container -->
        <div dojoType="dijit.layout.ContentPane" region="top">
            Title
        </div>
        <!-- Left side -->
        <div dojoType="dijit.layout.ContentPane" region="left" id="addressContainer" splitter="true">
            <div style="text-align: center;">
                <!-- address -->
                <span id="addressInstructions">Address Contents</span>
            </div>
        </div>
        <!-- Tabs-->
        <div dojoType="dijit.layout.TabContainer" id="tabs" region="center" tabPosition="top">
            <!-- uncommenting the following results in map not acting the way it should -->
            <!--
            <div dojoType="dijit.layout.ContentPane" id="tab2" title="other">
                Some text in here.
            </div>-->
        </div>
    </div>
</body>
</html>

Map.js:

dojo.provide("IndyVIP.Widget.Map");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit._Templated");
dojo.require("dijit._Widget");

dojo.declare("IndyVIP.Widget.Map", [dijit.layout.ContentPane, dijit._Templated],
{
    map: null,

    //Specify the path of the HTML file that sets the look of the widget
    templatePath: dojo.moduleUrl("IndyVIP", "widget/templates/Map.html"),

    //The tab s title. Value overwritten in postMixInProperties
    title: "",

    widgetsInTemplate: true,

    startup: function() {
        this.map = new esri.Map( divMap );
        dojo.connect(this.map,  onLayerAdd , this, this.onLayerAdd);
        var layer = new esri.layers.ArcGISTiledMapServiceLayer( http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer );
        this.map.addLayer(layer);
    },

    onLayerAdd: function() {
        //Create symbol
        var lineColor = new dojo.Color( black );
        var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID,lineColor,1);
        var pointColor = new dojo.Color( red );
        var pointSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE,12,lineSymbol,pointColor);

        //Create point
        var x = 4.92;
        var y = 50.625;
        var point = new esri.geometry.Point(x,y,this.map.spatialReference);

        //Create template
        var template = new esri.InfoTemplate( A title , Some content );

        //Create graphic
        var graphic = new esri.Graphic(point,pointSymbol,null,template);

        //Add graphic to map
        this.map.graphics.clear();
        this.map.graphics.add(graphic);
    }

});

And finally, here s the widget s HTML template:

<div>
    <div id="divMap" dojoAttachPoint="divMap" style="width:300px;height:300px;border:1px solid #000;display:block;margin-left:auto;margin-right:auto;"></div>
</div>

I very much appreciate all of your suggestions so far. I feel like I am missing something elementary, but I can t quite figure it out.

Emmster

问题回答

The issue I was having when inheriting from dijit.layout.ContentPane was that my top div in my widget template did not specify dojoAttachPoint="containerNode". Doing this took care of the "node is null" error I was getting. I am still having issues with the map not behaving properly, but this seems related to the tab not being visible initially as dante hinted.

UPDATE: The other error I was having (the map not acting as it should) was due to the widget s template HTML having items above the map in the widget HTML as in my first example above (map.html). In the second example I provided, I took that extra stuff out, and that fixes the problem.

Inheriting from the ContentPane and having dojoAttachPoint="containerNode" on the root node seems to be mandatory for the tabs. This helped me to resolve a similar issue.





相关问题
Javascript drop down menu widget

I have a menu consisting of an <ul> in a Web CMS. I want several menu items to have sub-items that are displayed in a dropdown list. These sub-items are <ul>s as well. This is basically ...

placing widget in listbox/dropdown in gwt

i am using gwt to build my web site. i would like to create a dropdown/listbox that contains no just text but also images, meaning that in the drop down there will be a what ever widget that ill ...

Share & Embed Widget design samples?

I am searching for some sample interface or design for creating a "Share & Embed Widget or Link" interface in my website. I found scribd.com s interface interesting http://www.scribd.com/doc/...

Marketshare of cross-platform widget libraries?

For a variety of reasons, we re in the market for a cross-platform widget library. We re in the somewhat rare situation of not being tied to a particular programming language at this stage, so we get ...

Dojo Tabs as Custom Widgets

I ve created a number of widgets that are loaded as tab panes in a tabcontainer. Everything seems to work well, except I m getting different results when using my custom widgets vs. creating ...

google chat web client

I am looking for a google chat client that I can embed in my website so visitors can chat with me directly. I haven t found any widgets like the google voice widget in which a visitor is connected ...

Hiding a QWidget on a QToolbar?

I have directly added some QWidgets to a QToolbar but simply going widget->setVisible(false) did not work. Can someone please give me an example of how to show and hide a widget that is on a QToolbar? ...

热门标签