Reputation: 171
I am a total javascript/leaflet/ag-grid newbie, so please bear with me.
I am creating a website that allows users to query (add/remove) spatial points on a leaflet map based on selecting rows from ag-grid. I have no understanding/experience with React or Angular, so I am using vanilla javascript. Leaflet is used to display the data spatially.
I have spatial data that has GPS coordinates that are parent records. Each parent they have multiple children.
The spatial data is an external file I read into my HTML file. It looks like this:
var spatial_data = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature",
"properties": { "Name": "Boulder 1", "SpatialID": "Lower Blair_0" },
"geometry": { "type": "Point", "coordinates": [ -105.39079766, 41.19044516, 2510.159912109375 ] } },
{ "type": "Feature",
"properties": { "Name": "Boulder 2", "SpatialID": "Upper Blair_1" },
"geometry": { "type": "Point", "coordinates": [ -105.39058423, 41.19655902, 2534.4599609375 ] } }
]};
There are children records for each parent spatial ID. The data is within the .js code.
The functionality I am hoping for is someone could filter the ag-grid for a route called 'Slam Dunk' and that would provide the "SpatialID":"Lower Blair_0". If they filter for 'Test two' it provides the same SpatialID. This would be available to play around within the HTML file.
var rowData = [{"Route Name":"Slam Dunk","SpatialID":"Lower Blair_0"},
{"Route Name":"Test two","SpatialID":"Lower Blair_0"},
{"Route Name":"Test three","SpatialID":"Upper Blair_1"}];
var columnDefs= [
{field: 'Route Name', minWidth:10, sortable:true, filter:true},
{field: 'Sub-Area', minWidth:5, sortable:true, filter:true},
];
const gridOptions = {
columnDefs: columnDefs,
rowData: rowData,
defaultColDef:{
flex:1,
minWidth:100
},
rowSelection: 'multiple',
pagination:true
};
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
};
function grabFilteredData(){
let rowData = [];
gridOptions.api.forEachNodeAfterFilter(node => {
rowData.push(node.data.SpatialID);
});
var uniqueID = rowData.filter(onlyUnique);
return uniqueID;
}
document.addEventListener('DOMContentLoaded', () => {
const gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
});
I can easily send 'test' to the console. That provides me with the ability to check that my onSelectionChanged()
is working; however, I really need to pass the output from onSelectionChanged()
as an array. I need to pass that and use that in an embedded script within my HTML. This is so I can filter the data in my leaflet layers and features.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Read in the geojson-->
<script src='assets/spatialdata.json'></script>
<script src="https://unpkg.com/[email protected]/dist/ag-grid-community.min.js"></script>
<script src="myownscript.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="bstrap/js/bootstrap.min.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.10.1/bootstrap-table.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css">
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-alpine.css">
</head>
<body>
<script >
var sat_data = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/satellite-streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'my.api.key'
});
var bounds = new L.LatLngBounds(new L.LatLng(41.008,-106.710), new L.LatLng(41.813,-104.861));
var baseMaps = {
"Satellite":sat_data
};
var map = L.map('map', {
center: [41.210, -105.360],
zoom: 11,
layers:[osm,sat_data],
noWrap:true,
maxBounds:bounds,
maxBoundsViscosit:1.0
});
L.control.layers(baseMaps).addTo(map);
var promise = $.getJSON("/assets/vedauwoo.geojson");
promise.then(function(data){
var allData = L.geoJson(data,{
onEachFeature: function(feature,layer){
layer.bindPopup('<h4> Area Name: '+feature.properties.Name+'</h4><p>Grades: '+feature.properties.Grade+'</p>');
}
});
var others = L.geoJson(data, {
onEachFeature: function(feature,layer){
layer.bindPopup('<h4> Area Name: '+feature.properties.Name+'</h4><p>Grades: '+feature.properties.Grade+'</p>');
},
filter: function(feature,layer){
}
});
var layerGroup = L.layerGroup().addTo(map);
allData.addTo(layerGroup)
$("#others").click(function() {
var dataToSubset = grabFilteredData();
var subset_data = L.geoJson(data, {
onEachFeature: function(feature,layer){
layer.bindPopup('<h4> Area Name: '+feature.properties.Name+'</h4><p>Grades: '+feature.properties.Grade+'</p>');
},
filter: function(feature,layer){
return dataToSubset.includes(feature.properties.SpatialID);
}
});
//Works in a hacky way by sending the ID over
layerGroup.removeLayer(allData)
layerGroup.addLayer(subset_data)
window.map_id = subset_data._leaflet_id;
});
$("#allData").click(function() {
layerGroup.removeLayer(map_id)
layerGroup.addLayer(allData)
});
</script>
</body>
</html>
I have tried extensive searching. For some reason, the majority of use cases for gridOptions.api.getSelectedRows()
or forEachNodeAfterFilter
end with an example of using console.log(). I need to actually pass that information along instead of just outputting to the console. I am not sure if this is a misunderstanding on my part for how JS works, or if it is expected behavior from ag-grid, but it doesn't seem possible.
This doesn't seem to work as the console.log() in the .js file doesn't work, and in the script in the HTML it can not find test.
I am primarily a statistician/python programmer, so this a new foray for me. It is likely I am missing a bigger picture thing and if so, I would appreciate alternatives to my current approach.
Upvotes: 0
Views: 343
Reputation: 507
So once onSelectionChanged
is called with the filtered rows - what script do you need to pass it to?
I assume you want to link the table with the leaflet map. If so, you need to
If the filtering in the table and thus the leaflet layer data update happens multiple times, you need to remove the existing layer and add a new one, as far as I know. Check this post.
Upvotes: 1