diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/OrganismController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/OrganismController.java index 0696e3199d3286564a4b108e05b3357551c0516c..4473a1a8d4ac2b7e61fb018a481fd06b9ead2ca2 100644 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/OrganismController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/OrganismController.java @@ -311,6 +311,7 @@ public class OrganismController extends HttpServlet { request.setAttribute("cropPest", cropPest); } request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request))); + request.setAttribute("messageKey", request.getParameter("messageKey")); request.getRequestDispatcher("/cropPestForm.ftl").forward(request, response); } else if(action.equals("submitCropPest")) diff --git a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java index 57b7b8fdbb538b9e44c4d1be374cc64e09c8a493..5adfe7915673526377a87ba50b4c6cc62696d16c 100644 --- a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java @@ -267,6 +267,38 @@ public class OrganismBean { } } + /** + * Searching recursively upwards in organism tree to find a cropPest. + * @param cropOrganismId id of the crop + * @param isPrimaryCrop false if this is the original crop, true if search upwards + * @return + */ + public CropPest getCropPestRecursive(Integer cropOrganismId, boolean isPrimaryCrop) + { + // Try to find a cropPest for this crop + CropPest cropPest = this.getCropPest(cropOrganismId); + // If found AND either it is the primary crop OR it's a parent set to include all child crops + // we return it + if(cropPest != null && (isPrimaryCrop || cropPest.getIncludeAllChildCrops())) + { + return cropPest; + } + // If not, check if parent crop exists and keep on searching + // (If no parent crop, we're done and return empty handed) + else + { + Organism o = em.find(Organism.class, cropOrganismId); + if(o.getParentOrganismId() != null) + { + return this.getCropPestRecursive(o.getParentOrganismId(), false); + } + else + { + return null; + } + } + } + public CropPest storeCropPest(CropPest cropPest) { return em.merge(cropPest); diff --git a/src/main/java/no/nibio/vips/logic/service/LogicService.java b/src/main/java/no/nibio/vips/logic/service/LogicService.java index fa00289ed5354571648d74803ef30f431fe0b383..07a4764d030c1cf8d65e7a8c01aa68219a8d8c0a 100644 --- a/src/main/java/no/nibio/vips/logic/service/LogicService.java +++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java @@ -48,6 +48,7 @@ import javax.ws.rs.core.Response; import no.nibio.vips.coremanager.service.ManagerResource; import no.nibio.vips.entity.WeatherObservation; import no.nibio.vips.logic.authenticate.PasswordValidationException; +import no.nibio.vips.logic.entity.CropPest; import no.nibio.vips.logic.entity.ForecastResult; import no.nibio.vips.logic.i18n.SessionLocaleUtil; import no.nibio.vips.logic.entity.ForecastConfiguration; @@ -592,6 +593,22 @@ public class LogicService { } } + @GET + @Path("organism/croppest/{cropOrganismId}") + @Produces("application/json;charset=UTF-8") + public Response getCropPest(@PathParam("cropOrganismId") Integer cropOrganismId) + { + CropPest retVal = SessionControllerGetter.getOrganismBean().getCropPestRecursive(cropOrganismId,true); + if(retVal != null) + { + return Response.ok().entity(retVal).build(); + } + else + { + return Response.status(Response.Status.NO_CONTENT).build(); + } + } + private ManagerResource getManagerResource() { Client client = ClientBuilder.newClient(); diff --git a/src/main/webapp/js/util.js b/src/main/webapp/js/util.js index f86837a8bc52d5e8abece528208ac616782a3086..adebd204fecb46cff0e7516df55a3bc4c5e2e461 100644 --- a/src/main/webapp/js/util.js +++ b/src/main/webapp/js/util.js @@ -21,3 +21,16 @@ function setFieldValue(theForm, fieldName, value) { theForm[fieldName] = value; } + +var compareSelectListOptions = function(a,b) +{ + if(a.text < b.text) + { + return -1; + } + if(a.text > b.text) + { + return 1; + } + return 0; +} diff --git a/src/main/webapp/templates/cropPestForm.ftl b/src/main/webapp/templates/cropPestForm.ftl index e534dbaee4cdd6067e8c9648a8bce2645f93bd42..e709ec318626f0c9c1d054cf12629bf1232aed61 100644 --- a/src/main/webapp/templates/cropPestForm.ftl +++ b/src/main/webapp/templates/cropPestForm.ftl @@ -40,6 +40,9 @@ <#macro page_contents> <div class="singleBlockContainer"> <h1>${i18nBundle.editCropPests}</h1> + <#if messageKey?has_content> + <div class="alert alert-success">${i18nBundle(messageKey)}</div> + </#if> <#assign formId = "cropPestForm"> <form id="${formId}" action="/organism?action=submitCropPest" method="POST" role="form" onsubmit="return validateForm(this);"> <div class="form-group"> diff --git a/src/main/webapp/templates/observationForm.ftl b/src/main/webapp/templates/observationForm.ftl index 8b0617a8ac928e76a8a4a2fa15d3ee7d163713ea..8715c0e4995eb533e275bf128eef5baf2ddc7c30 100755 --- a/src/main/webapp/templates/observationForm.ftl +++ b/src/main/webapp/templates/observationForm.ftl @@ -35,6 +35,7 @@ <script type="text/javascript" src="/js/constants.js"></script> <script type="text/javascript" src="/js/resourcebundle.js"></script> <script type="text/javascript" src="/js/validateForm.js"></script> + <script type="text/javascript" src="/js/util.js"></script> <script type="text/javascript" src="/js/objectGISInfoMap.js"></script> <script type="text/javascript"> var organizationId = ${user.organizationId.organizationId}; @@ -131,6 +132,70 @@ mw.buildWidgets(); }; + var updateCropPests = function(){ + var theForm = document.getElementById('observationForm'); + var selectedCropId = theForm["cropOrganismId"].options[theForm["cropOrganismId"].options.selectedIndex].value; + // If this is not a new observation, or the selected crop is not in the database, we keep calm + if(theForm["observationId"].value !== "-1" || selectedCropId == "-10") + { + return; + } + $.getJSON( "/rest/organism/croppest/" + selectedCropId, function( json ) { + updateCropPestsCallback(json); + }) + .fail(function() { + alert( "Error getting pests for this crop. Please contact system administrator" ); + }); + }; + + var updateCropPestsCallback = function(cropPest) { + var pestList = document.getElementById('observationForm')["organismId"]; + if(cropPest == null) + { + // Need to reorganize pests back to default + var allPests = []; + for(var i=2;i<pestList.options.length;i++) + { + allPests.push(pestList.options[i]); + } + allPests.sort(compareSelectListOptions); + pestList.options.length=2; // Keeping the top two + for(var i=0;i<allPests.length;i++) + { + pestList.options[pestList.options.length] = allPests[i]; + } + } + else + { + var prioritatedPests = []; + var unprioritatedPests = [] + for(var i=2;i<pestList.options.length;i++) + { + if(cropPest.pestOrganismIds.indexOf(parseInt(pestList.options[i].value)) >= 0) + { + //console.log(pestList.options[i].value + " is prioritated"); + prioritatedPests.push(pestList.options[i]); + } + else if(pestList.options[i].value != "-1") // Avoiding the "---" option + { + //console.log(pestList.options[i].value + " is unprioritated"); + unprioritatedPests.push(pestList.options[i]); + } + + } + pestList.options.length=2; // Keeping the top two + for(var i=0;i<prioritatedPests.length;i++) + { + pestList.options[pestList.options.length] = prioritatedPests[i]; + } + pestList.options[pestList.options.length] = new Option("---","-1"); + for(var i=0;i<unprioritatedPests.length;i++) + { + pestList.options[pestList.options.length] = unprioritatedPests[i]; + } + } + }; + </script> </#macro> <#macro page_contents> @@ -156,7 +221,7 @@ <div class="form-group"> <label for="cropOrganismId">${i18nBundle.cropOrganismId}</label> - <select class="form-control" name="cropOrganismId" <#if observation.organism?has_content>readonly="readonly"<#else>onblur="validateField(this);"</#if>> + <select class="form-control" name="cropOrganismId" <#if observation.organism?has_content>readonly="readonly"<#else>onblur="validateField(this);"</#if> onchange="updateCropPests();"> <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> <#list allCrops?sort_by("latinName") as cropOrganism>