javaScript: Split one function into two - javascript

I have the following working function (the lower part of it is not shown):
<script type="text/javascript">
function plan_click(clicked_id){
let var_plan;
let var_sgldbl;
var_sgldbl = 'sgl';
var_plan = clicked_id;
document.getElementById(clicked_id).style.background = "green";
/* new code*/
let var_tab01;
switch (var_plan) {
case '101':
var_tab01 = 201;
document.getElementById(var_tab01).style.background = "green";
break;
}}
</script>
I want the function to be split into two functions at the /new code/ - in separate scripts as the new "tabeller" function might be placed in a js.-file. The "tabeller"-function should be called from the plan_click-function and receive the actual values from the variables: var_plan and var_sgldbl.
Which code should be inserted to make the split effective?

Just move the code out to another function. var_plan should be a parameter, while var_tab01 can be the return value.
function plan_click(clicked_id) {
let var_plan;
let var_sgldbl;
var_sgldbl = 'sgl';
var_plan = clicked_id;
document.getElementById(clicked_id).style.background = "green";
let var_tab01 = tabeler(var_plan);
...
}
function tabeler(var_plan)
let var_tab01;
switch (var_plan) {
case '101':
var_tab01 = 201;
document.getElementById(var_tab01).style.background = "green";
break;
...
}
return var_tab01;
}

Related

Better way of searching specific keywords in strings in JavaScript

I am working with an array of urls and for each url i wanna find a image corresponding to the site domain. my first attempt was
const url = new URL(props.url);
const platform = url.hostname.split(".")[1];
console.log(platform)
const platform_logos = {
"codechef": "images/chef.png",
"withgoogle": "images/google.png",
.
.
.
"codeforces": "images/codeforces.png",
}
let platform_logo = platform_logos[platform];
but it doesnt work with url of type 'https://momo2022fr.hackerearth.com' so i had to resort to
let platform_logo = "images/code.png"
if (url.includes("hackerearth")) {
platform_logo = "images/hackerearth.png"
}
else if (url.includes("hackerrank")) {
platform_logo = "images/hackerrank.png"
}
else if (url.includes("codeforces")) {
platform_logo = "images/codeforces.png"
}
else if (url.includes("codechef")) {
platform_logo = "images/chef.png"
}
else if (url.includes("atcoder")) {
platform_logo = "images/atcoder.png"
}
else if (url.includes("leetcode")) {
platform_logo = "images/leetcode.png"
}
else if (props.url.includes("withgoogle")) {
platform_logo = "images/google.png"
}
Is there any better way of writing the code below, it just feels like it violates DRY
You could change how you're reading the url to only get the root domain.
location.hostname.split('.').reverse().splice(0,2).reverse().join('.').split('.')[0]
This code would give hackerearth for https://momo2022fr.hackerearth.com/.
So there are several ways of achieving this.
These are just two from the top of my head.
Parsing the url and using a switch() to determine the outcome, with fallback if none is found.
const url = new URL("https://www.withgoogle.com/search?q=test");
const sites = [
"hackerearth",
"hackerrank",
"codeforces",
"codechef",
"atcoder",
"leetcode",
"withgoogle",
];
console.info(url.hostname);
const site = url.hostname.match(new RegExp(`${sites.join("|")}`));
let logo = "";
switch (site[0]) {
case "hackerearth":
logo = "images/hackerearth.png";
break;
case "hackerrank":
logo = "images/hackerrank.png";
break;
case "codeforces":
logo = "images/codeforces.png";
break;
case "codechef":
logo = "images/chef.png";
break;
case "atcoder":
logo = "images/atcoder.png";
break;
case "leetcode":
logo = "images/leetcode.png";
break;
case "withgoogle":
logo = "images/google.png";
break;
default:
logo = "images/code.png";
break;
}
console.info(logo);
Then there is the modern way, with less code and programming the fallback.
// const url = new URL("https://eee.com/test");
const url = new URL("https://www.withgoogle.com/search?q=test");
const sites = {
hackerearth: "images/hackerearth.png",
hackerrank: "images/hackerrank.png",
codeforces: "images/codeforces.png",
codechef: "images/chef.png",
atcoder: "images/atcoder.png",
leetcode: "images/leetcode.png",
withgoogle: "images/google.png",
default: "images/code.png",
};
let site = url.hostname.match(new RegExp(`${Object.keys(sites).join("|")}`));
if (site === null) {
site = "default";
}
console.info(site, sites[site]);
You could just do the same thing as in your first solution and store the mapping from the substring to the image path in an ocject:
const platform_logos = {
"hackerearth": "images/hackerearth.png",
"hackerrank": "images/hackerrank.png",
"codeforces": "images/codeforces.png",
"codechef": "images/chef.png",
"atcoder": "images/atcoder.png",
"leetcode": "images/leetcode.png",
"withgoogle": "images/google.png"
};
Then you could iterate over the key-value pairs in your object to find the key that is part of the URL and return it once it matches:
function getLogo(url) {
for(const [key, value] of Object.entries(platform_logos)) {
if(url.contains(key)) {
return value;
}
}
}
let platform_logo = getLogo(url);
You can iterate over the images and check URL:
const url = "https://example.com/codechef/asdasd/...";
const platform_logos = {
"codechef": "images/chef.png",
"withgoogle": "images/google.png",
"codeforces": "images/codeforces.png",
}
let img = "default.png";
for (const [key, value] of Object.entries(platform_logos)) {
if (url.includes(key)) {
img = value;
break;
}
}
console.log(img);

How to display HTML class of current node in JS

I have variables which:
display the result (result), and
reference the current node (thisNode).
What do I need to change in my code so that it would display the HTML class?
var thisNode = document.body.firstChild;
var result = document.getElementById("resultOfButton");
result.InnerHTML = thisNode.;
/* Here, in JS are there any ways like displaying the class name,
like nodeClass */
Please give recommendations for my code. There may be some errors. Thank you.
var thisNode = document.body.firstChild;
var result = document.getElementById("resultOfButton");
var block = false;
function buttonDown()
{
if(block == true)
{
thisNode = thisNode.parentElement.firstChild;
block = false;
}
thisNode = thisNode.nextSibling;
result.innerHTML = thisNode.nodeName;
if(thisNode == thisNode.parentNode.lastChild)
{
block = true
}
}
function buttonUp()
{
// not done now...
}
function buttonEnter()
{
thisNode = thisNode.firstChild;
result.innerHTML = thisNode.c;
}
function buttonBack()
{
// not done now...
}
I think you're asking for the className attribute. I copied your first sample and added some code so you can run it on this page. You'll get the second emoji replaced by the class name of the inserted element.
var thisNode = document.getElementById("thisNode"); // document.body.firstChild;
var result = document.getElementById("resultOfButton");
result.innerHTML = thisNode.className; /*Here, in JS are there any ways like displaying the class name, like nodeClass*/
<div id="thisNode" class="sample-class">🙂</div>
<div id="resultOfButton">🙃</div>
Quoting MDN:
"The className property of the Element interface gets and sets the value of the class attribute of the specified element."

Function parameter not carried to switch statement in JavaScript

I've been making a basic game but I've encountered a problem while trying to make a function that would be usable among several occasions by using the switch statement. The output I keep getting when I run the function is the default code block. Here's some sample code:
function battle(boss) {
slaying = true;
while(slaying) {
switch(boss) {
case 'boss1':
console.log('This is' + boss1.name);
break;
case 'boss2':
console.log('This is' + boss2.name);
break;
default:
console.log('No boss');
break;
}
slaying = false;
}
}
function Boss(name) {
this.name = name;
}
var boss1 = new Boss('boss1');
var boss2 = new Boss('boss2');
battle(boss1);

Changing an image in a switch statement

I have an image in my HTML, but i would like to change the image when an answer is given by the user. For some reason the first function works, but the image doesn't change.. Can someone help me please.
This is my code so far:
window.onload = function () {
'use strict';
var showMessage = function (text) {
var messageCenter = document.getElementById('messageCenter');
messageCenter.innerHTML += "<p>" + text + "</p>\n";
};
var checkName = function (name) {
switch (prompt("What is your name?")) {
case "Leonard":
showMessage("Leonard! How did I not recognize you! Why would you like to get rid of me!");
break;
case "Penny":
showMessage("Penny Penny Penny! You've got so much to learn.");
break;
case "Howard":
showMessage("Howard, the only one without a Ph.D");
break;
case "Raj":
showMessage("Interesting. You're afraid of insects and women. Ladybugs must render you catatonic!");
break;
default:
showMessage("Well, I'm not familiair with you. I don't like to talk to strange people.");
break;
}
};
checkName()
var myImage = document.getElementById('sheldon');
var checkCase = function (img) {
switch (img) {
case "Leonard":
myImage("verbaasd.jpg");
break;
case "Penny":
myImage("les.jpg");
break;
case "Howard":
myImage("howard.jpg");
break;
case "Raj":
myImage("loser.jpg");
break;
default:
myImage("sheldon.jpg");
break;
}
};
checkCase()
};
Your error is in myImage(). You set this variable with a DOM object and call it as a normal function. This gives you an error. You also forgot to store the name and pass it as argument to your checking functions.
Your code should be:
window.onload = function () {
'use strict';
var name = prompt("What is your name?");
var showMessage = function showMessage(text) {
var messageCenter = document.getElementById('messageCenter');
messageCenter.innerHTML += "<p>" + text + "</p>\n";
};
var checkName = function (name) {
switch (name) {
case "Leonard":
showMessage("Leonard! How did I not recognize you! Why would you like to get rid of me!");
break;
case "Penny":
showMessage("Penny Penny Penny! You've got so much to learn.");
break;
case "Howard":
showMessage("Howard, the only one without a Ph.D");
break;
case "Raj":
showMessage("Interesting. You're afraid of insects and women. Ladybugs must render you catatonic!");
break;
default:
showMessage("Well, I'm not familiair with you. I don't like to talk to strange people.");
break;
}
};
checkName(name);
var myImage = function myImage(img) {
var sheldon = document.getElementById('sheldon');
sheldon.innerHTML = '<img src="' + img + '"/>';
};
var checkCase = function (name) {
switch (name) {
case "Leonard":
myImage("verbaasd.jpg");
break;
case "Penny":
myImage("les.jpg");
break;
case "Howard":
myImage("howard.jpg");
break;
case "Raj":
myImage("loser.jpg");
break;
default:
myImage("sheldon.jpg");
break;
}
};
checkCase(name);
};
Now your myImage() is a function which insert a new image inside a container with ID sheldon.
If you don't want to have a container for the image, and instead you want reference directly to the image, can change the myImage() function in:
var myImage = function myImage(img) {
var sheldon = document.getElementById('sheldon');
sheldon.src = img;
};
BTW, I see that you're learning so it's right to start from the basics, but remember that there are cleaner ways to do that.
Hope it's helpful to you.

Reference issue with Javascript

I have an array of objects cached on client side using JS array.
var scannerDictionary = new Array(); //Holds all scanners unmodified
var modifiedScannerDictionary = new Array(); //Holds all scanners with modified values
The properties of each object is set/changed using GUI and updated in the object. Each object contains list of InputParameters (array of Parameter class containing Name, Value and other members).
Please have a look on GUI.
Below is the code i used to render the controls -
function renderControls(scannerId) {
var currentScanner = modifiedScannerDictionary[scannerId];
//Render Input Parameters
$("#tblInputCriteria").find('tr:gt(5)').remove();
for(var i=0;i<currentScanner.InputParameters.length;i++) {
var propType = currentScanner.InputParameters[i].DataType;
var inParName = currentScanner.InputParameters[i].Name;
switch(propType) {
case 0: //Number
var eRow1 = $("#tblInputCriteria").find('#emptyNumRow').clone();
$(eRow1).removeClass('hidden').attr('id', 'Row_'+currentScanner.InputParameters[i].Name);
$(eRow1).appendTo($('#tblInputCriteria'));
var prop1 = $(eRow1).find('#InNumPropName');
$(prop1).attr('id', 'InNumPropName_'+currentScanner.InputParameters[i].Name);
var propName1 = currentScanner.InputParameters[i].Name;
$(prop1).html(propName1);
var propVal1 = $(eRow1).find('#InNumPropValue');
$(propVal1).attr('id', 'InNumPropValue_'+currentScanner.InputParameters[i].Name);
$(propVal1).val(currentScanner.InputParameters[i].Value);
$(propVal1).blur(function () {
if(!ValidateNumber(this, propName1)) {
alert('Value should be numeric in ' + propName1);
setTimeout(function() {$(propVal1).focus();}, 100);
}else {
UpdateData(currentScanner.Id, propName1, $(propVal1).val());
}
});
break;
case 1: //String
var eRow2 = $("#tblInputCriteria").find('#emptyStrRow').clone();
$(eRow2).removeClass('hidden').attr('id', 'Row_'+currentScanner.InputParameters[i].Name);
$(eRow2).appendTo($('#tblInputCriteria'));
var prop2 = $(eRow2).find('#InStrPropName');
$(prop2).attr('id', 'InStrPropName_'+currentScanner.InputParameters[i].Name);
var propName2 = currentScanner.InputParameters[i].Name;
$(prop2).html(propName2);
var propVal2 = $(eRow2).find('#InStrPropValue');
$(propVal2).attr('id', 'InStrPropValue_'+currentScanner.InputParameters[i].Name);
$(propVal2).val(currentScanner.InputParameters[i].Value);
$(propVal2).blur(function () {
UpdateData(currentScanner.Id, propName2, $(propVal2).val());
});
break;
case 2: //Boolean
var eRow3 = $("#tblInputCriteria").find('#emptyBoolRow').clone();
$(eRow3).removeClass('hidden').attr('id', 'Row_'+currentScanner.InputParameters[i].Name);
$(eRow3).appendTo($('#tblInputCriteria'));
var prop3 = $(eRow3).find('#InBoolPropName');
$(prop3).attr('id', 'InBoolPropName_'+currentScanner.InputParameters[i].Name);
var propName3 = currentScanner.InputParameters[i].Name;
$(prop3).html(propName3);
var propVal3 = $(eRow3).find('#InBoolPropValue');
$(propVal3).attr('id', 'InBoolPropValue_'+currentScanner.InputParameters[i].Name);
$(propVal3).val(currentScanner.InputParameters[i].Value);
$(propVal3).blur(function () {
UpdateData(currentScanner.Id, propName3, $(propVal3).val());
});
break;
}
}
}
PROBLEM:
The problem here is of the variables inside switch working as reference variable. So the UpdateData() function gets the last Name for similar type properties. i.e. if fields are of Number type then only the last property is updated by UpdateData() method.
Can anybody help me out solve this issue. Thanks for sharing your time and wisdom.
Try something like the following. Its a tad overkill, but will bind the values of the variables to the closures.
var fnOnBlur = (function(thePropName, thePropVal) {
return function () {
if(!ValidateNumber(this, thePropName)) {
alert('Value should be numeric in ' + thePropName);
setTimeout(function() {$(thePropVal).focus();}, 100);
}else {
UpdateData(currentScanner.Id, thePropName, $(thePropVal).val());
}
};
})(propName1, propVal1);
$(propVal1).blur( fnOnBlur );
The link that Felik King supplied has much more detailed discussion.

Categories

Resources