/    Sign up×
Community /Pin to ProfileBookmark

Uncaught ReferenceError: $ is not defined

Hello! I have this code that is supposed to load images from my pc and display it in a local website (only accessible in my work’s network). The images are forecast images used for weather forecasting. But I keep getting the Uncaught Error when inspect it in my browser.

The Error:
https://ibb.co/Y0RSvZ9

The Console Output:
https://ibb.co/Kz8x6GW

The HTML:

[code]
<div class=”row”>
<div class=”col-3″>
<div class=”form-group”>
<h3 class=”card-title”>Products:</h3>
<select class=”form-control select2″ id=”select” style=”width: 100%;”>
<option selected disabled>Select a Forecast Parameter</option>
<optgroup label=”Wind Speed (m/s) and Direction”>
<option value=”Surface”>Surface Wind Speed (m/s) and Direction</option>
<option value=”200hPa”>200hPa Wind Speed (m/s) and Direction</option>
<option value=”300hPa”>300hPa Wind Speed (m/s) and Direction</option>
<option value=”500hPa”>500hPa Wind Speed (m/s) and Direction</option>
<option value=”700hPa”>700hPa Wind Speed (m/s) and Direction</option>
<option value=”850hPa”>850hPa Wind Speed (m/s) and Direction</option>
<option value=”925hPa”>925hPa Wind Speed (m/s) and Direction</option>
</optgroup>
<optgroup label=”Accumulated Rainfall”>
<option selected value=”pcp_1hr”>1-hour Accumulated Rainfall and Surface Winds</option>
<option value=”pcp_1hr”>1-hour Accumulated Rainfall and 850hpa Wind</option>
<option value=”pcp_1hr_850hPa”>1-hour Accumulated Rainfall and Surface Winds</option>
<option value=”pcp_3hr”>3-hour Accumulated Rainfall and Surface Winds</option>
<option value=”pcp_3hr_850hPa”>3-hour Accumulated Rainfall and 850hpa Wind</option>
<option value=”pcp_6hr”>6-hour Accumulated Rainfall and Surface Winds</option>
<option value=”pcp_6hr_850hPa”>6-hour Accumulated Rainfall and 850hPa Wind</option>
<option value=”pcp_12hr”>12-hour Accumulated Rainfall and Surface Winds</option>
<option value=”pcp_12hr_850hPa”>12-hour Accumulated Rainfall and Surface Winds</option>
</optgroup>
<optgroup label=”24-hour Accumulated Rainfall”>
<option value=”sym1″>24-hour Accumulated Rainfall (mm)</option>
<option value=”sym2″>24-hour Accumulated Rainfall (mm)</option>
<option value=”sym3″>24-hour Accumulated Rainfall (mm)</option>
</optgroup>
<optgroup label=”Total Cloud Cover”>
<option value=”cc”>Total Cloud Cover (%)</option>
</optgroup>
<optgroup label=”Mean Sea Level Pressure”>
<option value=”prmsl”>Mean Sea Level Pressure (hPa)</option>
</optgroup>
<optgroup label=”Relative Humidity”>
<option value=”rh”>Surface Relative Humidity (%)</option>
</optgroup>
<optgroup label=”Temperature”>
<option value=”temp”>Surface Temperature (&deg;C)</option>
</optgroup>
</select>
</div><!– form-group for forecast parameters –>
<div class=”form-group clearfix”>
<h3 class=”card-title”>Domain:</h3><br><br>
<div class=”icheck-primary d-inline”>
<input type=”radio” name=”optradio-domain” value=”d01″ id=”radioPrimary1″ checked>
<label for=”radioPrimary1″>Domain 1</label>
</div>
<div class=”icheck-primary d-inline”>
<input type=”radio” name=”optradio-domain” value=”d02″ id=”radioPrimary2″>
<label for=”radioPrimary2″>Domain 2</label>
</div>
</div><!– form-group for –>
<div class=”form-group clearfix”>
<h3 class=”card-title”>Animation Interval:</h3><br><br>
<div class=”icheck-primary d-inline”>
<input type=”radio” value=”1″ id=”radioPrimary3″ name=”optradio” checked>
<label for=”radioPrimary3″>1</label>
</div>
<div class=”icheck-primary d-inline”>
<input type=”radio” value=”3″ id=”radioPrimary4″ name=”optradio”>
<label for=”radioPrimary4″>3</label>
</div>
<div class=”icheck-primary d-inline”>
<input type=”radio” value=”6″ id=”radioPrimary5″ name=”optradio”>
<label for=”radioPrimary5″>6</label>
</div>
<div class=”icheck-primary d-inline”>
<input type=”radio” value=”12″ id=”radioPrimary6″ name=”optradio”>
<label for=”radioPrimary6″>12</label>
</div>
<div class=”icheck-primary d-inline”>
<input type=”radio” value=”24″ id=”radioPrimary7″ name=”optradio”>
<label for=”radioPrimary7″>24</label>
</div>
</div>

</div><!– col-3 –>

<div class=”col-9″>
<div id=”forecast-container” class=”hidden”>
<div class=”controls”>
<a class=”btn btn-app”>
<i class=”fas fa-fast-forward” id=”first-btn”></i> First
</a>
<a class=”btn btn-app”>
<i class=”fas fa-step-forward” id=”next-btn”></i> Next
</a>
<a class=”btn btn-app”>
<i class=”fas fa-step-backward” id=”prev-btn”></i> Previous
</a>
<a class=”btn btn-app”>
<i class=”fas fa-fast-backward” id=”last-btn”></i> Last
</a>
<a class=”btn btn-app”>
<i class=”fas fa-play” id=”start-stop-btn”></i> Stop
</a>
</div>
<div id=”img-container”>
<img id=”forecast-img” src=””>
</div>
</div>
</div>
[/code]

The JS:

[code]
<script>
var basicdata = {
//”200hPa” is the ID of the forecast parameter, the value in the #form-control.
//the same logic is applied to the other forecast parameters.
“200hPa”: {
“path”: “200hPa”,
},
“300hPa”: {
“path”: “300hPa”,
},
“500hPa”: {
“path”: “500hPa”,
},
“700hPa”: {
“path”: “700hPa”,
},
“850hPa”: {
“path”: “850hPa”,
},
“925hPa”: {
“path”: “925hPa”,
},
“cc”: {
“path”: “cc”,
},
“pcp_1hr”: {
“path”: “pcp_1hr”,
},
“pcp_1hr_850hPa”: {
“path”: “pcp_1hr_850hPa”,
},
“pcp_3hr”: {
“path”: “pcp_3hr”,
},
“pcp_3hr_850hPa”: {
“path”: “pcp_3hr_850hPa”,
},
“pcp_6hr”: {
“path”: “pcp_6hr”,
},
“pcp_6hr_850hPa”: {
“path”: “pcp_6hr_850hPa”,
},
“pcp_12hr”: {
“path”: “pcp_12hr”,
},
“pcp_12hr_850hPa”: {
“path”: “pcp_12hr_850hPa”,
},
“sym1”: {
“path”: “sym1”,
},
“sym2”: {
“path”: “sym2”,
},
“sym3”: {
“path”: “sym3”,
},
“prmsl”: {
“path”: “prmsl”,
},
“rh”: {
“path”: “rh”,
},
“Surface”: {
“path”: “Surface”,
},
“temp”: {
“path”: “temp”,
}
}
//Prepare the DOM elements
var theimg = document.getElementById(‘forecast-img’);

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

//ipdate the list of images every 60 seconds
setInterval(getUrlAndLoad, 10);

//timer that repeats the functions every 50ms
setInterval(function () {
console.log(idx, step);
//change image only
//1. if the forecast date is empty
//2. if the animation is not stopped by any corresponding buttons
if (forecastdata.length > 0 && !stopped) {
if (forecastdata[idx]) {
//display the images
theimg.src = forecastdata[idx].img;
} else {
//get new forecastdata
getUrlAndLoad();
idx=0;
}
idx += step;
if (idx >= forecastdata.length) idx = 0;
}
}, 450);

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

//this function is called anytime a parameter (step, domain, forecast parameter) is changed
function getUrlAndLoad () {
//get value of #form-control
//it contains the ID of the forecast parameter that has been selected
var val = $(“#select”).val();
//get the the domain
var domain = $(“input[name=’optradio-domain’]:checked”).val();
thedomains = $(“input[name=’optradio-domain’]”);
//container for the forecasts
thecontainer = $(“#forecast-container”);
//remove all domain classes from the container
thedomains.each(function (idx, ele) {
thecontainer.removeClass($(this).val());
});
//add current domain as a class to the container
thecontainer.addClass(domain);
console.log(basicdata[val].path, domain);
//read the lists of images by executing the PHP Script
$.getJSON(“loadpywrf.php”,
//object containing the URL parameters that will be handled over to the PHP Script
{ path: basicdata[val].path, domain: domain },
//this function is called when the PHP scripts has been executed successfully
function (data) {
//the parameter data contains the list of images
console.log(data);
//transfer the list of the correspoding variable
forecastdata = data;
//make the container that keeps the forecast visible
$(“#forecast-container”).removeClass(“hidden”);
});
}

//add event handler to the #select
//all necessary actions will be done by the function getUrlAndLoad
$(“input[name=’optradio-domain’]”).on(“change”, function () {
getUrlAndLoad();
//reset idx
idx = 0;
});

//add eventhandler to the radiobuttons for the domain
//all necessary actions will be done by the 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” and 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 event handler to the first button
$(“#first-btn”).on(“click”, function() {
event.preventDefault();
// stop the 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 ti will start at this index
idx = 0;
//update the image
theimg.src = forecastdata[idx].img;
});

//add event handler for the “last-btn”
//similar to the first button but the index is set to the last element
$(“#last-btn”).on(“click”, function() {
event.preventDefault();
stopped = true;
$(“#start-stop-btn”).text(“Start”);
idx = forecastdata.length -1;
theimg.src = forecastdata[idx].img;
});

//add eventhandler to the prev 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 the overflow at the end
if (idx < 0) idx = forecastdata.length -1;
theimg.src = forecastdata[idx].img;
});

</script>
[/code]

The PHP Script: (*Security is not an issue for this website because its only for displaying forecast images to be viewed by meteorologists and only viewable within our network*)

[code]
<?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 = “../home/francis/operations/pywrf_output/” . $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 < 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’ => $img, ‘date’ => $date, ‘utc’ => $utc, ‘forecasthour’ => $forecasthour];
}
}
//encode array in JSON format and output it
echo json_encode($forecastdata);
?>
[/code]

The UI view:
https://ibb.co/7XdH6Fc

to post a comment
JavaScript

7 Comments(s)

Copy linkTweet thisAlerts:
@NogDogNov 22.2021 — Have you loaded the JQuery library somewhere in all of that? ($ is the default variable it uses for the main JQuery obejct -- or whatever it's called, I'm not much of JavaScript expert.)
Copy linkTweet thisAlerts:
@frncsknauthorNov 22.2021 — @NogDog#1639689 yes I load it at the bottom most part of the code like this:
<i>
</i>&lt;!-- jQuery --&gt;
&lt;script src="../css/bootstrap/plugins/jquery/jquery.min.js"&gt;&lt;/script&gt;
Copy linkTweet thisAlerts:
@NogDogNov 22.2021 — > @frncskn#1639690 I load it at the bottom most part of the code

So...could it be that it hasn't loaded yet when the other code in question is trying to reference it? 🤔
Copy linkTweet thisAlerts:
@frncsknauthorNov 22.2021 — @NogDog#1639691 Hi. That is unlikely because the script is already defined below the code. And I already checked if its properly loading, and it is. That's why I'm dumbfounded why this error is popping up.
Copy linkTweet thisAlerts:
@frncsknauthorNov 22.2021 — @NogDog#1639691 EDIT: I put all the js scripts back inside the <head> of the html and now the error disappeared but the images are still not being displayed
Copy linkTweet thisAlerts:
@NogDogNov 22.2021 — > @frncskn#1639693 images are still not being displayed

I'll have to leave that to the JavaScript gurus. Fortunately there are some very good ones here. :)
Copy linkTweet thisAlerts:
@frncsknauthorNov 22.2021 — @NogDog#1639694 Thank you for helping 😁
×

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.16,
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,
)...