Select to view content in your preferred language

Need simple example: add tabs to widget

7847
57
Jump to solution
01-19-2018 08:44 AM
JamesCrandall
MVP Frequent Contributor

LaunchPad theme

WABDev 2.5

Custom Widget

I'm looking for the simplest, most straight forward example of adding 2 tabs to a new widget (an absolute vanilla panel).  THIS thread seemed to be close but I'm not seeing the expected result (no CSS example?). 

Looking for the most basic form of HTML, JS and CSS to get this implemented.

TIA

0 Kudos
57 Replies
JamesCrandall
MVP Frequent Contributor

That did it Robert.  Thanks a million for taking the time on this.

0 Kudos
by Anonymous User
Not applicable

I added a Tab to Robert's Elevation Profile tool to explain to our end users how it measures and where the data come from ...   Georgia Coastal Hazards Portal   Basically I'd already worked out his example above, by looking at how he created the first two tabs already in the widget.  It's a great way to add an 'About' with some details to a widget! I created this a while back in 2.4 but seems to be the same still.

in Widget.js....

 _initTabContainer: function () {var tabs = [];         
tabs.push({title: this.nls.measurelabel,           
content: this.tabNode1});         
tabs.push({           
title: this.nls.resultslabel,           
content: this.tabNode2});         
tabs.push({             
title: this.nls.aboutlabel,             
content: this.tabNode3});         
this.selTab = this.nls.measurelabel;         
this.tabContainer = new TabContainer({           
tabs: tabs,           
selected: this.selTab}, 
this.tabMain);

And widget.html...

<div class="${baseClass} profile-tab-node" data-dojo-attach-point="tabNode3">
<div style="padding-top:8px;">
<div>
<span>
<b>To create an Elevation Profile follow these steps.</b> <br> <br> 1. Click the Measure button. <br> <br> 2. Click a starting location on the screen. <br> <br> 3. Click again on additional locations on the map to measure to. Double-click to set the ending location. To simply create a straight line profile, single-click the left mouse button for the starting location, and then double-click the left mouse button for the ending of the profile line. You may choose distance units. The elevation profile generated is based on the National Elevation Dataset as documented in the following links. <br> <br> <a href="https://nationalmap.gov/elevation.html" target="_blank">US National Map - Elevation</a><br /> <br> <a href="http://www.arcgis.com/home/item.html?id=3300cfc33ca74a9fac69d2e0f4ea46e5" target="_blank">Elevation Profile Calculation </a><br /><br> <a href="http://www.arcgis.com/home/item.html?id=0383ba18906149e3bd2a0975a0afdb8e" target="_blank">Ground Surface Elevation 30m</a>
</span>
</div>
<div data-dojo-attach-point="_aboutNode"></div>
</div>
</div>

And a few strings like the title as defined in nls  - strings.js  

///for example...//   aboutlabel: "About",

JamesCrandall
MVP Frequent Contributor

Excellent!

JamesCrandall
MVP Frequent Contributor

From Roberts excellent simplified example, I cannot seem to identify what I've done wrong.  Getting error: "Unexpected token (" on the  _initTabContainer: function() and running out of things to try.

define(['dojo/_base/declare',
  'dijit/_WidgetsInTemplateMixin',
  'jimu/BaseWidget',
  'jimu/dijit/TabContainer',
  'jimu/utils',
  'dojo/_base/lang',
  'dojo/on'
    ],
 function(declare,
  _WidgetsInTemplateMixin,
  BaseWidget,
  TabContainer,
  utils,
  lang,
  on) {
  return declare([_WidgetsInTemplateMixin, BaseWidget]), {
   postCreate: function() {
    this._initTabContainer();
    _initTabContainer: function() {
     var tabs = [];
     tabs.push({
      title: 'Tab 1',
      content: this.tabNode1
     });
     tabs.push({
      title: 'Tab 2',
      content: this.tabNode2
     });
     this.selTab = 'Tab 1';
     this.tabContainer = new TabContainer({
      tabs: tabs,
      selected: this.selTab
     }, this.tabIdentify);
     this.tabContainer.startup();
     this.own(on(this.tabContainer, 'tabChanged', lang.hitch(this, function(title) {
      if (title !== 'Tab 1') {
       //do something now that Tab 2 has been selected
      }
     })));
     utils.setVerticalCenter(this.tabContainer.domNode);
    };
  };
 }
  });
0 Kudos
KenBuja
MVP Esteemed Contributor

You inserted the function into the postCreate function. It should look like this

  postCreate: function() {    
    this._initTabContainer();
  },

  _initTabContainer: function() {‍‍‍‍‍
JamesCrandall
MVP Frequent Contributor

Thank you, Ken!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

James,

  Go back to this post:

https://community.esri.com/thread/208243-need-simple-example-add-tabs-to-widget#comment-744000 

and get that updated code to use as I fixed your syntax in that thread post.

Arne_Gelfert
Frequent Contributor

Ken Buja, Robert Scheitlin, GISP --  Folks, this isn't an active thread but it was tremendously helpful. (Funny thing is I started with the same London-Paris-Tokyo example first.)

I'm working on a widget that includes a 3-step workflow that is to span three (3) tab in the widget's main panel. So Ken's first example above, after some renaming of elements, worked like a charm. But I'd like to conditionally constrain when tabs become selectable. They should show up in the ribbon right from the start but you shouldn't be able to select tab 2 unless you've done your thing in tab 1.

No luck yet making this work with CSS rules or something more clunky like:

on(this.tab,'tabChanged',lang.hitch(this,function(title){
        if(title == "Tab2" || title == "Tab3"){
          
          //If I knew how to select a tab, I could force it back
          // to Tab1 unless all conditions are met
          
   }
}));‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

What's the best approach here?

0 Kudos
Arne_Gelfert
Frequent Contributor

NO luck with that... this is what I' doing ...

var step1Tab, step2Tab, step3Tab, tabs;
 step1Tab = {
   title: "Step 1",
   content: this.step1Node
 };
 step2Tab = {
   title: "Step 2",
   disabled : true,
   content: this.step2Node
 };
 step3Tab = {
   title: "Step 3",
   disabled: true,
   content: this.step3Node
 };

 tabs = [step1Tab, step2Tab, step3Tab];

 this.tabCT = new TabContainer({
 tabs: tabs
 }, this.tabDiv);

 
 this.tabCT.startup();
         

HTML

 <div class="esriCTTabDiv" data-dojo-attach-point="tabDiv" data-dojo-type="dijit/layout/TabContainer">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-attach-point="step1" class="esriCTTabNode" id="step1"></div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-attach-point="step2" class="esriCTFullHeight esriCTTabNode" id="step2"></div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-attach-point="step3" class="esriCTFullHeight esriCTTabNode" id="step3" ></div>
 </div>

So far so good. This works great. I get three tabs that are div's that I can populate with content... text, button, whatever...

But how do I make Step 2 and Step 3 "unselectable", and how do activate them via some event handler when some condition is met after some Step 1 action has taken place?

My suspicion is that I'm getting the programmatic and declarative wires crossed because I'm having issues getting references using registry.byId(). 

0 Kudos