Reputation: 89
function change_myselect(sel) {
return new sel;
}
function customers () {
var xmlhttp, myObj, i, tbl = '';
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
tbl += '<table border="1">';
for (i in myObj) {
tbl += '<tr><td>' + myObj[i] + '</td></tr>' ;
}
tbl += '</table>';
document.getElementById('showSelection').innerHTML = tbl;
}
};
xmlhttp.open('GET', 'suppliers.txt', true);
xmlhttp.send();
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h2>Make a table based on the value of a drop down menu.</h2>
<select onchange="change_myselect(customers)">
<option value="">Choose an option</option>
<option value="customers">Customers</option>
<option value="products">Products</option>
<option value="suppliers">Suppliers</option>
</select>
<p id="showSelection"></p>
function change_myselect(sel) {
return new sel;
}
function customers () {
var xmlhttp, myObj, i, tbl = '';
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
tbl += '<table border="1">';
for (i in myObj) {
tbl += '<tr><td>' + myObj[i] + '</td></tr>' ;
}
tbl += '</table>';
document.getElementById('showSelection').innerHTML = tbl;
}
};
xmlhttp.open('GET', 'customers.txt', true);
xmlhttp.send();
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h2>Make a table based on the value of a drop down menu.</h2>
<select onchange="change_myselect(this.value)">
<option value="">Choose an option</option>
<option value="customers">Customers</option>
<option value="products">Products</option>
<option value="suppliers">Suppliers</option>
</select>
<p id="showSelection"></p>
I want to make a table based on the value of a drop-down menu. I've used an ONCHANGE event handler to get the value of the option and pass it to the change_myselect function to retrieve the respective information from the server with JSON. When i write the name of the CUSTOMERS function, in the change_myselect function it works fine. But when i use THIS.VALUE, it does not work. I've used the NEW key word to return and call the CUSTOMERS function without using parentheses.
Upvotes: 3
Views: 131
Reputation: 2213
It looks like the issue with code above is that you are referring to
this.value
You could revisit your change_myselect
function to expect event
as argument and then extract selected value from event, for example:
var change_myselect = function(event) {
var selectedValue = event && event.target && event.target.value || '';
return selectedValue || '';
};
make sure that you also modify HTML portion of your code to to pass event as argument as well:
<select onchange="change_myselect(event)">
Also you could store output of change_myselect
in another variable to use down the road in your http request logic.
Upvotes: 1
Reputation: 23406
Everything you get from the HTML is string. When you pass literally written customers
to change_myselect
function, it's a reference to customers
function. When you pass this.value
, it's just a string. That's why you get an error instead of a function call.
Based on your code, it looks like you want to call a function which has the same name as the value of the selected option. In JavaScript, strings can't directly be converted to references (in a rational way), which is what you need, when you refer a function. You'd need a helper object to get the reference.
// Helper object contains methods calling the functions
const handlers = {
customers () {customers();},
products () {products();},
suppliers () {suppliers();}
}
function change_myselect(sel) {
// Check, if the passed property name is a function in handlers object
if (typeof handlers[sel] === 'function') {
// A method named as the passed string was found
// Call the found method
handlers[sel]();
}
}
function customers () {
console.log('customers called');
}
function products () {
console.log('products called');
}
function suppliers () {
console.log('suppliers called');
}
<h2>Make a table based on the value of a drop down menu.</h2>
<select onchange="change_myselect(this.value)">
<option value="">Choose an option</option>
<option value="customers">Customers</option>
<option value="products">Products</option>
<option value="suppliers">Suppliers</option>
</select>
<p id="showSelection"></p>
In change_myselect
, the code checks, if the helper object contains a method which has the same name as the passed string. For this we use bracket notation, where the string in the brackets is evaluated as a property of the object before the brackets. If the passed property is found, the code calls the method in handlers
object, using the bracket notation again. Notice the parenthesis at the end of the line. The helper method then calls the actual function, which does the job.
If you've customer
function to call only, then just leave the methods referring to the other functions out from the helper object. You can also simplify the code by placing the code of the functions to the methods of handlers
object directly.
Upvotes: 2
Reputation: 11
You actually don't use your select's value anywhere or performing any xhr request. Try changing your js code to something like this:
function performXhr(entity) {
var xmlhttp,
myObj,
i,
tbl = "";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
tbl += '<table border="1">';
for (i in myObj) {
tbl += "<tr><td>" + myObj[i] + "</td></tr>";
}
tbl += "</table>";
document.getElementById("showSelection").innerHTML = tbl;
}
};
xmlhttp.open("GET", `${entity}.txt`, true);
xmlhttp.send();
}
and your HTML markup
<select onchange="performXhr(this.value)">
<option value="">Choose an option</option>
<option value="customers">Customers</option>
<option value="products">Products</option>
<option value="suppliers">Suppliers</option>
</select>
Upvotes: 1