Refactor GIS data editor form to use Bootstrap classes

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
Maurício Meneghini Fauth 2024-05-31 04:23:17 -03:00
parent bd4bcc92d6
commit f30b98e977
No known key found for this signature in database
GPG Key ID: 6A16FD38AFC89CC8
10 changed files with 82 additions and 87 deletions

View File

@ -1,15 +0,0 @@
.gis-coordinates-list {
padding-left: 10px;
border-left: 2px solid grey;
margin-bottom: 10px;
}
#gis_data {
min-height: 230px;
}
#gis_data_editor {
input[type="text"] {
width: 75px;
}
}

View File

@ -2,7 +2,6 @@
@import "bootstrap";
@import "common";
@import "enum-editor";
@import "gis";
@import "navigation";
@import "designer";
@import "codemirror";

View File

@ -4,7 +4,6 @@
@import "root";
@import "common";
@import "enum-editor";
@import "../../bootstrap/scss/gis";
@import "navigation";
@import "designer";
@import "codemirror";

View File

@ -2,7 +2,6 @@
@import "../../bootstrap/scss/bootstrap";
@import "common";
@import "../../pmahomme/scss/enum-editor";
@import "../../bootstrap/scss/gis";
@import "navigation";
@import "../../pmahomme/scss/designer";
@import "../../pmahomme/scss/codemirror";

View File

@ -2,7 +2,6 @@
@import "../../bootstrap/scss/bootstrap";
@import "common";
@import "enum-editor";
@import "../../bootstrap/scss/gis";
@import "navigation";
@import "designer";
@import "codemirror";

View File

@ -53,21 +53,21 @@ function makeAddButton (prefix: string, cls: string, label: string, type: string
function makeCoordinateInputs (prefix: string, data): string {
return (
'<label>' +
'<div class="col"><label class="input-group input-group-sm"><span class="input-group-text">' +
window.Messages.strX +
' <input type="text" name="' + prefix + '[x]" value="' + (data ? data.x : '') + '">' +
'</label>' +
' <label>' +
'</span><input class="form-control" type="text" name="' + prefix + '[x]" value="' + (data ? data.x : '') + '">' +
'</label></div>' +
'<div class="col"><label class="input-group input-group-sm"><span class="input-group-text">' +
window.Messages.strY +
' <input type="text" name="' + prefix + '[y]" value="' + (data ? data.y : '') + '">' +
'</label> '
'</span><input class="form-control" type="text" name="' + prefix + '[y]" value="' + (data ? data.y : '') + '">' +
'</label></div>'
);
}
function makePointNInputs (prefix: string, index: number, data): string {
return (
'<div class="gis-coordinates">' +
window.Messages.strPoint + ' ' + (index + 1) + ': ' +
'<div class="gis-coordinates row gx-2 align-items-center mb-2"><div class="col-2">' +
window.Messages.strPoint + ' ' + (index + 1) + ':</div>' +
makeCoordinateInputs(withIndex(prefix, index), data) +
'</div>'
);
@ -75,9 +75,9 @@ function makePointNInputs (prefix: string, index: number, data): string {
function makePointInputs (prefix: string, data): string {
return (
'<div class="gis-coordinates-list">' +
'<div class="gis-coordinates">' +
window.Messages.strPoint + ': ' +
'<div class="gis-coordinates-list card-body">' +
'<div class="gis-coordinates row gx-2 align-items-center"><div class="col-2">' +
window.Messages.strPoint + ':</div>' +
makeCoordinateInputs(prefix, data) +
'</div>' +
'</div>'
@ -94,7 +94,7 @@ function makeMultiPointInputs (prefix: string, data): string {
}
return (
'<div class="gis-coordinates-list">' +
'<div class="gis-coordinates-list card-body">' +
inputs.join('') +
makeDataLengthInput(prefix, i) +
makeAddButton(prefix, 'addPoint', window.Messages.strAddPoint, 'POINT') +
@ -113,7 +113,7 @@ function makeLineStringInputs (prefix: string, data, type: string): string {
}
return (
'<div class="gis-coordinates-list">' +
'<div class="gis-coordinates-list card-body">' +
inputs.join('') +
makeDataLengthInput(prefix, i) +
makeAddButton(prefix, 'addPoint', window.Messages.strAddPoint, 'LINESTRING') +
@ -127,15 +127,17 @@ function makeMultiLineStringInputs (prefix: string, data): string {
let i = 0;
while (d[i] || i < 1) {
inputs.push(
window.Messages.strLineString + ' ' + (i + 1) + ':',
makeLineStringInputs(withIndex(prefix, i), d[i], 'MULTILINESTRING')
'<div class="card mb-3"><div class="card-header">',
window.Messages.strLineString + ' ' + (i + 1) + ':</div>',
makeLineStringInputs(withIndex(prefix, i), d[i], 'MULTILINESTRING'),
'</div>'
);
++i;
}
return (
'<div class="gis-coordinates-list">' +
'<div class="gis-coordinates-list card-body">' +
inputs.join('') +
makeDataLengthInput(prefix, i) +
makeAddButton(prefix, 'addLine', window.Messages.strAddLineString, 'MULTILINESTRING') +
@ -149,15 +151,17 @@ function makePolygonInputs (prefix: string, data, type: string): string {
let i = 0;
while (d[i] || i < 1) {
inputs.push(
(i === 0 ? window.Messages.strOuterRing : window.Messages.strInnerRing + ' ' + i) + ':',
makeLineStringInputs(withIndex(prefix, i), d[i], type)
'<div class="card mb-3"><div class="card-header">',
(i === 0 ? window.Messages.strOuterRing : window.Messages.strInnerRing + ' ' + i) + ':</div>',
makeLineStringInputs(withIndex(prefix, i), d[i], type),
'</div>'
);
++i;
}
return (
'<div class="gis-coordinates-list">' +
'<div class="gis-coordinates-list card-body">' +
inputs.join('') +
makeDataLengthInput(prefix, i) +
makeAddButton(prefix, 'addLine', window.Messages.strAddInnerRing, 'POLYGON') +
@ -171,15 +175,17 @@ function makeMultiPolygonInputs (prefix: string, data): string {
let i = 0;
while (d[i] || i < 1) {
inputs.push(
window.Messages.strPolygon + ' ' + (i + 1) + ':',
makePolygonInputs(withIndex(prefix, i), d[i], 'MULTIPOLYGON')
'<div class="card mb-3"><div class="card-header">',
window.Messages.strPolygon + ' ' + (i + 1) + ':</div>',
makePolygonInputs(withIndex(prefix, i), d[i], 'MULTIPOLYGON'),
'</div>'
);
++i;
}
return (
'<div class="gis-coordinates-list">' +
'<div class="gis-coordinates-list card-body">' +
inputs.join('') +
makeDataLengthInput(prefix, i) +
makeAddButton(prefix, 'addPolygon', window.Messages.strAddPolygon, 'MULTIPOLYGON') +
@ -206,10 +212,10 @@ function makeGeometryCollectionGeometryInputs (prefix: string, index: number, da
select.setAttribute('name', withIndex(prefix, index, 'gis_type'));
return (
'<div class="gis-geometry">' +
'<div class="gis-geometry-type">' +
window.Messages.strGeometry + ' ' + (index + 1) + ': ' + select.outerHTML +
'</div>' +
'<div class="gis-geometry card mb-3">' +
'<div class="gis-geometry-type card-header"><div class="row align-items-center"><div class="col-auto">' +
window.Messages.strGeometry + ' ' + (index + 1) + ':</div><div class="col">' + select.outerHTML +
'</div></div></div>' +
fn(withIndex(prefix, index, type), data ? data[type] : null, type) +
'</div>'
);
@ -224,11 +230,11 @@ function makeGeometryCollectionInputs (prefix: string, data): string {
}
return (
'<div class="gis-geometry-list">' +
'<div class="gis-geometry-list card"><div class="card-body">' +
inputs.join('') +
makeDataLengthInput('gis_data[GEOMETRYCOLLECTION]', i) +
makeAddButton(prefix, 'addGeom', window.Messages.strAddGeometry, 'GEOMETRYCOLLECTION') +
'</div>'
'</div></div>'
);
}
@ -237,7 +243,7 @@ function makeGeometryInputs (gisData): string {
const geometry = gisData[0][type];
const fn = INPUTS_GENERATOR[type];
return fn(withIndex('gis_data', 0, type), geometry, type);
return '<div class="card">' + fn(withIndex('gis_data', 0, type), geometry, type) + '</div>';
}
/**
@ -389,13 +395,13 @@ function addLineStringOrInnerRing () {
const $a = $(this);
const prefix = $a.data('prefix');
const type = $a.data('geometryType');
const dataLength = this.parentElement.querySelectorAll(':scope > .gis-coordinates-list').length;
const dataLength = this.parentElement.querySelectorAll(':scope > .card > .gis-coordinates-list').length;
$('input[name=\'' + prefix + '[data_length]' + '\']').val(dataLength + 1);
const label = type === 'MULTILINESTRING' ? window.Messages.strLineString : window.Messages.strInnerRing;
const n = type === 'MULTILINESTRING' ? dataLength + 1 : dataLength;
const html = makeLineStringInputs(withIndex(prefix, dataLength), null, type);
$a.before('<div class="gis-geometry-type">' + label + ' ' + n + ':</div>', html);
$a.before('<div class="card mb-3"><div class="gis-geometry-type card-header">' + label + ' ' + n + ':</div>' + html + '</div>');
updateResult();
}
@ -406,11 +412,11 @@ function addLineStringOrInnerRing () {
function addPolygon () {
const $a = $(this);
const prefix = $a.data('prefix');
const dataLength = this.parentElement.querySelectorAll(':scope > .gis-coordinates-list').length;
const dataLength = this.parentElement.querySelectorAll(':scope > .card > .gis-coordinates-list').length;
$('input[name=\'' + prefix + '[data_length]' + '\']').val(dataLength + 1);
const html = makePolygonInputs(withIndex(prefix, dataLength), null, 'MULTIPOLYGON');
$a.before('<div class="gis-geometry-type">' + window.Messages.strPolygon + ' ' + (dataLength + 1) + ':</div>', html);
$a.before('<div class="card mb-3"><div class="gis-geometry-type card-header">' + window.Messages.strPolygon + ' ' + (dataLength + 1) + ':</div>' + html + '</div>');
updateResult();
}
@ -441,13 +447,15 @@ function onGeometryTypeChange () {
if (isSubGeom) {
const fn = INPUTS_GENERATOR[type];
html = fn(withIndex(prefix, type), null, type);
$(typeSelect.parentElement.parentElement.parentElement.nextElementSibling).replaceWith(html);
} else {
html = type === 'GEOMETRYCOLLECTION'
? makeGeometryCollectionInputs(prefix, {})
: makeGeometryInputs({ 'gis_type': type, '0': {} });
}
$(typeSelect.parentElement.nextElementSibling).replaceWith(html);
$(typeSelect.parentElement.parentElement.nextElementSibling).replaceWith(html);
}
updateResult();
}

View File

@ -52,7 +52,6 @@ AJAX.registerTeardown('table/select.js', function () {
$('#togglesearchformlink').off('click');
$(document).off('submit', '#tbl_search_form.ajax');
$('select.geom_func').off('change');
$(document).off('click', 'span.open_search_gis_editor');
$('body').off('change', 'select[name*="criteriaColumnOperators"]'); // Fix for bug #13778, changed 'click' to 'change'
});
@ -194,7 +193,7 @@ AJAX.registerOnload('table/select.js', function () {
// Following section is related to the 'function based search' for geometry data types.
// Initially hide all the open_search_gis_editor spans
$('span.open_search_gis_editor').hide();
$('.open_search_gis_editor').hide();
$('select.geom_func').on('change', function () {
var $geomFuncSelector = $(this);
@ -244,7 +243,7 @@ AJAX.registerOnload('table/select.js', function () {
}
// if the chosen function's output is a geometry, enable GIS editor
var $editorSpan = $geomFuncSelector.parents('tr').find('span.open_search_gis_editor');
var $editorSpan = $geomFuncSelector.parents('tr').find('.open_search_gis_editor');
if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0) {
$editorSpan.show();
} else {
@ -252,17 +251,17 @@ AJAX.registerOnload('table/select.js', function () {
}
});
$(document).on('click', 'span.open_search_gis_editor', function (event) {
event.preventDefault();
var $span = $(this);
const gisEditorModal = document.getElementById('gisEditorModal');
gisEditorModal?.addEventListener('show.bs.modal', event => {
// @ts-ignore
const button = $(event.relatedTarget as HTMLButtonElement);
// Current value
var value = $span.parent('td').children('input[type=\'text\']').val();
let value = button.parent('td').children('input[type=\'text\']').val();
// Field name
var field = 'Parameter';
const field = 'Parameter';
// Column type
var geomFunc = $span.parents('tr').find('.geom_func').val();
var type = 'GEOMETRY';
const geomFunc = button.parents('tr').find('.geom_func').val();
const type = 'GEOMETRY';
if (!value) {
if (geomFunc === 'Envelope') {
value = 'POLYGON()';
@ -274,7 +273,7 @@ AJAX.registerOnload('table/select.js', function () {
}
// Names of input field and null checkbox
var inputName = $span.parent('td').children('input[type=\'text\']').attr('name');
const inputName = button.parent('td').children('input[type=\'text\']').attr('name');
window.openGISEditor(value, field, type, inputName);
});

View File

@ -13,25 +13,34 @@
<div class="col">
<div id="gis_data" class="gis-geometry mb-3" data-gis-data="{{ gis_data|json_encode }}">
<template id="gis_type_template">
<select class="gis_type">
{% for gis_type in gis_types|slice(0, 6) %}
<select class="gis_type form-select">
{% for gis_type in gis_types|filter(v => v != 'GEOMETRYCOLLECTION') %}
<option value="{{ gis_type }}">{{ gis_type }}</option>
{% endfor %}
</select>
</template>
{# Header section - Inclueds GIS type selector and input field for SRID #}
<div class="gis-geometry-type">
<select name="gis_data[gis_type]" class="gis_type{{ column_type != 'GEOMETRY' ? ' hide' }}">
{% for gis_type in gis_types %}
<option value="{{ gis_type }}"{{ geom_type == gis_type ? ' selected="selected"' }}>
{{ gis_type }}
</option>
{% endfor %}
</select>
<div class="gis-geometry-type mb-3 row">
<div class="col">
<label class="form-label" for="gisDataEditorTypeSelect">{{ t('Geometry type:') }}</label>
{% if column_type == 'GEOMETRY' %}
<select id="gisDataEditorTypeSelect" name="gis_data[gis_type]" class="gis_type form-select">
{% for gis_type in gis_types %}
<option value="{{ gis_type }}"{{ geom_type == gis_type ? ' selected' }}>
{{ gis_type }}
</option>
{% endfor %}
</select>
{% else %}
<input type="text" id="gisDataEditorTypeSelect" name="gis_data[gis_type]" class="form-control" value="{{ geom_type }}" disabled readonly>
{% endif %}
</div>
<label for="srid">{{ t('SRID:', context = 'Spatial Reference System Identifier') }}</label>
<input id="srid" name="gis_data[srid]" type="text" value="{{ srid }}">
<div class="col-auto">
<label class="form-label" for="srid"><abbr title="{{ t('Spatial Reference System Identifier') }}">{{ t('SRID:', context = 'Spatial Reference System Identifier') }}</abbr></label>
<input class="form-control" id="srid" name="gis_data[srid]" type="text" value="{{ srid }}">
</div>
</div>
{# End of header section #}
</div>

View File

@ -114,15 +114,13 @@
{{ max_upload_size }}
{% endif %}
{{ select_option_for_upload|raw }}
{% else %}
{% elseif column.pmaType in gis_data_types %}
{{ value|raw }}
{% endif %}
{% if column.pmaType in gis_data_types %}
<span class="open_gis_editor" data-row-id="{{ row_id }}"></span>
<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#gisEditorModal" data-row-id="{{ row_id }}">
<button type="button" class="btn btn-link open_gis_editor" data-bs-toggle="modal" data-bs-target="#gisEditorModal" data-row-id="{{ row_id }}">
{{ get_icon('b_edit', t('Edit/Insert')) }}
</button>
{% else %}
{{ value|raw }}
{% endif %}
{% endif %}
</td>

View File

@ -28,9 +28,9 @@
class="textfield"
id="field_{{ column_index }}">
{% if in_fbs %}
<span class="open_search_gis_editor">
{{ link_or_button('#', null, get_icon('b_edit', t('Edit/Insert'))) }}
</span>
<button type="button" class="btn btn-link open_search_gis_editor" data-bs-toggle="modal" data-bs-target="#gisEditorModal">
{{ get_icon('b_edit', t('Edit/Insert')) }}
</button>
{% endif %}
{% elseif column_type starts with 'enum'
or (column_type starts with 'set' and in_zoom_search_edit) %}