Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select by attribute for newly added layers #3

Open
khibma opened this issue Nov 22, 2018 · 6 comments
Open

Select by attribute for newly added layers #3

khibma opened this issue Nov 22, 2018 · 6 comments

Comments

@khibma
Copy link

khibma commented Nov 22, 2018

Hi, excellent widget, thank you! I'm putting together an app that also includes the Add Data widget and it appears your widget doesn't auto-update if new layers are added to the app. Simply, for your reference, here is the approach I've taken with your code to handle the situation. The changes are way too much to make a PR. I've migrated code out of idWebMapLayers.js and into widget.js as well as a bunch of linting changes. If you or someone else finds it useful, great! If not, no problems!

Thanks again

`
define([//Dojo
'dojo/_base/declare',
'dojo/_base/lang',
'dojo/dom-construct',
'dojo/dom-style',
'dojo/Deferred',
'dojo/dom',
'dojo/_base/html',
//Jimu
'jimu/BaseWidget',
'jimu/dijit/LoadingShelter',
'jimu/SelectionManager',
'jimu/dijit/Message',
//Dijit
'dijit/dijit',
'dijit/form/Select',
'dijit/form/Button',
//Esri
'esri/tasks/query',
'esri/tasks/QueryTask',
//Files
'xstyle/css!./files/bootstrap.min.css',
'./files/jquery-3.3.1.min',
'./files/bootstrap.min',
//domReady!
'dojo/domReady!'
],
function(declare, lang, domConstruct, domStyle, Deferred, dom, html, BaseWidget, LoadingShelter,
SelectionManager, Message, dijit, Select, Button, Query, QueryTask) {

return declare([BaseWidget], {

shelter: null,
layerName: null,
layer: null,
field: null,
url: null,
uniqueValue: null,
ese: null,
selectedField: null,
selectionManager: SelectionManager.getInstance(),

startup: function(){
this.layerChooserNodeID = "layerChooserNodeEvent";
this.inherited(arguments);
this._setWidgetSize();
this._initLoadingShelter();
this._initLayerChooser();
this._initButtons();

// Listen for new layers and add them to query options
this.map.on("layer-add-result", lang.hitch(this, function(l) {
console.log("a layer was added ");
var selectLayer = dijit.byId(this.layerChooserNodeID);
selectLayer.addOption(this._makeLayerOption(this.folderUrl, [l.layer], "*"));
}));

// Listen for layers being removed and update query list
this.map.on("layer-remove", lang.hitch(this, function(l) {
console.log("a layer was removed ");
var selectLayer = dijit.byId(this.layerChooserNodeID);
var lid = l.layer.id;

for(var i=0; i < selectLayer.options.length; i++){
    if (selectLayer.options[i].value === lid){
        selectLayer.removeOption(i);
    }
}

}));

},

_setWidgetSize: function(){
var panel = this.getPanel();
panel.position.height = 550;
//panel.setPosition(panel.position);
panel.panelManager.normalizePanel(panel);
},

_initLoadingShelter: function(){
this.shelter = new LoadingShelter({
hidden: false
});
this.shelter.placeAt(this.loadingNode);
this.shelter.startup();
this.shelter.hide();
},

_createLayerSelect: function(id, layerNode, map, geometry){
new Select({
name: layerNode,
id: id
}).placeAt(layerNode).startup();

var selectLayer = dijit.byId(id);

var layers = [];
for(var i = 0; i < map.graphicsLayerIds.length; i++) {
  var layerObject = map.getLayer(map.graphicsLayerIds[i]);
  if(layerObject.url){
    layers.push(layerObject);
  } 
}

selectLayer.addOption(this._makeLayerOption(this.folderUrl, layers, geometry));

},

_makeLayerOption: function(f, layers, geometry){
var r = layers.map(function(record){
switch(true){
case record.geometryType === "esriGeometryPolygon" && (geometry === '' || geometry === 'polygon'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryPoint" && (geometry === '
' || geometry === 'point'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryLine" && (geometry === '' || geometry === 'line'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryPolyLine" && (geometry === '
' || geometry === 'line'):
return html.create("option", {
label: ' ' + record.name,
value: record.id
});
case record.geometryType === "esriGeometryMultiPatch" && (geometry === '*' || geometry === 'multiPatch'):
return html.create("option", {
label: ' M ' + record.name,
value: record.id
});
default:
return null;
}
});
return r;
},

_initLayerChooser: function(){
var idForChangeEvent = "layerChooserNodeEvent";

this._createLayerSelect(idForChangeEvent, "layerChooserNode", this.map, "*");

this.layerName = dijit.byId(idForChangeEvent).value;
this._fieldMultiSelect(this.layerName); 
this.selectFrom.innerHTML = 'SELECT * FROM ' + this.layerName  + ' WHERE:';

dijit.byId(idForChangeEvent).on("change", lang.hitch(this, function(evt){
    this._updateFieldMultiSelect('fieldsMultiSelect', evt);
    this.selectFrom.innerHTML = 'SELECT * FROM ' + evt + ' WHERE:';
}));

},

_fieldMultiSelect: function(layerId){
this.layer = this.map.getLayer(layerId);
this.url = this.layer.url;
var fields = this.layer.fields;
this.field = this.layer.fields;

for(var i in fields){
    var opData = domConstruct.create('option');
    opData.innerHTML = fields[i].name;
    opData.value = fields[i].name;
    dom.byId('fieldsMultiSelect').appendChild(opData);
}

var self = this;
$('#fieldsMultiSelect').on('change', function(){
    self.selectedField = $(this).val();
    $('#textBoxNode').val( $('#textBoxNode').val() + $(this).val() );
    
    var $uniques = $('#uniquesMultiSelect' + ' option');
    $.each($uniques, function(index, element) {
    element.remove();
    });
});

$('#uniquesMultiSelect').on('change', function(){
    $('#textBoxNode').val( $('#textBoxNode').val() + "'" + $(this).val() + "'" );
});

},

_updateFieldMultiSelect: function(id, layerId){
var $uniques = $('#' + id + ' option');
$.each($uniques, function(index, element) {
element.remove();
});

this.layer = this.map.getLayer(layerId);
this.url = this.layer.url;
var fields = this.layer.fields;
this.field = this.layer.fields;

for(var i in fields){
    var opData = domConstruct.create('option');
    opData.innerHTML = fields[i].name;
    opData.value = fields[i].name;
    dom.byId(id).appendChild(opData);
}

},

_initButtons: function(){
for(var i in this.config.ids){
new Button({
label: this.nls.buttons[this.config.ids[i]],
value: this.nls.buttons[this.config.ids[i]],
class: "button",
onClick: function(){
$('#textBoxNode').val( $('#textBoxNode').val() + ' ' + this.get("value") + ' ' );
}
}, this[this.config.ids[i]]);
}
},

_getUniqueValues: function(){
this.shelter.show();
var query = new Query();
query.where = '1=1';
query.outFields = this.selectedField;
new QueryTask(this.url).execute(query, lang.hitch(this, function(results){
var map = results.features.map(lang.hitch(this, function(record){
return record.attributes[this.selectedField[0]];
}));
var def = new Deferred();
def.resolve(map);
def.then(lang.hitch(this, function(results){
return results.sort()
.filter(lang.hitch(this, function(x, i){
return results.indexOf(x) === i;
}));
})).then(lang.hitch(this, function(results){
var $uniques = $('#uniquesMultiSelect option');
$.each($uniques, function(index, element){
element.remove();
});
return results;
})).then(lang.hitch(this, function(results){
this._updateUniquesMultiselect('uniquesMultiSelect', results);
})).then(lang.hitch(this, function(results){
this.shelter.hide();
}));
}));
},

_updateUniquesMultiselect: function(id, data){
for(var i in data){
var opData = domConstruct.create('option');
opData.innerHTML = data[i];
opData.value = data[i];
dom.byId(id).appendChild(opData);
}
},

_performQuery: function(){
var query = new Query();
query.where = $('#textBoxNode').val();
query.outFields = ["*"];
if (this.url.indexOf("MapServer") > 0) {
query.returnGeometry = true;
}
new QueryTask(this.url).execute(query, lang.hitch(this, function(results){
this.selectionManager.setSelection(this.layer, results.features);
}),function(error){
new Message({
message: "There was a problem selecting."
});
});
},

_confirmQuery: function(){
var query = new Query();
query.where = $('#textBoxNode').val();
query.outFields = ["*"];
new QueryTask(this.url).execute(query, lang.hitch(this, function(results){
if(results.features.length !== 0){
new Message({
message: "There expression was successfully verified."
});
}else{
new Message({
message: "The expression was verified successfully, but no records were returned."
});
}
}),function(error){
new Message({
message: "There was an error with the expression."
});
});
},

_clearSelection: function(){
this.selectionManager.clearSelection(this.layer);
this.sqlquery.value = "";
var $uniques = $('#uniquesMultiSelect' + ' option');
$.each($uniques, function(index, element) {
element.remove();
});
}
});
});`

@amit200635k
Copy link

this is not workin in WAB 2.9 or 2.5.
it says setting/setting.js is not found.
so the url of layers is missing.
plzz check

@AdriSolid
Copy link
Owner

@khibma

Thanks! You are right, the widget is not ready to update itself if the user adds new layers, I will review it, merge the code and add you in the 'readme' file or something.

Cheers!

@amit200635k
Copy link

@AdriSolid
i have service urls instead of graphicsLayerIds and i want to pull layers & fields from there. i m trying but stuck.
Can u make it setting wise so the user can add service/layer url. in setting page.
Thanks.

@AdriSolid
Copy link
Owner

@amit200635k
I'm pretty busy at the moment.. So I won't be able to develop anything else.. Anyway, the idea of this widget is just to filter de data using sql and highlight the matched features, so you have to have always the graphic layer on the map

Cheers!

@amit200635k
Copy link

@AdriSolid
Is there any way ?
By using the service url user can filter things easily, no need of graphic layer.
Btw if u have time plzz look in to it. this will help many.

Have fun & Enjoy ur time.
Cheers!

@AdriSolid
Copy link
Owner

AdriSolid commented Dec 8, 2018

Hey @amit200635k !
I know what you mean, but this widget was developed for the reason I told you, therefore, the fact to use a service url means that I should redo the whole widget for that propose.. Or create a new one. Sorry but I cannot help you..

Best.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants