Skip to content

Commit

Permalink
✨ [open-formulieren/open-forms#2177] Allow manually deleting features
Browse files Browse the repository at this point in the history
Due to some formio magic, the `resetValue` flag is needed when performing the `setValue` call. Without this flag it isn't allowed to set a field value to `null` or `undefined`.We also need to use the value `null`, instead of `undefined`. This because setting the value to `undefined` isn't reflected as a value change (what we need, to re-render the component).
This is described in node_modules/formiojs/components/_classes/component/Component.js:2524
  • Loading branch information
robinmolen committed Jan 21, 2025
1 parent 5724539 commit f604fb2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
35 changes: 24 additions & 11 deletions src/components/Map/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,35 @@ const LeaftletMap = ({
const className = getBEMClassName('leaflet-map', modifiers);

const onFeatureCreate = event => {
onGeoJsonFeatureSet(event.layer.toGeoJSON());
updateGeoJsonFeature(event.layer);
};

const onFeatureDelete = () => {
// The value `null` is needed to make sure that Formio actually updates the value.
// node_modules/formiojs/components/_classes/component/Component.js:2528
onGeoJsonFeatureSet(null);
};

const onSearchMarkerSet = event => {
onGeoJsonFeatureSet(event.marker.toGeoJSON());
updateGeoJsonFeature(event.marker);
};

useEffect(() => {
if (!featureGroupRef.current) {
return;
const updateGeoJsonFeature = newFeatureLayer => {
if (featureGroupRef.current) {
const newFeatureLayerId = newFeatureLayer._leaflet_id;
const layers = featureGroupRef.current?.getLayers();
// Limit the amount of features to 1, by removing the previous layer
if (layers.length > 1) {
const oldLayerIds = layers
.map(layer => layer._leaflet_id)
.filter(layerId => layerId !== newFeatureLayerId);
oldLayerIds.forEach(oldLayerId => {
featureGroupRef.current?.removeLayer(oldLayerId);
});
}
}
// Remove the old layers and add the new one.
// This limits the amount of features to 1
featureGroupRef.current?.clearLayers();
featureGroupRef.current?.addLayer(Leaflet.geoJSON(geoJsonFeature));
});
onGeoJsonFeatureSet(newFeatureLayer.toGeoJSON());
};

return (
<>
Expand All @@ -139,9 +152,9 @@ const LeaftletMap = ({
<EditControl
position="topright"
onCreated={onFeatureCreate}
onDeleted={onFeatureDelete}
edit={{
edit: false,
remove: false,
}}
draw={{
rectangle: false,
Expand Down
11 changes: 8 additions & 3 deletions src/formio/components/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class Map extends Field {
}

get emptyValue() {
return '';
return undefined;
}

/**
Expand Down Expand Up @@ -90,8 +90,8 @@ export default class Map extends Field {
super.destroy();
}

onGeoJsonSet(newLatLng) {
this.setValue(newLatLng, {modified: true});
onGeoJsonSet(newGeoJson) {
this.setValue(newGeoJson, {modified: true});
}

renderReact() {
Expand Down Expand Up @@ -123,6 +123,11 @@ export default class Map extends Field {
}

setValue(value, flags = {}) {
if (value === null) {
// The `resetValue` flag is needed to allow the setting of `undefined` or `null` values.
// node_modules/formiojs/components/_classes/component/Component.js:2526
flags.resetValue = true;
}
const changed = super.setValue(value, flags);
// re-render if the value is set, which may be because of existing submission data
if (changed) this.renderReact();
Expand Down

0 comments on commit f604fb2

Please sign in to comment.