/    Sign up×
Community /Pin to ProfileBookmark

Dynamically load data in javascript

have some code that I will show below and I want to dynamically load some images using javascript. The images to be loaded are coming from my python script and will be processing some data every 3 hours. After the process from the python is done. The output image is then displayed in a website. So the input of the images needs to be dynamic.

[code]<script>
function playImages(parameter) {
var path = “”;
if(parameter == “precip”) {
path = “path to the precip folder”
}else if(parameter == “temp”) {
path = “path to the temp folder”
} else {
path = “path to the wind folder”
}
let listOfImages = [
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00000.png”,
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00100.png”,
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00200.png”,
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00300.png”,
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00400.png”,
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00500.png”,
“pyqgis-ops/PrecipRate/prate_rpnprate-postwrf_d01_20180923_0600_f00600.png”
];

let currentKey = 0;
let sizeOfImages = listOfImages.length;

setInterval(function(){
let strSplit = listOfImages[currentKey].split(‘-‘);
let removeOtherText = strSplit[1].replace(“postwrf_d01_”,””).replace(“.png”,””);
let dateSplit = removeOtherText.split(‘_’);

$(“#img-container”).attr(‘src’, listOfImages[currentKey]);
$(“#img-container”).attr(‘data-key’, currentKey);
$(“#date”).text(dateSplit[0] + ‘ ‘ + dateSplit[1] + ‘ ‘ + dateSplit[2]);
currentKey = currentKey + 1;

if(currentKey == sizeOfImages) {
currentKey = 0;
}
},1500);
}

playImages(“precip”);
let strSplit = “prate_rpnprate-postwrf_d01_20180923_0600_f00000.png”.split(‘-‘);
let removeOtherText = strSplit[1].replace(“postwrf_d01_”,””).replace(“.png”,””);
let dateSplit = removeOtherText.split(‘_’);
console.log(dateSplit[0]);
console.log(dateSplit[1]);
console.log(dateSplit[2]);
// $(“#select”).change(function() {
// playImages();
// });

</script>[/code]

The code above is just a scratch because I have no prior knowledge on how to use javascript. and the let listofImages part is how I “manually” load the images. any help will be greatly appreciated

Edited by site staff: Inserted code tags.

to post a comment
JavaScript

335 Comments(s)

Copy linkTweet thisAlerts:
@SempervivumJun 19.2019 — Please use code tags when posting code, it will increase readability a lot.

https://www.bbcode.org/examples/?id=15
Copy linkTweet thisAlerts:
@frncsknauthorJun 19.2019 — @Sempervivum#1605015 noted!. Thank you for the heads up
Copy linkTweet thisAlerts:
@SempervivumJun 19.2019 — One question to start with: Is listOfImages static? The file names seem to contain a date and I suspect this might be dynamic?
Copy linkTweet thisAlerts:
@frncsknauthorJun 19.2019 — @Sempervivum#1605020 Yes listOfImages is static. I did this for testing and see if the script as a whole works. But I want the script to be dynamic.

Because I have a python script that runs every 3 hours. and its output are the images to be displayed using js. The images needs to be changed every 3 hours so it needs to be dynamic
Copy linkTweet thisAlerts:
@frncsknauthorJun 19.2019 — @Sempervivum#1605020 My python script processes 3 parameters (rainfall, wind and temperature. they are all saved as images) and they all are saved in subfolders inside my var/www/html (ie. /var/www/html/ops/Prate/ so on). I want to know how to load my script's outputs to my web portal using java script. I don't want to define filenames because it needs to be "dynamic" meaning what is processed by the script. that will be displayed in my portal. Sorry for grammar. english is not my first language
Copy linkTweet thisAlerts:
@SempervivumJun 19.2019 — Let's see if I understand this correctly:

Your python script creates images and their filenames are defined according the pattern visible in listOfImages? And you intend to pick the latest image and display it on your website? And extract date and time from the filename and display it in #date?
Copy linkTweet thisAlerts:
@frncsknauthorJun 19.2019 — @Sempervivum#1605053 My python script creates images that are arranged numerically and hopefully displayed in the website also numerically. so for example my script creates 0-144 images they have to be displayed accordingly. I want to extract the filename and also display it because it provides the date of the forecast, the utc, and the forecast hour. those are additional information that I need to display.
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — I see.

"prate_rpnprate-postwrf_d01_20180923_0600_f00000.png"

is the file name (e. g.) of one image. Obviously "20180923" is the date. Which is utc and which is forecast hour?

Seems to me that this can be done better in PHP by use of the function glob() for reading the images.
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605097 for example prate_rpnprate-postwrf_d01_20180923_0600_f00000.png is one of the filenames 20180923 is the date 0600 is the utc and f00000 is the forecast hour. I attached an image below for better understanding. That is just a sample since I have no idea how to properly do this.

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-20/1560990956-969408-kazam-screenshot-00003.png]
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — Is it really necessary to update the images cyclically every 1.5 sec.? Or do you mean every 1500 secs?

Anyway, as already written above, this can be done easily by PHP:
$images = glob("forecast/*.png");
foreach ($images as $img) {
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result) {
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
echo '&lt;figure&gt;&lt;img src="' . $img . '"&gt;';
echo '&lt;figcaption&gt;date: ' . $date . ', utc: ' . $utc . ', forecasthour: ' . $forecasthour;
echo '&lt;/figcaption&gt;&lt;/figure&gt;';
}
}
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605100 the images are played like a gif. its for forecasting purposes. and 1500 is milliseconds. that is the interval between images.
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — I see. Can be done either, however my local time is past 3:00 AM. Have to finish now.
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605102 Thank you so much for the help and patience! I have other queries but I will just reserve that some other time. Thanks again!
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605100 Hello! I tested your suggestion and this is the output:
<i>
</i>&lt;?php
$images = glob("pyqgis-ops/Temperature/*.png");
foreach ($images as $img) {
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result) {
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
echo '&lt;figure&gt;&lt;img src="' . $img . '"&gt;';
echo '&lt;figcaption&gt;date: ' . $date . ', utc: ' . $utc . ', forecasthour: ' . $forecasthour;
echo '&lt;/figcaption&gt;&lt;/figure&gt;';
}
} <br/>
?&gt;


The output:

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-20/1561009350-90915-kazam-screenshot-00004.png]

Is it possible that they are located in one place? then when the image changes that creates the illusion of it becoming a gif?
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — Yes, of course this is possible. Try this code, it works for me:
$images = glob("pyqgis-ops/Temperature/*.png");
$forecastdata = [];
foreach ($images as $img) {
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result) {
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
$forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
}
}
?&gt;
&lt;figure id="figure-forecast"&gt;&lt;/figure&gt;;
&lt;script&gt;
var forecastdata = &lt;?php echo json_encode($forecastdata); ?&gt;;
var idx = 0;
var tpl = <span><code>
&amp;lt;img src=&quot;{src}&quot;&amp;gt;
&amp;lt;figcaption&amp;gt;date: {date}, utc: {utc}, forecasthour: {forecasthour};
&amp;lt;/figcaption&amp;gt;</code></span>;
var thefigure = document.getElementById('figure-forecast');
setInterval(function() {
var thehtml = tpl
.replace('{src}', forecastdata[idx].img)
.replace('{date}', forecastdata[idx].date)
.replace('{utc}', forecastdata[idx].utc)
.replace('{forecasthour}', forecastdata[idx].forecasthour);
thefigure.innerHTML = thehtml;
idx++;
if (idx == forecastdata.length) idx = 0; <br/>
}, 1500);
&lt;/script&gt;
When an image is loaded the first time there might be some flickering. This can be fixed by preloading the images.
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605107 WOW! It worked for me too. but yeah there is some flickering. maybe css can handle the flickering once I put this in my main code. thank you sooo much

can php handle animation interval?
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — Try if preloading helps:
&lt;script&gt;
var forecastdata = &lt;?php echo json_encode($forecastdata); ?&gt;;

<i> </i>// preload images in order to avoid flickering
<i> </i>var imgs = [];
<i> </i>for (var i = 0; i &lt; forecastdata.length; i++) {
<i> </i> var imgs[i] = new Image();
<i> </i> imgs[i].src = forecastdata[idx].img;
<i> </i>}
<i> </i>
<i> </i>var idx = 0;
<i> </i>var tpl = <span><code>
&lt;i&gt; &lt;/i&gt; &amp;lt;img src=&quot;{src}&quot;&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;figcaption&amp;gt;date: {date}, utc: {utc}, forecasthour: {forecasthour};
&lt;i&gt; &lt;/i&gt; &amp;lt;/figcaption&amp;gt;</code></span>;
<i> </i>var thefigure = document.getElementById('figure-forecast');
<i> </i>setInterval(function() {
<i> </i> var thehtml = tpl
<i> </i> .replace('{src}', forecastdata[idx].img)
<i> </i> .replace('{date}', forecastdata[idx].date)
<i> </i> .replace('{utc}', forecastdata[idx].utc)
<i> </i> .replace('{forecasthour}', forecastdata[idx].forecasthour);
<i> </i> thefigure.innerHTML = thehtml;
<i> </i> idx++;
<i> </i> if (idx == forecastdata.length) idx = 0;
<i> </i>}, 1500);
&lt;/script&gt;

I'm note shure what you mean "can php handle animation interval?". It is possible to apply some transition effects like sliding or blending by use of javascript. The easiest way to do this is using a library like cycle2:

http://jquery.malsup.com/cycle2/
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605111 I mean if for example the one that you made the animation interval is by 1 meaning the animation will start with frame 1 then 2 and so on. say I want the animation to be by 3 then it will skip frames and start the animation on frame 3 then 6, 9 and so on.
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — Yes, this can be done by extending the PHP a bit:
&lt;?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$images = glob("forecast/*.png");
$forecastdata = [];
$intv = 3;
$idx = 0;
foreach ($images as $img) {
if ($idx % $intv == 0) {
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result) {
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
$forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
}
}
$idx++;
}
?&gt;
This time I did not test it as I had not enough images.
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605114 Thank you so much for your help and patience! I will try your suggestion
Copy linkTweet thisAlerts:
@SempervivumJun 20.2019 — You're welcome!

In the meantime I found two errors in the code for preloading. This should be correct now:
// preload images in order to avoid flickering
var imgs = [];
for (var i = 0; i &lt; forecastdata.length; i++) {
imgs[i] = new Image();
imgs[i].src = forecastdata[i].img;
}
Copy linkTweet thisAlerts:
@frncsknauthorJun 20.2019 — @Sempervivum#1605135 Yes. I just tried it and it throws me an error too. Thank you so much. You've saved me so much pain.
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605135 Hello! do you have any alternatives or suggestions for this?

My main code has a dropdown menu:
<i>
</i> &lt;div class="col-md-2"&gt;
&lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
&lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;h3&gt;Products:&lt;/h3&gt;
&lt;select id="select"&gt;
&lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
&lt;option value="prate"&gt;Precipitation Rate&lt;/option&gt;
&lt;option value="temp"&gt;Temperature&lt;/option&gt;
&lt;option value="wind"&gt;Wind&lt;/option&gt;
&lt;/select&gt;
&lt;/div&gt;

<i> </i> &lt;div class="col-md-9"&gt;
<i> </i> &lt;div class="content-area"&gt;
<i> </i> **THE CONTENT SUPPOSED TO BE DISPLAYED HERE**
<i> </i> &lt;/div&gt;
<i> </i> &lt;/div&gt;


And I have this js that controls the dropdown. when I have html files it works but now the selected value is php it doesn't work now. here is the code of my js:
<i>
</i>$("#select").on('change', function() {
let jThis = $(this);
let selectVal = jThis.val();

if(selectVal == "prate") {
$(".content-area").get("pyqgis-ops/PrecipRate/prate.php");
} else if(selectVal == "temp") {
$(".content-area").load("/pyqgis-ops/Temperature/temp.html");
} else if(selectVal == "wind") {
$(".content-area").load("/pyqgis-ops/Wind850mb/wind.html");
} else {
$(".content-area").html("No filters");
}
});
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — Why did you use get instead of load? get will not return the output of the script but a jqXHR object. When I change it to load everything works fine.
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605175 Yes. my bad I changed it back to load. but It throws me 2 errors:

1st is this is the code:
<i>
</i> &lt;?php
$images = glob ("pyqgis-ops/PrecipRate/*.png");
$forecastdata = [];
foreach ($images as $img) {
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result){
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
$forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
}
}
?&gt;

This is the error: Uncaught TypeError: Cannot read property 'img' of undefined
at eval (eval at &lt;anonymous&gt; (jquery.js:2), &lt;anonymous&gt;:18:49)


2nd code: (I only changed the path since the php file is inside the precip folder same as the images)
<i>
</i> &lt;?php
$images = glob ("*.png");
$forecastdata = [];
foreach ($images as $img) {
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result){
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
$forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
}
}
?&gt;

This is the error: Failed to load resource: the server responded with a status of 404 (Not Found)
Maybe its a path issue but I'm not sure. The date, utc, and forecast hour is showing but the image is not

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-21/1561100936-879346-kazam-screenshot-00005.png]
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — Please post the lines where these errors occur. At the first error jquery is mentioned, thus it seems to be an error in the javascript not PHP.
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — PS: I suspect that the HTML file is located in a different folder than the PHP one. The PHP script gets relative paths for the images, i. e. if it's located in the same path as the images it will get the filenames only. However the base path for the javascript is the the path where the HTML file resides. That means that you need to add the folder to the filenames of the images like this:
&lt;script&gt;
var forecastdata = &lt;?php echo json_encode($forecastdata); ?&gt;;
var folder = 'somefolder/'; // added
// preload images in order to avoid flickering
var imgs = [];
for (var i = 0; i &lt; forecastdata.length; i++) {
imgs[i] = new Image();
imgs[i].src = folder + forecastdata[i].img; // changed here
}

<i> </i>var idx = 0;
<i> </i>var tpl = <span><code>
&lt;i&gt; &lt;/i&gt; &amp;lt;img src=&quot;{src}&quot;&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;figcaption&amp;gt;date: {date}, utc: {utc}, forecasthour: {forecasthour};
&lt;i&gt; &lt;/i&gt; &amp;lt;/figcaption&amp;gt;</code></span>;
<i> </i>var thefigure = document.getElementById('figure-forecast');
<i> </i>setInterval(function() {
<i> </i> var thehtml = tpl
<i> </i> .replace('{src}', folder + forecastdata[idx].img) // changed here
<i> </i> .replace('{date}', forecastdata[idx].date)
<i> </i> .replace('{utc}', forecastdata[idx].utc)
<i> </i> .replace('{forecasthour}', forecastdata[idx].forecasthour);
<i> </i> thefigure.innerHTML = thehtml;
<i> </i> idx++;
<i> </i> if (idx == forecastdata.length) idx = 0;
<i> </i>}, 1500);
&lt;/script&gt;
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605184 I traced it back to this line .replace('{src}', forecastdata[idx].img)[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-21/1561102265-56761-kazam-screenshot-00006.png]
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — Then it's obviously a path issue. Read my second posting above.
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605187 Yes the php file is located together with the images here /var/www/html/pyqgis-ops/PrecipRate/. the script that handles the filters of the dropwdown menu is located in /var/www/html/js/ and the main website is located in /var/www/html/gis.html

I tried your suggestion and it got me this error:
<i>
</i>VM2849:2 Uncaught SyntaxError: Unexpected token var
at eval (&lt;anonymous&gt;)
at jquery.js:2
at Function.globalEval (jquery.js:2)
at Ha (jquery.js:3)
at n.fn.init.append (jquery.js:3)
at n.fn.init.&lt;anonymous&gt; (jquery.js:3)
at Y (jquery.js:3)
at n.fn.init.html (jquery.js:3)
at Object.&lt;anonymous&gt; (jquery.js:4)
at i (jquery.js:2)


I don't know what the issue is with jquery because I just src'd it.
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — Is this:
/var/www/html/_gis.html_
the filename or the folder? The trailing "_" is confusing me.
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605190 That is just a typo. I'm so sorry but gis.html is the filename of the website that handles the dropdown menu and the display of the images
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — That's fine! Gonna look into now ...
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605190 I solved the error by putting the php files outside of the images and putting it beside the gis.html. edited the path in the js filter
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — I see, that's fine! Does the forecast work now?
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605194 Yes it does! Thank you so much again! You've been such a big help
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — You're welcome, that's fine that we got it working now!
Copy linkTweet thisAlerts:
@frncsknauthorJun 21.2019 — @Sempervivum#1605196 Is it ok if I have more questions? but its friday here so I will be asking those on monday

Again thank you so much. You've saved me. I'm rushing this project because the onset of the rainy season will be starting here soon so I need this to be finished.
Copy linkTweet thisAlerts:
@SempervivumJun 21.2019 — Is it ok if I have more questions?[/quote]Yes, of course, you're welcome!
Copy linkTweet thisAlerts:
@frncsknauthorJun 25.2019 — @Sempervivum#1605200 Hello. Can I ask a couple of other questions? I want to add some more features for the website
Copy linkTweet thisAlerts:
@SempervivumJun 25.2019 — @frncskn#1605318 Yes, feel free to ask.
Copy linkTweet thisAlerts:
@frncsknauthorJun 26.2019 — @Sempervivum#1605321 Hello! for example the one that you made the animation interval is by 1 meaning the animation will start with frame 1 then 2 and so on. say I want the animation to be by 3 then it will skip frames and start the animation on frame 3 then 6, 9 and so on.

I just want to know how to connect this code from my gis.html
<i>
</i> &lt;div class="col-md-2"&gt;
&lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
&lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
&lt;h5&gt;Products:&lt;/h5&gt;
&lt;select id="select"&gt;
&lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
&lt;option value="prate"&gt;Precipitation Rate&lt;/option&gt;
&lt;option value="temp"&gt;Temperature&lt;/option&gt;
&lt;option value="wind"&gt;Wind&lt;/option&gt;
&lt;option value="rh"&gt;Relative Humidity&lt;/option&gt;
&lt;option value="cc"&gt;Cloud Cover&lt;/option&gt;
&lt;/select&gt;
&lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
&lt;form&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio" checked&gt;1
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio"&gt;3
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio"&gt;6
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio"&gt;12
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio"&gt;24
&lt;/label&gt;
&lt;/form&gt;
&lt;/div&gt;


This is the js that controls the buttons:
<i>
</i>$("#select").on('change', function() {
let jThis = $(this);
let selectVal = jThis.val();

if(selectVal == "prate") {
$(".content-area").load("prate.php");
} else if(selectVal == "temp") {
$(".content-area").load("temp.php");
} else if(selectVal == "wind") {
$(".content-area").load("wind.php");
} else if(selectVal == "rh") {
$(".content-area").load("rh.php");
} else if(selecVal == "cc") {
$(".content-area").load("cc.php");
} else {
$(".content-area").html("error.html");
}
});

I guess the Animation Interval js will go together with js script above.
Copy linkTweet thisAlerts:
@SempervivumJun 26.2019 — say I want the animation to be by 3 then it will skip frames and start the animation on frame 3 then 6, 9 and so on.[/quote]
Try this (untested):
var idx = 0, step = 3;
var tpl = <span><code>
&amp;lt;img src=&quot;{src}&quot;&amp;gt;
&amp;lt;figcaption&amp;gt;date: {date}, utc: {utc}, forecasthour: {forecasthour};
&amp;lt;/figcaption&amp;gt;</code></span>;
var thefigure = document.getElementById('figure-forecast');
setInterval(function() {
var thehtml = tpl
.replace('{src}', folder + forecastdata[idx].img) // changed here
.replace('{date}', forecastdata[idx].date)
.replace('{utc}', forecastdata[idx].utc)
.replace('{forecasthour}', forecastdata[idx].forecasthour);
thefigure.innerHTML = thehtml;
idx += step;
if (idx &gt;= forecastdata.length) idx = 0; <br/>
}, 1500);
Copy linkTweet thisAlerts:
@SempervivumJun 26.2019 — PS: I overlooked that you want to control the step by radiobuttons. I'm going to code this later.
Copy linkTweet thisAlerts:
@frncsknauthorJun 26.2019 — @Sempervivum#1605399 the step = 3 If I want to add more. will it become step = 3, step=6, step and so on?
Copy linkTweet thisAlerts:
@frncsknauthorJun 26.2019 — @Sempervivum#1605399 thank you so much!

PS: I forgot that the frames starts with 0 not 1

ie. from f00000.png up tof14400.png = 145 images per forecast
Copy linkTweet thisAlerts:
@SempervivumJun 26.2019 — @frncskn#1605404 Does it work now including setting the step by the radiobuttons?
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605432 it works! but how will I "connect" it with the radio buttons?

The screenshot below is the "steps" of interval between images

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-27/1561598368-901109-kazam-screenshot-00000.png]
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — @frncskn#1605442 how will I "connect" it with the radio buttons?[/quote]
For simplicity I added value attributes containing the factors:
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio" value="1" checked&gt;1
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio" value="3"&gt;3
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio" value="6"&gt;6
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio" value="12"&gt;12
&lt;/label&gt;
&lt;label class="radio-inline"&gt;
&lt;input type="radio" name="optradio" value="24"&gt;24
&lt;/label&gt;
Then this jQuery does the job:
var step = 1;
$("input[name='optradio']").on("change", function () {
step = parseInt($("input[name='optradio']:checked").val());
});
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605449

> @Sempervivum#1605398 step = 3;

so I will add here step=1, step=3, step=6, step=12, step=24



> @Sempervivum#1605449 var step = 1;

> $("input[name='optradio']").on("change", function () {

> step = parseInt($("input[name='optradio']:checked").val());

> });

will I put this code here?

> @frncskn#1605387 $("#select").on('change', function() {

> let jThis = $(this);

> let selectVal = jThis.val();
>
> if(selectVal == "prate") {

> $(".content-area").load("prate.php");

> } else if(selectVal == "temp") {

> $(".content-area").load("temp.php");

> } else if(selectVal == "wind") {

> $(".content-area").load("wind.php");

> } else if(selectVal == "rh") {

> $(".content-area").load("rh.php");

> } else if(selecVal == "cc") {

> $(".content-area").load("cc.php");

> } else {

> $(".content-area").html("error.html");

> }

> });
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — You can put it below the code for the select:
&lt;script&gt;
$("#select").on('change', function () {
let jThis = $(this);
let selectVal = jThis.val();

<i> </i> if (selectVal == "prate") {
<i> </i> $(".content-area").load("thread181-wheather-forecast-2.php");
<i> </i> } else if (selectVal == "temp") {
<i> </i> $(".content-area").load("temp.php");
<i> </i> } else if (selectVal == "wind") {
<i> </i> $(".content-area").load("wind.php");
<i> </i> } else if (selectVal == "rh") {
<i> </i> $(".content-area").load("rh.php");
<i> </i> } else if (selecVal == "cc") {
<i> </i> $(".content-area").load("cc.php");
<i> </i> } else {
<i> </i> $(".content-area").html("error.html");
<i> </i> }
<i> </i> });
<i> </i> var step = 1;
<i> </i> $("input[name='optradio']").on("change", function () {
<i> </i> step = parseInt($("input[name='optradio']:checked").val());
<i> </i> });
<i> </i>&lt;/script&gt;

This:

step = 3;
so I will add here step=1, step=3, step=6, step=12, step=24
is not necessary.
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605454 It works! Thank you so much! Is there a way for it, if I select a radio button it refreshes and starts all over again?
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — Yes, simply set idx to 0 in the eventhandler for the radio buttons:
&lt;script&gt;
$("#select").on('change', function () {
let jThis = $(this);
let selectVal = jThis.val();

<i> </i> if (selectVal == "prate") {
<i> </i> $(".content-area").load("thread181-wheather-forecast-2.php");
<i> </i> } else if (selectVal == "temp") {
<i> </i> $(".content-area").load("temp.php");
<i> </i> } else if (selectVal == "wind") {
<i> </i> $(".content-area").load("wind.php");
<i> </i> } else if (selectVal == "rh") {
<i> </i> $(".content-area").load("rh.php");
<i> </i> } else if (selecVal == "cc") {
<i> </i> $(".content-area").load("cc.php");
<i> </i> } else {
<i> </i> $(".content-area").html("error.html");
<i> </i> }
<i> </i> });
<i> </i> var idx = 0, step = 1;
<i> </i> $("input[name='optradio']").on("change", function () {
<i> </i> step = parseInt($("input[name='optradio']:checked").val());
<i> </i> idx = 0;
<i> </i> });
<i> </i>&lt;/script&gt;

And remove this
var idx = 0;
from the Javascript in the PHP file.
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605460 It works! Thank you!

Is it possible if:

[upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-27/1561628004-171024-kazam-screenshot-00001.png]

The date, utc and forecast hour

can be placed here? instead being below the image. and styled like this:

Date:

UTC:

Forecast Hour:
<i>
</i>&lt;div class="col-md-3" style="display: inline;"&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;h3&gt;850mb Wind (km/h)&lt;/h3&gt;
***THIS IS WHERE THE DATE, UTC AND FORECAST HOUR WILL BE HOPEFULLY PLACED <br/>
&lt;/div&gt;

<i> </i>&lt;div class="col-md-9" style="display: inline;"&gt;
<i> </i> &lt;?php
<i> </i> $images = glob ("pyqgis-ops/Wind850mb/*.png");
<i> </i> $forecastdata = [];
<i> </i> foreach ($images as $img) {
<i> </i> $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
<i> </i> if ($result){
<i> </i> $date = $matches[1];
<i> </i> $utc = $matches[2];
<i> </i> $forecasthour = $matches[3];
<i> </i> $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
<i> </i> }
<i> </i> }
<i> </i> ?&gt;
<i> </i> &lt;figure id="figure-forecast"&gt;&lt;/figure&gt;
<i> </i> &lt;script&gt;
<i> </i> var forecastdata = &lt;?php echo json_encode($forecastdata); ?&gt;;

<i> </i> // preload code to avoid flickering
<i> </i> var imgs = [];
<i> </i> for (var i = 0; i &lt; forecastdata.length; i++) {
<i> </i> imgs[i] = new Image();
<i> </i> imgs[i].src = forecastdata[i].img;
<i> </i> }

<i> </i> step = 1;
<i> </i> var tpl = <span><code>
&lt;i&gt; &lt;/i&gt; &amp;lt;img src=&quot;{src}&quot;&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;figcaption&amp;gt;date: {date}, utc: {utc}, forecasthour: {forecasthour};
&lt;i&gt; &lt;/i&gt; &amp;lt;/figcaption&amp;gt;</code></span>;
<i> </i> var thefigure = document.getElementById('figure-forecast');
<i> </i> setInterval(function () {
<i> </i> var thehtml = tpl
<i> </i> .replace('{src}', forecastdata[idx].img)
<i> </i> .replace('{date}', forecastdata[idx].date)
<i> </i> .replace('{utc}', forecastdata[idx].utc)
<i> </i> .replace('{forecasthour}', forecastdata[idx].forecasthour);
<i> </i> thefigure.innerHTML = thehtml;
<i> </i> idx += step;
<i> </i> if (idx &gt;= forecastdata.length) idx = 0;

<i> </i> }, 500);
<i> </i> &lt;/script&gt;

<i> </i>&lt;/div&gt;
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — This PHP/JS should do the job:
&lt;?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$images = glob("forecast/*.png");
$forecastdata = [];
$step = 1;
for ($i = 0; $i &lt; count($images); $i+=$step) {
$img = $images[$i];
$result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
if ($result) {
$date = $matches[1];
$utc = $matches[2];
$forecasthour = $matches[3];
$forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
}
}
?&gt;
&lt;div class="col-md-3" style="display: inline;"&gt;
&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;h3&gt;850mb Wind (km/h)&lt;/h3&gt;
&lt;span id="caption-forecast"&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;div class="col-md-9" style="display: inline;"&gt;
&lt;img id="img-forecast" src="";
&lt;/div&gt;

&lt;script&gt;
var forecastdata = &lt;?php echo json_encode($forecastdata); ?&gt;;

<i> </i>// preload images in order to avoid flickering
<i> </i>var imgs = [];
<i> </i>for (var i = 0; i &lt; forecastdata.length; i++) {
<i> </i> imgs[i] = new Image();
<i> </i> imgs[i].src = forecastdata[i].img;
<i> </i>}

<i> </i>var tplCaption = <span><code>
&lt;i&gt; &lt;/i&gt; &amp;lt;p&amp;gt;date: {date}&amp;lt;/p&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;p&amp;gt;utc: {utc}&amp;lt;/p&amp;gt;
&lt;i&gt; &lt;/i&gt; &amp;lt;p&amp;gt;forecasthour: {forecasthour}&amp;lt;/p&amp;gt;</code></span>;

<i> </i>var thecaption = document.getElementById('caption-forecast');
<i> </i>var theimg = document.getElementById('img-forecast');

<i> </i>setInterval(function() {
<i> </i> console.log(idx, step);
<i> </i> theimg.src = forecastdata[idx].img;
<i> </i> var thehtml = tplCaption
<i> </i> .replace('{src}', forecastdata[idx].img)
<i> </i> .replace('{date}', forecastdata[idx].date)
<i> </i> .replace('{utc}', forecastdata[idx].utc)
<i> </i> .replace('{forecasthour}', forecastdata[idx].forecasthour);
<i> </i> thecaption.innerHTML = thehtml;
<i> </i> idx += step;
<i> </i> if (idx &gt;= forecastdata.length) idx = 0;
<i> </i>}, 1500);
&lt;/script&gt;
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605464 it throws me an error :(
Uncaught ReferenceError: idx is not defined here console.log(idx, step);
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — My bad, forgot to mention this: idx has to be defined here now:
&lt;script&gt;
var forecastdata = &lt;?php echo json_encode($forecastdata); ?&gt;;

<i> </i>// preload code to avoid flickering
<i> </i>var imgs = [];
<i> </i>for (var i = 0; i &lt; forecastdata.length; i++) {
<i> </i> imgs[i] = new Image();
<i> </i> imgs[i].src = forecastdata[i].img;
<i> </i>}

<i> </i>var idx = 0, step = 1;
<i> </i>var tpl =
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605472 IT WORKS! thanks! this can be styled normally in css?
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — Yes, these are regular HTML elements and you can style them as usual.
Copy linkTweet thisAlerts:
@frncsknauthorJun 27.2019 — @Sempervivum#1605475 my boss just asked me if it is possible to put controls in this. Ie. Stop play first button (jump to the first frame w/c is 0) and last button (jump to the last frame which is 144). And if the speed of the animation can be controlled in the gui. She also asked if there is a way if there is a way for the page to autorefresh. (Ie. The page will refresh itself every 1 hr) This will be useful for the newly processed data to be shown. Because as of now I have to manually press the refresh button in the browser to see the changes.

EDIT: the flickering and stuttering sometimes returns
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — Yes, of course this is possible. However the current code is a bit confusing. I'd like to optimize it.
Copy linkTweet thisAlerts:
@SempervivumJun 27.2019 — Done. Code optimized:
  • 1. PHP file reduced, it gets the data only and returns it in JSON format.

  • 2. Template dropped, the values are inserted into the HTML elements directly.


  • Added start/stop button.

    Added first/last button, when one of these is pressed, the animation stops.

    Cyclical refresh added.

    Regarding the speed: IMO the speed is already controlled by the radiobuttons. We might consider changing the labels only so that they are specifying the speed.

    PHP:
    &lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $images = glob("forecast/*.png");
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;


    HTML and Javascript:
    &lt;!doctype html&gt;
    &lt;html lang="en"&gt;

    &lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;Wheather Forecast&lt;/title&gt;

    <i> </i>&lt;script src="https://code.jquery.com/jquery-3.2.1.min.js"&gt;&lt;/script&gt;
    <i> </i>&lt;style&gt;
    <i> </i> img {
    <i> </i> width: 300px;
    <i> </i> }
    <i> </i>&lt;/style&gt;
    &lt;/head&gt;

    &lt;body&gt;
    &lt;div class="content-area"&gt;&lt;/div&gt;
    &lt;div class="col-md-2"&gt;
    &lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
    &lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
    &lt;h5&gt;Products:&lt;/h5&gt;
    &lt;select id="select"&gt;
    &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    &lt;option value="prate"&gt;Precipitation Rate&lt;/option&gt;
    &lt;option value="temp"&gt;Temperature&lt;/option&gt;
    &lt;option value="wind"&gt;Wind&lt;/option&gt;
    &lt;option value="rh"&gt;Relative Humidity&lt;/option&gt;
    &lt;option value="cc"&gt;Cloud Cover&lt;/option&gt;
    &lt;/select&gt;
    &lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
    &lt;form&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="1" checked&gt;1
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="3"&gt;3
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="6"&gt;6
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="12"&gt;12
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="24"&gt;24
    &lt;/label&gt;
    &lt;/form&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;button id="first-btn"&gt;First&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class="col-md-3" style="display: inline;"&gt;
    &lt;br&gt;&lt;br&gt;&lt;br&gt;
    &lt;h3&gt;850mb Wind (km/h)&lt;/h3&gt;
    &lt;p&gt;Date: &lt;span id="forecast-date"&gt;&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;UTC: &lt;span id="forecast-utc"&gt;&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;Hour: &lt;span id="forecast-hour"&gt;&lt;/span&gt;&lt;/p&gt;
    &lt;/div&gt;

    <i> </i>&lt;div class="col-md-9" style="display: inline;"&gt;
    <i> </i> &lt;img id="forecast-img" src=""&gt;
    <i> </i>&lt;/div&gt;
    <i> </i>&lt;script&gt;
    <i> </i> var theimg = document.getElementById('forecast-img'),
    <i> </i> thedate = document.getElementById('forecast-date'),
    <i> </i> theUTC = document.getElementById('forecast-utc'),
    <i> </i> thehour = document.getElementById('forecast-hour');
    <i> </i> var idx = 0, step = 1, stopped = false;
    <i> </i> var forecastdata = [];

    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 1500);

    <i> </i> function loadForecast(url) {
    <i> </i> $.getJSON(url, function (data) {
    <i> </i> forecastdata = data;
    <i> </i> });
    <i> </i> }

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> switch (val) {
    <i> </i> case "prate":
    <i> </i> loadForecast("thread181-wheather-forecast-4.php");
    <i> </i> break;
    <i> </i> case "temp":
    <i> </i> loadForecast("temp.php");
    <i> </i> break;
    <i> </i> case "wind":
    <i> </i> loadForecast("wind.php");
    <i> </i> break;
    <i> </i> case "rh":
    <i> </i> loadForecast("rh.php");
    <i> </i> break;
    <i> </i> case "cc":
    <i> </i> loadForecast("cc.php");
    <i> </i> break;
    <i> </i> default:
    <i> </i> $(".content-area").html("error.html");
    <i> </i> }
    <i> </i> }
    <i> </i> $("#select").on('change', getUrlAndLoad);

    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> $("#start-stop-btn").on("click", function () {
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> $("#first-btn").on("click", function () {
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#last-btn").on("click", function () {
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i>&lt;/script&gt;
    &lt;/body&gt;

    &lt;/html&gt;
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605506 THANK YOU!!!

    If I want to add a next button (changes to the next frame/image) or previous
    <i>
    </i> $("#last-btn").on("click", function () {
    stopped = true;
    $("#start-stop-btn").text("Start");
    idx = forecastdata.length - 1;
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });

    This is the same code to follow?
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — Yes, this should be quite similar. You only need to increase the index:
    $("#next-btn").on("click", function () {
    stopped = true;
    $("#start-stop-btn").text("Start");
    idx += step;
    if (idx &gt;= forecastdata.length) idx = 0;
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });

    Unfortunately this code:
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    occurs multiplely. You might put it into a function.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — > @Sempervivum#1605522 Unfortunately this code:

    > theimg.src = forecastdata[idx].img;

    > thedate.innerHTML = forecastdata[idx].date;

    > theUTC.innerHTML = forecastdata[idx].utc;

    > thehour.innerHTML = forecastdata[idx].forecasthour;if("undefined"!==typeof hljs)hljs._ha();else if("undefined"===typeof hljsLoading){hljsLoading=1;var a=document.getElementsByTagName("head")[0],e=document.createElement("link");e.type="text/css";e.rel="stylesheet";e.href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/default.min.css";a.appendChild(e);e=document.createElement("script");e.type="text/javascript";e.onload=function(){var d={},f=0;hljs._hb=function(b){b.removeAttribute("data-hljs");var c=b.innerHTML;c in d?b.innerHTML=d[c]:(7<++f&&(d={},f=0),hljs.highlightBlock(b.firstChild),d[c]=b.innerHTML)};hljs._ha=function(){for(var b=document.querySelectorAll("pre[data-hljs]"),c=b.length;0<c;)hljs._hb(b.item(--c))};hljs._ha()};e.async=!0;e.src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/highlight.min.js";a.appendChild(e)}occurs multiplely. You might put it into a function.


    what is the side effect of that?
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — There is no side effect. The disadvantage is that it is not friendly to modifications: When changing anything in this code you need to edit in multiple places which is error-prone.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605524 I just tested the code above and it doesn't skip to the next frame
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — For me this code works fine. Do the IDs of the button and in the jQuery match?

    Note that this proceeds according the step that is defined by the radio buttons, i. e. when step is set to three it will skip to idx*3.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605533 If it skips is it still animating or not?

    When I click "next" it the selected parameter becomes deselected. I have to reselect the forecast parameter.

    Its like the button is "crashing"

    EDIT: The other buttons do the same behaviour sometimes :(
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — Is that page online? Then please post the URL.
    When I click "next" it the selected parameter becomes deselected. I have to reselect the forecast parameter.

    Its like the button is "crashing"[/quote]
    Is ther some automatic reloading?
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605537 sadly no. the webpage I'm making is only accessible here within the networks of our office
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — @frncskn#1605538 Then please post the HTML and JS file. I'm gonna try to test it.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605537

    Since you optimized the code. I can't figure out where to place this images.

    this needs to be placed beside the images. 1 forecast parameter has a corresponding color gradient.

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714820-609680-wind10.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714821-179510-wind.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714821-753746-temp.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714822-325367-rh.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714822-896002-prate.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714823-468492-cc.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-06-28/1561714824-63240-3hrlyaccu.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605539

    the HTML and JS
    <i>
    </i> &lt;div class="row" style="background-color: #f4f4f4;"&gt;
    <br/>
    <i> </i> &lt;div class="col-md-3"&gt;
    <i> </i> &lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
    <i> </i> &lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Products:&lt;/h5&gt;
    <i> </i> &lt;select id="select"&gt;
    <i> </i> &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    <i> </i> &lt;option value="prate"&gt;Surface Precipitation Rate&lt;/option&gt;
    <i> </i> &lt;option value="3HrAccum"&gt;3-Hr Accumulated Precipitation&lt;/option&gt;
    <i> </i> &lt;option value="temp"&gt;Surface Temperature&lt;/option&gt;
    <i> </i> &lt;option value="wind"&gt;850mb Wind&lt;/option&gt;
    <i> </i> &lt;option value="10mwind"&gt;10m Wind&lt;/option&gt;
    <i> </i> &lt;option value="rh"&gt;Relative Humidity&lt;/option&gt;
    <i> </i> &lt;option value="cc"&gt;Surface Cloud Cover&lt;/option&gt;
    <i> </i> &lt;/select&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="1" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="3"&gt;3
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="6"&gt;6
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="12"&gt;12
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="24"&gt;24
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;p&gt;Duration: 144.0h&lt;/p&gt;
    <i> </i> &lt;/form&gt;&lt;br&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-6" style="padding: 25px;"&gt;
    <i> </i> &lt;form style="display: block; float: left;font-size: 20px;"&gt;
    <i> </i> &lt;p&gt;Date Initialized: &lt;span id="forecast-date"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;UTC: &lt;span id="forecast-utc"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;Forecast Hour: &lt;span id="forecast-hour"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    <i> </i> &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    <i> </i> &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    <i> </i> &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    <i> </i> &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;img id="forecast-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;script&gt;
    <i> </i> var theimg = document.getElementById('forecast-img'),
    <i> </i> thedate = document.getElementById('forecast-date'),
    <i> </i> theUTC = document.getElementById('forecast-utc'),
    <i> </i> thehour = document.getElementById('forecast-hour');
    <i> </i> var idx = 0, step = 1, stopped = false;
    <i> </i> var forecastdata = [];

    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 500);

    <i> </i> function loadForecast(url) {
    <i> </i> $.getJSON(url, function (data) {
    <i> </i> forecastdata = data;
    <i> </i> });
    <i> </i> }

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> switch (val) {
    <i> </i> case "prate":
    <i> </i> loadForecast("prate.php");
    <i> </i> break;
    <i> </i> case "temp":
    <i> </i> loadForecast("temp.php");
    <i> </i> break;
    <i> </i> case "wind":
    <i> </i> loadForecast("wind.php");
    <i> </i> break;
    <i> </i> case "rh":
    <i> </i> loadForecast("rh.php");
    <i> </i> break;
    <i> </i> case "cc":
    <i> </i> loadForecast("cc.php");
    <i> </i> break;
    <i> </i> case "3HrAccum":
    <i> </i> loadForecast("3HrAccum.php");
    <i> </i> break;
    <i> </i> case "10mwind":
    <i> </i> loadForecast("10mwind.php");
    <i> </i> break;
    <i> </i> }
    <i> </i> }

    <i> </i> $("#select").on('change', getUrlAndLoad);

    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> $("#start-stop-btn").on("click", function() {
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> $("#first-btn").on("click", function() {
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#last-btn").on("click", function() {
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> &lt;/script&gt;


    NOTE: This is how I place the jquery (maybe this is somehow related) just to be sure
    <i>
    </i>&lt;!DOCTYPE html&gt;
    &lt;html lang="en"&gt;

    &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;GIS Mapping&lt;/title&gt;

    <i> </i>&lt;link href="css/bootstrap.css" rel="stylesheet"&gt;
    <i> </i>&lt;link href="css/home.css" rel="stylesheet"&gt;

    <i> </i>&lt;script src="js/jquery.js"&gt;&lt;/script&gt;
    <i> </i>&lt;script src="js/jsclock.js"&gt;&lt;/script&gt;
    <i> </i>&lt;script src="js/bootstrap.min.js"&gt;&lt;/script&gt;

    <i> </i>&lt;link rel="shortcut icon" href="img/pagasafavicon.png" type="image/x-icon"&gt;
    &lt;/head&gt;
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — @frncskn#1605541 Sorry for causing trouble by my optimisation. I have more in mind but will not implement it ;-)

    The color gradient images are easy to add, I'm gonna do this.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605543 Its ok! I like the way you optimized the code. I'm just not that familiar with it because I have no prior knowledge in using php or js until now. sorry

    If you have any suggestion (adding more controls like the animation interval) I would like to hear it because I'd like to add more "features"
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — @frncskn#1605544 I found the reason for the crashing when any of the buttons is pressed: You placed the buttons inside a form tag. The default type for a button tag is "submit". Thus when pressing a button the form is submitted which results in reloading the page when no action is specified. Can be fixed easily by suppressing the default action for each button:
    $("#start-stop-btn").on("click", function (event) {
    event.preventDefault();
    if (!stopped) {
    stopped = true;
    $(this).text("Start");
    } else {
    stopped = false;
    $(this).text("Stop");
    }
    });


    Adding the color gradient images was easy: I added a data attribute to the options of the select that specifies the path of the image. Note that there are no restrictions upon path, name and extension, you can choose them freely.
    &lt;select id="select"&gt;
    &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    &lt;option value="prate" data-colgradimg="images/colgrad1.png"&gt;Surface Precipitation Rate&lt;/option&gt;
    &lt;option value="3HrAccum" data-colgradimg="images/colgrad2.png"&gt;3-Hr Accumulated Precipitation&lt;/option&gt;
    &lt;!-- and so on --&gt;

    The javascript:
    function getUrlAndLoad() {
    var val = $("#select").val();
    var colgradimg = $("#select option:selected").data("colgradimg");
    $("#colgrad-img").attr("src", colgradimg);
    switch (val) {
    case "prate":
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — Complete HTML and JS:
    &lt;div class="row" style="background-color: #f4f4f4;"&gt;


    <i> </i> &lt;div class="col-md-3"&gt;
    <i> </i> &lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
    <i> </i> &lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Products:&lt;/h5&gt;
    <i> </i> &lt;select id="select"&gt;
    <i> </i> &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    <i> </i> &lt;option value="prate" data-colgradimg="images/colgrad1.png"&gt;Surface Precipitation Rate&lt;/option&gt;
    <i> </i> &lt;option value="3HrAccum" data-colgradimg="images/colgrad2.png"&gt;3-Hr Accumulated Precipitation&lt;/option&gt;
    <i> </i> &lt;option value="temp" data-colgradimg="images/colgrad3.png"&gt;Surface Temperature&lt;/option&gt;
    <i> </i> &lt;option value="wind"&gt;850mb Wind&lt;/option&gt;
    <i> </i> &lt;option value="10mwind"&gt;10m Wind&lt;/option&gt;
    <i> </i> &lt;option value="rh"&gt;Relative Humidity&lt;/option&gt;
    <i> </i> &lt;option value="cc"&gt;Surface Cloud Cover&lt;/option&gt;
    <i> </i> &lt;/select&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="1" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="3"&gt;3
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="6"&gt;6
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="12"&gt;12
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="24"&gt;24
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;p&gt;Duration: 144.0h&lt;/p&gt;
    <i> </i> &lt;/form&gt;&lt;br&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-6" style="padding: 25px;"&gt;
    <i> </i> &lt;form style="display: block; float: left;font-size: 20px;"&gt;
    <i> </i> &lt;p&gt;Date Initialized: &lt;span id="forecast-date"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;UTC: &lt;span id="forecast-utc"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;Forecast Hour: &lt;span id="forecast-hour"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt; &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    <i> </i> &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    <i> </i> &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    <i> </i> &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;img id="forecast-img" src=""&gt;
    <i> </i> &lt;img id="colgrad-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i>&lt;/div&gt;

    <i> </i>&lt;script&gt;
    <i> </i> var theimg = document.getElementById('forecast-img'),
    <i> </i> thedate = document.getElementById('forecast-date'),
    <i> </i> theUTC = document.getElementById('forecast-utc'),
    <i> </i> thehour = document.getElementById('forecast-hour');
    <i> </i> var idx = 0, step = 1, stopped = false;
    <i> </i> var forecastdata = [];

    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 500);

    <i> </i> function loadForecast(url) {
    <i> </i> $.getJSON(url, function (data) {
    <i> </i> forecastdata = data;
    <i> </i> });
    <i> </i> }

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> var colgradimg = $("#select option:selected").data("colgradimg");
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> switch (val) {
    <i> </i> case "prate":
    <i> </i> loadForecast("thread181-wheather-forecast-4.php");
    <i> </i> break;
    <i> </i> case "temp":
    <i> </i> loadForecast("temp.php");
    <i> </i> break;
    <i> </i> case "wind":
    <i> </i> loadForecast("wind.php");
    <i> </i> break;
    <i> </i> case "rh":
    <i> </i> loadForecast("rh.php");
    <i> </i> break;
    <i> </i> case "cc":
    <i> </i> loadForecast("cc.php");
    <i> </i> break;
    <i> </i> case "3HrAccum":
    <i> </i> loadForecast("3HrAccum.php");
    <i> </i> break;
    <i> </i> case "10mwind":
    <i> </i> loadForecast("10mwind.php");
    <i> </i> break;
    <i> </i> }
    <i> </i> }

    <i> </i> $("#select").on('change', getUrlAndLoad);

    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> $("#start-stop-btn").on("click", function (event) {
    <i> </i> event.preventDefault();
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> $("#first-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#last-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#prev-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx -= step;
    <i> </i> if (idx &lt; 0) idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i>&lt;/script&gt;
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605548 thank you for the correction! I will implement it later.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605548 IT WORKS! Again thank you for sticking by with all of my questions 😅

    I'll just adjust the size of the color bar on monday.

    I'm developing this webapp in a linux os. Some of my workmates are using windows if I access the portal in there pc the designs are misarranged the font is different. Can you recommend some settings in css for it to be cross platform?
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 —  the designs are misarranged the font is different. Can you recommend some settings in css for it to be cross platform?[/quote]One had to view the CSS in order to analyse this precisely. However I can give some general recommendations: Often the reason for layout issues is the use of absolute positioning or the outdated float. Use flex layout instead.

    Regarding the fonts: Without further measures a font needs to be installed on the system where the browser is running. However a font can be loaded from your webspace or from a common resource and is reliably available then. But this is a subject I didn't deal with yet. I recommend that you open a separate thread for this issue.
    Copy linkTweet thisAlerts:
    @frncsknauthorJun 28.2019 — @Sempervivum#1605556 I will just try and use a font that is both installed in linux and windows os. Thanks for the suggestions. I will read into it on monday because its weekend here now. thank you again! 😀
    Copy linkTweet thisAlerts:
    @SempervivumJun 28.2019 — @frncskn#1605559 You'r welcome, have a nice weekend!
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 01.2019 — @Sempervivum#1605560 Hello! out of curiosity. Is it possible to create a box (w/c is transparent inside) and fit this image in it?

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-01/1561960333-190667-wind-rpnwind-postwrf-d01-20180914-0300-f14400.png]

    Secondly, is it possible to put some text outside of the box?
    Copy linkTweet thisAlerts:
    @SempervivumJul 01.2019 — I'm shure that both is possible, however I do not completely understand what your intention is:

    Do you want to simply put a border or frame around the image? That can be done easily by CSS:

    https://developer.mozilla.org/en-US/docs/Web/CSS/border

    Regarding the text: Should it be static or dynamic, denpending on the image currently displayed?

    In the meantime I remembered that you had some trouble with flickering of the images when changing. I guess this is not yet fixed. We would have to add the preloading again.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 01.2019 — @Sempervivum#1605608 The text is static I just need to put some coordinates around the image. I'm thinking of a workaround because of the limitations of pyqgis. since I'm using the standalone version (no gui just pure python coding and limited access to the full capabilities of qgis the labels can't be produced) (the python library I'm using in generating the images) I will give you an example of what I'm trying to achieve:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-01/1561967722-580487-relative-humid.png]

    pls ignore the texts on left side. The "box" with the texts within the image is what I'm trying to achieve and I hope it can be done using css or any language that is web based.

    and about the flickering. It seems its been resolved. I've been running the portal now and changing the images and it seems the flickering has been solved.




    ADDITIONAL INFO:

    however, I have some concerns using css in that manner because the images that the python script produces have this weird white area outside of the main image and I don't know if css can somehow "bypass" that area and put the box where it needs to be.

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-01/1561968139-442394-kazam-screenshot-00002.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 01.2019 — I see, you want to add the labels at the left and at the bottom which are obviously indicating latitude and longitude? When the area the image is displaying is fixed, it can be done by HTML and CSS.

    What about the gradient image at the right? Should it's labelling also be added or is it included in the image?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 01.2019 — @Sempervivum#1605610 Yes. that is the last part of this project that needs to be added. I did the gradient separately using matplotlib and numpy. The gradient is a separate image like this: [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-01/1561968575-548979-prate.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 01.2019 — Removing the white border can be done easily by CSS and HTML, however it all depends on whether the labels at the axises will be static or dynamic.
    Copy linkTweet thisAlerts:
    @DemixlJul 01.2019 — I checked all its ok with img
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 01.2019 — @Sempervivum#1605612 the text is static.

    I drew what I hope the output should be here:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-01/1561970350-453629-kazam-screenshot-00003.png]
    Copy linkTweet thisAlerts:
    @4squarelogicJul 01.2019 — this in action by adding some java script and adding some CSS in our ajax callback. So go ahead and jump to your module directory and let's go ahead and open up step fourteen which is called "adding-javascript-and-CSS-with-ajax". Go ahead and copy the entire code and paste it over the code that's in your "interact dot module" file.

    And save it. Ok. So we just added two lines to this file, this "drupal_add_css" right here and "drupal_add_js" here.

    Now we've talked about both of these in previous videos and "drupal_add_js" extensively in our previous example and these are very simple implementations. Just to demonstrate what happens when we run these functions during an ajax call. The files that are added are "interact dot css" and "interact dash ajax dash loaded dot js".

    So let's go ahead and take a look at these two files real quick. I'm going to jump back to the module directory and I'm going to open "interact dot css" in my editor. This just says that any "a" tags user or any "h1" tags get a unique ...

    [b]Links removed by Site Staff so it doesn't look like you're spamming us. Please don't post them again.[/b]
    Copy linkTweet thisAlerts:
    @SempervivumJul 01.2019 — I created a rough draft of the labels at the left.

    HTML:
    &lt;div id="forecast-container"&gt;
    &lt;div id="labels-left-container"&gt;
    &lt;div class="label-left"&gt;30&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="img-container"&gt;
    &lt;img id="forecast-img"&gt;
    &lt;/div&gt;
    &lt;/div&gt;


    CSS:
    #img-container {

    <i> </i> /* dimensions of the image
    <i> </i> excluding white borders */
    <i> </i> width: 277px;
    <i> </i> height: 378px;

    <i> </i> border: 2px solid black;
    <i> </i> overflow: hidden;
    <i> </i> box-sizing: border-box;
    <i> </i> }

    <i> </i> #forecast-img {
    <i> </i> vertical-align: top;

    <i> </i> /* dimensions of the complete image
    <i> </i> including white borders */
    <i> </i> width: 377px;
    <i> </i> height: 478px;

    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -50px;

    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -50px;
    <i> </i> }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #labels-left-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> .label-left {
    <i> </i> text-align: right;

    <i> </i> /* the vertical distance between the labels */
    <i> </i> margin-top: 45px;

    <i> </i> padding-left: 5px;
    <i> </i> padding-right: 5px;
    <i> </i> }

    <i> </i> .label-left:first-child {
    <i> </i> /* amount the first label is shifted upwards */
    <i> </i> margin-top: -7px;
    <i> </i> }

    On my test page it looks like this:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-01/1561977640-602613-forecast-labels-left.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 01.2019 — @Sempervivum#1605631 wow! I will test this out tomorrow thank you so much!!
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605631 I tested your code and this is what I got:

    I'm having trouble in fitting my image correctly around the border.

    The dimension of the images (w/ the white background) is WIDTH:550 x HEIGHT:600
    The HTML:
    <i>
    </i> &lt;div class="row" style="background-color: #f4f4f4;"&gt;
    <br/>
    <i> </i> &lt;div class="col-md-3"&gt;
    <i> </i> &lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
    <i> </i> &lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Products:&lt;/h5&gt;
    <i> </i> &lt;select id="select"&gt;
    <i> </i> &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    <i> </i> &lt;option value="prate" data-colgradimg="img/prate.png"&gt;Surface Precipitation Rate&lt;/option&gt;
    <i> </i> &lt;option value="3HrAccum" data-colgradimg="img/3HrlyAccu.png"&gt;3-Hr Accumulated Precipitation&lt;/option&gt;
    <i> </i> &lt;option value="temp" data-colgradimg="img/temp.png"&gt;Surface Temperature&lt;/option&gt;
    <i> </i> &lt;option value="wind" data-colgradimg="img/wind.png"&gt;850mb Wind&lt;/option&gt;
    <i> </i> &lt;option value="10mwind" data-colgradimg="img/wind10.png"&gt;10m Wind&lt;/option&gt;
    <i> </i> &lt;option value="rh" data-colgradimg="img/rh.png"&gt;Relative Humidity&lt;/option&gt;
    <i> </i> &lt;option value="cc" data-colgradimg="img/cc.png"&gt;Surface Cloud Cover&lt;/option&gt;
    <i> </i> &lt;/select&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="1" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="3"&gt;3
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="6"&gt;6
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="12"&gt;12
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="24"&gt;24
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;p&gt;Duration: 144.0h&lt;/p&gt;
    <i> </i> &lt;/form&gt;&lt;br&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-2" style="padding: 25px;"&gt;
    <i> </i> &lt;form style="display: block; float: left;font-size: 20px;"&gt;
    <i> </i> &lt;p&gt;Date Initialized:&lt;span id="forecast-date"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;UTC:&lt;span id="forecast-utc"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;Forecast Hour:&lt;span id="forecast-hour"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-6"&gt;
    <i> </i> &lt;form style="display: block;"&gt;
    <i> </i> &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    <i> </i> &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    <i> </i> &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    <i> </i> &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    <i> </i> &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;div id="forecast-container"&gt;
    <i> </i> &lt;div id="labels-left-container"&gt;
    <i> </i> &lt;div class="label-left"&gt;30&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="img-container"&gt;
    <i> </i> &lt;img id="forecast-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;img id="colgrad-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;

    The CSS:
    <i>
    </i>/*IMAGE CONTAINER FOR FORECASTS*/

    #img-container {
    /*dimensions of the image excluding the white borders*/
    width: 550px;
    height: 600px;

    border: 1px solid black;
    overflow: hidden;
    box-sizing: border-box;
    }

    #forecast-img {
    vertical-align: top;

    /* dimensions of the complete image including the white borders*/
    height: 450px;
    width: 500px;

    /* size of the white border at the left*/
    margin-left: -50px;

    /*size of the white border on the top*/
    margin-top: -50px;
    }

    #forecast-container {
    display: flex;
    padding-top: 10px;
    }

    #labels-left-container {
    display: flex;
    flex-direction: column;
    }

    .label-left {
    text-align: right;

    /* the vertical distance between the labels */
    margin-top: 45px;

    padding-left: 5px;
    padding-right: 5px;
    }

    .label-left:first-child {
    /* amount the first label is shifted upwards */
    margin-top: 0px;
    }

    /*END OF LABELS HERE */

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-02/1562038136-701024-kazam-screenshot-00004.png]

    Here is one of the images for testing

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-02/1562038653-965964-prate-rpnprate-postwrf-d01-20180914-0300-f14300.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — Fine that you posted an original image. Took me some trial and error either to adjust the CSS but this should be correct now:
    #img-container {

    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 460px;
    <i> </i> height: 540px;

    <i> </i> border: 2px solid black;
    <i> </i> overflow: hidden;
    <i> </i> box-sizing: border-box;
    <i> </i> }

    <i> </i> #forecast-img {
    <i> </i> vertical-align: top;

    <i> </i> /* dimensions of the complete image
    <i> </i> including white borders */
    <i> </i> width: 550px;
    <i> </i> height: 600px;

    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -45px;

    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #labels-left-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> .label-left {
    <i> </i> text-align: right;

    <i> </i> /* the vertical distance between the labels */
    <i> </i> margin-top: 74px;

    <i> </i> padding-left: 5px;
    <i> </i> padding-right: 5px;
    <i> </i> }

    <i> </i> .label-left:first-child {
    <i> </i> /* amount the first label is shifted upwards */
    <i> </i> margin-top: -7px;
    <i> </i> }
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605663 I can't thank you enough for your patience! I will attend a short meeting and I will try your source code later. thank you so much!
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @frncskn#1605667 is the process of creating the labels for the left side same for when creating the labels on the bottom part?
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — @frncskn#1605669 Yes the process is similar but not exactly the same:

    HTML:
    &lt;div id="forecast-container"&gt;
    &lt;div id="labels-left-container"&gt;
    &lt;div class="label-left"&gt;30&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="right-container"&gt;
    &lt;div id="img-container"&gt;
    &lt;img id="forecast-img"&gt;
    &lt;/div&gt;
    &lt;div id="labels-bottom-container"&gt;
    &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;140&amp;deg;E&lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;


    CSS:
    #img-container {

    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 460px;
    <i> </i> height: 540px;

    <i> </i> border: 2px solid black;
    <i> </i> overflow: hidden;
    <i> </i> box-sizing: border-box;
    <i> </i> }

    <i> </i> #forecast-img {
    <i> </i> vertical-align: top;

    <i> </i> /* dimensions of the complete image
    <i> </i> including white borders */
    <i> </i> width: 550px;
    <i> </i> height: 600px;

    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -45px;

    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #labels-left-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> .label-left {
    <i> </i> text-align: right;

    <i> </i> /* the vertical distance between the labels */
    <i> </i> margin-top: 74px;

    <i> </i> padding-left: 5px;
    <i> </i> padding-right: 5px;
    <i> </i> }

    <i> </i> .label-left:first-child {
    <i> </i> /* amount the first label is shifted upwards */
    <i> </i> margin-top: -7px;
    <i> </i> }

    <i> </i> #right-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> #labels-bottom-container {
    <i> </i> display: flex;
    <i> </i> }

    <i> </i> .label-bottom {
    <i> </i> text-align: center;

    <i> </i> /* the horizontal distance between the labels */
    <i> </i> margin-left: 52px;

    <i> </i> padding-top: 2px;
    <i> </i> }

    <i> </i> .label-bottom:first-child {
    <i> </i> /* amount the first label is shifted left */
    <i> </i> margin-left: -20px;
    <i> </i> }
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605675 is it possible for the bounding box to "disappear" until a user selects a forecast parameter?
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — Yes, this is possilble. Should the box disappear only or the labels either?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605684 the labels as well if that is possible.

    Also I'm trying to edit the size and position of the color gradient. I'm trying to place the col grad beside the maps. Your suggestion will be highly appreciated

    <img id="colgrad-img" height="height here" width="width here" src="">

    The positioning will I put it next to the height and width or will it be placed in the css file.
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — Regarding the col grad image: It has large paddings at each side, should they be removed as we did for the main image? And should the height be adjusted in that way that it's equal to the height of the main image or should the original height be kept?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605686 I think the padding is the reason why I'm having trouble resizing and moving the image.

    Its better I think to "scale" the image.

    Smaller than the map.
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — I used the same procedure for hiding the paddings. Unfortunately after adjusting the height of the col grad image readability of it's labeld has grown bad.

    HTML:
    &lt;div id="forecast-container" class="hidden"&gt;
    &lt;div id="labels-left-container"&gt;
    &lt;div class="label-left"&gt;30&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="right-container"&gt;
    &lt;div id="img-container"&gt;
    &lt;img id="forecast-img"&gt;
    &lt;/div&gt;
    &lt;div id="labels-bottom-container"&gt;
    &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;140&amp;deg;E&lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="colgrad-img-container"&gt;
    &lt;img id="colgrad-img"&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;

    CSS:
    #img-container {

    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 460px;
    <i> </i> height: 540px;

    <i> </i> border: 2px solid black;
    <i> </i> overflow: hidden;
    <i> </i> box-sizing: border-box;
    <i> </i> }

    <i> </i> #forecast-img {
    <i> </i> vertical-align: top;

    <i> </i> /* dimensions of the complete image
    <i> </i> including white borders */
    <i> </i> width: 550px;
    <i> </i> height: 600px;

    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -45px;

    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #forecast-container.hidden {
    <i> </i> visibility: hidden;
    <i> </i> }

    <i> </i> #labels-left-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> .label-left {
    <i> </i> text-align: right;

    <i> </i> /* the vertical distance between the labels */
    <i> </i> margin-top: 74px;

    <i> </i> padding-left: 5px;
    <i> </i> padding-right: 5px;
    <i> </i> }

    <i> </i> .label-left:first-child {
    <i> </i> /* amount the first label is shifted upwards */
    <i> </i> margin-top: -7px;
    <i> </i> }

    <i> </i> #right-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> #labels-bottom-container {
    <i> </i> display: flex;
    <i> </i> }

    <i> </i> .label-bottom {
    <i> </i> text-align: center;

    <i> </i> /* the horizontal distance between the labels */
    <i> </i> margin-left: 52px;

    <i> </i> padding-top: 2px;
    <i> </i> }

    <i> </i> .label-bottom:first-child {
    <i> </i> /* amount the first label is shifted left */
    <i> </i> margin-left: -20px;
    <i> </i> }

    <i> </i> #colgrad-img-container {
    <i> </i> width: 120px;
    <i> </i> height: 740px;
    <i> </i> margin-top: -7px;
    <i> </i> transform: scale(0.747);
    <i> </i> transform-origin: left top;
    <i> </i> }

    <i> </i> #colgrad-img {
    <i> </i> width: 300px;
    <i> </i> height: 900px;
    <i> </i> margin-left: -125px;
    <i> </i> margin-top: -80px;
    <i> </i> }

    JS:
    function loadForecast(url) {
    $.getJSON(url, function (data) {
    forecastdata = data;
    $("#forecast-container").removeClass("hidden");
    });
    }
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605691 about the readability I'll just adjust the image in python and create a new one that will satisfy the settings that you set :)
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605691

    when I try tried the code &lt;div id="forecast-container" class="hidden"&gt;
    This is the output even though I selected a parameter:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-02/1562062029-284147-kazam-screenshot-00000.png]

    And when I comment the class="hidden"
    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-02/1562062102-197145-kazam-screenshot-00001.png]

    And a weird line that is supposed to be the colorgradient appears.

    SideNote: The controls above to adjust them. I'll just use padding?
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — Did you add the javascript in loadForecast()?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605702 Ow wait my bad. I'm so sorry about that
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605702 it works now. Thanks. The colgrad images sometimes gets a bit blurred but maybe its the cache of the browser. I have to force reload a couple of times to see the changes

    I have another question. Say for example the output images I've been showing you is domain 1 (it covers the philippine area of responsibilty).

    My boss wants to add a domain 2 (it covers just the map of the philippines)

    In the website I've already added a 2 radio buttons to select either d01 or d02. All the process remains the same. Just additional images.

    I will provide the output tomorrow. I have to code them in python first.
    Copy linkTweet thisAlerts:
    @SempervivumJul 02.2019 — The colgrad images sometimes gets a bit blurred[/quote]Scaling an image as it is done by the CSS will always result in a loss of quality. A solution might be to create the image in the dimensions that are finally needed but I don't know if this is possilble for you.
    Say for example the output images I've been showing you is domain 1 (it covers the philippine area of responsibilty).

    My boss wants to add a domain 2 (it covers just the map of the philippines)

    In the website I've already added a 2 radio buttons to select either d01 or d02. All the process remains the same. Just additional images.[/quote]
    I don't understand this yet. Are the regions the images are displaying different and need different labels?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 02.2019 — @Sempervivum#1605712 I will show an example tomorrow. Once I figure out the process in the python side. But yes the domain 2 image is smaller than domain 1 so the size of the box will be different and the label but I think the only adjustment in the label is the labels from the buttom will be decreased.

    This is a rough approximation of what a domain 2 python output looks like:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-02/1562076983-273327-20190702-214421.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605712 Hello I finally figured out the process in domain 2. this is the sample image (the dimension is same as the image in domain 1) WIDTH:550 x HEIGHT:600
    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-03/1562138683-974316-d02-rpnwind-postwrf-d02-20180914-0600-f00100.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — @frncskn#1605746 I finally figured out the process in domain 2.[/quote]That's fine! Does this mean that everything is done or do you need further assistance?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605747 I'll explain it by code:

    I separated the Images by domain.

    where will I put the option that I can select a different domain for the same parameter?
    <i>
    </i> function getUrlAndLoad() {
    var val = $("#select").val();
    var colgradimg = $("#select option:selected").data("colgradimg");
    $("#colgrad-img").attr("src", colgradimg);
    switch (val) {
    case "prate":
    loadForecast("d01-prate.php");
    break;
    case "temp":
    loadForecast("d01-temp.php");
    break;
    case "wind":
    loadForecast("d01-wind.php");
    break;
    case "rh":
    loadForecast("d01-rh.php");
    break;
    case "cc":
    loadForecast("d01-cc.php");
    break;
    case "3HrAccum":
    loadForecast("d01-3HrAccum.php");
    break;
    case "10mwind":
    loadForecast("d01-10mwind.php");
    break;
    }
    }

    The php code of a d01 parameter:

    PHP:
    <i>
    </i> &lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $images = glob("pyqgis-ops/3HrlyAccuRain/d01/*.png");
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;

    The php code of a d02 parameter: (same as the code above the only difference is the path to the images)
    <i>
    </i> $images = glob("pyqgis-ops/3HrlyAccuRain/d02/*.png");


    The HTML code of the radio button of the selection of domains:
    <i>
    </i>&lt;h5&gt;Domain: &lt;/h5&gt;
    &lt;form&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="1" checked&gt;1
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="2"&gt;2
    &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    &lt;/form&gt;


    and for example I will select a domain 2 forecast parameter: This has to be edited?
    <i>
    </i>function getUrlAndLoad() {
    var val = $("#select").val();
    var colgradimg = $("#select option:selected").data("colgradimg");
    $("#colgrad-img").attr("src", colgradimg);
    switch (val) {
    case "prate":
    loadForecast("d01-prate.php");
    break;
    case "temp":
    loadForecast("d01-temp.php");
    break;
    case "wind":
    loadForecast("d01-wind.php");
    break;
    case "rh":
    loadForecast("d01-rh.php");
    break;
    case "cc":
    loadForecast("d01-cc.php");
    break;
    case "3HrAccum":
    loadForecast("d01-3HrAccum.php");
    break;
    case "10mwind":
    loadForecast("d01-10mwind.php");
    break;
    }
    }


    and lastly since the image of the domain 2 is smaller the "box" is different. so will there be another "box" assigned for the domain 1 (w/c is already done by you). and another box for the domain 2.


    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — @frncskn#1605749 Adding the domain to the path of the images IMO is a fine approach. In order not to have to create an additional set of PHP files I recomment to hand over the domain as a GET parameter and add it to the image URL in PHP:
    function loadForecast(url, dmn) {
    $.getJSON(url, {domain: dmn}, function (data) {
    forecastdata = data;
    $("#forecast-container").removeClass("hidden");
    });
    }

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> var colgradimg = $("#select option:selected").data("colgradimg");
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> var domain = $("input[name='optradio']:checked").val();
    <i> </i> switch (val) {
    <i> </i> case "prate":
    <i> </i> loadForecast("prate.php", domain);
    <i> </i> break;
    <i> </i> case "temp":
    <i> </i> loadForecast("temp.php", domain);
    <i> </i> break;
    <i> </i> case "wind":
    <i> </i> loadForecast("wind.php", domain);
    <i> </i> break;
    <i> </i> // and so on
    <i> </i> }
    <i> </i> }
    Shurely you will be able to adjust the PHP files accordingly.

    We might consider to go a step further and hand over the type of forecast (rain, temp, wind, ...) to the PHP file either. Doing so we would need only one PHP file where the path of the images is composed dynamically.

    and lastly since the image of the domain 2 is smaller the "box" is different. so will there be another "box" assigned for the domain 1 (w/c is already done by you). and another box for the domain 2.[/quote]I considered to create a second box either in the beginning but now I think it would be easier to use the same box and switch the dimensions by CSS.
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — PS: The same applies to the labels, latitude and longitude, AFAIK they will have to be adjusted too. Could be done in a similar way by CSS.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605752 I got this error when I tried your code and the display of the images disappeared :(

    Also I'm not sure if
    <i>
    </i>&lt;h5&gt;Domain: &lt;/h5&gt;
    &lt;form&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="1" checked&gt;1
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="2"&gt;2
    &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    &lt;/form&gt;

    "optradio" is the correct name to be assigned. because when I click the radio button of the domain. it doesn't change the image, instead it adds another sort of animation interval to the image that is selected.
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — Take it exactly as I posted it (curly braces):
    function loadForecast(url, dmn) {
    $.getJSON(url, {domain: dmn}, function (data) {
    forecastdata = data;
    $("#forecast-container").removeClass("hidden");
    });
    }
    {domain: dmn} is an object and $.getJSON will create an URL parameter based on it like this:

    prate.php?domain=d02

    Then in the PHP the parameter is available as a GET parameter:

    $domain = $_GET('domain');
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605756 Is it like this?
    <i>
    </i>&lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $domain=$_GET('domain');
    $images = glob("pyqgis-ops/PrecipRate/d01/*.png");
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — Additionally you need to put the domain into the the image path like this:
    $domain=$_GET('domain');
    $images = glob("pyqgis-ops/PrecipRate/" . domain . "/*.png");
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — Regarding this:
    &lt;form&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="1" checked&gt;1
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio" value="2"&gt;2
    &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    &lt;/form&gt;
    Sorry, I forgot to mention this: We have chose a different name for these radio buttons, e. g. this:
    &lt;form&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio-domain" value="1" checked&gt;1
    &lt;/label&gt;
    &lt;label class="radio-inline"&gt;
    &lt;input type="radio" name="optradio-domain" value="2"&gt;2
    &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    &lt;/form&gt;
    and use it like this:
    function getUrlAndLoad() {
    var val = $("#select").val();
    var colgradimg = $("#select option:selected").data("colgradimg");
    $("#colgrad-img").attr("src", colgradimg);
    var domain = $("input[name='optradio-domain']:checked").val();
    switch (val) {
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605758

    just to clarify within the a forecast folder (ie. PrecipRate) I created 2 additional folders inside (d01 and d02). So I separated the two types of images

    The previous process I have 7 php files one for each parameter (w/c is domain 1). now that my boss insisted on the visualization of another domain I thought maybe it is the same process just additional files so I created another 7 php files for domain 2. sorry I'm so confused right now
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — No, it will not be necessary to create another 7 php files. Creating these files would not be enough, they would have to be called each and this would result in a complex structure of switch and if's. I would prefer the way I proposed earlier, have only one PHP file and compose the path of the images dynamically. If you agree I would create the code for this procedure.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605762 If you could show me that will be awesome.

    because what I did I thought that will be will the much simpler route
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — OK, I'm going to code this. Will come back when I'm ready.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605765 THANK YOU SO MUCH!
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — Done.

    forecast.php:
    &lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $domain = $_GET['domain'];
    $path = $_GET['path'];
    $completepath = "pyqgis-ops/" . $domain . "/" . $path . "/*.png";
    $images = glob($completepath);
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/-([^-]+)-([^-]+)-([^-]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — HTML:
    &lt;div class="row" style="background-color: #f4f4f4;"&gt;


    <i> </i> &lt;div class="col-md-3"&gt;
    <i> </i> &lt;h1&gt;Weather Maps (PyQGIS)&lt;/h1&gt;
    <i> </i> &lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Products:&lt;/h5&gt;
    <i> </i> &lt;select id="select"&gt;
    <i> </i> &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    <i> </i> &lt;option value="prate" data-colgradimg="images/1561968575-548979-prate.png"&gt;
    <i> </i> Surface Precipitation Rate
    <i> </i> &lt;/option&gt;
    <i> </i> &lt;option value="3HrAccum" data-colgradimg="images/colgrad2.png"&gt;3-Hr Accumulated Precipitation&lt;/option&gt;
    <i> </i> &lt;option value="temp" data-colgradimg="images/colgrad3.png"&gt;Surface Temperature&lt;/option&gt;
    <i> </i> &lt;option value="wind"&gt;850mb Wind&lt;/option&gt;
    <i> </i> &lt;option value="10mwind"&gt;10m Wind&lt;/option&gt;
    <i> </i> &lt;option value="rh"&gt;Relative Humidity&lt;/option&gt;
    <i> </i> &lt;option value="cc"&gt;Surface Cloud Cover&lt;/option&gt;
    <i> </i> &lt;/select&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Domain:&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio-domain" value="d01" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio-domain" value="d02"&gt;2
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="1" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="3"&gt;3
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="6"&gt;6
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="12"&gt;12
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="24"&gt;24
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;p&gt;Duration: 144.0h&lt;/p&gt;
    <i> </i> &lt;/form&gt;&lt;br&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-6" style="padding: 25px;"&gt;
    <i> </i> &lt;form style="display: block; float: left;font-size: 20px;"&gt;
    <i> </i> &lt;p&gt;Date Initialized: &lt;span id="forecast-date"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;UTC: &lt;span id="forecast-utc"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;Forecast Hour: &lt;span id="forecast-hour"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt; &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    <i> </i> &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    <i> </i> &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    <i> </i> &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    <i> </i> &lt;/form&gt;
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — JS:
    var basicdata = {
    "prate": {
    "path": "3HrlyAccuRain",
    "colgradimg": "1561968575-548979-prate.png"
    },
    "temp": {
    "path": "path-for-temp",
    "colgradimg": "colgrad2.png"
    }
    }
    var theimg = document.getElementById('forecast-img'),
    thedate = document.getElementById('forecast-date'),
    theUTC = document.getElementById('forecast-utc'),
    thehour = document.getElementById('forecast-hour');
    var idx = 0, step = 1, stopped = false;
    var forecastdata = [];

    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 500);

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> var colgradimg = "images/" + basicdata[val].colgradimg;
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> var domain = $("input[name='optradio-domain']:checked").val();
    <i> </i> $.getJSON("getforecast.php",
    <i> </i> { path: basicdata[val].path, domain: domain },
    <i> </i> function (data) {
    <i> </i> forecastdata = data;
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }

    <i> </i> $("#select").on('change', getUrlAndLoad);

    <i> </i> $("input[name='optradio-domain']").on("change", getUrlAndLoad);

    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> $("#start-stop-btn").on("click", function (event) {
    <i> </i> event.preventDefault();
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> $("#first-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#last-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#prev-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx -= step;
    <i> </i> if (idx &lt; 0) idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605771Wow! that one php file will handle all the parameters and domains? Or do I still need one copy for each parameter?
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — You need to complete this object:
    var basicdata = {
    "prate": {
    "path": "3HrlyAccuRain",
    "colgradimg": "1561968575-548979-prate.png"
    },
    "temp": {
    "path": "path-for-temp",
    "colgradimg": "colgrad2.png"
    }
    }
    "prate", "temp", "wind" ... are the types of forecast which are defined by the values of the select.

    My paths look like this:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-03/1562150434-774150-forecast-domains.png]

    This code works for me so far that the correct image is displayed. Unfortunately I had only the two sample images you posted earlier. If the code doesn't work for you it would be advisable that you post another two images, one more for prate and one more for wind.

    Adjustment of the CSS still has to be done.
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — @frncskn#1605774 Yes, this one php file will handle all of it. It's controlled by the two parameters "path" and "domain".
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605775 the javascript above will be placed in the html file correct?

    Unfortunately I'm going home right now. All I have here in my phone are 2 gifs of the sample forecasts of the d02 that I showed my boss earlier today.

    Here they are:
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 — Yes, you can place the javascript in the HTML file. Put it below the HTML.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605783 i can't send the gif. I will send some images tomorrow. Thanks!

    The js above can you explain what does it do?
    Copy linkTweet thisAlerts:
    @SempervivumJul 03.2019 —  var basicdata = {
    <i> </i> "prate": {
    <i> </i> "path": "3HrlyAccuRain",
    <i> </i> "colgradimg": "1561968575-548979-prate.png"
    <i> </i> },
    <i> </i> "temp": {
    <i> </i> "path": "path-for-temp",
    <i> </i> "colgradimg": "colgrad2.png"
    <i> </i> }
    <i> </i> }


    "prate", "temp", "wind" ... are the types of forecast which are defined by the values of the select.

    The complete path of the images looks like this:
    "pyqgis-ops/3HrlyAccuRain/d02/*.png"
    `3HrlyAccuRain</C> is inserted based on the field "path" in the object above.<br/>
    <C>
    d02</C> is the value of the select for the domains.

    When writing this I noticed that I mixed up domain and path in my configuration. When the domain is placed below the PHP has to be changed like this:<br/>
    <C>
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";`
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 03.2019 — @Sempervivum#1605786 its ok. I will just check all your codes tomorrow! I can't thank you enough! I hope we can finish this by the end of this week or early next week
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605786 Hello here are the sample images for all the forecast parameters and their respective domains:

    10m wind d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562199959-34663-d01-rpn10mwind-postwrf-d01-20180914-0600-f14400.png]

    10m wind d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562199983-259690-d02-rpn10mwind-postwrf-d02-20180914-0600-f04700.png]

    850mb wind d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200006-925138-d01-rpnwind-postwrf-d01-20180914-0600-f14300.png]

    850mb wind d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200015-994838-d02-rpnwind-postwrf-d02-20180914-0600-f04800.png]

    preciprate d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200042-978809-d01-rpnprate-postwrf-d01-20180914-0600-f14200.png]

    preciprate d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200055-121851-d02-rpnprate-postwrf-d02-20180914-0600-f04600.png]

    temperature d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200075-59840-d01-rpntemp-postwrf-d01-20180914-0600-f14400.png]

    temperature d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200087-387382-d02-rpntemp-postwrf-d02-20180914-0600-f04700.png]

    relative humidity d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200104-937909-d01-rpnrh-postwrf-d01-20180914-0600-f14300.png]

    relative humidity d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200121-247792-d02-rpnrh-postwrf-d02-20180914-0600-f04500.png]

    Cloud Cover d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200143-850216-d01-rpncc-postwrf-d01-20180914-0600-f14200.png]

    Cloud Cover d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200156-361829-d02-rpncc-postwrf-d02-20180914-0600-f04600.png]

    3hr precip accum d01

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200182-407511-d01-rpn3hrlyaccum-postwrf-d01-20180914-0600-f14300.png]

    3hr precip accum d02

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200202-282984-d02-rpn3hrlyaccum-postwrf-d02-20180914-0600-f04600.png]

    And this are the colorgrad images for all the parameters

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200545-967173-wind10.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200546-362767-wind.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200546-759650-temp.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200547-148182-rh.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200547-549505-prate.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200547-948749-cc.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562200548-370425-3hrlyaccu.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605786 I'm getting this error:
    <i>
    </i>Uncaught TypeError: Cannot read property 'colgradimg' of undefined
    at HTMLSelectElement.getUrlAndLoad (gis.html:218)
    at HTMLSelectElement.dispatch (jquery.js:3)
    at HTMLSelectElement.q.handle (jquery.js:3)

    <i>
    </i>Uncaught TypeError: Cannot read property 'colgradimg' of undefined
    at getUrlAndLoad (gis.html:218)

    I checked the error is somewhere here:
    <i>
    </i>var colgradimg = "img/" + basicdata[val].colgradimg;


    The Update PHP:
    <i>
    </i>&lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $domain = $_GET['domain'];
    $path = $_GET['path'];
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";
    $images = glob($completepath);
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;

    The updated JS:
    <i>
    </i>&lt;script&gt;
    var basicdata = {
    "prate": {
    "pyqgis-ops/PrecipRate/d01/*.png": "prate",
    "colgradimg": "prate.png"
    },
    "temp": {
    "ppyqgis-ops/PrecipRate/d01/*.png": "temp",
    "colgradimg": "temp.png"
    }
    }
    var theimg = document.getElementById('forecast-img'),
    thedate = document.getElementById('forecast-date'),
    theUTC = document.getElementById('forecast-utc'),
    thehour = document.getElementById('forecast-hour');
    var idx = 0, step = 1, stopped = false;
    var forecastdata = [];

    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 500);

    <i> </i> //function loadForecast(url, dmn) {
    <i> </i> //$.getJSON(url, {domain: dmn}, function (data) {
    <i> </i> // forecastdata = data;
    <i> </i> // $("#forecast-container").removeClass("hidden");
    <i> </i> // });
    <i> </i> //}

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> var colgradimg = "img/" + basicdata[val].colgradimg;
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> var domain = $("input[name='optradio-domain']:checked").val();
    <i> </i> $.getJSON("d01-prate.php",
    <i> </i> { path: basicdata[val].path, domain: domain },
    <i> </i> function (data) {
    <i> </i> forecastdata = data;
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }
    <i> </i>
    <i> </i> $("#select").on('change', getUrlAndLoad);

    <i> </i> $("input[name='optradio-domain']").on("change", getUrlAndLoad);

    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605786 some additional info:

    the forecast parameters folders in my pc looks like this:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562203403-456945-kazam-screenshot-00000.png]

    Then if one of the parameters is opened:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562203446-33767-kazam-screenshot-00001.png]

    then the color bars are located here:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562203826-567535-kazam-screenshot-00002.png]
    Copy linkTweet thisAlerts:
    @800helplinenumberJul 04.2019 — McAfee offers two particular antivirus suites, McAfee customer service phone number Total Protection and McAfee LiveSafe.McAfee Total Protection McAfee Support phone numberIn the 2019 territory, there’s no contrast between the security suites regarding highlights, yet the LiveSafe is just accessible with the OEM bargains, McAfee customer service phone number which implies you can’t get it. McAfee Total Protection is accessible online for procurement McAfee Support phone number.McAfee customer service number Total Protection McAfee Total Protection is the organization’s top-rated and most famous antivirus suite. Other than giving astounding insurance against a wide range of malware dangers (as we’ll find in the later segment), it offers practically all the propelled highlights/utilities that are typically found in most of the top of the line security suites. McAfee helpline phone number A portion of the propelled highlights incorporate a two-way firewall (effectively screens your system traffic and ruins assaults before they start), a record-destroying instrument (gives you a chance to erase your delicate documents without leaving traces), the File Lock utility McAfee customer service number (an encryption device that permits you to make virtual, secret key secured drives where you can store your private information) by McAfee Support phone number.McAfee customer service number The Safe Family module McAfee customer service phone number — which offers progressed parental control highlights — and the propelled True Key secret phrase chief are likewise part of the item McAfee phone number. Insurance against data fraud and unsafe sites/joins is likewise consolidated into the suite by McAfee Support phone number.To ensure your PC is running easily, McAfee helpline phone number incorporates a few presentation advancement highlights, McAfee phone number for example, Quick Clean and PC Boost.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @frncskn#1605807 UPDATE: No errors are showing in chrome but no output is showing either :(
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum UPDATE: No errors are showing in chrome but no output is showing either 🙁
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — The error is located in the basicdata, it should read like this: var basicdata = {
    "prate": {
    "path": "PrecipRate",
    "colgradimg": "prate.png"
    },
    "3HrAccum": {
    "path": "3HrlyAccuRain",
    "colgradimg": "3HrlyAccuRain.png"
    },
    "temp": {
    "path": "Temperature",
    "colgradimg": "temp.png"
    }
    }
    "path" is the key, do not change it.

    "3HrlyAccuRain" e. g. is the value, it represents the part of the path visible in your screenshot.

    The complete path in composed in this line of the PHP:
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";

    The path of the colgrad image is composed here:
    var val = $("#select").val();
    var colgradimg = "images/" + basicdata[val].colgradimg;

    maybe you will need to update the folder.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — > @Sempervivum#1605822 $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";

    @Sempervivum#1605822 so I will just type this as it is? not change anything?

    UPDATE: I edited the "path" in the js and this is the output:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562224884-715871-kazam-screenshot-00003.png]

    The border box and the "box" where the colgrad supposed to be now appeared but the images have not appeared yet.

    EDIT AGAIN: I changed the path of the colgrad and now the colgrad images appears

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562225111-41117-kazam-screenshot-00004.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — Yes, leave the $completepath as it is, the parameters $path and $domain will be inserted dynamically.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605824

    I got this error:
    <i>
    </i>gis.html:285 Uncaught TypeError: Cannot read property 'img' of undefined
    at HTMLButtonElement.&lt;anonymous&gt; (gis.html:285)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.q.handle (jquery.js:3)
    (anonymous) @ gis.html:285
    dispatch @ jquery.js:3
    q.handle @ jquery.js:3
    gis.html:297 Uncaught TypeError: Cannot read property 'img' of undefined
    at HTMLButtonElement.&lt;anonymous&gt; (gis.html:297)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.q.handle (jquery.js:3)
    (anonymous) @ gis.html:297
    dispatch @ jquery.js:3
    q.handle @ jquery.js:3
    gis.html:309 Uncaught TypeError: Cannot read property 'img' of undefined
    at HTMLButtonElement.&lt;anonymous&gt; (gis.html:309)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.q.handle (jquery.js:3)
    (anonymous) @ gis.html:309
    dispatch @ jquery.js:3
    q.handle @ jquery.js:3
    gis.html:274 Uncaught TypeError: Cannot read property 'img' of undefined
    at HTMLButtonElement.&lt;anonymous&gt; (gis.html:274)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.q.handle (jquery.js:3)
    (anonymous) @ gis.html:274
    dispatch @ jquery.js:3
    q.handle @ jquery.js:3
    gis.html:285 Uncaught TypeError: Cannot read property 'img' of undefined
    at HTMLButtonElement.&lt;anonymous&gt; (gis.html:285)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.q.handle (jquery.js:3)

    here:
    <i>
    </i>gis.html:285
    $("#first-btn").on("click", function() {
    event.preventDefault();
    stopped = true;
    $("#start-stop-btn").text("Start");
    idx = 0;
    **theimg.src = forecastdata[idx].img;**
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });

    <i> </i> $("#last-btn").on("click", function() {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> **theimg.src = forecastdata[idx].img;**
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> **theimg.src = forecastdata[idx].img;**
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#prev-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx -= step;
    <i> </i> if (idx &lt; 0) idx = forecastdata.length - 1;
    <i> </i> **theimg.src = forecastdata[idx].img;**
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    The errors are highlighted with an asterisk. Maybe because the images are not loaded that is why this error appears?
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — The reason for these errors and why the main image is not displayed is the same: The PHP script returns an empty array.

    Insert some console.log in order to check the parameters: function getUrlAndLoad() {
    var val = $("#select").val();
    var colgradimg = "img/" + basicdata[val].colgradimg;
    $("#colgrad-img").attr("src", colgradimg);
    var domain = $("input[name='optradio-domain']:checked").val();
    console.log(basicdata[val].path, domain);
    $.getJSON("d01-prate.php",
    { path: basicdata[val].path, domain: domain },
    function (data) {
    console.log(data);
    forecastdata = data;
    $("#forecast-container").removeClass("hidden");
    });
    }
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — Unfortunately I have to finish for today as I have some trip and will not be online this afternoon. If you don't get it working please post the basicdata again.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605826

    I tried the console and still it no images are showing in the website
    <i>
    </i>function getUrlAndLoad() {
    var val = $("#select").val();
    var colgradimg = "img/" + basicdata[val].colgradimg;
    $("#colgrad-img").attr("src", colgradimg);
    var domain = $("input[name='optradio-domain']:checked").val();
    console.log(basicdata[val].path, domain);
    $.getJSON("d01-prate.php",
    { path: basicdata[val].path, domain: domain },
    function (data) {
    console.log(data);
    forecastdata = data;
    $("#forecast-container").removeClass("hidden");
    });
    }
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605828 this is the vardata
    <i>
    </i> var basicdata = {
    "prate": {
    "path": "prate",
    "colgradimg": "colgrad-img/prate.png"
    },
    "temp": {
    "path": "temp",
    "colgradimg": "colgrad-img/temp.png"
    },
    "wind": {
    "path": "wind",
    "colgradimg": "colgrad-img/wind.png"
    },
    "3HrAccum": {
    "path": "3HrAccum",
    "colgradimg": "colgrad-img/3HrlyAccu.png"
    },
    "10mwind": {
    "path": "10mwind",
    "colgradimg": "colgrad-img/wind10.png"
    },
    "rh": {
    "path": "rh",
    "colgradimg": "colgrad-img/rh.png"
    },
    "cc": {
    "path": "cc",
    "colgradimg": "colgrad-img/cc.png"
    }
    }
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — I see, the paths are wrong, you need those visible in your screenshot:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562228055-170042-folders.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605831
    <i>
    </i>var basicdata = {
    "prate": {
    "path": "PrecipRate",
    "colgradimg": "colgrad-img/prate.png"
    },
    "temp": {
    "path": "Temperature",
    "colgradimg": "colgrad-img/temp.png"
    },
    "wind": {
    "path": "Wind850mb",
    "colgradimg": "colgrad-img/wind.png"
    },
    "3HrAccum": {
    "path": "3HrlyAccuRain",
    "colgradimg": "colgrad-img/3HrlyAccu.png"
    },
    "10mwind": {
    "path": "10mwind",
    "colgradimg": "colgrad-img/wind10.png"
    },
    "rh": {
    "path": "RelativeHumidity",
    "colgradimg": "colgrad-img/rh.png"
    },
    "cc": {
    "path": "CloudCover",
    "colgradimg": "colgrad-img/cc.png"
    }
    }
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — Yes, this is better. If it doesn't work now, check the console.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605831 Or do I need to specify the full path?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605833 It still doesn't work. there is no error in the console. Until I press a button in like the next or prev. then the error will appear

    I'll post the php file here. maybe there is something wrong:
    <i>
    </i>&lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $domain = $_GET['domain'];
    $path = $_GET['path'];
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";
    $images = glob($completepath);
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — The php looks fine. We need to add some diagnostics. Will do this this evening.

    At least the console should display some output bases on console.log
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605

    ok. thank you so much!

    this is what the console displays now when I select a parameter (but still no images are displayed in the webapp)

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562231839-35308-kazam-screenshot-00006.png]

    then when I press the controls the same error about the img appears.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605837 ok. thank you so much!

    this is what the console displays now when I select a parameter (but still no images are displayed in the webapp)

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-04/1562231984-570356-kazam-screenshot-00006.png]

    then when I press the controls the same error about the img appears.
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — The second parameter 1 is wrong, should read d01. This is the value of the radio buttons for the domain. You need to change it to d01 and d02.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605844 what part? the basicdata?
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — In the html of the radio buttons for the domain, the value attribute
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605846 it works now!! thanks! but the d02 box needs some adjustment and that is it.
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — That's fine! Fortunately my train has wlan. I prepared the adjustment for d02 already. Will post them this evening.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605848 its ok! my shift is about to end myself. take care on your trip thanks again.

    I have a small favor to ask I will send the working code here. can you put some comments on what the code does?

    for me to better understand in debugging in the future.

    THE JS:
    <i>
    </i> &lt;script&gt;
    var basicdata = {
    "prate": {
    "path": "PrecipRate",
    "colgradimg": "colgrad-img/prate.png"
    },
    "temp": {
    "path": "Temperature",
    "colgradimg": "colgrad-img/temp.png"
    },
    "wind": {
    "path": "Wind850mb",
    "colgradimg": "colgrad-img/wind.png"
    },
    "3HrAccum": {
    "path": "3HrlyAccuRain",
    "colgradimg": "colgrad-img/3HrlyAccu.png"
    },
    "10mwind": {
    "path": "10mwind",
    "colgradimg": "colgrad-img/wind10.png"
    },
    "rh": {
    "path": "RelativeHumidity",
    "colgradimg": "colgrad-img/rh.png"
    },
    "cc": {
    "path": "CloudCover",
    "colgradimg": "colgrad-img/cc.png"
    }
    }
    var theimg = document.getElementById('forecast-img'),
    thedate = document.getElementById('forecast-date'),
    theUTC = document.getElementById('forecast-utc'),
    thehour = document.getElementById('forecast-hour');
    var idx = 0, step = 1, stopped = false;
    var forecastdata = [];

    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 500);

    <i> </i> function loadForecast(url, dmn) {
    <i> </i> $.getJSON(url, {domain: dmn}, function (data) {
    <i> </i> forecastdata = data;
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }

    <i> </i> function getUrlAndLoad() {
    <i> </i> var val = $("#select").val();
    <i> </i> var colgradimg = "img/" + basicdata[val].colgradimg;
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> var domain = $("input[name='optradio-domain']:checked").val();
    <i> </i> console.log(basicdata[val].path, domain);
    <i> </i> $.getJSON("d01-prate.php",
    <i> </i> { path: basicdata[val].path, domain: domain },
    <i> </i> function (data) {
    <i> </i> console.log(data);
    <i> </i> forecastdata = data;
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }
    <i> </i>
    <i> </i> $("#select").on('change', getUrlAndLoad);

    <i> </i> $("input[name='optradio-domain']").on("change", getUrlAndLoad);

    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> $("#start-stop-btn").on("click", function (event) {
    <i> </i> event.preventDefault();
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> $("#first-btn").on("click", function() {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#last-btn").on("click", function() {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> $("#prev-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx -= step;
    <i> </i> if (idx &lt; 0) idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> &lt;/script&gt;

    THE PHP:
    <i>
    </i>&lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    $domain = $_GET['domain'];
    $path = $_GET['path'];
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";
    $images = glob ($completepath);
    $forecastdata = [];
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    echo json_encode($forecastdata);
    ?&gt;
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — Commented JS:
    var basicdata = {
    // "prate" is the ID of the forecast or value in the select
    "prate": {
    // "path" is the key, don't change it
    // "PrecipRate" is the value, one level in the complete path
    // of the files
    // This is the complete path:
    // pyqgis-ops/3HrlyAccuRain/d02/*.png
    // +------------
    // |
    // the path to be entered here
    "path": "PrecipRate",
    // the color gradient image at the right
    "colgradimg": "colgrad-img/prate.png"
    },
    "temp": {
    "path": "Temperature",
    "colgradimg": "colgrad-img/temp.png"
    },
    "wind": {
    "path": "Wind850mb",
    "colgradimg": "colgrad-img/wind.png"
    },
    "3HrAccum": {
    "path": "3HrlyAccuRain",
    "colgradimg": "colgrad-img/3HrlyAccu.png"
    },
    "10mwind": {
    "path": "10mwind",
    "colgradimg": "colgrad-img/wind10.png"
    },
    "rh": {
    "path": "RelativeHumidity",
    "colgradimg": "colgrad-img/rh.png"
    },
    "cc": {
    "path": "CloudCover",
    "colgradimg": "colgrad-img/cc.png"
    }
    }

    // Prepare some DOM elements
    var theimg = document.getElementById('forecast-img'),
    thedate = document.getElementById('forecast-date'),
    theUTC = document.getElementById('forecast-utc'),
    thehour = document.getElementById('forecast-hour');

    // idx is the index of the image that is currently display
    // step is the amount the index is increased in each cycle
    // stopped indicates if the animation is running or stopped
    var idx = 0, step = 1, stopped = false;

    // the list of images, in the beginning it is empty
    var forecastdata = [];

    // update list of images every 60 seconds
    setInterval(getUrlAndLoad, 60000);

    // timer that repeats the function every 500 ms
    setInterval(function () {
    console.log(idx, step);
    // change image only
    // 1. if forecastdata is not empty
    // 2. if the animation is not stopped by the corresponding button
    if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    // display image
    theimg.src = forecastdata[idx].img;
    // display additional information date, utc, forecasthour
    // in the corresponding DOM elements
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    // increase index by step so that in the next cycle
    // the next image will be displayed
    idx += step;
    // if the end of the list of images is exceeded:
    // start from the beginning
    if (idx &gt;= forecastdata.length) idx = 0;
    }
    }, 500);

    // currently obsolete
    function loadForecast(url, dmn) {
    $.getJSON(url, { domain: dmn }, function (data) {
    forecastdata = data;
    $("#forecast-container").removeClass("hidden");
    });
    }

    // this function is called everytimes when any parameter
    // (step, domain, type of forecast) is changed
    function getUrlAndLoad() {
    // get value of select
    // it contains the ID of the forecast that has been selected
    var val = $("#select").val();
    // get path of colgrad image and display it
    // in the corresponding DOM element
    var colgradimg = "img/" + basicdata[val].colgradimg;
    $("#colgrad-img").attr("src", colgradimg);
    // get domain
    // it is the value of the radio button that is currently selected
    var domain = $("input[name='optradio-domain']:checked").val();
    console.log(basicdata[val].path, domain);
    // read list of images by executing the PHP script
    $.getJSON("d01-prate.php",
    // object containing the URL parameters that will
    // be handed over to the PHP script
    { path: basicdata[val].path, domain: domain },
    // this funktion is called when the PHP script has been
    // executed successfully
    function (data) {
    // the parameter data contains the list of images
    console.log(data);
    // transfer the list to the corresponding variable
    forecastdata = data;
    // make the container that keeps the forecast visible
    $("#forecast-container").removeClass("hidden");
    });
    }

    // add eventhandler to the select
    // all necessary actions will be done by the function getUrlAndLoad
    $("#select").on('change', getUrlAndLoad);

    // add eventhandler to the radiobuttons for the domain
    // all necessary actions will be done by the function getUrlAndLoad
    $("input[name='optradio-domain']").on("change", getUrlAndLoad);

    // add eventhandler to the radiobuttons for the step or speed
    // of the animation
    $("input[name='optradio']").on("change", function () {
    step = parseInt($("input[name='optradio']:checked").val());
    idx = 0;
    });

    // add eventhandler to the start/stop button
    $("#start-stop-btn").on("click", function (event) {
    event.preventDefault();
    // toggle variable "stopped" und text of the button
    // the variable "stopped" is used in the cyclical callback
    // of the timer
    if (!stopped) {
    stopped = true;
    $(this).text("Start");
    } else {
    stopped = false;
    $(this).text("Stop");
    }
    });

    // add eventhandler to the "first" button
    $("#first-btn").on("click", function () {
    event.preventDefault();
    // stop animation so that the user can view
    // the first forecast
    stopped = true;
    $("#start-stop-btn").text("Start");
    // set index to 0
    // when the animation is started again it will start
    // at this index
    idx = 0;
    // update image and additional fields
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });

    // add eventhandler to the "first" button
    // similar to the "first" button but
    // index is set to the last element in the list of images
    $("#last-btn").on("click", function () {
    event.preventDefault();
    stopped = true;
    $("#start-stop-btn").text("Start");
    idx = forecastdata.length - 1;
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });

    // add eventhandler to the "first" button
    // similar to the "first" button but
    // index is set to the next element in the list of images
    $("#next-btn").on("click", function () {
    event.preventDefault();
    stopped = true;
    $("#start-stop-btn").text("Start");
    idx += step;
    // take into account overflow at the end
    if (idx &gt;= forecastdata.length) idx = 0;
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });

    // add eventhandler to the "first" button
    // similar to the "first" button but
    // index is set to the previous element in the list of images
    $("#prev-btn").on("click", function () {
    event.preventDefault();
    stopped = true;
    $("#start-stop-btn").text("Start");
    idx -= step;
    // take into account overflow at the beginning
    if (idx &lt; 0) idx = forecastdata.length - 1;
    theimg.src = forecastdata[idx].img;
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    });
    Copy linkTweet thisAlerts:
    @SempervivumJul 04.2019 — Commented PHP:
    &lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    // get domain and path from GET parameters
    $domain = $_GET['domain'];
    $path = $_GET['path'];
    // create the complete path from these values
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";
    // read the list of images based on the complete path
    $images = glob($completepath);
    $forecastdata = [];
    // loop over the images
    // $step is obsolete as it is set to 1 and not changed later
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    // get additional parameters from the path of the current image
    $result = preg_match('/-([^-]+)-([^-]+)-([^-]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    // add image and additional parameters to the array
    // that will be output
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    // encode array in JSON format and output it
    echo json_encode($forecastdata);
    ?&gt;
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 04.2019 — @Sempervivum#1605863 thank you so much!

    did you send the configuration for the d02 box?
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — but the d02 box needs some adjustment and that is it.[/quote]
    I choosed the following procedure for adjusting the d02 box:
  • - Add the domain as a class to the main container

  • - All adjustment is done by CSS based on this class

  • - For the forecast image there is only one container whose measurements are adjusted

  • - For the labels I decided to define different containers where the matching one is made visible and the other one not


  • This is the javascript that adds the domain as a class:
    // this function is called everytimes when any parameter
    // (step, domain, type of forecast) is changed
    function getUrlAndLoad() {
    // get value of select
    // it contains the ID of the forecast that has been selected
    var val = $("#select").val();
    // get path of colgrad image and display it
    // in the corresponding DOM element
    var colgradimg = "img/" + basicdata[val].colgradimg;
    $("#colgrad-img").attr("src", colgradimg);
    // get domain
    // it is the value of the radio button that is currently selected
    var domain = $("input[name='optradio-domain']:checked").val();
    // radio buttons for the domains

    <i> </i> // *** This section was added
    <i> </i> thedomains = $("input[name='optradio-domain']");
    <i> </i> // container for the forecast
    <i> </i> thecontainer = $("#forecast-container");
    <i> </i> // remove all domain classes from the container
    <i> </i> thedomains.each(function (idx, ele) {
    <i> </i> thecontainer.removeClass($(this).val());
    <i> </i> });
    <i> </i> // add current domain as a class to the container
    <i> </i> thecontainer.addClass(domain);
    <i> </i> // *** end of added section

    <i> </i> // read list of images by executing the PHP script
    <i> </i> $.getJSON("getforecast.php",
    <i> </i> // object containing the URL parameters that will
    <i> </i> // be handed over to the PHP script
    <i> </i> { path: basicdata[val].path, domain: domain },
    <i> </i> // this funktion is called when the PHP script has been
    <i> </i> // executed successfully
    <i> </i> function (data) {
    <i> </i> // the parameter data contains the list of images
    <i> </i> console.log(data);
    <i> </i> // transfer the list to the corresponding variable
    <i> </i> forecastdata = data;
    <i> </i> // make the container that keeps the forecast visible
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }
    HTML and CSS will follow ...
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — HTML:
    &lt;div id="forecast-container" class="hidden"&gt;
    &lt;div class="labels-left-container d01"&gt;
    &lt;div class="label-left"&gt;30&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="labels-left-container d02"&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="right-container"&gt;
    &lt;div id="img-container"&gt;
    &lt;img id="forecast-img"&gt;
    &lt;/div&gt;
    &lt;div class="labels-bottom-container d01"&gt;
    &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;140&amp;deg;E&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="labels-bottom-container d02"&gt;
    &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;140&amp;deg;E&lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="colgrad-img-container"&gt;
    &lt;img id="colgrad-img"&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    CSS will follow ...
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — CSS:
    &lt;style&gt;
    #forecast-container.hidden {
    visibility: hidden;
    }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #img-container {
    <i> </i> border: 2px solid black;
    <i> </i> overflow: hidden;
    <i> </i> box-sizing: border-box;
    <i> </i> }

    <i> </i> #forecast-container.d01 #img-container {
    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 460px;
    <i> </i> height: 540px;
    <i> </i> }

    <i> </i> #forecast-container.d02 #img-container {
    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 330px;
    <i> </i> height: 540px;
    <i> </i> }

    <i> </i> #forecast-img {
    <i> </i> vertical-align: top;

    <i> </i> /* dimensions of the complete image
    <i> </i> including white borders */
    <i> </i> width: 550px;
    <i> </i> height: 600px;
    <i> </i> }

    <i> </i> #forecast-container.d01 #forecast-img {
    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -45px;
    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> #forecast-container.d02 #forecast-img {
    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -110px;
    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> .labels-left-container {
    <i> </i> display: none;
    <i> </i> }

    <i> </i> #forecast-container.d01 .labels-left-container.d01 {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> #forecast-container.d02 .labels-left-container.d02 {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> .label-left {
    <i> </i> text-align: right;
    <i> </i> padding-left: 5px;
    <i> </i> padding-right: 5px;
    <i> </i> }

    <i> </i> .labels-left-container.d01 .label-left {
    <i> </i> /* the vertical distance between the labels */
    <i> </i> margin-top: 74px;
    <i> </i> }

    <i> </i> .labels-left-container.d01 .label-left:first-child {
    <i> </i> /* the amount the first label is shifted upwards */
    <i> </i> margin-top: -7px;
    <i> </i> }

    <i> </i> .labels-left-container {
    <i> </i> display: none;
    <i> </i> }

    <i> </i> .labels-bottom-container {
    <i> </i> display: none;
    <i> </i> }

    <i> </i> #forecast-container.d01 .labels-bottom-container.d01 {
    <i> </i> display: flex;
    <i> </i> flex-direction: row;
    <i> </i> }

    <i> </i> #forecast-container.d02 .labels-bottom-container.d02 {
    <i> </i> display: flex;
    <i> </i> flex-direction: row;
    <i> </i> }

    <i> </i> .label-bottom {
    <i> </i> text-align: center;
    <i> </i> padding-top: 2px;
    <i> </i> }

    <i> </i> .labels-bottom-container.d01 .label-bottom {
    <i> </i> /* the horizontal distance between the labels */
    <i> </i> margin-left: 52px;
    <i> </i> }

    <i> </i> .labels-bottom-container.d01 .label-bottom:first-child {
    <i> </i> /* the amount the first label is shifted left */
    <i> </i> margin-left: -20px;
    <i> </i> }

    <i> </i> #right-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> #labels-bottom-container {
    <i> </i> display: flex;
    <i> </i> }

    <i> </i> #colgrad-img-container {
    <i> </i> width: 120px;
    <i> </i> height: 740px;
    <i> </i> margin-top: -7px;
    <i> </i> transform: scale(0.747);
    <i> </i> transform-origin: left top;
    <i> </i> }

    <i> </i> #colgrad-img {
    <i> </i> width: 300px;
    <i> </i> height: 900px;
    <i> </i> margin-left: -125px;
    <i> </i> margin-top: -80px;
    <i> </i> }
    <i> </i> &lt;/style&gt;
    Maybe you can adjust the CSS for the labels of d02 yourself.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 05.2019 — @Sempervivum#1605880

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-05/1562334653-493412-kazam-screenshot-00007.png]

    thank you! the box for the d02 worked. and yeah the labels are messed up. both the labels for d01 and d02 are showing up simultaneously
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — The containers for the labels are made invisible at first by this CSS:
    .labels-left-container {
    display: none;
    }

    <i> </i> .labels-bottom-container {
    <i> </i> display: none;
    <i> </i> }
    Did you take over it? Note that I changed the selector for the labels from ID to class. Did you take over this?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 05.2019 — @Sempervivum#1605900 in the css to avoid confusion I just copied the whole css that you recently sent.

    My bad I changed the id to class.

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-05/1562344236-190462-kazam-screenshot-00008.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — That was OK, did you copy the HTML either?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 05.2019 — @Sempervivum#1605910 Yes I did. [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-05/1562345006-292494-kazam-screenshot-00009.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — My bad I changed the id to class.[/quote]Does this mean it works now?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 05.2019 — @Sempervivum#1605912 Yes. just the adjustment of the label

    CSS is weird. in my pc as you can see its the arrangement looks normal, but when I access the website in a pc with a big monitor the style gets misplaced
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — I have a full HD screen and when I switch my browser (Opera) to full screen everything looks fine. There might be two reasons when the display is weird for you:

  • 1. Another browser might display the forecast in a different way. Which one are you using? I didn't test other browsers yet.


  • 2. Another CSS might affect the display of the forecast.


  • Please post a screenshot of the weird display.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 05.2019 — @Sempervivum#1605914 I use google chrome on the other pc. The only issue with the display is the pc with the big monitor. all of my workmates pc's that I tested. the forecasts are the same size as in my pc

    Its saturday here now. I can post the picture on monday
    Copy linkTweet thisAlerts:
    @SempervivumJul 05.2019 — OK, have a nice weekend!
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 05.2019 — @Sempervivum#1605919 thanks you! have a nice weekend ahead yourself!
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 08.2019 — @Sempervivum#1605919

    I'm having trouble trying to align the controls (the buttons). so I decided to create a set of buttons for each domain but I can't get it to appear 😅

    THE HTML:
    <i>
    </i> &lt;div id="controls-d01" class="hidden"&gt; <br/>
    &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id="controls-d02" class="hidden"&gt; <br/>
    &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;/div&gt;

    THE CSS:
    <i>
    </i>#controls-d01.hidden {
    visibility: hidden;
    }

    #controls-d01 {
    **I'm stuck in this part
    }

    #controls-d02.hidden {
    visibility: hidden;
    }

    #controls-d02 {
    **I'm stuck in this part
    }
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 08.2019 — @Sempervivum#1605919

    I'm having trouble trying to align the controls (the buttons). so I decided to create a set of buttons for each domain but I can't get it to appear 😅

    THE HTML:
    <i>
    </i> &lt;div id="controls-d01" class="hidden"&gt; <br/>
    &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id="controls-d02" class="hidden"&gt; <br/>
    &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;/div&gt;

    THE CSS:
    <i>
    </i>#controls-d01.hidden {
    visibility: hidden;
    }

    #controls-d01 {
    **I'm stuck in this part
    }

    #controls-d02.hidden {
    visibility: hidden;
    }

    #controls-d02 {
    **I'm stuck in this part
    }
    Copy linkTweet thisAlerts:
    @SempervivumJul 08.2019 — @frncskn#1605966 I doubt that aligning the controls will be easier if you multiply them. There will be another issue: The buttons are identified by IDs. However IDs have to be unique within the document. Multiple IDs will result in trouble.

    IMO the best would be if you specify how the controls should be aligned. Inside the -forecast-container? Referring to the main forecast image? It might be helpful if you post an image showing the position.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 08.2019 — @Sempervivum#1605970 I reverted the code.

    HTML:
    <i>
    </i>&lt;form style="padding-right: 450px; padding-bottom: 20px;"&gt; <br/>
    &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;/form&gt; <br/>

    d01 looks like this:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-08/1562565713-941955-kazam-screenshot-00000.png]

    d02 looks like this:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-08/1562565728-717080-kazam-screenshot-00001.png]

    I'm asking this because some of the buttons close to the colgradimg seems to be unresponsive sometimes.

    maybe because it overlaps with the padding of the colgrad image?
    Copy linkTweet thisAlerts:
    @SempervivumJul 08.2019 — I see. I assume that d01 is OK and it should be aligned like this. And that d01 is wrong?

    I propose that we put the controls into #forecast-container then it should be easy to center them.

    Unfortunately I have some other activity right now (craftsmen in my home). Will reply later.
    Copy linkTweet thisAlerts:
    @SempervivumJul 08.2019 — @frncskn#1605973 I created a rough demo where the controls are centered relative to the main image. Check if this meets your requirement. Details, e. g. margin/padding between controls and image can be adjusted later.

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-08/1562572395-253840-forecast-controls.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 08.2019 — @Sempervivum#1605975 yes! that work! thank you so much!

    have you tried the d02?
    Copy linkTweet thisAlerts:
    @SempervivumJul 08.2019 — Fine that it's ok for you. d02 needs a minor adjustment. Before doing this I wanted to be shure that it's ok.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 08.2019 — @Sempervivum#1605979 I think there is some "performance issues" with the code because sometimes when I press the radio button for the domain 2. the previous image gets stuck like this:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-08/1562579032-431615-kazam-screenshot-00000.png]

    The only fix is to select an animation invterval and it will return to normal
    Copy linkTweet thisAlerts:
    @SempervivumJul 08.2019 — There is some console.log in the callback of the timer:
    setInterval(function () {
    console.log(idx, step);
    Check if the correspondig output is still alive when the error occurs.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 08.2019 — @Sempervivum#1606004

    I checked and I got this error:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-08/1562629850-665161-kazam-screenshot-00002.png]

    And it traced back to this line of code:
    <i>
    </i> theimg.src = forecastdata[idx].img;


    And there is some cache issues. ie. The images on the screenshot above are now changed. but the browser still plays it even though the files in my pc are already deleted

    EDIT: I think(?) I solved the cache and reloading issue by adding ?ver=3.2.1 in the jquery link

    I'm not sure if that is the fix. I also placed ?v=1.1 after the filename of the css files that I'm using.
    Copy linkTweet thisAlerts:
    @SempervivumJul 09.2019 — I see. Try if this fixes it:
    // add eventhandler to the select
    // all necessary actions will be done by the function getUrlAndLoad
    $("#select").on('change', function () {
    getUrlAndLoad();
    // reset idx
    idx = 0;
    });
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 09.2019 — @Sempervivum#1606029

    I did this like you said:
    <i>
    </i>//add event handler to the #select
    //all necessary actions will be done by the function getUrlAndLoad
    $("#select").on('change', function () {
    getUrlAndLoad();
    // this resets the idx
    idx = 0;
    });


    And the error and problem that I posted above still persists unfortunately
    Copy linkTweet thisAlerts:
    @SempervivumJul 09.2019 — Is there any output in the console [b]before[/b] the error happens?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 09.2019 — @Sempervivum#1606032

    This is what the console looks like before I press the domain 2 button that causes the error:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-09/1562654599-515409-kazam-screenshot-00000.png]

    This is what the console looks like after I press the domain 2 button:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-07-09/1562654681-723594-kazam-screenshot-00001.png]
    Copy linkTweet thisAlerts:
    @SempervivumJul 09.2019 — Unfortunately I didn't read your error description carefully: The error occurs when the [b]domain[/b] is changed, not the type of forecast by the select. Try this instead:
    // add eventhandler to the radiobuttons for the domain
    // all necessary actions will be done by the function getUrlAndLoad
    $("input[name='optradio-domain']").on("change", function () {
    getUrlAndLoad();
    // reset idx
    idx = 0;
    });

    Copy linkTweet thisAlerts:
    @frncsknauthorJul 09.2019 — @Sempervivum#1606036 It works now! But there is now about a 5second delay when I select a forecast parameter
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 09.2019 — > @Sempervivum#1605975 I created a rough demo where the controls are centered relative to the main image. Check if this meets your requirement. Details, e. g. margin/padding between controls and image can be adjusted later.

    Can I see the adjustments you made to the buttons?
    Copy linkTweet thisAlerts:
    @SempervivumJul 09.2019 — @frncskn#1606038 Unfortunately I'm online on a mobile connection right now which is very slow. I will post the CSS for the controls this evening. Gonna reflect about the delay now ...
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 09.2019 — @Sempervivum#1606039 its ok! I was just curious how are you able to put the buttons on the top of the container. 😅
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 09.2019 — @Sempervivum#1606039

    the delays that I'm saying is just sporadic. like right now when I'm selecting a forecast parameter there is no delay. then maybe the delay will happen later
    Copy linkTweet thisAlerts:
    @SempervivumJul 09.2019 — Fast internet available again. I shifted the control buttons into #right-container. That name is a bit confusing as for now it's the middle one. This is the HTML:
    &lt;div id="forecast-container" class="hidden"&gt;
    &lt;div class="labels-left-container d01"&gt;
    &lt;div class="label-left"&gt;30&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="labels-left-container d02"&gt;
    &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="right-container"&gt;
    &lt;div id="controls"&gt;
    &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt; &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id="img-container"&gt;
    &lt;img id="forecast-img"&gt;
    &lt;/div&gt;
    &lt;div class="labels-bottom-container d01"&gt;
    &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;140&amp;deg;E&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="labels-bottom-container d02"&gt;
    &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    &lt;div class="label-bottom"&gt;140&amp;deg;E&lt;/div&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    &lt;div id="colgrad-img-container"&gt;
    &lt;img id="colgrad-img"&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    CSS will follow ...
    Copy linkTweet thisAlerts:
    @SempervivumJul 09.2019 — CSS is limited to #forecast-container and it's child so that I'm fairly shure that it will not interfere with the rest of your page.
    #forecast-container.hidden {
    visibility: hidden;
    }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #forecast-container #controls {
    <i> </i> display: flex;
    <i> </i> justify-content: center;
    <i> </i> }

    <i> </i> #forecast-container #forecast-lower {
    <i> </i> display: flex;
    <i> </i> justify-content: center;
    <i> </i> }

    <i> </i> #img-container {
    <i> </i> border: 2px solid black;
    <i> </i> overflow: hidden;
    <i> </i> box-sizing: border-box;
    <i> </i> }

    <i> </i> #forecast-container.d01 #img-container {
    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 460px;
    <i> </i> height: 540px;
    <i> </i> }

    <i> </i> #forecast-container.d02 #img-container {
    <i> </i> /* dimensions of the inner image
    <i> </i> excluding white borders */
    <i> </i> width: 330px;
    <i> </i> height: 540px;
    <i> </i> }

    <i> </i> #forecast-img {
    <i> </i> vertical-align: top;

    <i> </i> /* dimensions of the complete image
    <i> </i> including white borders */
    <i> </i> width: 550px;
    <i> </i> height: 600px;
    <i> </i> }

    <i> </i> #forecast-container.d01 #forecast-img {
    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -45px;
    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> #forecast-container.d02 #forecast-img {
    <i> </i> /* size of the white border at the left */
    <i> </i> margin-left: -110px;
    <i> </i> /* size of the white border on top */
    <i> </i> margin-top: -30px;
    <i> </i> }

    <i> </i> .labels-left-container {
    <i> </i> display: none;
    <i> </i> }

    <i> </i> #forecast-container.d01 .labels-left-container.d01 {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> #forecast-container.d02 .labels-left-container.d02 {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> }

    <i> </i> .label-left {
    <i> </i> text-align: right;
    <i> </i> padding-left: 5px;
    <i> </i> padding-right: 5px;
    <i> </i> }

    <i> </i> .labels-left-container.d01 .label-left {
    <i> </i> /* the vertical distance between the labels */
    <i> </i> margin-top: 74px;
    <i> </i> }

    <i> </i> .labels-left-container.d01 .label-left:first-child {
    <i> </i> /* the amount the first label is shifted upwards */
    <i> </i> margin-top: 14px;
    <i> </i> }

    <i> </i> .labels-left-container {
    <i> </i> display: none;
    <i> </i> }

    <i> </i> .labels-bottom-container {
    <i> </i> display: none;
    <i> </i> }

    <i> </i> #forecast-container.d01 .labels-bottom-container.d01 {
    <i> </i> display: flex;
    <i> </i> flex-direction: row;
    <i> </i> }

    <i> </i> #forecast-container.d02 .labels-bottom-container.d02 {
    <i> </i> display: flex;
    <i> </i> flex-direction: row;
    <i> </i> }

    <i> </i> .label-bottom {
    <i> </i> text-align: center;
    <i> </i> padding-top: 2px;
    <i> </i> }

    <i> </i> .labels-bottom-container.d01 .label-bottom {
    <i> </i> /* the horizontal distance between the labels */
    <i> </i> margin-left: 52px;
    <i> </i> }

    <i> </i> .labels-bottom-container.d01 .label-bottom:first-child {
    <i> </i> /* the amount the first label is shifted left */
    <i> </i> margin-left: -20px;
    <i> </i> }

    <i> </i> #forecast-container.d01 #right-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> width: 460px;
    <i> </i> }

    <i> </i> #forecast-container.d02 #right-container {
    <i> </i> display: flex;
    <i> </i> flex-direction: column;
    <i> </i> width: 330px;
    <i> </i> }

    <i> </i> #labels-bottom-container {
    <i> </i> display: flex;
    <i> </i> }

    <i> </i> #colgrad-img-container {
    <i> </i> width: 120px;
    <i> </i> height: 740px;
    <i> </i> margin-top: -7px;
    <i> </i> transform: scale(0.747);
    <i> </i> transform-origin: left top;
    <i> </i> margin-top: 15px;
    <i> </i> }

    <i> </i> #colgrad-img {
    <i> </i> width: 300px;
    <i> </i> height: 900px;
    <i> </i> margin-left: -125px;
    <i> </i> margin-top: -80px;
    <i> </i> }
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 10.2019 — @Sempervivum#1606076
    <i>
    </i>gis.html:275 Uncaught TypeError: Cannot read property 'colgradimg' of undefined
    at getUrlAndLoad (gis.html:275)
    getUrlAndLoad @ gis.html:275
    setInterval (async)
    (anonymous) @ gis.html:240


    I get this weird error. and the performance issues of when selecting domains :(
    Copy linkTweet thisAlerts:
    @SempervivumJul 10.2019 — I assume that the error occurs in this line:
    function getUrlAndLoad() {
    // get value of select
    // it contains the ID of the forecast that has been selected
    var val = $("#select").val();
    // get path of colgrad image and display it
    // in the corresponding DOM element
    var colgradimg = "img/" + basicdata[val].colgradimg; // &lt;---
    $("#colgrad-img").attr("src", colgradimg);

    BTW: Will have to switch to a slow connection again. Be patient if I cannot answer immediately.
    Copy linkTweet thisAlerts:
    @SempervivumJul 10.2019 — PS: Is this error permanent or sporadical? Did it occur after applying the last HTML and CSS or is it independent?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 10.2019 — @Sempervivum#1606091 It is sporadic. it disappears before I select a forecast parameter. and like I said the performance errors are sometimes occurring then when I refresh a page or new data is loaded it will weirdly disappear
    Copy linkTweet thisAlerts:
    @SempervivumJul 10.2019 — I'm not shure if this will help, but try this:
    // timer that repeats the function every 500 ms
    setInterval(function () {
    console.log(idx, step);
    // change image only
    // 1. if forecastdata is not empty
    // 2. if the animation is not stopped by the corresponding button
    if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    if (forecastdata[idx]) {
    // display image
    theimg.src = forecastdata[idx].img;
    } else {
    // get new forecast data
    getUrlAndLoad();
    idx = 0;
    }
    // display additional information date, utc, forecasthour
    // in the corresponding DOM elements
    thedate.innerHTML = forecastdata[idx].date;
    theUTC.innerHTML = forecastdata[idx].utc;
    thehour.innerHTML = forecastdata[idx].forecasthour;
    // increase index by step so that in the next cycle
    // the next image will be displayed
    idx += step;
    // if the end of the list of images is exceeded:
    // start from the beginning
    if (idx &gt;= forecastdata.length) idx = 0;
    }
    }, 500);
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 10.2019 — @Sempervivum#1606099 I tried the code. and it seems that it fixed the performance issue. the lag time between the selection of the parameters is gone :)

    but the colgrad error is still there.
    Copy linkTweet thisAlerts:
    @SempervivumJul 10.2019 — @frncskn#1606101 Regarding the colgrad error: Obviously this:

    `basicdata[val]</C><br/>
    doesn't exist. <C>
    val`
    is the value of the select. These values have to match the keys in the basicdata. Did you change anything here?
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 10.2019 — @Sempervivum#1606107 i didn't change anything. So basically this error can be neglected? Because as I observed the error shows up when I don't select a parameter then disappears when I do select a parameter.
    Copy linkTweet thisAlerts:
    @SempervivumJul 10.2019 — Does this error occur after page load when no parameter is selected yet? And is there no visible effect? I would try to suppress it anyway.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 10.2019 — @Sempervivum#1606118 Yes. when I refresh the page and no parameter is selected the error appears. but when I select a parameter no errors are showing in the console.

    Is it possible if I refresh the page a parameter is automatically selected ie. the preciprate? I think that will suppress the error.
    Copy linkTweet thisAlerts:
    @SempervivumJul 10.2019 — Of course this is possible. Shift the "selected" attribute in the select to the option for preciprate and call `getUrlAndLoad()` at the bottom of the javascript section.
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 11.2019 — @Sempervivum#1606131 Thanks for the suggestion. I will get back to you in a couple of days. I'll just have to make the documentation for this project (The ERD etc..) thank you for the patience :)
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 05.2019 — @Sempervivum#1606131 Hello is it possible to put like a slider for the speed of the images?
    Copy linkTweet thisAlerts:
    @SempervivumAug 05.2019 — Welcome back! Does the other code work so far?

    Regarding your question: There is an input of type "range". You can use it in order to set the speed or step or interval. If you don't succeed in impelementing it, come back.

    https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 05.2019 — @Sempervivum#1607179 Thank you! I'm busy with the documentations 😂 especially the Functional Decomposition Diagram and Context Diagram -_-. Anyways I will check and will return as soon as possible thank you!
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607179 Hello 😄 I have more questions to you because my boss wants more features to the website that we made

    Inside the map there is a horizontal line from the 20 degree and 10 degree labels to the other side and a vertical line from the 120 degree and 130 degree label to the other side. is it possible to put that line in our project?

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-08-23/1566524370-286870-kazam-screenshot-00004.png]
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — Welcome back! Shurely this will be possible. However I remember, that the images are created by a Python script. Wouldn't it be better and, maybe, easier, to draw the lines at that level?
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607904 No. that is sadly one of the limitations of the python library that I'm using.
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — OK. Would this requirement appy to all of the images?
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607906 Yes. its like a "proxy" for a grid box
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — OK, I'm gonna look into ...
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — ... looked into my test configuration and at the first glance I'm a bit confused:

    All of the images I have in the folder pyqgis-ops already have a grid.

    Please explain.
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607910 ahh I will send you new images. That is the older version. Yes I can put grid but that problem is I can't modify that grid so my boss suggested to just remove it.

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-08-23/1566548258-141258-d01-rpn3hrlyaccum-postwrf-d01-20181118-0600-f00600.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-08-23/1566548282-671935-d02-rpn3hrlyaccum-postwrf-d02-20181120-0300-f01600.png]
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — Thanks, that will do to start with.

    I consider the following: Till now we created the labels by HTML elements and positioned each label individually. We might continue this procedure when creating the grid but I'm afraid it would grow too confusing.

    An alternative might be: Draw all of it, the image, the labels and the grid, on a canvas. Then it would be easy to draw labels and grid lines by an algorithm. No need to position them individually.

    Pro: Easier to create and modify.

    Con: Canvas cannot be scaled up losslessly and thus it's difficult to make the whole thing responsive. However the basis for the complete display is the PNG image which cannot be scaled up anyway.

    What do you think?
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607912 Do you have a sample for that suggestion?

    To make it clear. You will draw the bounding box, the lines and the coordinate labels?
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — Yes, in the meantime I noticed that the images need to be cropped. I would do the cropping, drawing the grid lines and the coordinate labels by the canvas API. Unfortunately I don't have a sample, but to clarify, all of this would be configurable in a list like this (rough draft):
    <i>
    </i>var datad01 = {
    cropLeft: 50px,
    cropRight: 40px,
    cropTop: 30px,
    cropBottom: 45px,
    paddingLeft: 40px, // space for labels
    paddingBottom: 40px, // space for labels
    startVerticalLabelPos: 0px,
    startVerticalLabelNumber: 120,
    stepVerticalLabelPos: 50px,
    stepVerticalLabelNumber: 10,
    // the same for horizontal labels and grid lines
    }
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607915 Yes it needs to be cropped because the white spaces around the image.

    but if the lines are to be drawn using the other method?

    btw. have you tried running a shell script in a website? (the shell script will be handled by php)
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — I forgot the grid lines:
    var datad01 = {
    cropLeft: 50px,
    cropRight: 40px,
    cropTop: 30px,
    cropBottom: 45px,
    paddingLeft: 40px, // space for labels
    paddingBottom: 40px, // space for labels
    startVerticalLabelPos: 0px,
    startVerticalLabelNumber: 120,
    startVerticalGridLine: 0px;
    stepVerticalLabelPos: 50px,
    stepVerticalLabelNumber: 10,
    stepVerticalGridLine: 25px,
    // the same for horizontal labels and grid lines
    }
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 23.2019 — @Sempervivum#1607918 Thank you so much!
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — The main benefit is that the parameters are not scattered through the HTML and the CSS but condensed in this data structure.
    Copy linkTweet thisAlerts:
    @SempervivumAug 23.2019 — I coded a basic version for cropping and drawing the image, the labels and the grid by use of the library jCanvas. This is the output:

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-08-23/1566592015-432014-forecast-jcanvas.png]

    Some finetuning left to be done, e. g. centering the labels. And of course integration in the complete site.
    Copy linkTweet thisAlerts:
    @frncsknauthorAug 27.2019 — @Sempervivum#1607942 Hello sorry for the late response. We celebrated a holiday last Monday hence no work 😅
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 02.2019 — @Sempervivum#1607942 Hello. I have to remove this?

    then where do I have to put the code you posted above?
    <i>
    </i> &lt;div class="col-md-7"&gt; <br/>
    &lt;div id="forecast-container" class="hidden"&gt;

    <i> </i> &lt;div class="labels-left-container d01" style="font-size: 13px;"&gt;
    <i> </i> &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="labels-left-container d02" style="font-size: 12px;"&gt;
    <i> </i> &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;18&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;16&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;14&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;12&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;8&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;6&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="right-container"&gt;
    <i> </i> &lt;div class="controls" style="padding-bottom: 5px;"&gt;
    <i> </i> &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    <i> </i> &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    <i> </i> &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    <i> </i> &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    <i> </i> &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="img-container"&gt;
    <i> </i> &lt;img id="forecast-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="labels-bottom-container d01" style="font-size: 13px;"&gt;
    <i> </i> &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="labels-bottom-container d02" style="font-size: 12px;"&gt;
    <i> </i> &lt;div class="label-bottom"&gt;118&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;122&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;124&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;126&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="colgrad-img-container"&gt;
    <i> </i> &lt;img id="colgrad-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — Hi, I'm sorry, I'd had to add some explanations and post the code that crops the image and creates the labels.

    To start with I created a stand-alone page for developing and testing the code. I used a library named jCanvas.

    This is the code:
    &lt;!doctype html&gt;
    &lt;html lang="en"&gt;

    &lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;Wheather Forecast&lt;/title&gt;

    <i> </i>&lt;script src="https://code.jquery.com/jquery-3.2.1.min.js"&gt;&lt;/script&gt;
    <i> </i>&lt;script src="js/jcanvas.js"&gt;&lt;/script&gt;
    <i> </i>&lt;style&gt;
    <i> </i> body {
    <i> </i> margin: 0;
    <i> </i> }
    <i> </i>&lt;/style&gt;
    &lt;/head&gt;

    &lt;body&gt;
    &lt;canvas id="cv-forecast"&gt;&lt;/canvas&gt;
    &lt;script&gt;
    var datad01 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels
    startVerticalLabelPos: 0,
    startVerticalLabelNumber: 30,
    stepVerticalLabelPos: 100,
    stepVerticalLabelNumber: 5,
    startHorizontalGridLine: 0,
    stepHorizontalGridLine: 100,
    startHorizontalLabelPos: 60,
    startHorizontalLabelNumber: 60,
    stepHorizontalLabelPos: 200,
    stepHorizontalLabelNumber: 10,
    startVerticalGridLine: 0,
    stepVerticalGridLine: 100,
    }
    var marginText = 5,
    suffixVertical = '°N',
    suffixHorizontal = '°E',
    strokeWidthGrid = 1,
    strokeWidthBorder = 2;
    var cv = $("#cv-forecast");
    var dataCv = datad01;
    var forecastImg = new Image();
    forecastImg.onload = createForecast;
    forecastImg.src = 'pyqgis-ops/3HrlyAccuRain/d01/1566548258-141258-d01-rpn3hrlyaccum-postwrf-d01-20181118-0600-f00600.png';
    function createForecast() {
    function drawVerticalLabels() {
    var x = dataCv.paddingLeft - dataCv.marginText;
    for (var y = dataCv.startVerticalLabelPos,
    nr = dataCv.startVerticalLabelNumber;
    y &lt; hCv - dataCv.paddingBottom;
    y += dataCv.stepVerticalLabelPos, nr -= dataCv.stepVerticalLabelNumber) {
    var text = nr + suffixVertical;
    cv.drawText({
    layer: true,
    name: text,
    x: 0, y: y,
    fillStyle: '#36c', strokeWidth: 2,
    text: text,
    fromCenter: false
    });
    var wText = cv.measureText(text).width;
    cv.setLayer(text, {
    x: dataCv.paddingLeft - wText - marginText
    });
    }
    }
    function drawHorizontalLabels() {
    var y = hCv - dataCv.paddingBottom + marginText;
    for (var x = dataCv.startHorizontalLabelPos,
    nr = dataCv.startHorizontalLabelNumber;
    x &lt; wCv;
    x += dataCv.stepHorizontalLabelPos, nr += dataCv.stepHorizontalLabelNumber) {
    var text = nr + suffixHorizontal;
    cv.drawText({
    layer: true,
    name: text,
    x: x, y: y,
    fillStyle: '#36c', strokeWidth: 2,
    text: text,
    fromCenter: false
    });
    var wText = cv.measureText(text).width;
    // cv.setLayer(text, { x: dataCv.paddingLeft - wText - marginText });
    }
    }
    function drawHorizontalLines() {
    var x1 = dataCv.paddingLeft, x2 = wCv;
    for (var y = dataCv.startHorizontalGridLine - strokeWidthGrid / 2;
    y &lt; hCv - dataCv.paddingBottom;
    y += dataCv.stepHorizontalGridLine) {
    cv.drawLine({
    layer: true,
    strokeStyle: '#000', strokeWidth: strokeWidthGrid,
    x1: x1, y1: y, x2: x2, y2: y,
    fromCenter: false
    });
    }
    }
    function drawVerticalLines() {
    var y1 = 0, y2 = hCv - dataCv.paddingBottom;
    for (var x = dataCv.paddingLeft + dataCv.startVerticalGridLine - strokeWidthGrid / 2;
    x &lt; wCv;
    x += dataCv.stepVerticalGridLine) {
    cv.drawLine({
    layer: true,
    strokeStyle: '#000', strokeWidth: strokeWidthGrid,
    x1: x, x2: x, y1: y1, y2: y2,
    fromCenter: false
    });
    }
    }
    var wImg = this.width, hImg = this.height;
    var wCv = wImg - dataCv.cropLeft - dataCv.cropRight + dataCv.paddingLeft,
    hCv = hImg - dataCv.cropTop - dataCv.cropBottom + dataCv.paddingBottom;
    cv.attr('width', wCv + 500);
    cv.attr('height', hCv + 500);
    cv.drawImage({
    layer: true,
    source: forecastImg,
    x: dataCv.paddingLeft, y: 0,
    sWidth: wImg - dataCv.cropRight - dataCv.cropLeft,
    sHeight: hImg - dataCv.cropBottom - dataCv.cropTop,
    sx: dataCv.cropLeft, sy: dataCv.cropTop,
    fromCenter: false, cropFromCenter: false
    }).drawRect({
    layer: true,
    strokeStyle: '#000', strokeWidth: strokeWidthBorder,
    x: dataCv.paddingLeft, y: 0,
    width: wImg - dataCv.cropRight - dataCv.cropLeft,
    height: hImg - dataCv.cropBottom - dataCv.cropTop,
    fromCenter: false
    });
    drawVerticalLabels();
    drawHorizontalLabels();
    drawVerticalLines();
    drawHorizontalLines();
    cv.drawLayers();
    }
    &lt;/script&gt;
    &lt;/body&gt;

    &lt;/html&gt;

    jcanvas.js in my next posting.
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — Posting jcanvas.js was not possible as it was too large. Please download it from here:

    http://webentwicklung.ulrichbangert.de/js/jcanvas.js

    Please text the code and check if it fits your needs. As a next step we will integrate it into the complete page.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 02.2019 — @Sempervivum#1608232

    Hello! I tested your code and this is the output:

    Can I ask if its possible to reduce the grid lines inside the box?

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-09-02/1567413995-352990-kazam-screenshot-00000.png]
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — Can I ask if its possible to reduce the grid lines inside the box?[/quote]Do you mean that the distance between the grid lines should be larger or that there should be less lines? This is possible, the paramter `stepVerticalLabelPos</C> defines the distance in pixels.

    I didn't include the colgraph image in the canvas yet and I'm unsure if I shoud do. Pro: The current <C>
    basicdata`
    would get obsolute, only on set of data; the height could be set equal to the heigt of the forecast image automatically.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 02.2019 — @Sempervivum#1608234 I'm sorry. That question I think should be asked after you set the code in the main website.
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — I added some comments to the config data:
    var datad01 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels

    <i> </i> // start position of the vertical labels in pixels,
    <i> </i> // i. e. the position of the first label
    <i> </i> startVerticalLabelPos: 0,

    <i> </i> // start for the vertical label numbers
    <i> </i> startVerticalLabelNumber: 30,

    <i> </i> // step for the position of the vertical labels in pixels
    <i> </i> // i. e. the distance between the labels
    <i> </i> stepVerticalLabelPos: 100,

    <i> </i> // step for the vertical label numbers
    <i> </i> stepVerticalLabelNumber: 5,

    <i> </i> // start position for the horizontal grid lines in pixels,
    <i> </i> // i. e. the position of the first line
    <i> </i> startHorizontalGridLine: 0,

    <i> </i> // step for the horizontal grid lines,
    <i> </i> // i. e. the distance between the horizontal lines
    <i> </i> stepHorizontalGridLine: 100,
    <i> </i> startHorizontalLabelPos: 60,

    <i> </i> // horizontal labels at the bottom and vertical grid lines
    <i> </i> // are configured like the ones above
    <i> </i> startHorizontalLabelNumber: 60,
    <i> </i> stepHorizontalLabelPos: 200,
    <i> </i> stepHorizontalLabelNumber: 10,
    <i> </i> startVerticalGridLine: 0,
    <i> </i> stepVerticalGridLine: 100,
    <i> </i> }
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — I'm gonna start adding the canvas to my complete test page now ...
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 02.2019 — @Sempervivum#1608236 Do I need to post the code of the website here? the html and css?
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — I have a test site on my local computer. However I'm not shure if it still matches yours. Might be advisable to make it equal.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 02.2019 — @Sempervivum#1608239 Noted. Thank you
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — I've integrated the code in my test files.

    I created an external JS file for the JS that draws on the canvas and named it draw-forecast.js

    The code reads:
    var datad01 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingTop: 15,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels

    <i> </i>// start position of the vertical labels in pixels,
    <i> </i>// i. e. the position of the first label
    <i> </i>startVerticalLabelPos: 0,

    <i> </i>// start for the vertical label numbers
    <i> </i>startVerticalLabelNumber: 30,

    <i> </i>// step for the position of the vertical labels in pixels
    <i> </i>// i. e. the distance between the labels
    <i> </i>stepVerticalLabelPos: 100,

    <i> </i>// step for the vertical label numbers
    <i> </i>stepVerticalLabelNumber: 5,

    <i> </i>// start position for the horizontal grid lines in pixels,
    <i> </i>// i. e. the position of the first line
    <i> </i>startHorizontalGridLine: 0,

    <i> </i>// step for the horizontal grid lines,
    <i> </i>// i. e. the distance between the horizontal lines
    <i> </i>stepHorizontalGridLine: 100,
    <i> </i>startHorizontalLabelPos: 60,

    <i> </i>// horizontal labels at the bottom and vertical grid lines
    <i> </i>// are configured like the ones above
    <i> </i>startHorizontalLabelNumber: 60,
    <i> </i>stepHorizontalLabelPos: 200,
    <i> </i>stepHorizontalLabelNumber: 10,
    <i> </i>startVerticalGridLine: 0,
    <i> </i>stepVerticalGridLine: 100,
    }

    var datad02 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingTop: 15,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels

    <i> </i>// start position of the vertical labels in pixels,
    <i> </i>// i. e. the position of the first label
    <i> </i>startVerticalLabelPos: 0,

    <i> </i>// start for the vertical label numbers
    <i> </i>startVerticalLabelNumber: 30,

    <i> </i>// step for the position of the vertical labels in pixels
    <i> </i>// i. e. the distance between the labels
    <i> </i>stepVerticalLabelPos: 100,

    <i> </i>// step for the vertical label numbers
    <i> </i>stepVerticalLabelNumber: 5,

    <i> </i>// start position for the horizontal grid lines in pixels,
    <i> </i>// i. e. the position of the first line
    <i> </i>startHorizontalGridLine: 0,

    <i> </i>// step for the horizontal grid lines,
    <i> </i>// i. e. the distance between the horizontal lines
    <i> </i>stepHorizontalGridLine: 100,
    <i> </i>startHorizontalLabelPos: 60,

    <i> </i>// horizontal labels at the bottom and vertical grid lines
    <i> </i>// are configured like the ones above
    <i> </i>startHorizontalLabelNumber: 60,
    <i> </i>stepHorizontalLabelPos: 200,
    <i> </i>stepHorizontalLabelNumber: 10,
    <i> </i>startVerticalGridLine: 0,
    <i> </i>stepVerticalGridLine: 100,
    }

    var marginText = 5,
    suffixVertical = '°N',
    suffixHorizontal = '°E',
    strokeWidthGrid = 1,
    strokeWidthBorder = 2;

    function drawForecast(imgpath, domain) {
    var cv = $("#cv-forecast");
    var forecastImg = new Image();
    if (domain == 'd01') var dataCv = datad01;
    else var dataCv = datad02;
    var dataCv = datad01;
    forecastImg.onload = createForecast;
    forecastImg.src = imgpath;
    function createForecast() {
    function drawVerticalLabels() {
    var x = dataCv.paddingLeft - dataCv.marginText;
    for (var y = dataCv.paddingTop + dataCv.startVerticalLabelPos,
    nr = dataCv.startVerticalLabelNumber;
    y &lt; hCv - dataCv.paddingBottom;
    y += dataCv.stepVerticalLabelPos, nr -= dataCv.stepVerticalLabelNumber) {
    var text = nr + suffixVertical;
    cv.drawText({
    layer: true,
    name: text,
    x: 0, y: y,
    fillStyle: '#36c', strokeWidth: 2,
    text: text,
    fromCenter: false
    });
    var wText = cv.measureText(text).width,
    hText = cv.measureText(text).height;
    cv.setLayer(text, {
    x: dataCv.paddingLeft - wText - marginText,
    y: y - hText / 2
    });
    }
    }
    function drawHorizontalLabels() {
    var y = hCv - dataCv.paddingBottom + marginText;
    for (var x = dataCv.startHorizontalLabelPos,
    nr = dataCv.startHorizontalLabelNumber;
    x &lt; wCv;
    x += dataCv.stepHorizontalLabelPos, nr += dataCv.stepHorizontalLabelNumber) {
    var text = nr + suffixHorizontal;
    cv.drawText({
    layer: true,
    name: text,
    x: x, y: y,
    fillStyle: '#36c', strokeWidth: 2,
    text: text,
    fromCenter: false
    });
    var wText = cv.measureText(text).width;
    cv.setLayer(text, { x: x - wText / 2 });
    }
    }
    function drawHorizontalLines() {
    var x1 = dataCv.paddingLeft, x2 = wCv;
    for (var y = dataCv.paddingTop + dataCv.startHorizontalGridLine - strokeWidthGrid / 2;
    y &lt; hCv - dataCv.paddingBottom;
    y += dataCv.stepHorizontalGridLine) {
    cv.drawLine({
    layer: true,
    strokeStyle: '#000', strokeWidth: strokeWidthGrid,
    x1: x1, y1: y, x2: x2, y2: y,
    fromCenter: false
    });
    }
    }
    function drawVerticalLines() {
    var y1 = dataCv.paddingTop, y2 = hCv - dataCv.paddingBottom;
    for (var x = dataCv.paddingLeft + dataCv.startVerticalGridLine - strokeWidthGrid / 2;
    x &lt; wCv;
    x += dataCv.stepVerticalGridLine) {
    cv.drawLine({
    layer: true,
    strokeStyle: '#000', strokeWidth: strokeWidthGrid,
    x1: x, x2: x, y1: y1, y2: y2,
    fromCenter: false
    });
    }
    }
    var wImg = this.width, hImg = this.height;
    var wCv = wImg - dataCv.cropLeft - dataCv.cropRight + dataCv.paddingLeft,
    hCv = hImg - dataCv.cropTop - dataCv.cropBottom + dataCv.paddingTop + dataCv.paddingBottom;
    cv.attr('width', wCv);
    cv.attr('height', hCv);
    cv.drawImage({
    layer: true,
    source: forecastImg,
    x: dataCv.paddingLeft, y: dataCv.paddingTop,
    sWidth: wImg - dataCv.cropRight - dataCv.cropLeft,
    sHeight: hImg - dataCv.cropBottom - dataCv.cropTop,
    sx: dataCv.cropLeft, sy: dataCv.cropTop,
    fromCenter: false, cropFromCenter: false
    }).drawRect({
    layer: true,
    strokeStyle: '#000', strokeWidth: strokeWidthBorder,
    x: dataCv.paddingLeft, y: dataCv.paddingTop,
    width: wImg - dataCv.cropRight - dataCv.cropLeft,
    height: hImg - dataCv.cropBottom - dataCv.cropTop,
    fromCenter: false
    });
    drawVerticalLabels();
    drawHorizontalLabels();
    drawVerticalLines();
    drawHorizontalLines();
    cv.drawLayers();
    }
    }
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — HTML: I replaced the the image container by the canvas:
    &lt;div id="forecast-container" class="hidden"&gt;
    &lt;canvas id="cv-forecast"&gt;&lt;/canvas&gt;
    &lt;div id="colgrad-img-container"&gt;
    &lt;img id="colgrad-img"&gt;
    &lt;/div&gt;
    &lt;/div&gt;
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — The CSS could be simplified a lot as the labels are obsolete now:
    #forecast-container.hidden {
    visibility: hidden;
    }

    <i> </i> #forecast-container {
    <i> </i> display: flex;
    <i> </i> align-items: flex-start;
    <i> </i> padding-top: 10px;
    <i> </i> }

    <i> </i> #forecast-container #controls {
    <i> </i> display: flex;
    <i> </i> justify-content: center;
    <i> </i> }

    <i> </i> #forecast-container #forecast-lower {
    <i> </i> display: flex;
    <i> </i> justify-content: center;
    <i> </i> }

    <i> </i> #colgrad-img-container {
    <i> </i> width: 120px;
    <i> </i> height: 740px;
    <i> </i> margin-top: -7px;
    <i> </i> transform: scale(0.754);
    <i> </i> transform-origin: left top;
    <i> </i> margin-top: 8px;
    <i> </i> }

    <i> </i> #colgrad-img {
    <i> </i> width: 300px;
    <i> </i> height: 900px;
    <i> </i> margin-left: -125px;
    <i> </i> margin-top: -80px;
    <i> </i> }
    Copy linkTweet thisAlerts:
    @SempervivumSep 02.2019 — Minor modifications in the existing JS, I marked them with an arrrow <---
    var basicdata = {
    // "prate" is the ID of the forecast or value in the select
    "prate": {
    // "path" is the key, don't change it
    // "PrecipRate" is the value, one level in the complete path
    // of the files
    // This is the complete path:
    // pyqgis-ops/3HrlyAccuRain/d02/*.png
    // +------------
    // |
    // the path to be entered here
    "path": "PrecipRate",
    // the color gradient image at the right
    "colgradimg": "colgrad-img/prate.png"
    },
    "temp": {
    "path": "Temperature",
    "colgradimg": "colgrad-img/temp.png"
    },
    "wind": {
    "path": "Wind850mb",
    "colgradimg": "colgrad-img/wind.png"
    },
    "3HrAccum": {
    "path": "3HrlyAccuRain",
    "colgradimg": "colgrad-img/3HrlyAccu.png"
    },
    "10mwind": {
    "path": "10mwind",
    "colgradimg": "colgrad-img/wind10.png"
    },
    "rh": {
    "path": "RelativeHumidity",
    "colgradimg": "colgrad-img/rh.png"
    },
    "cc": {
    "path": "CloudCover",
    "colgradimg": "colgrad-img/cc.png"
    }
    }

    <i> </i> // Prepare some DOM elements
    <i> </i> var theimg = document.getElementById('forecast-img'),
    <i> </i> thedate = document.getElementById('forecast-date'),
    <i> </i> theUTC = document.getElementById('forecast-utc'),
    <i> </i> thehour = document.getElementById('forecast-hour');

    <i> </i> // idx is the index of the image that is currently display
    <i> </i> // step is the amount the index is increased in each cycle
    <i> </i> // stopped indicates if the animation is running or stopped
    <i> </i> var idx = 0, step = 1, stopped = false;

    <i> </i> // the domain that is currently set &lt;---
    <i> </i> var domain; // &lt;---

    <i> </i> // the list of images, in the beginning it is empty
    <i> </i> var forecastdata = [];

    <i> </i> // update list of images every 60 seconds
    <i> </i> setInterval(getUrlAndLoad, 60000);

    <i> </i> // timer that repeats the function every 500 ms
    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> // change image only
    <i> </i> // 1. if forecastdata is not empty
    <i> </i> // 2. if the animation is not stopped by the corresponding button
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> if (forecastdata[idx]) {
    <i> </i> // draw forecast image on canvas &lt;---
    <i> </i> drawForecast(forecastdata[idx].img, domain); // &lt;---
    <i> </i> } else {
    <i> </i> // get new forecast data
    <i> </i> getUrlAndLoad();
    <i> </i> }
    <i> </i> // display additional information date, utc, forecasthour
    <i> </i> // in the corresponding DOM elements
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> // increase index by step so that in the next cycle
    <i> </i> // the next image will be displayed
    <i> </i> idx += step;
    <i> </i> // if the end of the list of images is exceeded:
    <i> </i> // start from the beginning
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 500);

    <i> </i> // currently obsolete
    <i> </i> function loadForecast(url, dmn) {
    <i> </i> $.getJSON(url, { domain: dmn }, function (data) {
    <i> </i> forecastdata = data;
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }

    <i> </i> // this function is called everytimes when any parameter
    <i> </i> // (step, domain, type of forecast) is changed
    <i> </i> function getUrlAndLoad() {
    <i> </i> // get value of select
    <i> </i> // it contains the ID of the forecast that has been selected
    <i> </i> var val = $("#select").val();
    <i> </i> // get path of colgrad image and display it
    <i> </i> // in the corresponding DOM element
    <i> </i> var colgradimg = "img/" + basicdata[val].colgradimg;
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> // get domain
    <i> </i> // it is the value of the radio button that is currently selected
    <i> </i> domain = $("input[name='optradio-domain']:checked").val(); // &lt;--- removed var in order to make it global
    <i> </i> // radio buttons for the domains
    <i> </i> thedomains = $("input[name='optradio-domain']");
    <i> </i> // container for the forecast
    <i> </i> thecontainer = $("#forecast-container");
    <i> </i> // remove all domain classes from the container
    <i> </i> thedomains.each(function (idx, ele) {
    <i> </i> thecontainer.removeClass($(this).val());
    <i> </i> });
    <i> </i> // add current domain as a class to the container
    <i> </i> thecontainer.addClass(domain);
    <i> </i> // read list of images by executing the PHP script
    <i> </i> $.getJSON("getforecast.php",
    <i> </i> // object containing the URL parameters that will
    <i> </i> // be handed over to the PHP script
    <i> </i> { path: basicdata[val].path, domain: domain },
    <i> </i> // this funktion is called when the PHP script has been
    <i> </i> // executed successfully
    <i> </i> function (data) {
    <i> </i> // the parameter data contains the list of images
    <i> </i> console.log(data);
    <i> </i> // transfer the list to the corresponding variable
    <i> </i> forecastdata = data;
    <i> </i> // make the container that keeps the forecast visible
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }

    <i> </i> // add eventhandler to the select
    <i> </i> // all necessary actions will be done by the function getUrlAndLoad
    <i> </i> $("#select").on('change', function () {
    <i> </i> getUrlAndLoad();
    <i> </i> // reset idx
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> // add eventhandler to the radiobuttons for the domain
    <i> </i> // all necessary actions will be done by the function getUrlAndLoad
    <i> </i> $("input[name='optradio-domain']").on("change", function () {
    <i> </i> getUrlAndLoad();
    <i> </i> // reset idx
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> // add eventhandler to the radiobuttons for the step or speed
    <i> </i> // of the animation
    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> // add eventhandler to the start/stop button
    <i> </i> $("#start-stop-btn").on("click", function (event) {
    <i> </i> event.preventDefault();
    <i> </i> // toggle variable "stopped" und text of the button
    <i> </i> // the variable "stopped" is used in the cyclical callback
    <i> </i> // of the timer
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> // add eventhandler to the "first" button
    <i> </i> $("#first-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> // stop animation so that the user can view
    <i> </i> // the first forecast
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> // set index to 0
    <i> </i> // when the animation is started again it will start
    <i> </i> // at this index
    <i> </i> idx = 0;
    <i> </i> // update image and additional fields
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> // add eventhandler to the "first" button
    <i> </i> // similar to the "first" button but
    <i> </i> // index is set to the last element in the list of images
    <i> </i> $("#last-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> // add eventhandler to the "first" button
    <i> </i> // similar to the "first" button but
    <i> </i> // index is set to the next element in the list of images
    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> // take into account overflow at the end
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> // add eventhandler to the "first" button
    <i> </i> // similar to the "first" button but
    <i> </i> // index is set to the previous element in the list of images
    <i> </i> $("#prev-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx -= step;
    <i> </i> // take into account overflow at the beginning
    <i> </i> if (idx &lt; 0) idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608261Can I ask where is to put the path for the images?
    Copy linkTweet thisAlerts:
    @SempervivumSep 03.2019 — The script gets the path from `forecastdata</C>:<br/>
    <C>
    drawForecast(forecastdata[idx].img, domain);</C><br/>
    And <C>
    forecastdata`
    is returned by the PHP script that grabs the images on the server.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608288 can you give me an example in the code. I'm lost in that one sorry 😅
    Copy linkTweet thisAlerts:
    @SempervivumSep 03.2019 — The image paths and additional imformation, e. g. UTC time, are read by use of $.getJSON here:
    $.getJSON("getforecast.php",
    // object containing the URL parameters that will
    // be handed over to the PHP script
    { path: basicdata[val].path, domain: domain },
    // this funktion is called when the PHP script has been
    // executed successfully
    function (data) {
    // the parameter data contains the list of images
    console.log(data);
    // transfer the list to the corresponding variable
    forecastdata = data;
    // make the container that keeps the forecast visible
    $("#forecast-container").removeClass("hidden");
    });

    The name of the script, getforecast.php may be different for you.

    And the PHP script is this:
    // get domain and path from GET parameters
    $domain = $_GET['domain'];
    $path = $_GET['path'];
    // create the complete path from these values
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";
    // read the list of images based on the complete path
    $images = glob($completepath);
    $forecastdata = [];
    // loop over the images
    // $step is obsolete as it is set to 1 and not changed later
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    // get additional parameters from the path of the current image
    $result = preg_match('/-([^-]+)-([^-]+)-([^-]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    // add image and additional parameters to the array
    // that will be output
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    // encode array in JSON format and output it
    echo json_encode($forecastdata);
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608291

    I'm getting this error. I combined the js script from the operational website and the js script for the canvas
    <i>
    </i>var colgradimg = "img/" + basicdata[val].colgradimg;

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-09-03/1567495271-863177-kazam-screenshot-00001.png]
    Copy linkTweet thisAlerts:
    @SempervivumSep 03.2019 — Unfortunately the error text is not visible in the image. Hover the cross are view the console.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608294

    This is the code where the error exists
    var colgradimg = "img/" + basicdata[val].colgradimg;

    and the error says:
    Uncaught TypeError: Cannot read property 'colgradimg' of undefined
    at getUrlAndLoad
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608294

    This is the code where the error exists
    var colgradimg = "img/" + basicdata[val].colgradimg;

    and the error says:
    Uncaught TypeError: Cannot read property 'colgradimg' of undefined
    at getUrlAndLoad
    Copy linkTweet thisAlerts:
    @SempervivumSep 03.2019 — Did you keep the array basicdata?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608297 yes
    Copy linkTweet thisAlerts:
    @SempervivumSep 03.2019 — If I remember your site is not public, thus I'm not able to view it. As mentioned previously, I should take over your original code. Please post all, HTML, CSS and JS or make it available for download.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608299 can you provide an email address?

    EDIT:

    I'll just post all the source codes here instead
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608299 *note that all codes that I will post is the unedited working version

    gis.html
    <i>
    </i>&lt;!--
    Created By : Francis Kane D. Balmores
    For : Numerical Modeling Section
    Research &amp; Development and Training Division
    Philippine Atmospheric, Geophysical and Astronomical Services Administration

    <i> </i> This is a site designed to show several NWP products made by the Numerical Modeling Section.
    <i> </i> Made using Sublime Text and VSCode.
    Date Started : 2018 November 08
    HTML5 Version : 2015 December 3
    --&gt;
    &lt;!DOCTYPE html&gt;
    &lt;html lang="en"&gt;

    &lt;head&gt;
    &lt;meta charset="utf-8"&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
    &lt;title&gt;GIS Mapping&lt;/title&gt;

    <i> </i>&lt;script src="js/jquery.js?ver=3.2.1"&gt;&lt;/script&gt;
    <i> </i>&lt;script src="js/bootstrap.min.js?"&gt;&lt;/script&gt;
    <i> </i>&lt;script src="js/jsclock.js"&gt;&lt;/script&gt;

    <i> </i>&lt;link href="css/bootstrap.css?v=1.1" rel="stylesheet"&gt;
    <i> </i>&lt;link href="css/home.css?v=1.1" rel="stylesheet"&gt;
    <i> </i>
    <i> </i>&lt;link rel="shortcut icon" href="img/pagasafavicon.png" type="image/x-icon"&gt;
    &lt;/head&gt;

    &lt;body onLoad = "setClock('utclocalsec')"&gt;

    &lt;!--NAVIGATION BAR--&gt;
    &lt;nav class="navbar navbar-default navbar-fixed-top"&gt;
    &lt;div class="container-fluid"&gt;
    &lt;div class="navbar-header"&gt;
    &lt;button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"&gt;
    &lt;span class="sr-only"&gt;Toggle navigation&lt;/span&gt;
    &lt;span class="icon-bar"&gt;&lt;/span&gt;
    &lt;span class="icon-bar"&gt;&lt;/span&gt;
    &lt;span class="icon-bar"&gt;&lt;/span&gt;
    &lt;/button&gt;
    &lt;a style="padding-left: 5px;" class="navbar-brand" href="home.html"&gt;&lt;img src="img/logo.png"&gt;&lt;span&gt;Weather Research Portal&lt;/span&gt;&lt;/a&gt;
    &lt;/div&gt;
    &lt;!--LEFT MENU--&gt;
    &lt;div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"&gt;
    &lt;ul class="nav navbar-nav"&gt;
    &lt;li class="dropdown"&gt;
    &lt;a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"&gt;Account&lt;span class="caret"&gt;&lt;/span&gt;&lt;/a&gt;
    &lt;ul class="dropdown-menu"&gt;
    &lt;li&gt;&lt;a href="login.php"&gt;Log Out&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;/li&gt;
    &lt;/ul&gt;
    &lt;!--END OF LEFT MENU--&gt;

    &lt;!--RIGHT MENU--&gt;
    &lt;ul class="nav navbar-nav navbar-right"&gt;
    &lt;li&gt;&lt;a href="home.html"&gt;Home&lt;/a&gt;&lt;/li&gt;
    &lt;li class="dropdown"&gt;
    &lt;a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"&gt;Products&lt;span class="caret"&gt;&lt;/span&gt;&lt;/a&gt;
    &lt;ul class="dropdown-menu"&gt;
    &lt;li&gt;&lt;a href="tctracker.html"&gt;Typhoon Tracker&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="gis.html"&gt;PyQGIS Weather Maps&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#"&gt;Statistical Post-Processing&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#"&gt;Grads Weather Maps&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li class="dropdown"&gt;
    &lt;a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"&gt;Projects and Guides&lt;span class="caret"&gt;&lt;/span&gt;&lt;/a&gt;
    &lt;ul class="dropdown-menu"&gt;
    &lt;li&gt;&lt;a href="scriptexec.php"&gt;Script Execution Test&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="Gitlab.html"&gt;Beginner's Guide to Gitlab&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="forecastguide.html"&gt;Description of Forecast Products&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li&gt;&lt;a href="#"&gt;Contact Us&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;!--END OF RIGHT MENU--&gt;
    &lt;/div&gt;
    &lt;/nav&gt;
    &lt;!--END OF NAVIGATION BAR--&gt;

    &lt;center&gt;
    &lt;div class="row" style="background-color: #f4f4f4;"&gt;
    <br/>
    <i> </i> &lt;div class="col-md-3"&gt;
    <i> </i>
    <i> </i> &lt;h3&gt;Weather Maps (PyQGIS)&lt;/h3&gt;
    <i> </i> &lt;span id="jsclock1"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Products:&lt;/h5&gt;
    <i> </i> &lt;select id="select"&gt;
    <i> </i> &lt;option selected disabled&gt;Select a Forecast Parameter&lt;/option&gt;
    <i> </i> &lt;option value="prate" data-colgradimg="img/colgrad-img/prate.png"&gt;Surface Precipitation Rate&lt;/option&gt;
    <i> </i> &lt;option value="3HrAccum" data-colgradimg="img/colgrad-img/3HrlyAccu.png"&gt;3-Hr Accumulated Rainfall&lt;/option&gt;
    <i> </i> &lt;option value="temp" data-colgradimg="img/colgrad-img/temp.png"&gt;Surface Temperature&lt;/option&gt;
    <i> </i> &lt;option value="wind" data-colgradimg="img/colgrad-img/wind.png"&gt;850 millibar Wind&lt;/option&gt;
    <i> </i> &lt;option value="10mwind" data-colgradimg="img/colgrad-img/wind10.png"&gt;10 meter Wind&lt;/option&gt;
    <i> </i> &lt;option value="rh" data-colgradimg="img/colgrad-img/rh.png"&gt;2 meter Relative Humidity&lt;/option&gt;
    <i> </i> &lt;option value="cc" data-colgradimg="img/colgrad-img/cc.png"&gt;Total Cloud Cover&lt;/option&gt;
    <i> </i> &lt;/select&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;h5&gt;Domain:&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio-domain" value="d01" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio-domain" value="d02"&gt;2
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;h5&gt;Animation Interval (hr):&lt;/h5&gt;
    <i> </i> &lt;form&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="1" checked&gt;1
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="3"&gt;3
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="6"&gt;6
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="12"&gt;12
    <i> </i> &lt;/label&gt;
    <i> </i> &lt;label class="radio-inline"&gt;
    <i> </i> &lt;input type="radio" name="optradio" value="24"&gt;24
    <i> </i> &lt;/label&gt;&lt;br&gt;&lt;br&gt;
    <i> </i> &lt;p&gt;For domain 1 forecasts: 144.0h&lt;br&gt;For domain 2 forecasts: 048.0h&lt;/p&gt;
    <i> </i> &lt;/form&gt;&lt;br&gt;
    <i> </i>
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-2"&gt;
    <i> </i> &lt;form id="forecast-label"&gt;
    <i> </i> &lt;p&gt;Date Initialized:&lt;span id="forecast-date"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;UTC:&lt;span id="forecast-utc"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;p&gt;Forecast Hour:&lt;span id="forecast-hour"&gt;&lt;/span&gt;&lt;/p&gt;
    <i> </i> &lt;/form&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;div class="col-md-7"&gt;
    <i> </i> &lt;div id="forecast-container" class="hidden"&gt;

    <i> </i> &lt;div class="labels-left-container d01" style="font-size: 13px;"&gt;
    <i> </i> &lt;div class="label-left"&gt;25&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;15&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;5&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="labels-left-container d02" style="font-size: 12px;"&gt;
    <i> </i> &lt;div class="label-left"&gt;20&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;18&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;16&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;14&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;12&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;10&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;8&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;div class="label-left"&gt;6&amp;deg;N&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="right-container"&gt;
    <i> </i> &lt;div class="controls" style="padding-bottom: 5px;"&gt;
    <i> </i> &lt;button id="first-btn"&gt;First&lt;&lt;&lt;/button&gt;
    <i> </i> &lt;button id="last-btn"&gt;Last&gt;&gt;&lt;/button&gt;
    <i> </i> &lt;button id="prev-btn"&gt;Previous&lt;/button&gt;
    <i> </i> &lt;button id="next-btn"&gt;Next&lt;/button&gt;
    <i> </i> &lt;button id="start-stop-btn"&gt;Stop&lt;/button&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="img-container"&gt;
    <i> </i> &lt;img id="forecast-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="labels-bottom-container d01" style="font-size: 13px;"&gt;
    <i> </i> &lt;div class="label-bottom"&gt;115&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;125&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;130&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;135&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="labels-bottom-container d02" style="font-size: 12px;"&gt;
    <i> </i> &lt;div class="label-bottom"&gt;118&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;120&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;122&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;124&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;div class="label-bottom"&gt;126&amp;deg;E&lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div id="colgrad-img-container"&gt;
    <i> </i> &lt;img id="colgrad-img" src=""&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i>&lt;/div&gt;

    <i> </i> &lt;script&gt;
    <i> </i> var basicdata = {
    <i> </i> //"prate" is the ID of the forecast parameter, the value in the #select.
    <i> </i> //the same logic is applied to all of the forecast parameters below.
    <i> </i> "prate": {
    <i> </i> "path": "PrecipRate",
    <i> </i> //"path" is constant
    <i> </i> //"PrecipRate" is the value, one level in the complete path of the files
    <i> </i> "colgradimg": "colgrad-img/prate.png"
    <i> </i> //colgradimg is the color bar image and its path
    <i> </i> },
    <i> </i> "temp": {
    <i> </i> "path": "Temperature",
    <i> </i> "colgradimg": "colgrad-img/temp.png"
    <i> </i> },
    <i> </i> "wind": {
    <i> </i> "path": "Wind850mb",
    <i> </i> "colgradimg": "colgrad-img/wind.png"
    <i> </i> },
    <i> </i> "3HrAccum": {
    <i> </i> "path": "3HrlyAccuRain",
    <i> </i> "colgradimg": "colgrad-img/3HrlyAccu.png"
    <i> </i> },
    <i> </i> "10mwind": {
    <i> </i> "path": "10mwind",
    <i> </i> "colgradimg": "colgrad-img/wind10.png"
    <i> </i> },
    <i> </i> "rh": {
    <i> </i> "path": "RelativeHumidity",
    <i> </i> "colgradimg": "colgrad-img/rh.png"
    <i> </i> },
    <i> </i> "cc": {
    <i> </i> "path": "CloudCover",
    <i> </i> "colgradimg": "colgrad-img/cc.png"
    <i> </i> }
    <i> </i> }
    <i> </i> //Preparing some DOM elements
    <i> </i> var theimg = document.getElementById('forecast-img'),
    <i> </i> thedate = document.getElementById('forecast-date'),
    <i> </i> theUTC = document.getElementById('forecast-utc'),
    <i> </i> thehour = document.getElementById('forecast-hour');

    <i> </i> //idx is the index of the image that is currently displayed
    <i> </i> //step is the amount the index increments in each cycle
    <i> </i> //stopped indicates if the animation is running or stopped
    <i> </i> var idx = 0, step = 1, stopped = false;
    <i> </i> //the list of images, in the beginning is empty
    <i> </i> var forecastdata = [];

    <i> </i> //update the list of images every 60 seconds
    <i> </i> setInterval(getUrlAndLoad, 10);

    <i> </i> //timer that repeats the function every 50ms
    <i> </i> setInterval(function () {
    <i> </i> console.log(idx, step);
    <i> </i> //change image only
    <i> </i> //1. if the forecastdata is not empty
    <i> </i> //2. if the animation is not stopped by any of the corresponding buttons
    <i> </i> if (forecastdata.length &gt; 0 &amp;&amp; !stopped) {
    <i> </i> if (forecastdata[idx]) {
    <i> </i> //display the images
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> } else {
    <i> </i> //get new forecastdata
    <i> </i> getUrlAndLoad();
    <i> </i> idx=0;
    <i> </i> }
    <i> </i> //display the additional information (the date, utc, and forecasthour) in the corresponding DOM Elements
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> //increase index by step so that in the next cycle the next image will be displayed
    <i> </i> //then start from the beginning
    <i> </i> idx += step;
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> }
    <i> </i> }, 450);

    <i> </i> function loadForecast(url, dmn) {
    <i> </i> $.getJSON(url, {domain: dmn}, function (data) {
    <i> </i> forecastdata = data;
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }

    <i> </i> //this function is called anytime a parameter (step, domain, forecast parameter) is changed
    <i> </i> function getUrlAndLoad() {
    <i> </i> //get value of the #select
    <i> </i> //it contains the ID of the forecast parameter that has been selected
    <i> </i> var val = $("#select").val();
    <i> </i> //get the path of the colgrad image and display it on the corresponding DOM element
    <i> </i> var colgradimg = "img/" + basicdata[val].colgradimg;
    <i> </i> $("#colgrad-img").attr("src", colgradimg);
    <i> </i> //get domain
    <i> </i> //it is the value of the radio button that is currently selected
    <i> </i> var domain = $("input[name='optradio-domain']:checked").val();
    <i> </i> thedomains = $("input[name='optradio-domain']");
    <i> </i> //container for the forecasts
    <i> </i> thecontainer = $("#forecast-container");
    <i> </i> //remove all domain classes from the container
    <i> </i> thedomains.each(function (idx, ele) {
    <i> </i> thecontainer.removeClass($(this).val());
    <i> </i> });
    <i> </i> //add current domain as a class to the container
    <i> </i> thecontainer.addClass(domain);
    <i> </i> console.log(basicdata[val].path, domain);
    <i> </i> //read the list of images by executing the PHP Script
    <i> </i> $.getJSON("main.php",
    <i> </i> //object containing the URL parameters that will be handed over to the PHP Script
    <i> </i> { path: basicdata[val].path, domain: domain },
    <i> </i> //this function is called when the PHP script has been executed successfully
    <i> </i> function (data) {
    <i> </i> //the parameter data contains the list of images
    <i> </i> console.log(data);
    <i> </i> //transer the list of the corresponding variable
    <i> </i> forecastdata = data;
    <i> </i> //make the container that keeps the forecast visible
    <i> </i> $("#forecast-container").removeClass("hidden");
    <i> </i> });
    <i> </i> }
    <i> </i>
    <i> </i> //add event handler to the #select
    <i> </i> //all necessary actions will be done by the function getUrlAndLoad
    <i> </i> $("input[name='optradio-domain']").on("change", function () {
    <i> </i> getUrlAndLoad();
    <i> </i> // reset idx
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> //add eventhandler to the radiobuttons for the domain
    <i> </i> //all necessary actions will be done by the getUrlAndLoad
    <i> </i> $("input[name='optradio-domain']").on("change", getUrlAndLoad);

    <i> </i> //add eventhandler to the radiobuttons for the step or speed of the animation
    <i> </i> $("input[name='optradio']").on("change", function () {
    <i> </i> step = parseInt($("input[name='optradio']:checked").val());
    <i> </i> idx = 0;
    <i> </i> });

    <i> </i> //add eventhandler to the start/stop button
    <i> </i> $("#start-stop-btn").on("click", function (event) {
    <i> </i> event.preventDefault();
    <i> </i> //toggle variable "stopped" and text of the button
    <i> </i> //the variable "stopped" is used in the cyclical callback of the timer
    <i> </i> if (!stopped) {
    <i> </i> stopped = true;
    <i> </i> $(this).text("Start");
    <i> </i> } else {
    <i> </i> stopped = false;
    <i> </i> $(this).text("Stop");
    <i> </i> }
    <i> </i> });

    <i> </i> //add event handler to the "first" button
    <i> </i> $("#first-btn").on("click", function() {
    <i> </i> event.preventDefault();
    <i> </i> //stop the animation so that the user can view the first forecast
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> //set index to 0
    <i> </i> //when the animation is started again it will start at this index
    <i> </i> idx = 0;
    <i> </i> //update image and additional fields
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> //add eventhandler to the "first" button
    <i> </i> //similar to the first button but the index is set to the last element in the list of images.
    <i> </i> $("#last-btn").on("click", function() {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });
    <i> </i>
    <i> </i> //add eventhandler to the "first" button
    <i> </i> //similar to the first button but the index is set to the next element in the list of images.
    <i> </i> $("#next-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx += step;
    <i> </i> //take into account the overflow at the end
    <i> </i> if (idx &gt;= forecastdata.length) idx = 0;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> //add eventhandler to the "first" button
    <i> </i> //similar to the first button but index is set to the previous element in the list of images.
    <i> </i> $("#prev-btn").on("click", function () {
    <i> </i> event.preventDefault();
    <i> </i> stopped = true;
    <i> </i> $("#start-stop-btn").text("Start");
    <i> </i> idx -= step;
    <i> </i> //take into account the overflow at the end
    <i> </i> if (idx &lt; 0) idx = forecastdata.length - 1;
    <i> </i> theimg.src = forecastdata[idx].img;
    <i> </i> thedate.innerHTML = forecastdata[idx].date;
    <i> </i> theUTC.innerHTML = forecastdata[idx].utc;
    <i> </i> thehour.innerHTML = forecastdata[idx].forecasthour;
    <i> </i> });

    <i> </i> &lt;/script&gt;

    <i> </i>&lt;!--ABOUT US--&gt;
    <i> </i>&lt;div class="row"&gt;
    <i> </i> &lt;div class="col-md-6"&gt;
    <i> </i> &lt;img class="pagasa-icon" src="img/icon.png"&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="col-md-6"&gt;
    <i> </i> &lt;p class="section-title"&gt;ABOUT US&lt;/p&gt;
    <i> </i> &lt;span&gt;
    <i> </i> &lt;br&gt;&lt;p style="font-size:20px"&gt;The Numerical Modeling Section undertakes researches on the application of Numerical Weather Prediction in understanding unusual weather patterns and extreme rainfall events&lt;/p&gt;
    <i> </i> &lt;/span&gt;
    <i> </i> &lt;/div&gt;
    <i> </i>&lt;/div&gt;

    <i> </i>&lt;!--PRODUCTS--&gt;
    <i> </i>&lt;div style="background-color: #f4f4f4"&gt;
    <i> </i> &lt;div class="row"&gt;
    <i> </i> &lt;p class="section-title" &gt;PRODUCTS&lt;/p&gt;
    <i> </i> &lt;br&gt;
    <i> </i>
    <i> </i> &lt;div class="col-md-2 col-md-offset-2"&gt;
    <i> </i> &lt;a href="tctracker.html"&gt;&lt;img src="img/1.png" style="height: 150px; width: 150px;"&gt;&lt;br&gt;
    <i> </i> &lt;p class="font-15"&gt;TROPICAL CYCLONE TRACKER&lt;/p&gt;&lt;/a&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="col-md-2"&gt;
    <i> </i> &lt;a href="#"&gt;&lt;img src="img/3.png" style="height: 150px; width: 150px;"&gt;&lt;br&gt;
    <i> </i> &lt;p class="font-15"&gt;STATISTICAL POST-PROCESSING&lt;/p&gt;&lt;/a&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="col-md-2"&gt;
    <i> </i> &lt;a href="gis.html"&gt;&lt;img src="img/2.png" style="height: 150px; width: 150px;"&gt;&lt;br&gt;
    <i> </i> &lt;p class="font-15"&gt;PyQGIS WEATHER MAPS&lt;/p&gt;&lt;/a&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="col-md-2"&gt;
    <i> </i> &lt;a href="#"&gt;&lt;img src="img/4.png" style="height: 150px; width: 150px;"&gt;&lt;br&gt;
    <i> </i> &lt;p class="font-15"&gt;GRADS WEATHER MAPS&lt;/p&gt;&lt;/a&gt;
    <i> </i> &lt;/div&gt;

    <i> </i> &lt;/div&gt;
    <i> </i>&lt;/div&gt;
    <i> </i>&lt;!--FOOTER--&gt;
    <i> </i>
    <i> </i> &lt;!--SOCIAL MEDIA FOOTER--&gt;
    <i> </i>&lt;div class="footer" style="background-color: #00d2d3"&gt;
    <i> </i> &lt;a href="https://www.facebook.com/PAGASA.DOST.GOV.PH/?ref=br_rs" target="_blank"&gt;&lt;img src="img/social media/fb.png" width="50px"&gt;&lt;/a&gt;
    <i> </i> &lt;a href="https://twitter.com/dost_pagasa?lang=en" target="_blank"&gt;&lt;img src="img/social media/twit.png" width="50px"&gt;&lt;/a&gt;
    <i> </i> &lt;a href="https://www.youtube.com/channel/UCpyLikj1x70S8UPxVqsPr6g" target="_blank"&gt;&lt;img src="img/social media/youtube.png" width="50px"&gt;&lt;/a&gt;
    <i> </i>&lt;/div&gt;
    <i> </i> &lt;!--END OF SOCIAL MEDIA FOOTER--&gt;
    <i> </i>&lt;div style="background-color: #1e1c1b"&gt;
    <i> </i> &lt;div class="row"&gt;
    <i> </i> &lt;div class="col-md-4"&gt;
    <i> </i> &lt;span class="footer-content"&gt;
    <i> </i> &lt;b&gt;Address&lt;/b&gt;
    <i> </i> &lt;hr class="style1"&gt;
    <i> </i> Philippine Atmospheric Geophysical and Astronomical Services Administration
    <i> </i> &lt;br&gt;Weather and Flood Forecasting Center
    <i> </i> &lt;br&gt;BIR Road, Diliman, Quezon City
    <i> </i> &lt;br&gt;Metro Manila 1100
    <i> </i> &lt;br&gt;(632)4342696
    <i> </i> &lt;br&gt;[email protected]
    <i> </i> &lt;/span&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="col-md-4"&gt;
    <i> </i> &lt;span class="footer-content"&gt;
    <i> </i> &lt;b&gt;ABOUT GOV.PH&lt;/b&gt;
    <i> </i> &lt;hr class="style1"&gt;
    <i> </i> &lt;br&gt;&lt;a class="footer-links" href="https://www.gov.ph/"&gt;GOV.PH&lt;/a&gt;
    <i> </i> &lt;hr class="style1"&gt;
    <i> </i> &lt;br&gt;&lt;a class="footer-links" href="https://www.officialgazette.gov.ph/"&gt;Official Gazette&lt;/a&gt;
    <i> </i> &lt;/span&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;div class="col-md-4"&gt;
    <i> </i> &lt;span class="footer-content"&gt;
    <i> </i> &lt;b&gt;Government Links&lt;/b&gt;
    <i> </i> &lt;hr class="style1"&gt;
    <i> </i> &lt;br&gt;&lt;a class="footer-links" href="http://bagong.pagasa.dost.gov.ph/"&gt;Philippine Atmospheric Geophysical and Astronomical Services Administration&lt;/a&gt;
    <i> </i> &lt;hr class="style1"&gt;
    <i> </i> &lt;br&gt;&lt;a class="footer-links" href="http://www.dost.gov.ph/"&gt;Department of Science and Technology&lt;/a&gt;
    <i> </i> &lt;/span&gt;
    <i> </i> &lt;/div&gt;
    <i> </i> &lt;/div&gt;
    <i> </i>&lt;/div&gt;
    <i> </i>&lt;!--END OF FOOTER--&gt;
    &lt;/center&gt;

    &lt;/body&gt;
    &lt;/html&gt;


    home.css
    <i>
    </i>/*{
    border-style: solid;
    border-width: 0.1px;
    }*/

    * {
    font-family: 'Trebuchet MS', Helvetica, sans-serif;

    }
    .box {
    border: 1px solid black;
    }
    .site-header {
    background-image: url(img/bg.jpg);
    background-size: 100%;
    margin-top: 50px;
    padding-top: 20%;
    padding-bottom: 20%;
    }
    .site-title {
    font-size: 50px;
    font-weight: bold;
    color: #fff;
    }
    .section-title {
    font-size: 50px;
    font-weight: bold;
    }
    .site-description {
    font-family: 'Trebuchet MS', Helvetica, sans-serif;
    font-style: italic;
    font-size:30px;
    color:#fff;
    }
    /*.col-md-2 {
    border: 0px solid black;
    padding: 10px;
    }*/
    .font-15 {
    font-size: 15px;
    font-weight: bold;
    }
    .footer {
    padding-top: 25px;
    padding-bottom: 25px;
    }
    div.footer &gt; a {
    padding-left: 5px;
    padding-right: 5px;
    }
    .footer-content {
    color: #dfe6e9;
    }
    hr.style1 {
    border: 0;
    height: 1px;
    background-image: linear-gradient(to right, rgba(154, 154, 154, 0), rgba(154, 154, 154, 0.75), rgba(154, 154, 154, 0));
    }
    .footer-links {
    color: #dfe6e9;
    }

    .button-run {
    cursor: pointer;
    background: #33b5e5;
    width: 25%;
    border: 0;
    margin: 30px;
    padding: 15px 15px;
    color: #ffffff;
    transition: 0.3s ease;
    }
    .button-run:hover {
    background: #dfe6e9;
    color: #ffffff;
    }

    .pagasa-icon {
    width: 20%;
    }

    /* FORM SPAN FOR THE FORECAST LABEL: (UTC, DATE, FORECAST HOUR)*/
    #forecast-label {
    text-align: left;
    padding-top: 20px;
    font-size: 18px;
    }
    #select, #option, #label {
    cursor: pointer;
    width: 230px;
    }
    /* END FOR SPAN FOR THE FORECAST LABEL */

    /* START FOR THE LABELS OF THE BOUNDING BOX, COLGRAD AND BUTTONS */
    #forecast-container.hidden {
    visibility: hidden;
    }

    #forecast-container {
    display: flex;
    padding-top: 10px;
    }

    #forecast-container #controls {
    display: flex;
    justify-content: center;
    }

    .controls #first-btn, #last-btn,
    #prev-btn, #next-btn, #start-stop-btn {
    background-color: white;
    color: black;
    border: 1px solid black;
    border-radius: 1.5px;
    transition-duration: 0.3s;
    cursor: pointer;
    }

    #first-btn:hover, #last-btn:hover,
    #prev-btn:hover, #next-btn:hover, #start-stop-btn:hover {
    background-color: #555555;
    color: white;
    }

    #img-container {
    border: 2px solid black;
    overflow: hidden;
    box-sizing: border-box;
    }

    #forecast-container.d01 #img-container {
    /* dimensions of the inner image
    excluding white borders */
    width: 460px;
    height: 540px;
    }

    #forecast-container.d02 #img-container {
    /* dimensions of the inner image
    excluding white borders */
    width: 330px;
    height: 540px;
    }

    #forecast-img {
    vertical-align: top;
    /* dimensions of the complete image
    including white borders */
    width: 550px;
    height: 600px;
    }

    #forecast-container.d01 #forecast-img {
    /* size of the white border at the left */
    margin-left: -45px;
    /* size of the white border on top */
    margin-top: -30px;
    }

    #forecast-container.d02 #forecast-img {
    /* size of the white border at the left */
    margin-left: -110px;
    /* size of the white border on top */
    margin-top: -30px;
    }

    .labels-left-container {
    display: none;
    }

    #forecast-container.d01 .labels-left-container.d01 {
    display: flex;
    flex-direction: column;
    }

    #forecast-container.d02 .labels-left-container.d02 {
    display: flex;
    flex-direction: column;
    }

    .label-left {
    text-align: right;
    padding-left: 5px;
    padding-right: 5px;
    }

    .labels-left-container.d01 .label-left {
    /* the vertical distance between the labels */
    margin-top: 105px;
    }

    .labels-left-container.d01 .label-left:first-child {
    /* the amount the first label is shifted upwards */
    margin-top: 25px;
    }

    .labels-left-container.d02 .label-left {
    /* the vertical distance between the labels */
    margin-top: 50px;
    }
    <br/>
    .labels-left-container.d02 .label-left:first-child {
    /* the amount the first label is shifted upwards */
    margin-top: 50px;
    }

    .labels-left-container {
    display: none;
    }

    .labels-bottom-container {
    display: none;
    }

    #forecast-container.d01 .labels-bottom-container.d01 {
    display: flex;
    flex-direction: row;
    }

    #forecast-container.d02 .labels-bottom-container.d02 {
    display: flex; <br/>
    flex-direction: row;
    }

    .label-bottom {
    text-align: center;
    padding-top: 2px;
    }

    .labels-bottom-container.d01 .label-bottom {
    /* the horizontal distance between the labels */
    margin-left: 77px;
    }

    .labels-bottom-container.d01 .label-bottom:first-child {
    /* the amount the first label is shifted left */
    margin-left: -17px;
    }

    .labels-bottom-container.d02 .label-bottom {
    /* the horizontal distance between the labels */
    margin-left: 35px;
    }
    <br/>
    .labels-bottom-container.d02 .label-bottom:first-child {
    /* the amount the first label is shifted left */
    margin-left: 15px;
    }

    #forecast-container.d01 #right-container {
    display: flex;
    flex-direction: column;
    width: 460px;
    }

    #forecast-container.d02 #right-container {
    display: flex;
    flex-direction: column;
    width: 330px;
    }

    #labels-bottom-container {
    display: flex;
    }

    #colgrad-img-container {
    width: 100px;
    height: 750px;
    margin-top: 5px;
    transform: scale(0.747);
    transform-origin: left top;
    margin-top: 45px;
    }

    #colgrad-img {
    width: 300px;
    height: 750px;
    margin-left: -125px;
    margin-top: -40px;
    }

    h5, form {
    font-size: 15px; <br/>
    }
    /*END OF LABELS HERE */


    /*TABLE FOR DESCRIPTION OF FORECAST PARAMETERS*/
    table {
    border-collapse: collapse;
    width: 100%;
    }

    td, th {
    border: 1px solid black;
    text-align: left;
    padding: 8px;
    }
    tr:nth-child(even) {
    background-color: white;
    }
    /* END FOR TABLE STYLE*/



    main.php
    <i>
    </i>&lt;?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    //getting the domain and path from the GET parameters
    $domain = $_GET['domain'];
    $path = $_GET['path'];
    //create the complete path from these values
    $completepath = "pyqgis-ops/" . $path . "/" . $domain . "/*.png";
    //read the list of images based on the complete path
    $images = glob ($completepath);
    $forecastdata = [];
    //loop over the images
    //$step is obsolete as it is set to 1 and not changed later
    $step = 1;
    for ($i = 0; $i &lt; count($images); $i+=$step) {
    $img = $images[$i];
    //getting additional parameters from the path of the current image
    $result = preg_match('/_([^_]+)_([^_]+)_([^_]+).png/', $img, $matches);
    if ($result) {
    $date = $matches[1];
    $utc = $matches[2];
    $forecasthour = $matches[3];
    //add image and additional parameters to the array. that will be the output
    $forecastdata[] = ['img' =&gt; $img, 'date' =&gt; $date, 'utc' =&gt; $utc, 'forecasthour' =&gt; $forecasthour];
    }
    }
    //encode array in JSON format and output it
    echo json_encode($forecastdata);
    ?&gt;
    Copy linkTweet thisAlerts:
    @SempervivumSep 03.2019 — That's fine, I'm gonna look into ...
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 03.2019 — @Sempervivum#1608302 Thanks
    Copy linkTweet thisAlerts:
    @SempervivumSep 04.2019 — Hi frncskn, integration finished, did you read my PN?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 04.2019 — @Sempervivum#1608353 what is a PN? 😅 sorry
    Copy linkTweet thisAlerts:
    @SempervivumSep 04.2019 — Sorry, I meant PM, "private message".

    Try this link:

    https://www.webdeveloper.com/d/385695-wheather-site

    or search for your name in the overview of the forum.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 05.2019 — @Sempervivum#1608356 Hello! Thanks for the files! but the d02 is not yet cropped?
    Copy linkTweet thisAlerts:
    @SempervivumSep 05.2019 — @frncskn#1608390 You need to configure the cropping for D02 here:
    var datad02 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    Obviously the white borders for D02 are larger. Measure their sizes by an image processing software.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 05.2019 — @Sempervivum#1608393 Thank you! Already done :) Where is the line to edit the coordinate labels?
    Copy linkTweet thisAlerts:
    @SempervivumSep 05.2019 — var datad02 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingTop: 15,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels

    <i> </i>// start position of the vertical labels in pixels,
    <i> </i>// i. e. the position of the first label
    <i> </i>startVerticalLabelPos: 0,

    <i> </i>// start for the vertical label numbers
    <i> </i>startVerticalLabelNumber: 30,

    <i> </i>// step for the position of the vertical labels in pixels
    <i> </i>// i. e. the distance between the labels
    <i> </i>stepVerticalLabelPos: 100,

    <i> </i>// step for the vertical label numbers
    <i> </i>stepVerticalLabelNumber: 5,

    `startVerticalLabelNumber</C> is the first label and <C>stepVerticalLabelNumber` is the step the label is decremented by. "°N" or "°E" will be added. Thus the labels will read:

    30°N 25°N 20°N 15°N and so on
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 05.2019 — @Sempervivum#1608398 How can I edit the number of coordinates?

    for d01 I need just 5 for the N: 25, 20, 15, 10 and 5 and for the E: 115, 120, 125, 130 and 135

    for d02 I need 8 for the N: 6, 8, 10, 12, 14, 16, 18 and 20 and for the E: 118, 120, 122, 124 and 126

    This error is showing and the page seems to "slow"
    <i>
    </i>Uncaught RangeError: Maximum call stack size exceeded
    at new jCanvasObject (jcanvas.js:82)
    at r.fn.init.drawImage (jcanvas.js:3996)
    at _drawLayer (jcanvas.js:1225)
    at r.fn.init.drawLayers (jcanvas.js:1503)
    at jcanvas.js:3980
    at r.fn.init.drawImage (jcanvas.js:4028)
    at _drawLayer (jcanvas.js:1225)
    at r.fn.init.drawLayers (jcanvas.js:1503)
    at jcanvas.js:3980
    at r.fn.init.drawImage (jcanvas.js:4028)
    Copy linkTweet thisAlerts:
    @SempervivumSep 05.2019 — How can I edit the number of coordinates?

    for d01 I need just 5 for the N: 25, 20, 15, 10 and 5 and for the E: 115, 120, 125, 130 and 135

    for d02 I need 8 for the N: 6, 8, 10, 12, 14, 16, 18 and 20 and for the E: 118, 120, 122, 124 and 126[/quote]

    var datad01 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingTop: 15,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels

    <i> </i>// start position of the vertical labels in pixels,
    <i> </i>// i. e. the position of the first label
    <i> </i>startVerticalLabelPos: 0,

    <i> </i>// start for the vertical label numbers
    <i> </i>startVerticalLabelNumber: 25, // &lt;--

    <i> </i>// step for the position of the vertical labels in pixels
    <i> </i>// i. e. the distance between the labels
    <i> </i>stepVerticalLabelPos: 100,

    <i> </i>// step for the vertical label numbers
    <i> </i>stepVerticalLabelNumber: 5, // &lt;--

    <i> </i>// start position for the horizontal grid lines in pixels,
    <i> </i>// i. e. the position of the first line
    <i> </i>startHorizontalGridLine: 0,

    <i> </i>// step for the horizontal grid lines,
    <i> </i>// i. e. the distance between the horizontal lines
    <i> </i>stepHorizontalGridLine: 100,
    <i> </i>startHorizontalLabelPos: 60,

    <i> </i>// horizontal labels at the bottom and vertical grid lines
    <i> </i>// are configured like the ones above
    <i> </i>startHorizontalLabelNumber: 135, // &lt;--
    <i> </i>stepHorizontalLabelPos: 200,
    <i> </i>stepHorizontalLabelNumber: 5, // &lt;--
    <i> </i>startVerticalGridLine: 0,
    <i> </i>stepVerticalGridLine: 100,
    }

    var datad02 = {
    cropLeft: 45,
    cropRight: 43,
    cropTop: 30,
    cropBottom: 27,
    paddingTop: 15,
    paddingLeft: 60, // space for labels
    paddingBottom: 20, // space for labels

    <i> </i>// start position of the vertical labels in pixels,
    <i> </i>// i. e. the position of the first label
    <i> </i>startVerticalLabelPos: 0,

    <i> </i>// start for the vertical label numbers
    <i> </i>startVerticalLabelNumber: 20, // &lt;--

    <i> </i>// step for the position of the vertical labels in pixels
    <i> </i>// i. e. the distance between the labels
    <i> </i>stepVerticalLabelPos: 100,

    <i> </i>// step for the vertical label numbers
    <i> </i>stepVerticalLabelNumber: 2, // &lt;--

    <i> </i>// start position for the horizontal grid lines in pixels,
    <i> </i>// i. e. the position of the first line
    <i> </i>startHorizontalGridLine: 0,

    <i> </i>// step for the horizontal grid lines,
    <i> </i>// i. e. the distance between the horizontal lines
    <i> </i>stepHorizontalGridLine: 100,
    <i> </i>startHorizontalLabelPos: 60,

    <i> </i>// horizontal labels at the bottom and vertical grid lines
    <i> </i>// are configured like the ones above
    <i> </i>startHorizontalLabelNumber: 120, // &lt;--
    <i> </i>stepHorizontalLabelPos: 200,
    <i> </i>stepHorizontalLabelNumber: 2, // &lt;--
    <i> </i>startVerticalGridLine: 0,
    <i> </i>stepVerticalGridLine: 100,
    }
    I marked the lines relevant for the labels with an arrow // <--

    Additionally you will need to adjust the spacing between the labels by this value:
    // step for the position of the vertical labels in pixels
    // i. e. the distance between the labels
    stepVerticalLabelPos: 100,


    Regarding the error: Did you modify the code I sent you in some way?

    In the code you posted recently this line may cause an overload of the browser:
    setInterval(getUrlAndLoad, 10);
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — > @Sempervivum#1608418 Regarding the error: Did you modify the code I sent you in some way?

    > In the code you posted recently this line may cause an overload of the browser:

    > setInterval(getUrlAndLoad, 10);


    And I didn't modify the code in any other way other than the changing of the coordinates.

    That line of code is commented out so I think that is not the issue.

    EDIT:

    another error appears:
    Uncaught TypeError: Cannot read property 'date' of undefined
    at test.html:228

    when I trace it. This line is the culprit:
    thedate.innerHTML = forecastdata[idx].date;
    Copy linkTweet thisAlerts:
    @SempervivumSep 06.2019 — Difficult to locate the error when one cannot view the code live. Check if you can put a test version online. If there is no link to the main HTML file, it would not be visible in public.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — @Sempervivum#1608426 any suggestion on how to do that?

    The error occurs again. it looks like something is messing up within the jcanvas.js

    <i>
    </i>jcanvas.js:3964 Uncaught RangeError: Maximum call stack size exceeded
    at jcanvas.js:3964
    at r.fn.init.drawImage (jcanvas.js:4028)
    at _drawLayer (jcanvas.js:1225)
    at r.fn.init.drawLayers (jcanvas.js:1503)
    at jcanvas.js:3980
    at r.fn.init.drawImage (jcanvas.js:4028)
    at _drawLayer (jcanvas.js:1225)
    at r.fn.init.drawLayers (jcanvas.js:1503)
    at jcanvas.js:3980
    at r.fn.init.drawImage (jcanvas.js:4028)
    Copy linkTweet thisAlerts:
    @SempervivumSep 06.2019 — Do you have webspace?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — @Sempervivum#1608429 nope I don't have.

    Teamviewer?
    Copy linkTweet thisAlerts:
    @SempervivumSep 06.2019 — Teamviewer might be an option. I have it installed but when starting I only get an option to permit access for my taxing software. I have to check this further.

    However I have some other activitay now. Is it OK for you if we continue next monday? Then I could make Teamviewer runnable during the weekend.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — @Sempervivum#1608431 Yes monday is good. So that will be September 9 here in the philippines. but do you have any hunch on what is the cause of this problem?

    Because the performance between the Operational page and this "test" page is very different.
    Copy linkTweet thisAlerts:
    @SempervivumSep 06.2019 — This:
    another error appears:

    Uncaught TypeError: Cannot read property 'date' of undefined

    at test.html:228

    when I trace it. This line is the culprit:

    thedate.innerHTML = forecastdata[idx].date;[/quote]
    makes me suspect that there is something wrong about the images. Is the complete structure of folders (starting from pyqgis-ops) where the images are located available in your test configuration?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — Another thing is happening now. When I select for a domain. the previous domain's label still shows up. What happens then is that it overlaps.

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-09-06/1567747152-104875-kazam-screenshot-00002.png]

    [upl-image-preview url=https://www.webdeveloper.com/assets/files/2019-09-06/1567747152-595797-kazam-screenshot-00003.png]
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — @Sempervivum#1608433 but the path for the images is provided in the php file right?
    Copy linkTweet thisAlerts:
    @SempervivumSep 06.2019 — Yes, it's composed in the PHP file. However the images have to be present in their folders.

    When I select for a domain. the previous domain's label still shows up. What happens then is that it overlaps.[/quote]I see. I'm gonna check this during the weekend.

    For now I have to finish, as my other activity is waiting. See you on Monday.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 06.2019 — @Sempervivum#1608436 Yes they are present in the folder. I checked because the operational version of this website as I am trying to figure out what is wrong with this.

    What date is next monday for you over there?
    Copy linkTweet thisAlerts:
    @SempervivumSep 06.2019 — My timezone is CET (Germany). Next monday will be 2019-09-09.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608449 Hello
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — Hi, I'm online now. You proposed using Teamviewer in order to enable me to view the code live in your environment.

    I have it not installed yet and additionally I read some information that teamviewer has become more strict regarding commercial use and locks the account if they suspect that there is commercial use.

    Therefore I would like to check for an alternative. If you have a windows computer available we might try the built in the remote service feature. What do you think?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608597 Hello. The problem is I'm using ubuntu 16.04 as my os
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — I see. No alternative windows computer available? To start with it would be sufficient if I could use the developer tools of a browser.

    If not, I already have a teamviewer account and could install it.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608599 Unfortunately no. All of our computers here in the office are using linux based os.

    developer tools? as in with for example in google chrome?
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — @frncskn#1608600 Yes
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — PS: Started installing, the installer asks if there is non-commercial use. Does this apply to your organisation?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608603 I'm also using non-commercial for team viewer.

    and I'm using team viewer 14
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — You mentioned chrome browser above. Would Remote Chrome Desktop be an alternative?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608607 Yes that can be an alternative. I just finished setting up mine
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — Remote Desktop ready. I need your access key now.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608609 can you see my pc now?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608609 390401764567
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — Opened connection, do you get a prompt?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608612 Yes. I accepted it. There is no live chat function here?
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — Busy icon still turning ...

    I'm afraid there will be no live chat.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#16086 I'll stop and. Try and reconnecting
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — Tried two times an got a timeout.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608617 try it again. thanks
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608617 685314897097
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608617 are you connected now?
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — No, busy-icon still turning ...
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — Maybe your firewall blocks the connection?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608623 056668610051
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608624 Do I have to do anything after I give you access key?

    This is the first time I'm using this so maybe I'm missing something after I give the access key to you
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — When I open the connection you should get a prompt and accept the request. That's all.

    I tried opening via 056668610051 and got a timeout.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608627 can you try it backwards? give me an access key
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — BTW: We should not abuse the forum for online chat. Do you have a Whatsapp account or Skype?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 11.2019 — @Sempervivum#1608629 I have skype. [email protected]
    Copy linkTweet thisAlerts:
    @SempervivumSep 11.2019 — That's fine, I'm going to connect ...
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 13.2019 — @Sempervivum#1608633 Hello. I just finished integrating the changes. I'm baffled because the "selected value" in the forecast selection is not working
    Copy linkTweet thisAlerts:
    @SempervivumSep 13.2019 — Did you receive the file draw-forecast.txt, renamed it back to draw-forecast.js and copied it to the js folder?

    Does the console show any errors?
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 13.2019 — @Sempervivum#1608719 as of now, no errors are showing up.
    Copy linkTweet thisAlerts:
    @SempervivumSep 13.2019 — Did you receive the file draw-forecast.txt, renamed it back to draw-forecast.js and copied it to the js folder?[/quote]
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 13.2019 — @Sempervivum#1608721 Yes I received the email and already made the necessary changes to the js script.
    Copy linkTweet thisAlerts:
    @sundarban123Sep 13.2019 — This is the first time I visit your forum, it is really nice

    I'd like to share a website with you https://sundarbanpackages.com/ let me know how you feel about this website.
    Copy linkTweet thisAlerts:
    @frncsknauthorSep 23.2019 — @Sempervivum#1608721 Hello
    Copy linkTweet thisAlerts:
    @SempervivumSep 23.2019 — Hallo, I'm so sorry, I had a lot of other acitivies in the past days and coding has taken a back seat. We should continue via email, however I don't remember your email address and don't find a suitable keyword to search for in my inbox. Please send me an email again.
    Copy linkTweet thisAlerts:
    @frncsknauthorOct 07.2019 — @Sempervivum#1608976 Hello
    Copy linkTweet thisAlerts:
    @frncsknauthorApr 02.2020 — @Sempervivum#1608976 Hello Ulrich. Just checking how are you over there in your country?
    Copy linkTweet thisAlerts:
    @SempervivumApr 10.2020 — Hi there, sorry for replying late. Fine that you care. Yes I'm fine here, hope you are doing fine either. Some restrictions in daily life here. Fortunately I'm in retirement, therefore the limitations in business do not affect me. Many of the employed persons are in home office. What about your working place? Do I remember correctly that it was something educational? Is it still open or are you in home office too?

    And what about your wheather site? Is everything fine?

    All the best and best regards from northern germany - Ulrich
    Copy linkTweet thisAlerts:
    @frncsknauthorJul 07.2020 — @Sempervivum#1617287 Hello! Good to here that you are fine. We are fine as well. The weather site is finished.

    I am currently working remotely from home. I was just about to ask you about some mysql and php stuff.

    Regards as well from the philippines! - francis
    Copy linkTweet thisAlerts:
    @anawillhathwayApr 06.2022 —  Create a script element.
    Set the src , async , and type attributes.
    Append the script element to the body.
    Check if the file loaded or not in the load event.
    Copy linkTweet thisAlerts:
    @SempervivumApr 06.2022 — @anawillhathway#1643510

    No benefit in resurrecting a year old thread, closing.
    Copy linkTweet thisAlerts:
    @SempervivumApr 06.2022 — {"locked":true}
    ×

    Success!

    Help @frncskn spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 4.23,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,

    tipper: @Samric24,
    tipped: article
    amount: 1000 SATS,
    )...