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!
Solved! Go to Solution.
Martin,
How are you attempting to access the "reportFeatures" variable in your other function? It should be accessed as this.reportFeatures.
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';
}
}}));
},
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);
});
},
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.
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?
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);
}
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?
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;
},
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';
}
}
}));
},
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