Skip to content
Snippets Groups Projects
Commit 20ff5c51 authored by Lene Wasskog's avatar Lene Wasskog
Browse files

feat: Make crop, pest and location uneditable for observations in time series

parent 9441c79f
No related branches found
No related tags found
1 merge request!206VIPSUTV-1047 Editing observations belonging to timeseries
This commit is part of merge request !206. Comments created here will be created in the context of that merge request.
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
$(document).ready(function () { $(document).ready(function () {
// Make sure that there is a datetime picker present for HTML5 // Make sure that there is a datetime picker present for HTML5
// date input fields // date input fields
...@@ -67,7 +66,7 @@ ...@@ -67,7 +66,7 @@
// Otherwise, center and zoom to organizations's default // Otherwise, center and zoom to organizations's default
<#if observation.location?has_content> <#if observation.location?has_content>
initGisInfoMap([${(observation.location.x?c)!""}, ${(observation.location.y?c)!""}], 10, true); initGisInfoMap([${(observation.location.x?c)!""}, ${(observation.location.y?c)!""}], 10, true);
<#else> <#elseif !observation.observationTimeSeries?has_content>
var geoInfo = <#if observation.geoinfo?has_content>${observation.geoinfo}<#else> var geoInfo = <#if observation.geoinfo?has_content>${observation.geoinfo}<#else>
{ {
} }
...@@ -87,6 +86,10 @@ ...@@ -87,6 +86,10 @@
initObservationData(${observation.organism.organismId}, organizationId); initObservationData(${observation.organism.organismId}, organizationId);
</#if> </#if>
<#if observation.observationTimeSeries?has_content>
displayObservationTimeSeriesInfo()
</#if>
// Activating file selection // Activating file selection
$('.btn-file :file').on('fileselect', function (event, numFiles, label) { $('.btn-file :file').on('fileselect', function (event, numFiles, label) {
...@@ -136,6 +139,20 @@ ...@@ -136,6 +139,20 @@
}); });
} }
/**
* Crop, pest and location should not be editable for observations belonging to time series. We avoid displaying
* form elements in these cases, and rather display the values statically.
*/
function displayObservationTimeSeriesInfo() {
document.getElementById("cropDisplayName").innerHTML = nameForCropOrganismId("${observation.cropOrganismId}");
document.getElementById("pestDisplayName").innerHTML = nameForOrganismId("${observation.organismId}");
fetchPOIs(function (allPois) {
const locationName = nameForLocationPointOfInterestId("${observation.locationPointOfInterestId}", allPois);
document.getElementById("locationDisplayName").innerHTML = locationName || null;
});
initLocationMap("${observation.locationPointOfInterestId}")
}
function getDataSchema(organismId, organizationId) { function getDataSchema(organismId, organizationId) {
$.getJSON("/rest/observationdata/schema/" + organizationId + "/" + organismId, buildForm); $.getJSON("/rest/observationdata/schema/" + organizationId + "/" + organismId, buildForm);
} }
...@@ -223,6 +240,32 @@ ...@@ -223,6 +240,32 @@
var allPois = []; var allPois = [];
function fetchPOIs(callback) {
$.getJSON("/rest/poi/user", function (json) {
callback(json);
});
}
function buildPOIList(poiListElement, allPois, poiTypes, selectedPointOfInterestId) {
poiListElement.options.length = 1;
for (const [typeId, typeName] of Object.entries(poiTypes)) {
poiListElement.options[poiListElement.options.length] = new Option("-- " + typeName + " --", "-1");
for (let i = 0; i < allPois.length; i++) {
const poi = allPois[i];
if (poi.pointOfInterestTypeId == typeId) {
const poiOption = new Option(poi.name, poi.pointOfInterestId);
if (poi.pointOfInterestId === selectedPointOfInterestId) {
poiOption.selected = true;
}
poiListElement.options[poiListElement.options.length] = poiOption;
}
}
}
}
/** /**
* Fetches locations, farms, fields, traps and weather stations, renders the list * Fetches locations, farms, fields, traps and weather stations, renders the list
*/ */
...@@ -234,32 +277,17 @@ ...@@ -234,32 +277,17 @@
3: "${i18nBundle.fields}", 3: "${i18nBundle.fields}",
5: "${i18nBundle.traps}" 5: "${i18nBundle.traps}"
}; };
$.getJSON("/rest/poi/user", function (json) { const poiListElement = document.getElementById("locationPointOfInterestId");
const allPois = json; if (!poiListElement) {
const poiListElement = document.getElementById("locationPointOfInterestId"); return;
poiListElement.options.length = 1; }
// Iterate through each point of interest type
for (const [typeId, typeName] of Object.entries(poiTypes)) { fetchPOIs(function (allPois) {
poiListElement.options[poiListElement.options.length] = new Option("-- " + typeName + " --", "-1"); buildPOIList(poiListElement, allPois, poiTypes, selectedPointOfInterestId);
// Iterate through all POIs and add them to the list if they match the type
for (let i = 0; i < allPois.length; i++) {
const poi = allPois[i];
if (poi.pointOfInterestTypeId == typeId) {
const poiOption = new Option(poi.name, poi.pointOfInterestId);
if (poi.pointOfInterestId === selectedPointOfInterestId) {
poiOption.selected = true;
}
poiListElement.options[poiListElement.options.length] = poiOption;
}
}
}
showCorrectMap(); showCorrectMap();
}); });
} }
// If locationPointOfInterestId is selected OR observation drawing map is deliberately disabled, // If locationPointOfInterestId is selected OR observation drawing map is deliberately disabled,
// show map for locations // show map for locations
// If not, show the observation drawing map // If not, show the observation drawing map
...@@ -268,14 +296,17 @@ ...@@ -268,14 +296,17 @@
function showCorrectMap() { function showCorrectMap() {
var locationList = document.getElementById("locationPointOfInterestId"); var locationList = document.getElementById("locationPointOfInterestId");
if (hideObservationFormMap && locationList.options[locationList.options.selectedIndex].value == "-1") { if (hideObservationFormMap && locationList.options[locationList.options.selectedIndex].value == "-1") {
document.getElementById("observationFormMap").style.display = "none"; document.getElementById("observationFormMap").style.display = "none";
document.getElementById("poiFormMap").style.display = "block"; document.getElementById("poiFormMap").style.display = "block";
initLocationMap(null); initLocationMap(null);
} else if (locationList.options[locationList.options.selectedIndex].value != "-1") { } else if (locationList.options[locationList.options.selectedIndex].value != "-1") {
document.getElementById("observationFormMap").style.display = "none"; document.getElementById("observationFormMap").style.display = "none";
document.getElementById("poiFormMap").style.display = "block"; document.getElementById("poiFormMap").style.display = "block";
initLocationMap(locationList.options[locationList.options.selectedIndex].value); initLocationMap(locationList.options[locationList.options.selectedIndex].value);
} else { } else {
document.getElementById("observationFormMap").style.display = "block"; document.getElementById("observationFormMap").style.display = "block";
document.getElementById("poiFormMap").style.display = "none"; document.getElementById("poiFormMap").style.display = "none";
} }
...@@ -337,6 +368,24 @@ ...@@ -337,6 +368,24 @@
} }
} }
// Return name for given cropOrganismId
function nameForCropOrganismId(cropOrganismId) {
const crop = cropList.find(crop => crop.organismId == cropOrganismId);
return crop ? crop.displayName : null;
}
// Return name for given organismId
function nameForOrganismId(organismId) {
const pest = organismList.find(pest => pest.organismId == organismId);
return pest ? pest.displayName : null;
}
// Return name for given point of interest id
function nameForLocationPointOfInterestId(pointOfInterestId, allPois) {
const location = allPois.find(loc => loc.pointOfInterestId == pointOfInterestId);
return location ? location.name : null;
}
/** /**
* Based on the selected crop category: Put the related crops * Based on the selected crop category: Put the related crops
* on top of the crops list * on top of the crops list
...@@ -386,6 +435,10 @@ ...@@ -386,6 +435,10 @@
function renderCropList(matchingCropOrganismOptions, theRest) { function renderCropList(matchingCropOrganismOptions, theRest) {
var cropOrganismIdList = document.getElementById("cropOrganismIdList"); var cropOrganismIdList = document.getElementById("cropOrganismIdList");
if (!cropOrganismIdList) {
// HTML element does not exist for observations in time series
return;
}
cropOrganismIdList.options.length = 1; cropOrganismIdList.options.length = 1;
for (var i in matchingCropOrganismOptions) { for (var i in matchingCropOrganismOptions) {
cropOrganismIdList.options[cropOrganismIdList.options.length] = matchingCropOrganismOptions[i]; cropOrganismIdList.options[cropOrganismIdList.options.length] = matchingCropOrganismOptions[i];
...@@ -432,6 +485,15 @@ ...@@ -432,6 +485,15 @@
</#if> </#if>
]; ];
var organismList = [
<#list allPests as organism>
{
organismId: ${organism.organismId},
displayName: "${organism.getLocalName(currentLocale.language)!""} (${organism.latinName!""})"
},
</#list>
];
/** /**
* Does all the ifs and buts before form can potentially be submitted * Does all the ifs and buts before form can potentially be submitted
*/ */
...@@ -497,102 +559,128 @@ ...@@ -497,102 +559,128 @@
: ${observation.lastEditedByUser.firstName} ${observation.lastEditedByUser.lastName}</label> : ${observation.lastEditedByUser.firstName} ${observation.lastEditedByUser.lastName}</label>
</div> </div>
</#if> </#if>
<#if ! observation.organism?has_content> <#if observation.observationTimeSeries?has_content>
<div class="form-group">
<label>Tidsserie: ${observation.observationTimeSeries.name}</label><br>
<i>Tidsserier opprettes via appen VIPS feltobservasjoner. Kultur, organisme og sted er
felles for alle observasjoner innenfor en tidsserie, og kan derfor ikke redigeres per
observasjon.</i>
</div>
<div class="form-group">
<label for="cropOrganismId">${i18nBundle.cropOrganismId}</label>
<span id="cropDisplayName"></span>
</div>
<div class="form-group">
<label for="organismId">${i18nBundle.organism}</label>
<span id="pestDisplayName"></span>
</div>
<div class="form-group">
<label for="locationPointOfInterestId">${i18nBundle.location}</label>
<span id="locationDisplayName"></span>
</div>
<input type="hidden" name="cropOrganismId" value="${observation.cropOrganism.organismId}">
<input type="hidden" name="organismId" value="${observation.organism.organismId}">
<input type="hidden" name="locationPointOfInterestId"
value="${observation.locationPointOfInterestId}">
<input type="hidden" name="locationVisibility" value="${locationVisibilityFormValue}">
<#else>
<#if ! observation.organism?has_content>
<div class="form-group">
<label for="cropCategoryId">${i18nBundle.listSelectedCropCategoryOnTop}</label>
<select class="form-control" id="cropCategoryIdList" name="cropCategoryId"
onchange="filterCrops(this.options[this.options.selectedIndex].value);">
<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.cropCategory?lower_case}</option>
<!-- Options added by JavaScript function renderCropCategories() -->
</select>
</div>
</#if>
<div class="form-group"> <div class="form-group">
<label for="cropCategoryId">${i18nBundle.listSelectedCropCategoryOnTop}</label> <label for="cropOrganismId">${i18nBundle.cropOrganismId}</label>
<select class="form-control" id="cropCategoryIdList" name="cropCategoryId" <select class="form-control" id="cropOrganismIdList" name="cropOrganismId"
onchange="filterCrops(this.options[this.options.selectedIndex].value);"> <#if observation.observationId?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly" <#else> onblur="validateField(this);" onchange="updateCropPests();"</#if>>
<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.cropCategory?lower_case}</option> <#if ! observation.observationId?has_content || user.isSuperUser() || user.isOrganizationAdmin()>
<!-- Options added by JavaScript function renderCropCategories() --> <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.cropOrganismId?lower_case}</option>
<option value="-10"
<#if (observation.cropOrganism?has_content && observation.cropOrganism.organismId == -10)>selected="selected"</#if>>${i18nBundle.missingInDatabase}</option>
</#if>
</select> </select>
<span class="help-block" id="${formId}_cropOrganismId_validation"></span>
</div> </div>
</#if> <div class="form-group">
<div class="form-group"> <label for="organismId">${i18nBundle.organism}</label>
<label for="cropOrganismId">${i18nBundle.cropOrganismId}</label> <select class="form-control" name="organismId"
<select class="form-control" id="cropOrganismIdList" name="cropOrganismId" <#if observation.organism?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly"
<#if observation.observationId?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly" <#else> onblur="validateField(this);" onchange="updateCropPests();"</#if>> <#else>onchange="<#if noBroadcast>updateHeadingAndText(this.options[this.options.selectedIndex].text);</#if>initObservationData(this.options[this.options.selectedIndex].value,organizationId);"
<#if ! observation.observationId?has_content || user.isSuperUser() || user.isOrganizationAdmin()> onblur="validateField(this);"</#if>>
<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.cropOrganismId?lower_case}</option> <#if !observation.organism?has_content || user.isSuperUser() || user.isOrganizationAdmin()>
<option value="-10" <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.organism?lower_case}</option>
<#if (observation.cropOrganism?has_content && observation.cropOrganism.organismId == -10)>selected="selected"</#if>>${i18nBundle.missingInDatabase}</option> <option value="-10"
</#if> <#if (observation.organism?has_content && observation.organism.organismId == -10)>selected="selected"</#if>>${i18nBundle.missingInDatabase}</option>
</select> <#list allPests as organism>
<span class="help-block" id="${formId}_cropOrganismId_validation"></span>
</div>
<div class="form-group">
<label for="organismId">${i18nBundle.organism}</label>
<select class="form-control" name="organismId"
<#if observation.organism?has_content && ! user.isSuperUser() && ! user.isOrganizationAdmin()>readonly="readonly"
<#else>onchange="<#if noBroadcast>updateHeadingAndText(this.options[this.options.selectedIndex].text);</#if>initObservationData(this.options[this.options.selectedIndex].value,organizationId);"
onblur="validateField(this);"</#if>>
<#if ! observation.organism?has_content || user.isSuperUser() || user.isOrganizationAdmin()>
<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.organism?lower_case}</option>
<option value="-10"
<#if (observation.organism?has_content && observation.organism.organismId == -10)>selected="selected"</#if>>${i18nBundle.missingInDatabase}</option>
<#list allPests as organism>
<option value="${organism.organismId}"
<#if (observation.organism?has_content && observation.organism.organismId == organism.organismId)>selected="selected"</#if>
>${organism.getLocalName(currentLocale.language)!""} (${organism.latinName!""}
) ${hierarchyCategories.getName(organism.hierarchyCategoryId)?upper_case}</option>
</#list>
<#else>
<#list allPests as organism>
<#if (observation.organism?has_content && observation.organism.organismId == organism.organismId)>
<option value="${organism.organismId}" <option value="${organism.organismId}"
selected="selected">${organism.getLocalName(currentLocale.language)!""} <#if (observation.organism?has_content && observation.organism.organismId == organism.organismId)>selected="selected"</#if>
(${organism.latinName!""} >${organism.getLocalName(currentLocale.language)!""} (${organism.latinName!""}
) ${hierarchyCategories.getName(organism.hierarchyCategoryId)?upper_case}</option> ) ${hierarchyCategories.getName(organism.hierarchyCategoryId)?upper_case}</option>
</#if> </#list>
</#list> <#else>
</#if> <#list allPests as organism>
</select> <#if (observation.organism?has_content && observation.organism.organismId == organism.organismId)>
<span class="help-block" id="${formId}_organismId_validation"></span> <option value="${organism.organismId}"
selected="selected">${organism.getLocalName(currentLocale.language)!""}
(${organism.latinName!""}
) ${hierarchyCategories.getName(organism.hierarchyCategoryId)?upper_case}</option>
</#if>
</#list>
</#if>
</select>
<span class="help-block" id="${formId}_organismId_validation"></span>
</div> </div>
<div class="form-group">
<label for="locationPointOfInterestId">${i18nBundle.location}&nbsp;&nbsp;<button role="button"
type="button"
onclick="addNewLocationPopup();">${i18nBundle.addNew}</button>
</label>
<select class="form-control" name="locationPointOfInterestId" id="locationPointOfInterestId"
onchange="showCorrectMap();" <#if editAccess!="W">readonly="readonly"</#if>>
<option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.location?lower_case}</option>
</select>
<span class="help-block" id="${formId}_locationPointOfInterestId_validation"></span>
</div>
<#if editAccess!="W" && observation.locationIsPrivate?has_content && observation.locationIsPrivate == true>
<input type="hidden" name="locationVisibility" value="private"/>
<#else>
<div class="form-group"> <div class="form-group">
<div class="radio"> <label for="locationPointOfInterestId">${i18nBundle.location}&nbsp;&nbsp;<button
<label> role="button" type="button"
<input type="radio" name="locationVisibility" value="public" onclick="addNewLocationPopup();">${i18nBundle.addNew}</button>
<#if locationVisibilityFormValue == "public">checked="checked"</#if> </label>
/> <select class="form-control" name="locationPointOfInterestId" id="locationPointOfInterestId"
</label> onchange="showCorrectMap();" <#if editAccess!="W">readonly="readonly"</#if>>
${i18nBundle.locationIsPublic} <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.location?lower_case}</option>
</div> </select>
<div class="radio"> <span class="help-block" id="${formId}_locationPointOfInterestId_validation"></span>
</div>
<label> <#if editAccess!="W" && observation.locationIsPrivate?has_content && observation.locationIsPrivate == true>
<input type="radio" name="locationVisibility" value="private" <input type="hidden" name="locationVisibility" value="private"/>
<#if locationVisibilityFormValue == "private">checked="checked"</#if> <#else>
/> <div class="form-group">
</label>
${i18nBundle.locationIsPrivate}
</div>
<#list polygonServices as polygonService>
<div class="radio"> <div class="radio">
<label> <label>
<input type="radio" name="locationVisibility" <input type="radio" name="locationVisibility" value="public"
value="mask_${polygonService.polygonServiceId}" <#if locationVisibilityFormValue == "public">checked="checked"</#if>
<#if locationVisibilityFormValue == "mask_" + polygonService.polygonServiceId>checked="checked"</#if>
/> />
${i18nBundle.maskObservationWith} ${polygonService.polygonServiceName}
</label> </label>
${i18nBundle.locationIsPublic}
</div> </div>
</#list> <div class="radio">
</div>
<label>
<input type="radio" name="locationVisibility" value="private"
<#if locationVisibilityFormValue == "private">checked="checked"</#if>
/>
</label>
${i18nBundle.locationIsPrivate}
</div>
<#list polygonServices as polygonService>
<div class="radio">
<label>
<input type="radio" name="locationVisibility"
value="mask_${polygonService.polygonServiceId}"
<#if locationVisibilityFormValue == "mask_" + polygonService.polygonServiceId>checked="checked"</#if>
/>
${i18nBundle.maskObservationWith} ${polygonService.polygonServiceName}
</label>
</div>
</#list>
</div>
</#if>
</#if> </#if>
<div class="form-group"> <div class="form-group">
<label for="organizationGroupId">${i18nBundle.availableFor} ${i18nBundle.organizationGroupList?lower_case}</label> <label for="organizationGroupId">${i18nBundle.availableFor} ${i18nBundle.organizationGroupList?lower_case}</label>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment