Select to view content in your preferred language

How to collapse containing ContentPane upon FeatureTable close

4455
6
Jump to solution
12-08-2015 02:39 PM
JeffJacobson
Frequent Contributor

In the Using FeatureTable sample, when the user clicks the close button on the FeatureTable's header, the table collapses but the ContentPane that contains the table does not resize, making it pointless for the user to close the table because they do not gain any extra space for the map.

I have a similar layout and need to know how to resize the content pane when the feature table is closed. I don't see any "table-close" event, so how do I resize the content pane when the user closes the table?

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Jeff,

   Here is a sample of how to do it:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Using FeatureTable</title>
  <link rel="stylesheet" href="http://js.arcgis.com/3.15/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.15/esri/css/esri.css">
  <script src="http://js.arcgis.com/3.15/"></script>

  <style>
    html, body, #map{
      width:100%;
      height:100%;
      margin:0;
      padding:0;
    }
  </style>

  <script>
    var map;

    require([
      "esri/IdentityManager",
      "esri/layers/FeatureLayer",
      "esri/dijit/FeatureTable",
      "esri/geometry/webMercatorUtils",
      "esri/map",
      "dojo/dom-construct",
      "dojo/dom",
      "dojo/dom-style",
      "dojo/dom-class",
      "dojo/dom-geometry",
      "dojo/parser",
      "dojo/ready",
      "dojo/on",
      "dojo/_base/lang",
      "dijit/registry",
      "dijit/form/Button",
      "dijit/layout/ContentPane",
      "dijit/layout/BorderContainer",
      "dijit/form/TextBox"
    ], function (
      IdentityManager, FeatureLayer, FeatureTable, webMercatorUtils, Map,
      domConstruct, dom, domStyle, domClass, domGeometry, parser, ready, on,lang,
      registry, Button, ContentPane, BorderContainer, TextBox
    ) {

      parser.parse();

      ready(function(){

        var myFeatureLayer;
        var map = new Map("map",{
          basemap: "dark-gray"
        });

        map.on("load", loadTable);

        var myButton = new Button({
          label: "Load",
          onClick: loadTable
        }, "loadButton").startup();


        function loadTable(){

          // Create the feature layer
          myFeatureLayer = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Warren_College_Trees/FeatureServer...", {
            mode: FeatureLayer.MODE_ONDEMAND,
            outFields:  ["Collected","Crew","Status","Spp_Code","Cmn_Name","Sci_Name","Street","Native"],
            visible: true,
            id: "fLayer"
          });

          on(myFeatureLayer, "load", function(evt){
            console.log("Layer loaded");
            var extent = myFeatureLayer.fullExtent;
            if (webMercatorUtils.canProject(extent, map)) {
              map.setExtent( webMercatorUtils.project(extent, map) );
            }
          });

          if(registry.byId("myTableNode")){
            registry.byId("myTableNode").destroy();
            domConstruct.create("div", {id: "myTableNode"}, dom.byId("bot"));
            console.log("re-creating table");
          }

          // Add the feature layer to the map
          var oldLayer = map.getLayer("fLayer");
          if(oldLayer){
            map.removeLayer(oldLayer);
          }
          map.addLayer(myFeatureLayer);

          myTable = new FeatureTable({
            "featureLayer" : myFeatureLayer,
            //"dateOptions": {
            //  "timeEnabled" : true,
            //  "timePattern" : "HH:mm:ss",
            //  "datePattern" : "YYYY-MM-DD"
            //},
            "hiddenFields": ["FID","C_Seq","Street"],  // field that end-user can show, but is hidden on startup
            "map" : map
          }, 'myTableNode');

          // load event (must be before startup)
          on(myTable, "load", function(evt){
            console.log("The load event - ", evt);
          });

          myTable.startup();

          on(myTable, "dgrid-refresh-complete", function(evt){
            console.log("The dgrid-refresh-complete event - ", evt);
          });

          on(myTable, "dgrid-select", function(evt){
            console.log("The dgrid-select event - ", evt);
          });

          on(myTable, "dgrid-deselect", function(evt){
            console.log("The dgrid-deselect event - ", evt);
          });

          on(myTable.tableCloseButton, "click", function(evt){
            if(domClass.contains(evt.target, "toggleClosed")){
              console.info("Table is open");
              domStyle.set(registry.byId("botCP").domNode, "height", "50%");
              domStyle.set(registry.byId("mapCP").domNode, "height", "50%");
              registry.byId('mainBC').resize();
            }else{
              console.info("Table is closed");
              domStyle.set(registry.byId("botCP").domNode, "height", "10%");
              domStyle.set(registry.byId("mapCP").domNode, "height", "90%");
              registry.byId('mainBC').resize();
            }
          });
        }
      });
    });
  </script>
</head>

<body class="claro esri">
  <div id="mainBC" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;">
    <div id="mapCP" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:true" style="height:50%">
      <div id="map"></div>
    </div>
    <div id="botCP" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom', splitter:true" style="height:50%">
      <div id="myTableNode"></div>
    </div>
  </div>
</body>

</html>

View solution in original post

6 Replies
RobertScheitlin__GISP
MVP Emeritus

Jeff,

   Here is a sample of how to do it:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Using FeatureTable</title>
  <link rel="stylesheet" href="http://js.arcgis.com/3.15/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.15/esri/css/esri.css">
  <script src="http://js.arcgis.com/3.15/"></script>

  <style>
    html, body, #map{
      width:100%;
      height:100%;
      margin:0;
      padding:0;
    }
  </style>

  <script>
    var map;

    require([
      "esri/IdentityManager",
      "esri/layers/FeatureLayer",
      "esri/dijit/FeatureTable",
      "esri/geometry/webMercatorUtils",
      "esri/map",
      "dojo/dom-construct",
      "dojo/dom",
      "dojo/dom-style",
      "dojo/dom-class",
      "dojo/dom-geometry",
      "dojo/parser",
      "dojo/ready",
      "dojo/on",
      "dojo/_base/lang",
      "dijit/registry",
      "dijit/form/Button",
      "dijit/layout/ContentPane",
      "dijit/layout/BorderContainer",
      "dijit/form/TextBox"
    ], function (
      IdentityManager, FeatureLayer, FeatureTable, webMercatorUtils, Map,
      domConstruct, dom, domStyle, domClass, domGeometry, parser, ready, on,lang,
      registry, Button, ContentPane, BorderContainer, TextBox
    ) {

      parser.parse();

      ready(function(){

        var myFeatureLayer;
        var map = new Map("map",{
          basemap: "dark-gray"
        });

        map.on("load", loadTable);

        var myButton = new Button({
          label: "Load",
          onClick: loadTable
        }, "loadButton").startup();


        function loadTable(){

          // Create the feature layer
          myFeatureLayer = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Warren_College_Trees/FeatureServer...", {
            mode: FeatureLayer.MODE_ONDEMAND,
            outFields:  ["Collected","Crew","Status","Spp_Code","Cmn_Name","Sci_Name","Street","Native"],
            visible: true,
            id: "fLayer"
          });

          on(myFeatureLayer, "load", function(evt){
            console.log("Layer loaded");
            var extent = myFeatureLayer.fullExtent;
            if (webMercatorUtils.canProject(extent, map)) {
              map.setExtent( webMercatorUtils.project(extent, map) );
            }
          });

          if(registry.byId("myTableNode")){
            registry.byId("myTableNode").destroy();
            domConstruct.create("div", {id: "myTableNode"}, dom.byId("bot"));
            console.log("re-creating table");
          }

          // Add the feature layer to the map
          var oldLayer = map.getLayer("fLayer");
          if(oldLayer){
            map.removeLayer(oldLayer);
          }
          map.addLayer(myFeatureLayer);

          myTable = new FeatureTable({
            "featureLayer" : myFeatureLayer,
            //"dateOptions": {
            //  "timeEnabled" : true,
            //  "timePattern" : "HH:mm:ss",
            //  "datePattern" : "YYYY-MM-DD"
            //},
            "hiddenFields": ["FID","C_Seq","Street"],  // field that end-user can show, but is hidden on startup
            "map" : map
          }, 'myTableNode');

          // load event (must be before startup)
          on(myTable, "load", function(evt){
            console.log("The load event - ", evt);
          });

          myTable.startup();

          on(myTable, "dgrid-refresh-complete", function(evt){
            console.log("The dgrid-refresh-complete event - ", evt);
          });

          on(myTable, "dgrid-select", function(evt){
            console.log("The dgrid-select event - ", evt);
          });

          on(myTable, "dgrid-deselect", function(evt){
            console.log("The dgrid-deselect event - ", evt);
          });

          on(myTable.tableCloseButton, "click", function(evt){
            if(domClass.contains(evt.target, "toggleClosed")){
              console.info("Table is open");
              domStyle.set(registry.byId("botCP").domNode, "height", "50%");
              domStyle.set(registry.byId("mapCP").domNode, "height", "50%");
              registry.byId('mainBC').resize();
            }else{
              console.info("Table is closed");
              domStyle.set(registry.byId("botCP").domNode, "height", "10%");
              domStyle.set(registry.byId("mapCP").domNode, "height", "90%");
              registry.byId('mainBC').resize();
            }
          });
        }
      });
    });
  </script>
</head>

<body class="claro esri">
  <div id="mainBC" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;">
    <div id="mapCP" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:true" style="height:50%">
      <div id="map"></div>
    </div>
    <div id="botCP" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom', splitter:true" style="height:50%">
      <div id="myTableNode"></div>
    </div>
  </div>
</body>

</html>
JeffJacobson
Frequent Contributor

Thanks!

0 Kudos
JeffJacobson
Frequent Contributor

I created a Plunk that demonstrates this.

Below is the code that changes the size of the pane when the FeatureTable's close button is clicked. It is modified from Robert Scheitlin, GISP​'s sample in the following ways.

  • Whenever possible, using native methods instead dojo-specific equivalents.
  • When resizing the table pane, closed height is based on the height of the table's "grid menu" (the part that is still visible when the table is collapsed). Before resizing the table pane, the current height is stored in a data- attribute. When the table is re-opened, the new height is retrieved from the data- attribute.

  // resize panel when table close is toggled.
  table.tableCloseButton.addEventListener("click", function(e) {
    var gridMenuNode = registry.byId(table._gridMenu).domNode;
    var tableNode = registry.byId("tablePane").domNode;
    var borderContainer = registry.byId("borderContainer");
    var isOpening = e.target.classList.contains("toggleClosed");
    if (isOpening) {
      tableNode.style.height = tableNode.dataset.openHeight || "50%";
    } else {
      // Store the old height.
      tableNode.dataset.openHeight = tableNode.style.height || [tableNode.clientHeight, "px"].join("");
      // Set to "closed" height.
      tableNode.style.height = [gridMenuNode.clientHeight, "px"].join("");
    }
    borderContainer.resize();
  });
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jeff,

   This is the second time I have seen you post about using native methods instead of dojo. I am curious to know why you think this is important. You are using the JS API with loads Dojo and Dojo has spend alot of time ensuring that their classes are supported across a large range of browsers (new and old) i.e. cross browser compatible. And not all the native methods you are using are supported by older browsers liek inline style. So what is your basis for not using Dojo-specific?

0 Kudos
JeffJacobson
Frequent Contributor

It’s mainly just personal preference. I am more familiar with the native DOM manipulation than I am with the Dojo equivalents. I then use polyfills to handle browsers that don’t support these methods.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jeff,

   OK, just seems like learning the dojo methods would be beneficial to you as you would not need to polyfill.

0 Kudos