Problem with using change of global variable in loop in JavaScript - javascript

I have a global variable, that I want to change in a for-loop and use it later outside of 'for'
I wanted to write code to correct surname and name. For example:
user: NICK WATERSON ... code: Nick Waterson
user: nick waterson ... code: Nick Waterson
user: nIcK wAtErSoN ... code: Nick Waterson
let fTab = 0;
Register: while (true) {
var name = prompt('Your fullname:', '');
for (let i = 0; i < name.length; i++) {
if (name.charAt(i) == ' ') {
fTab = i;
break Register;
}
}
alert('Error!!')
}
name.toLowerCase();
alert('Your name is ' + name.charAt(0).toUpperCase() + name.substr(1, fTab) + name.charAt(i + fTab).toUpperCase() + name.substr(fTab + 2));
Program returns nothing, because can't find value of 'fTab'

As #Quentin mentioned in his comment, You are using an complex way to make the name in TitleCase.
You can use following way, it is easy to read and concise.
let name = prompt('Your fullname:', '');
let correctedName = name.split(' ')
.map(first => first[0].toUpperCase() + first.substr(1).toLowerCase())
.join(' ');
console.log(correctedName);

Program works fine for me, just replace i + fTab with 1 + fTab in the last line:
alert('Your name is ' + name.charAt(0).toUpperCase() + name.substr(1, fTab).toLowerCase() + name.charAt(1 + fTab).toUpperCase() + name.substr(fTab + 2).toLowerCase());

replace in alert line i + fTab with 1 + fTab AND name = name.toLowerCase();
let fTab = 0;
Register: while (true) {
var name = prompt('Your fullname:', '');
for (let i = 0; i < name.length; i++) {
if (name.charAt(i) == ' ') {
fTab = i;
break Register;
}
}
alert('Error!!')
}
name = name.toLowerCase();
alert('Your name is ' + name.charAt(0).toUpperCase() + name.substr(1, fTab) + name.charAt(fTab + 1).toUpperCase() + name.substr(fTab + 2));

Related

How to optimize and minify the following code

I am attaching an excerpt from my code:
document.getElementById("product-selector-25b").onchange = function () {
document.getElementById("purchase-25b").href = "https://example.com/?add-to-cart=" + this.selectedOptions[0].getAttribute('data-product') + "&" + "variation_id=" + this.value + "/";
}
document.getElementById("product-selector-26").onchange = function () {
document.getElementById("purchase-26").href = "https://example.com/?add-to-cart=" + this.selectedOptions[0].getAttribute('data-product') + "&" + "variation_id=" + this.value + "/";
}
document.getElementById("product-selector-29").onchange = function () {
document.getElementById("purchase-29").href = "https://example.com/?add-to-cart=" + this.selectedOptions[0].getAttribute('data-product') + "&" + "variation_id=" + this.value + "/";
}
document.getElementById("product-selector-Zx3").onchange = function () {
document.getElementById("purchase-Zx3").href = "https://example.com/?add-to-cart=" + this.selectedOptions[0].getAttribute('data-product') + "&" + "variation_id=" + this.value + "/";
}
document.getElementById("product-selector-001sfF").onchange = function () {
document.getElementById("purchase-001sfF").href = "https://example.com/?add-to-cart=" + this.selectedOptions[0].getAttribute('data-product') + "&" + "variation_id=" + this.value + "/";
}
As you can see, the code is repeated in everything except IDs getElementById("product-selector-25b") purchase-25b
The problem is that in total I have hundreds of different IDs and I believe that this code can be optimized somehow, but I don’t understand how. What do you advise?
Here is how you can refacto your code :
const selectors = [
"product-selector-25b",
"product-selector-26",
"product-selector-29",
"product-selector-Zx3",
"product-selector-001sfF"
];
const updateLink = (e) => {
const selectorId = e.target.id;
const productId = e.target.selectedOptions[0].getAttribute("data-product");
const variationId = e.target.value;
const purchaseId = `purchase-${selectorId.split("-")[1]}`;
document.getElementById(purchaseId).href = `https://example.com/?add-to-cart=${productId}&variation_id=${variationId}/`;
};
document.addEventListener("DOMContentLoaded", () => {
selectors.forEach(selectorId => {
const element = document.getElementById(selectorId);
if(element){
element.onchange = updateLink;
}else {
console.error(`Element with id ${selectorId} not found`)
}
});
});
Just add others ids to the array.
When you want to optimize a repetitive code, the idea is to create a reusable function and loop inside of it
My solution is this:
var elements = document.querySelectorAll('[id^="product-selector-"]');
var updateLink = function(el) {
var tagId = el.id.replace("product-selector-", "");
document.getElementById("purchase-" + tagId).href = "https://example.com/?add-to-cart=" + this.selectedOptions[0].getAttribute('data-product') + "&" + "variation_id=" + this.value + "/";
}
for (var i=0; i < elements.length; i++) {
elements[i].addEventListener("change", function(){
updateLink(this);
});
}
Note: I assume all IDs start with "product-selector-".
Otherwise you need to create an array which contains all the IDs.

Done / How to make a space printer in javascript

var arg = 5
var string = ' '
for (let i = 0; i < arg; i++) {
console.log('"' + string + '"')
}
I expected the output is:
" " \\ There are 5 spaces between the ""
But the output is:
" "
" "
" "
" "
" "
I am a newbie in javascript. Hope you will help me
you can use method string.padEnd that fill string with blank space until parameter pass to the method
var arg = 5;
var string = ' ';
string = string.padEnd(arg)
console.log('"' + string + '"');
reference : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
I don't think there is a way to console.log on the same line. You can do something like this
var arg = 5
var string = ' '
var final_string = ''
for (let i = 0; i < arg; i++)
final_string = final_string + string
}
console.log('"' + final_string + '"')
I think you can use or \xa0 for printing spaces
var arg = 5
var string = '\xa0\xa0\xa0\xa0\xa0';
for (let i = 0; i < arg; i++) {
console.log('"' + string + '"')
}
There are many ways to do this. One would be to do it via a loop. That way you can stay flexible. For loop has already been mentioned. here with a foreach loop.
let string = '';
[...Array(5).keys()].forEach(e => string += ' ');
console.log('"' + string + '"');

I cant solve this: to find the minimum number from an array that is input through prompt()

I cant solve this homework that needs to ask the user to enter student marks and output the minimum mark of the student, can someone please help me solve this problem:
<script>
function getMarks() {
var marks = prompt('Type the students marks, seperate each student mark with comma, do not write the percentage mark % .').split(',');
return marks;
}
var studentMarks = getMarks();
var arrayLength = studentMarks.length;
var studentNumber = 0;
var msg = '';
var i;
for (i = 0; i < arrayLength; i++) {
studentNumber = (i + 1);
msg += 'student ' + studentNumber + ': ';
msg += studentMarks[i] + '%' + '<br />';
} document.getElementById('marks').innerHTML = msg; document.getElementById('marke').innerHTML = math.min.apply(null, studentMarks) + '%';
</script>
I will do that in the following way:
function getMarks() {
var marks = prompt('Type the students marks, seperate each student mark with comma, do not write the percentage mark % .');
return marks.split(',').map(n => Number(n));
}
var marksArray = getMarks();
var studentMarks = Math.min(...marksArray);
var position = marksArray.indexOf(studentMarks);
var msg = 'Student ' + Number(position + 1) + ': ';
document.getElementById('marks').innerHTML = msg + studentMarks + '%';
<p id="marks"></p>

Javascript onclick dynamic for loop get a hold of index

Hello I have a problem gettig a hold of the index in the following code:
Contacts.push("test1 test 4232352");
Contacts.push("test2 test2 5435345");
for(var i = 0; i < Contacts.length; i++){
var res = Contacts[i].split(" ");
var font = document.createElement("FONT");
font.innerHTML = res[0] + " " + res[1];
font.style.marginLeft = "10px";
font.onclick = () => { console.log(i); };
document.getElementById("contacts_collection").appendChild(font);
}
in my mind it should print the index of the element I click on, but instead nomatter which of the 2 I click, it always prints '2'.
The problem is the delclaration of i using the statement var.
An alternative is declaring i using the statement let:
for(let i = 0; i < Contacts.length; i++){}
^^^
Or, you can use IIFE to keep the current value of i:
var Contacts = ["test1 test 4232352", "test2 test2 5435345"];
for (var i = 0; i < Contacts.length; i++) {
var res = Contacts[i].split(" ");
var font = document.createElement("FONT");
font.innerHTML = "<b>" + res[0] + " " + res[1] + "</b>";
font.style.marginLeft = "10px";
font.onclick = ((index) => () => {
console.log(index);
})(i);
document.body.appendChild(font);
}
You can also use the forEach() for your array.
DEMO
In ES5
var Contacts = ["test1 test 4232352", "test2 test2 5435345"],
font = '';
Contacts.forEach(function(v, i) {
v = v.split(" ");
font = document.createElement("FONT");
font.innerHTML = '<b>' + v[0] + ' ' + v[1] + ' </b><br>';
font.setAttribute("style", "margin-left:10px; cursor:pointer");
font.index = i;
font.onclick = function(e) {
console.log(e.target.parentElement.index);
};
document.getElementById('mydiv').appendChild(font);
});
<div id="mydiv"></div>
In ES6
const Contacts = ["test1 test 4232352", "test2 test2 5435345"];
Contacts.forEach((v, i) => {
v = v.split(" ");
let font = document.createElement("FONT");
font.innerHTML = `<b>${v[0]} ${v[1]}</b><br>`;
font.setAttribute("style", "margin-left:10px; cursor:pointer");
font.index = i;
font.onclick = (e => {
console.log(e.target.parentElement.index);
});
document.getElementById('mydiv').appendChild(font);
});
<div id="mydiv"></div>
You can also use for...in statement for array iterates.
DEMO
var Contacts = ["test1 test 4232352", "test2 test2 5435345"],
font = '',v;
for(let i in Contacts){
v = Contacts[i].split(" ");
font = document.createElement("FONT");
font.innerHTML = '<b>' + v[0] + ' ' + v[1] + ' </b><br>';
font.setAttribute("style", "margin-left:10px; cursor:pointer");
font.index = i;
font.onclick = function(e) {
console.log(e.target.parentElement.index);
};
document.getElementById('mydiv').appendChild(font);
};
<div id="mydiv"></div>

Cannot collect alle results of asynchronous call with geo.getLocations (Google Maps)

Below is my code. The problem is that recordsOut[0] is always undefined, whatever I try.
I know it has to do with the callback result. I tried to add some delays to give it more time to give a result back, but that did not help.
Any idea (with example please)? Very much appreciated.
function getAddress(id, searchValue) {
geo.getLocations(searchValue, function(result) {
if (result.Status.code == G_GEO_SUCCESS) {
var recordsOutStr = id + ';' + searchValue + ';';
for (var j = 0; j < result.Placemark.length; j++)
recordsOutStr += result.Placemark[j].address + ';' + result.Placemark[j].Point.coordinates[0] + ';' + result.Placemark[j].Point.coordinates[1];
recordsOut.push(recordsOutStr);
alert(recordsOutStr);
}
else {
var reason = "Code " + result.Status.code;
if (reasons[result.Status.code])
reason = reasons[result.Status.code]
alert('Could not find "' + searchValue + '" ' + reason);
}
});
}
function delay(ms)
{
var date = new Date();
var curDate = null;
do
{
curDate = new Date();
}
while (curDate - date < ms);
}
function processData()
{
objDataIn = document.getElementById("dataIn");
objDataOut = document.getElementById("dataOut");
if (objDataIn != null)
{
//alert(objDataIn.value);
if (objDataOut != null) {
recordsIn = explode(objDataIn.value, ';', true);
//for (i = 0; i < recordsIn.length; i++)
for (i = 0; i <= 5; i++)
{
addressStr = recordsIn[i]['address'] + ', ' +
recordsIn[i]['postalcode'] + ' ' +
recordsIn[i]['city'] + ', ' +
recordsIn[i]['country'];
getAddress(recordsIn[i]['id'], addressStr); //This will set resultStr
delay(200);
}
delay(5000);
alert('***' + recordsOut[0] + '***');
alert('***' + recordsOut[1] + '***');
alert('***' + recordsOut[2] + '***');
alert('***' + recordsOut[3] + '***');
alert('***' + recordsOut[4] + '***');
}
}
document.frmGeoCoder.submit();
}
Make sure that you have already defined recordsOut like this:
var recordsOut = [];
If you do it like this - var recordsOut; - it will be undefined.
If that doesn't work for you, please post the rest of the code, so we can see exactly what's going on.

Categories