diff --git a/ipmd/static/ipmd/js/ipmdlib.js b/ipmd/static/ipmd/js/ipmdlib.js index 043717d4f713f9d4967e926fb8c07775a6e072a4..0963a9eb4fd98f14aae37a5756a10dbe1561c4fe 100644 --- a/ipmd/static/ipmd/js/ipmdlib.js +++ b/ipmd/static/ipmd/js/ipmdlib.js @@ -154,7 +154,17 @@ async function getStationWeatherData(endpoint, weatherStationId, parameters, int + "&weatherStationId=" + weatherStationId + "¶meters=" + parameters.join(",") ); - return await response.json(); + + if(response.status == 200) + { + return await response.json(); + } + else + { + let errorMessage = "No weather data was returned. Message from the data source was: \n\n" + await response.text(); + alert(errorMessage); + return null; + } } /** @@ -177,7 +187,18 @@ async function getLocationWeatherData(endpoint, longitude, latitude, parameters, + "&latitude=" + latitude + "¶meters=" + parameters.join(",") ); - return (response.status == 200) ? await response.json() : null; + + if(response.status == 200) + { + return await response.json(); + } + else + { + let errorMessage = "No weather data was returned. Message from the data source was: \n\n" + await response.text(); + alert(errorMessage); + return null; + } + } /** @@ -500,13 +521,13 @@ function getUnix(aDate) } /** - * Saves a bit of typing. Currently checks if the val is either undefined or null + * Saves a bit of typing. Currently checks if the val is either undefined or null, and if a string == "" * @param {Object} val * @returns {Boolean} true if the value is considered empty */ function isEmpty(val) { - return val === undefined || val === null; + return val === undefined || val === null || (typeof val === "string" && val.trim() == ""); } // Keeping track of maps diff --git a/ipmd/templates/ipmd/saddlegallmidgeform.html b/ipmd/templates/ipmd/saddlegallmidgeform.html index cc2e680caffae718eb8ca4974dfd099397812e77..023edf430f461d9f90e45fc8fee62ae6af6c8e57 100644 --- a/ipmd/templates/ipmd/saddlegallmidgeform.html +++ b/ipmd/templates/ipmd/saddlegallmidgeform.html @@ -68,7 +68,7 @@ </div> <div class="col-md-6"><div id="forecastDatasourceMap"></div></div> </div> - <button class="btn btn-primary" type="button" onclick="submitData();">Submit</button> + <button class="btn btn-primary" type="button" onclick="submitData();">Run</button> <div style="aspect-ratio: 2;"> <canvas id="resultChart"></canvas> </div> @@ -168,8 +168,8 @@ // TODO: Remove this auto-mock!! /*editor.getValue().optionalData.startDate="2023-08-01"; - editor.getValue().optionalData.endDate="2023-08-19"; - document.getElementById("longitude").value="11.781989"; + editor.getValue().optionalData.endDate="2023-09-16"; + /*document.getElementById("longitude").value="11.781989"; document.getElementById("latitude").value="59.680468";*/ //submitData(); } @@ -356,7 +356,13 @@ */ function getLatLon() { - return [document.getElementById("longitude").value, document.getElementById("latitude").value]; + let lon = document.getElementById("longitude").value; + let lat = document.getElementById("latitude").value; + if(!isEmpty(lon) && !isEmpty(lat)) + { + return [lon,lat]; + } + else return null; } /** @@ -364,7 +370,27 @@ * Also collects weather data (which goes into the input data Json) */ async function submitData(){ + + // Input validation + const errors = editor.validate(); + if(errors.length) + { + console.log(errors); + alert("Input data errors. Please check your browser's error log. (TODO: improve this message!!)") + return; + } + let inputData = editor.getValue(); + + /* + The saddle gall midge model input_data schema does not require the dates to be set, + so we must check manually + */ + if(isEmpty(inputData.optionalData.startDate) || isEmpty(inputData.optionalData.endDate)) + { + alert("ERROR: Your start and/or end date is not set."); + return; + } // Add hidden parameters let fullSchema = JSON.parse(currentModelMetaData["execution"]["input_schema"]); const hiddenParameters = currentModelMetaData["execution"]["input_schema_categories"]["hidden"]; @@ -376,6 +402,12 @@ // Check for weatherData element. Assuming it's at the root node if(fullSchema["properties"]["weatherData"] !== undefined) { + // Input check + if(currentWeatherDatasource == undefined && currentForecastWeatherDatasource == undefined) + { + alert("ERROR: No weather datasource(s) selected"); + return; + } let forecastData = undefined; // 1. Historic weather data if(currentWeatherDatasource != undefined) @@ -384,6 +416,13 @@ { let weatherStationId = selectList.options[selectList.selectedIndex].value; + // Input check: Is a weather station selected? + if(weatherStationId == "-1") + { + alert("ERROR: No weather station has been selected"); + return; + } + weatherData = await getStationWeatherData( getWeatherDatasourceEndpoint(currentWeatherDatasource), weatherStationId, @@ -406,6 +445,11 @@ else { coordinate = getLatLon(); + if(coordinate == null) + { + alert("ERROR: Your location is not set"); + return; + } // Need to check that the selected datasource covers the requested location if(! await isPointCoveredByDatasource(coordinate, currentWeatherDatasource)) { @@ -436,6 +480,13 @@ // 2. Forecast weather data if(currentForecastWeatherDatasource != undefined) { + coordinate = getLatLon(); + if(coordinate == null) + { + alert("ERROR: Your location is not set"); + return; + } + // Need to check that the selected datasource covers the requested location if(! await isPointCoveredByDatasource(getLatLon(), currentForecastWeatherDatasource)) { @@ -444,8 +495,8 @@ } forecastData = await getLocationWeatherData( getWeatherDatasourceEndpoint(currentForecastWeatherDatasource), - document.getElementById("longitude").value, - document.getElementById("latitude").value, + coordinate[0], + coordinate[1], getPragmaticWeatherParameterList( function (){ let parameterList = []