Select to view content in your preferred language

Function to grab the selection from another widget

3976
25
Jump to solution
05-24-2018 10:32 AM
MartinOwens1
Frequent Contributor

I've created a feature action in eSearch that can open another widget and send the selected featureSet, but I'm having trouble retrieving the selection from the other widget. I'm trying to use the selection from the eSearch wiget as an input for the results of another widget. Any help would be great!

0 Kudos
25 Replies
RobertScheitlin__GISP
MVP Emeritus

Martin,

   How are you attempting to access the "reportFeatures" variable in your other function? It should be accessed as this.reportFeatures.

0 Kudos
MartinOwens1
Frequent Contributor

It's using a vatiable self = this

generateReport: function generateReport() {
      var self = this;
      if (this.reportName.attr('displayedValue') !== '') {
        var generateReports = new GenerateReports({
          config: this.config
        });
        // print the map
        if (this.reportType === 'PDF') {
          domClass.add(this.generateButton, 'disabled');
          this.generateButton.innerHTML = i18n.busyReportText;
          if (this.includeMapCheckBox.checked === true) {
            this._printMap().then(function (printUrl) {
              generateReports.convertImage(printUrl).then(function (mapPrint) {
                generateReports.convertImage(self.config.reportLogo).then(function (base64Img) {
                  generateReports.generateReport(self.reportFeatures, base64Img, self.comments.value, mapPrint, self.reportName.attr('displayedValue')).then(function () {
                    domClass.remove(self.generateButton, 'disabled');
                    self.generateButton.innerHTML = i18n.genReport;
                  });
                });
              });
            });
          } else {
            generateReports.convertImage(self.config.reportLogo).then(function (base64Img) {
              generateReports.generateReport(self.reportFeatures, base64Img, self.comments.value, null, self.reportName.attr('displayedValue')).then(function () {
                domClass.remove(self.generateButton, 'disabled');
                self.generateButton.innerHTML = i18n.genReport;
              });
            });
          }
        } else if (this.reportType === 'CSV') {
          self._exportCsv(self.reportFeatures);
        }
      } else {
        new Message({
          titleLabel: i18n.noNameMessgeTitle,
          message: i18n.noNameMessge
        });
      }
    },

The following code is used to select directly from this widget and it is working how it should:

    _selectFeatures: function _selectFeatures(type, startDate, endDate, geometry) {
      var self = this;

       var symbol = new SimpleMarkerSymbol(this.config.selectionSymbol);
      var addressPtsLayer = this.map.getLayer(this.config.layerId);
      addressPtsLayer.setSelectionSymbol(symbol);
       
    var query = new Query();
      if (!geometry) {
          var aaQuery = '';
      } else {
        query.geometry = geometry;
          array.forEach(this.map.graphicsLayerIds, lang.hitch(this, function(glId){
          var newlayer = this.map.getLayer(glId);
            if(newlayer.name === "Search Results"){
            this.eSearchGraphicsLayer = newlayer;
          }
          }));
       newlayer = this.eSearchGraphicsLayer;
      newlayer.clear();
      }


      query.outFields = ['*'];

      addressPtsLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function (results) {
          
        console.log('selection results from _SELECT Features: ' + results);
        if (results.length > 0) {
          self.reportFeatures = results;
          self.messageNode.innerHTML = '';
          self.messageNode.appendChild(document.createTextNode('Number of selected features: ' + results.length));
          self.generateButtonDiv.style.display = 'block';
          self.generateReportTable.style.display = 'block';
          self.clearButtonDiv.style.display = 'block';
          self.queryButtonDiv.style.display = 'none';
        } else {
          new Message({
            titleLabel: i18n.noMatchingMessge,
            message: i18n.noAddressPointsFound
          });
        }
      }, function (error) {
        console.error('ERROR: ', error);
      });
    },

This issue is the following not working correctly in the generateReport.

getFeatures: function() {
       this.generateButtonDiv.style.display = 'none';
      this.generateReportTable.style.display = 'none';
      this.clearButtonDiv.style.display = 'block';
      this.messageNode.innerHTML = '';
       
       var self = this;

        array.forEach(this.map.graphicsLayerIds, lang.hitch(this, function(layerId) {
          var layer = this.map.getLayer(layerId);
            if (layer.name === "Search Results"){

            addressPtsLayer = layer;

            
         if (addressPtsLayer.graphics.length > 0) {
          self._zoomAndSelectFeatures(addressPtsLayer);
          self.reportFeatures = addressPtsLayer;
          self.messageNode.innerHTML = '';
          self.messageNode.appendChild(document.createTextNode('Number of selected features: ' + addressPtsLayer.graphics.length));
          self.generateButtonDiv.style.display = 'block';
          self.generateReportTable.style.display = 'block';
          self.clearButtonDiv.style.display = 'block';
          self.queryButtonDiv.style.display = 'none';
        }  

   }}));  
},
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Martin,

   Hmm... you are using a mixture of self = this and lang.hitch. If you use lang.hitch you do not use a secondary variable assignment of self = this. 

Use this:

getFeatures: function() {
  this.generateButtonDiv.style.display = 'none';
  this.generateReportTable.style.display = 'none';
  this.clearButtonDiv.style.display = 'block';
  this.messageNode.innerHTML = '';

  array.forEach(this.map.graphicsLayerIds, lang.hitch(this, function(layerId) {
    var layer = this.map.getLayer(layerId);
    if (layer.name === "Search Results"){
      addressPtsLayer = layer;
      if (addressPtsLayer.graphics.length > 0) {
        this._zoomAndSelectFeatures(addressPtsLayer);
        this.reportFeatures = addressPtsLayer;
        this.messageNode.innerHTML = '';
        this.messageNode.appendChild(document.createTextNode('Number of selected features: ' + addressPtsLayer.graphics.length));
        this.generateButtonDiv.style.display = 'block';
        this.generateReportTable.style.display = 'block';
        this.clearButtonDiv.style.display = 'block';
        this.queryButtonDiv.style.display = 'none';
      }  
    }
  }));  
},
      generateReport: function generateReport() {
        if (this.reportName.attr('displayedValue') !== '') {
          var generateReports = new GenerateReports({
            config: this.config
          });
          // print the map
          if (this.reportType === 'PDF') {
            domClass.add(this.generateButton, 'disabled');
            this.generateButton.innerHTML = i18n.busyReportText;
            if (this.includeMapCheckBox.checked === true) {
              this._printMap().then(lang.hitch(this, function (printUrl) {
                generateReports.convertImage(printUrl).then(lang.hitch(this, function (mapPrint) {
                  generateReports.convertImage(this.config.reportLogo).then(lang.hitch(this, function (base64Img) {
                    generateReports.generateReport(this.reportFeatures, base64Img, this.comments.value, mapPrint, this.reportName.attr('displayedValue')).then(lang.hitch(this, function () {
                      domClass.remove(this.generateButton, 'disabled');
                      this.generateButton.innerHTML = i18n.genReport;
                    }));
                  }));
                }));
              }));
            } else {
              generateReports.convertImage(self.config.reportLogo).then(lang.hitch(this, function (base64Img) {
                generateReports.generateReport(this.reportFeatures, base64Img, this.comments.value, null, this.reportName.attr('displayedValue')).then(lang.hitch(this, function () {
                  domClass.remove(self.generateButton, 'disabled');
                  this.generateButton.innerHTML = i18n.genReport;
                }));
              }));
            }
          } else if (this.reportType === 'CSV') {
            this._exportCsv(this.reportFeatures);
          }
        } else {
          new Message({
            titleLabel: i18n.noNameMessgeTitle,
            message: i18n.noNameMessge
          });
        }
      },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
      _selectFeatures: function _selectFeatures(type, startDate, endDate, geometry) {
        var symbol = new SimpleMarkerSymbol(this.config.selectionSymbol);
        var addressPtsLayer = this.map.getLayer(this.config.layerId);
        addressPtsLayer.setSelectionSymbol(symbol);

        var query = new Query();
        if(!geometry) {
          var aaQuery = '';
        } else {
          query.geometry = geometry;
          array.forEach(this.map.graphicsLayerIds, lang.hitch(this, function(glId) {
            var newlayer = this.map.getLayer(glId);
            if(newlayer.name === "Search Results") {
              this.eSearchGraphicsLayer = newlayer;
            }
          }));
          newlayer = this.eSearchGraphicsLayer;
          newlayer.clear();
        }

        query.outFields = ['*'];
        addressPtsLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, lang.hitch(this, function(results) {
          console.log('selection results from _SELECT Features: ' + results);
          if(results.length > 0) {
            this.reportFeatures = results;
            this.messageNode.innerHTML = '';
            this.messageNode.appendChild(document.createTextNode('Number of selected features: ' + results.length));
            this.generateButtonDiv.style.display = 'block';
            this.generateReportTable.style.display = 'block';
            this.clearButtonDiv.style.display = 'block';
            this.queryButtonDiv.style.display = 'none';
          } else {
            new Message({
              titleLabel: i18n.noMatchingMessge,
              message: i18n.noAddressPointsFound
            });
          }
        }), function(error) {
          console.error('ERROR: ', error);
        });
      },
0 Kudos
MartinOwens1
Frequent Contributor

This is definitely cleaner and nicer than using the mix, but for some reason it is still not generating the attributes in the output for the getFeatures function. It finds the graphics updates the nodes and zooms to the features, but that is it. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Martin,

   So in the getFeature function you have line 12 

_zoomAndSelectFeatures

You are saying that it does zoom and select? Where does it fail in that function (since you have not shared that function it is hard for me to help)? What are the errors if any in the browsers web console?

0 Kudos
MartinOwens1
Frequent Contributor

No errors in the console. Is there a way perform a selection of those features based on the "Search Results" feature layer? Kind of the way it does in the _selectFeatures function:

addressPtsLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, lang.hitch(this, function(results)‍‍

As of right now the zoomAndSelect really only zooms. 

_zoomAndSelectFeatures: function (features) {
      this.map.setExtent(graphicsUntils.graphicsExtent(features.graphics), true);
}‍‍‍‍‍‍
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Martin,

   So your codes workflow is still very much a mystery to me. You have the getFeatures that finds the search results layer, zooms to the results, sets the this.reportFeatures and makes some node visible or not... So what fires the generateReport method and is the generateReports.generateReport expecting the this.reportFeatures to have a selection?

0 Kudos
MartinOwens1
Frequent Contributor

That is a great question. This is one of those widgets that I had stumbled across and could see a good use for in our department especially being integrated with your eSearch widget. I've been trying to retro fit this for our needs so things like the mix were already in there. The widget works properly using the selectFeatures function that’s why I asked the previous. I have looked through the code in the widget.js and the generateReport function is never referenced again, so I'm not sure how it is getting fired. It looks like in the GenerateReport.js it takes in "features" to construct the table in the pdf and then in the _constructTable it builds an array of the fields defined in the config file. Thanks a lot for your help btw!

This is from the GenerateReports.js:

    generateReport: function generateReport(features, logo, comments, mapPrint, reportName) {
      var deferred = new Deferred();
      var widget = this;
      var mapImage = {};
      var shouldBreak = '';
      // logic to include a map or not
      if (mapPrint != null) {
        mapImage = {
          image: mapPrint,
          width: 675,
          alignment: 'center'
        };
        shouldBreak = 'after';
      }
      var headers = [];
      var widths = [];
      array.forEach(this.config.pdfReportFields, function (fieldInfo) {
        headers.push(fieldInfo.header);
        widths.push(fieldInfo.width);
      }, this);

      var docDefinition = {
        pageOrientation: 'landscape',
        pageMargins: [18, 50, 18, 40],
        footer: function footer(currentPage, pageCount) {
          return {
            text: currentPage.toString() + ' of ' + pageCount,
            alignment: 'center'
          };
        },
        header: widget._formatHeader(logo),
        content: [{
          table: {
            headerRows: 1,
            dontBreakRows: true,
            widths: widths,
            body: widget._constructTable(headers, features),
          }
        }, {
          text: 'COMMENTS: ' + comments,
          margin: [0, 10, 0, 0],
          pageBreak: shouldBreak
        }, mapImage],
        styles: {
          header: {
            fontSize: 18,
            bold: true
          },
          subheader: {
            fontSize: 15,
            bold: true
          },
          quote: {
            italics: true
          },
          body: {
            fontSize: 6
          },
          tableHeaderOverview: {
            bold: true,
            fontSize: 9,
            color: 'white',
            fillColor: '#4c4c4c'
          }
        }
      };
      pdfMake.createPdf(docDefinition).download(reportName + '.pdf', function () {
        deferred.resolve();
      });
      return deferred.promise;
    },
_constructTable: function _constructTable(headers, addresses) {
      var _this = this;
      var self = this;
      var body = [];
      var headerText = [];
      for (var z = 0; z < headers.length; z++) {
        headerText.push({
          text: headers[z],
          style: 'tableHeaderOverview'
        });
      }
      body.push(headerText);

      var _loop = function _loop() {
        var row = [];
        array.forEach(_this.config.pdfReportFields, function (field) {
          if (field.type === 'string') {
            row.push(addresses[i].attributes[field.fieldName] !== null ? addresses[i].attributes[field.fieldName].toString() : '');
          } else if (field.type === 'date') {
            row.push(addresses[i].attributes[field.fieldName] !== null ? self._formatDate(addresses[i].attributes[field.fieldName]) : '');
          }
        }, self);
        body.push(row);
      };

      for (var i = 0; i < addresses.length; i++) {
        _loop();
      }
      return body;
    },
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Martin,

   So it appears that the generateReport function is expecting a array of graphics and right now you are setting the this.reportFeatures to the whole eSearch FeatureLayer. Make the change on line 13 to your getFeatures function.

getFeatures: function() {
  this.generateButtonDiv.style.display = 'none';
  this.generateReportTable.style.display = 'none';
  this.clearButtonDiv.style.display = 'block';
  this.messageNode.innerHTML = '';

  array.forEach(this.map.graphicsLayerIds, lang.hitch(this, function(layerId) {
    var layer = this.map.getLayer(layerId);
    if (layer.name === "Search Results"){
      addressPtsLayer = layer;
      if (addressPtsLayer.graphics.length > 0) {
        this._zoomAndSelectFeatures(addressPtsLayer);
        this.reportFeatures = addressPtsLayer.graphics;
        this.messageNode.innerHTML = '';
        this.messageNode.appendChild(document.createTextNode('Number of selected features: ' + addressPtsLayer.graphics.length));
        this.generateButtonDiv.style.display = 'block';
        this.generateReportTable.style.display = 'block';
        this.clearButtonDiv.style.display = 'block';
        this.queryButtonDiv.style.display = 'none';
      }  
    }
  }));  
},
0 Kudos
MartinOwens1
Frequent Contributor

This seems really close. It's generating the pdf but not constructing the table. Could the issue lie in using the config fields defined from this widget? In line 16 of the construct table:

array.forEach(_this.config.pdfReportFields
0 Kudos