';
-
// Selected searched lines button
html+= '
';
// 'Move selected to top' button
- html+= '
`;
// Filter button : only if no filter applied at startup
if( !startupFilter
- && ( !lizMap.lizmapLayerFilterActive || lizMap.lizmapLayerFilterActive == lname )
- ){
- html+= '
';
+ && ( !lizMap.lizmapLayerFilterActive || lizMap.lizmapLayerFilterActive == lname )){
+ html+= '
';
}
+ // Filter data by extent button
+ html+= `
+
'
@@ -588,16 +559,6 @@ var lizAttributeTable = function() {
html+= '
';
}
- // Refresh button (if limitDataToBbox is true)
- if( limitDataToBbox
- && config.layers[lname]['geometryType'] != 'none'
- && config.layers[lname]['geometryType'] != 'unknown'
- ){
- // Add button to refresh table
- html+= '
';
-
- }
-
// Get children content
var childHtml = getChildrenHtmlContent( lname );
var alc='';
@@ -643,7 +604,8 @@ var lizAttributeTable = function() {
}
html+= '
';
html+= '
';
- html+= '
';
+ const classes = 'attribute-table-table table table-hover table-condensed table-striped order-column cell-border';
+ html+= '
';
html+= '
'; // attribute-layer-content
@@ -685,59 +647,12 @@ var lizAttributeTable = function() {
$(tabContentId).remove(); //remove respective tab content
});
- if( childHtml ){
-
- // Bind adjust child columns when children tab visibility change
- $('#attribute-layer-' + cleanName + ' div.attribute-layer-child-content ul li a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
- var target = $(e.target).attr("href") // activated tab
- var dtable = $(target).find('table.dataTable');
- dtable.DataTable().tables().columns.adjust();
- });
- }
-
- if(limitDataToBbox){
- $('#attribute-layer-'+ cleanName + ' button.btn-refresh-table')
- .click(function(){
- // Reset button tooltip & style
- $(this)
- .attr('data-bs-toggle', 'tooltip')
- .attr('data-bs-title', lizDict['attributeLayers.toolbar.btn.refresh.table.tooltip'])
- .removeClass('btn-warning');
-
- // Disable if the layer is not visible
- let layer = lizMap.mainLizmap.map.getLayerByName(lizMap.getLayerNameByCleanName(cleanName));
- if( layer ) {
- if(warnResolution(layer)){
- return false;
- }
- }else{
- // do nothing if no layer found
- return false;
- }
-
- // Refresh table
- const tableSelector = '#attribute-layer-table-'+cleanName;
- $('#attribute-layer-main-'+cleanName+' > div.attribute-layer-content').hide();
-
- getDataAndFillAttributeTable(lname, null, tableSelector, false, () => {
- $('#attribute-layer-main-' + cleanName + ' > div.attribute-layer-content').show();
- refreshDatatableSize('#attribute-layer-main-' + cleanName);
- });
-
- return false;
- })
- .hover(
- function(){ $(this).addClass('btn-primary'); },
- function(){ $(this).removeClass('btn-primary'); }
- );
- }
-
if( childHtml ){
$('#attribute-layer-'+ cleanName + ' button.btn-toggle-children')
.click(function(){
var parentDir = $(this).parents('div.attribute-layer-main');
parentDir.find('div.attribute-layer-content').toggleClass('showChildren');
- parentDir.find('div.tabbable.attribute-layer-child-content').toggle();
+ parentDir.find('div.attribute-layer-child-content').toggle();
// Refresh parent table size
refreshDatatableSize('#attribute-layer-main-'+ cleanName);
return false;
@@ -753,8 +668,6 @@ var lizAttributeTable = function() {
$('#attribute-layer-main-' + cleanName).toggleClass('reduced', !$(this).hasClass('btn-primary'));
$('#attribute-table-panel-' + cleanName).toggleClass('visible', !$(this).hasClass('btn-primary'));
$(this).toggleClass('btn-primary');
-
- refreshDatatableSize('#attribute-layer-main-'+ cleanName);
return false;
});
}
@@ -775,27 +688,17 @@ var lizAttributeTable = function() {
);
// Bind click on "move selected to top" button
- $('#attribute-layer-'+ cleanName + ' button.btn-moveselectedtotop-attributeTable')
- .click(function(){
- var aTable = '#attribute-layer-table-' + $(this).val();
- var dTable = $( aTable ).DataTable();
- var previousOrder = dTable.order();
- previousOrder = $.grep(previousOrder, function(o){
- return o[0] != 0;
- });
- var selectedOrder = [ [0, 'asc'] ];
- var newOrder = selectedOrder.concat(previousOrder);
- dTable.order( newOrder ).draw();
-
- // Scroll to top
- $(aTable).parents('div.attribute-layer-content').scrollTop(0);
-
- return false;
- })
- .hover(
- function(){ $(this).addClass('btn-primary'); },
- function(){ $(this).removeClass('btn-primary'); }
- );
+ const moveSelectedToTopSelector = '#attribute-layer-' + cleanName + ' button.btn-moveselectedtotop-attributeTable';
+ document.querySelector(moveSelectedToTopSelector).addEventListener('click', (e) => {
+ const dTableSelector = '#attribute-layer-table-' + e.currentTarget.value;
+ const dTable = new DataTable(dTableSelector);
+ dTable.draw();
+
+ // Scroll to top
+ document.querySelector(dTableSelector).parentElement.scroll({
+ top: 0
+ }) ;
+ });
// Bind click on filter button
@@ -803,7 +706,7 @@ var lizAttributeTable = function() {
$('#attribute-layer-'+ cleanName + ' button.btn-filter-attributeTable')
.click(function(){
var aName = attributeLayersDic[ $(this).val() ];
- if( $(this).hasClass('btn-primary') ) {
+ if( $(this).hasClass('active') ) {
lizMap.events.triggerEvent( "layerfeatureremovefilter",
{ 'featureType': aName}
);
@@ -826,7 +729,9 @@ var lizAttributeTable = function() {
eFormat = 'GML3';
var cleanName = $(this).parents('div.attribute-layer-main:first').attr('id').replace('attribute-layer-main-', '');
var eName = attributeLayersDic[ cleanName ];
- lizMap.exportVectorLayer( eName, eFormat, limitDataToBbox );
+ const limitDataToBbox =
+ document.querySelector('.btn-filterbyextent-attributeTable.active[value="' + cleanName + '"]') ? true : false;
+ lizMap.exportVectorLayer(eName, eFormat, limitDataToBbox);
});
// Bind click on createFeature button
@@ -1020,11 +925,17 @@ var lizAttributeTable = function() {
{ 'featureType': aName, 'updateDrawing': true}
);
return false;
- })
- .hover(
- function(){ $(this).addClass('btn-primary'); },
- function(){ $(this).removeClass('btn-primary'); }
- );
+ }).hover(
+ function(){ $(this).addClass('btn-primary'); },
+ function(){ $(this).removeClass('btn-primary'); }
+ );
+
+ // Bind click on btn-filterbyextent button
+ document.querySelector('#attribute-layer-'+ cleanName + ' button.btn-filterbyextent-attributeTable').addEventListener('click', (e) => {
+ const layerId = e.currentTarget.getAttribute('data-layerid');
+ const dTable = new DataTable('table[data-layerid=' + layerId + ']');
+ dTable.draw();
+ });
}
/**
@@ -1126,9 +1037,10 @@ var lizAttributeTable = function() {
var cDiv = '
';
var tId = 'attribute-layer-table-' + lizMap.cleanName(parentLayerName) + '-' + lizMap.cleanName(childLayerName);
var tClass = 'attribute-table-table table table-hover table-condensed table-striped cell-border child-of-' + lizMap.cleanName(parentLayerName);
+ const dataLayerId = childLayerConfig.id;
cDiv+= '
';
cDiv+= '
';
- cDiv+= '
';
+ cDiv+= '
';
cDiv+= '
';
childDiv.push(cDiv);
@@ -1255,7 +1167,8 @@ var lizAttributeTable = function() {
if( relation.referencingLayer == childLayerConfig.id ){
filter = '"' + relation.referencingField + '" = ' + "'" + fp[relation.referencedField] + "'";
}
- getDataAndFillAttributeTable(childLayerName, filter, childTableSelector, false);
+
+ getDataAndFillAttributeTable(childLayerName, filter, true, childTableSelector, false);
}
}
}
@@ -1324,32 +1237,18 @@ var lizAttributeTable = function() {
if( cFeatures && cFeatures.length > 0 ){
// Format features for datatable
- formatDatatableFeatures(
+ var ff = formatDatatableFeatures(
cFeatures,
isChild,
hiddenFields,
lConfig['selectedFeatures'],
lConfig['id'],
- parentLayerID
- ).then((ff) => {
- var foundFeatures = ff.foundFeatures;
- var dataSet = ff.dataSet;
-
- // Datatable configuration
- if ( $.fn.dataTable.isDataTable( aTable ) ) {
- var oTable = $( aTable ).dataTable();
- oTable.fnClearTable();
- oTable.fnAddData( dataSet );
- }
- lConfig['features'] = foundFeatures;
- });
+ parentLayerID);
+ var foundFeatures = ff.foundFeatures;
+ lConfig['features'] = foundFeatures;
}
if ( !cFeatures || cFeatures.length == 0 ){
- if ( $.fn.dataTable.isDataTable( aTable ) ) {
- var oTable = $( aTable ).dataTable();
- oTable.fnClearTable();
- }
$(aTable).hide();
$('#attribute-layer-'+ cleanName +' span.attribute-layer-msg').html(
@@ -1369,13 +1268,12 @@ var lizAttributeTable = function() {
*
* @param aName
* @param aTable
- * @param cFeatures
* @param cAliases
* @param cTypes
* @param allColumnsKeyValues
* @param aCallback
*/
- function buildLayerAttributeDatatable(aName, aTable, cFeatures, cAliases, cTypes, allColumnsKeyValues, aCallback ) {
+ function buildLayerAttributeDatatable(aName, aTable, cAliases, cTypes, allColumnsKeyValues, aCallback ) {
// Get config
var lConfig = config.layers[aName];
@@ -1415,13 +1313,14 @@ var lizAttributeTable = function() {
// Pivot table ?
var isPivot = false;
+ let pivotId;
if( isChild
&& 'pivot' in config.attributeLayers[aName]
&& config.attributeLayers[aName]['pivot'] == 'True'
){
isPivot = true;
}
- var pivotReference = null;
+ let pivotReference = null;
// checks if the parent and child are related via pivot
if (parentLayerID) {
// means that the table is displayed as a child
@@ -1436,7 +1335,7 @@ var lizAttributeTable = function() {
}
if (parentLayerConfig && parentLayerConfig[1] && parentLayerConfig[1].cleanname && highlightedFeature) {
var childLayerId = lConfig.id;
- var pivotId = getPivotIdFromRelatedLayers(parentLayerID, childLayerId);
+ pivotId = getPivotIdFromRelatedLayers(parentLayerID, childLayerId);
if (pivotId) {
pivotReference = pivotId + ":" + highlightedFeature;
}
@@ -1464,196 +1363,198 @@ var lizAttributeTable = function() {
canDelete = true;
}
- cFeatures = typeof cFeatures !== 'undefined' ? cFeatures : null;
- if( !cFeatures ){
- // features is an object, let's transform it to an array
- // XXX IE compat: Object.values is not available on IE...
- var features = config.layers[aName]['features'];
- cFeatures = Object.keys(features).map(function (key) {
- return features[key];
- });
- }
+ // Create columns for datatable
+ var cdc = createDatatableColumns(aName, hiddenFields, cAliases, cTypes, allColumnsKeyValues, isChild, pivotReference, parentLayerID);
+ var columns = cdc.columns;
+ var firstDisplayedColIndex = cdc.firstDisplayedColIndex;
+
+ lConfig['alias'] = cAliases;
+ // Datatable configuration
+ if ( !DataTable.isDataTable( aTable ) ) {
+ const datatablesUrl = globalThis['lizUrls'].wms.replace('service', 'datatables');
+ const params = globalThis['lizUrls'].params;
+ params['layerId'] = lConfig.id;
+
+ DataTable.defaults.column.orderSequence = ['asc', 'desc'];
+ const oTable = new DataTable(aTable, {
+ serverSide: true
+ ,ajax: {
+ url: datatablesUrl + '?' + new URLSearchParams(params).toString(),
+ type: 'POST',
+ data: (d) => {
+ // Handle selected features moved to top
+ if (document.querySelector('.btn-moveselectedtotop-attributeTable.active[data-layerid="' + lConfig.id + '"]')) {
+ d.filteredfeatureids = lConfig['selectedFeatures'].join();
+ }
- var atFeatures = cFeatures;
- var dataLength = atFeatures.length;
+ // Handle filtered features
+ const filteredFeaturesIds = lConfig.filteredFeatures;
+ if (filteredFeaturesIds && filteredFeaturesIds.length > 0) {
+ d.filteredfeatureids = filteredFeaturesIds.join();
+ }
- if( cFeatures && cFeatures.length > 0 ){
- let keys = [], exp_f;
- let pkey = config.attributeLayers[aName]['primaryKey'] || null;
- if (pkey) {
- keys = cFeatures.map((f) =>
- `'${f.id.split(".")[1]}'`
- )
- exp_f = `"${pkey}" IN ( ${keys.join(' , ')} )`;
- }
+ // Handle features filtered by their parent
+ if(isChild) {
+ if(lConfig.line_filter) {
+ d.exp_filter = lConfig.line_filter;
+ }
+ } else {
+ const exp_filter = lConfig.request_params.exp_filter;
+ if (exp_filter) {
+ d.exp_filter = exp_filter;
+ }
+ }
+ // Handle features filtered by extent
+ if (document.querySelector('.btn-filterbyextent-attributeTable.active[value="' + cleanName + '"]')) {
+ const olView = lizMap.mainLizmap.map.getView();
+ // Force to get GeoJSON as 4326
+ d.srsname = 'EPSG:4326';
+ // As legacy code do not used import method
+ d.bbox = lizMap.ol.proj.transformExtent(
+ olView.calculateExtent(),
+ olView.getProjection().getCode(),
+ 'EPSG:4326',
+ ).join(',');
+ }
+ },
+ dataSrc: (json) => {
+ // Format data for DataTables
+ let formatedData = [];
+ if (!json.data) {
+ return formatedData;
+ }
- // Create columns for datatable
- var cdc = createDatatableColumns(aName, atFeatures, hiddenFields, cAliases, cTypes, allColumnsKeyValues);
- var columns = cdc.columns;
- var firstDisplayedColIndex = cdc.firstDisplayedColIndex;
+ // Get editable features
+ const editableFeatures = json.editableFeatures;
- // Format features for datatable
- formatDatatableFeatures(
- atFeatures,
- isChild,
- hiddenFields,
- lConfig['selectedFeatures'],
- lConfig['id'],
- parentLayerID,
- pivotReference
- ).then((ff) => {
- var foundFeatures = ff.foundFeatures;
- var dataSet = ff.dataSet;
-
- // Fill in the features object
- // only when necessary : object is empty or is not child or (is child and no full features list in the object)
- var refillFeatures = false;
- var dLen = lConfig['features'] ? Object.keys(lConfig['features']).length : 0;
- if( dLen == 0 ){
- refillFeatures = true;
- if( !isChild ){
- lConfig['featuresFullSet'] = true;
- }
- }
- else{
- if( isChild ){
- if( !lConfig['featuresFullSet'] ){
- refillFeatures = true;
+ for (const feature of json.data.features) {
+ const featID = parseInt(feature.id.split('.').pop());
+ let editionRestricted = '';
+ if (editableFeatures.status === 'restricted') {
+ editionRestricted = 'edition-restricted="true"';
+ if (editableFeatures.featuresids.includes(featID)) {
+ editionRestricted = 'edition-restricted="false"';
+ }
+ }
+ let bboxinfo = '';
+ if (feature.bbox) {
+ bboxinfo = `crs="EPSG:4326" `+
+ `bbox-minx="${feature.bbox[0]}" bbox-miny="${feature.bbox[1]}" `+
+ `bbox-maxx="${feature.bbox[2]}" bbox-maxy="${feature.bbox[3]}" `;
+ } else if (feature.geometry && feature.geometry.type == 'Point') {
+ const coords = feature.geometry.coordinates;
+ bboxinfo = `crs="EPSG:4326" `+
+ `bbox-minx="${coords[0]}" bbox-miny="${coords[1]}" `+
+ `bbox-maxx="${coords[0]}" bbox-maxy="${coords[1]}" `;
+ }
+ const ftb = `
`;
+
+ formatedData.push(Object.assign({
+ 'DT_RowId': featID,
+ 'lizSelected': '',
+ 'featureToolbar': ftb,
+ }, feature.properties));
+
+ // Copy received features to config
+ config.layers[aName]['features'][featID] = feature;
}
- }else{
- lConfig['featuresFullSet'] = true;
- refillFeatures = true;
+ return formatedData;
}
}
- if( refillFeatures ) {
- lConfig['features'] = foundFeatures;
- }
+ ,columns: columns
+ ,initComplete: function(settings) {
+ // Refresh size of datatable after data has been loaded
+ refreshDatatableSize('#'+$('#bottom-dock div.bottom-content.active div.attribute-layer-main').attr('id'));
+
+ // Trigger event telling attribute table is ready
+ const tableId = settings.api.table().node().id;
+ const featureType = tableId.split('attribute-layer-table-')[1];
- lConfig['alias'] = cAliases;
- // Datatable configuration
- if ( $.fn.dataTable.isDataTable( aTable ) ) {
- var oTable = $( aTable ).dataTable();
- oTable.fnClearTable();
- oTable.fnAddData( dataSet );
+ lizMap.events.triggerEvent("attributeLayerContentReady",{
+ 'featureType': featureType,
+ });
}
- else {
- // Search while typing in text input
- // Deactivate if too many items
- var searchWhileTyping = true;
- if( dataLength > 500000 ){
- searchWhileTyping = false;
+ ,order: [[ firstDisplayedColIndex, "asc" ]]
+ ,language: { url:globalThis['lizUrls']["dataTableLanguage"] }
+ ,deferRender: true
+ , createdRow: (row, data) => {
+ if ((lConfig['selectedFeatures'].includes(data.DT_RowId.toString()))) {
+ row.classList.add('selected');
+ data.lizSelected = 'a';
}
-
- var myDom = '<