scrollIntoView first found element within loop - javascript

I'm experimenting with data-, and ran into a problem that I can't solve at the moment.
I'm trying to scrollIntoView, e.g.: [0] , for the first 'clients[i]':
function search() {
searchTerm = document.getElementById("searchInput").value;
clients = document.getElementsByClassName("client");
for (var i = 0; i < clients.length; i++) {
find = clients[i].getAttribute("data-search-firstname");
if (searchTerm === find) {
console.log("Found: " + find);
selClient(clients[i]);
clients[i].scrollIntoView(); // not sure where to put [0] without an error
}
}
}
Thanks a ton!
EDIT:
For example, if I have multiple of the same 'clients[i]', I want the first client to scrollIntoView.

You just need to identify if i is the first result
function search() {
searchTerm = document.getElementById("searchInput").value;
clients = document.getElementsByClassName("client");
for (var i = 0; i < clients.length; i++) {
find = clients[i].getAttribute("data-search-firstname");
if (searchTerm === find) {
console.log("Found: " + find);
selClient(clients[i]);
if (i === 0) {
clients[i].scrollIntoView();
}
}
}
}
Or in your case it looks like you only want it scrolling to the first result in loop where searchterm === find so you might want to do this:
function search() {
searchTerm = document.getElementById("searchInput").value;
clients = document.getElementsByClassName("client");
var scrolled = false;
for (var i = 0; i < clients.length; i++) {
find = clients[i].getAttribute("data-search-firstname");
if (searchTerm === find) {
console.log("Found: " + find);
selClient(clients[i]);
if (!scrolled) {
clients[i].scrollIntoView();
scrolled = true;
}
}
}
}

Related

JavaScript - Nested FOR loop executing twice

I have a nested FOR loop that iterates over an object, and updating variables or attributes based on conditions. The last 'IF' on this loop formats a date and updates the field accordingly. For some reason the final line causes the loop to iterate twice, therefore updating the 'formattedDate' variable twice (in the object, there is only one single element with the 'childTag' = 'date'. Any help is appreciated!
for (let i = 0; i < submitFormData.tabs.length; i++) {
for (let j = 0; j < submitFormData.tabs[i].elements.length; j++) {
if (submitFormData.tabs[i].elements[j].childTag == "project_name") {
projectName = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_store") {
locationStore = ' #' + submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_street") {
locationStreet = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_city") {
locationCity = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_state") {
locationState = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "location_zip") {
locationZip = submitFormData.tabs[i].elements[j].value;
} else if (submitFormData.tabs[i].elements[j].childTag == "date") {
if (submitFormData.tabs[i].elements[j].value != "") {
console.log(submitFormData)
date = (submitFormData.tabs[i].elements[j].value.substring(0, 10));
formattedDate = (date.substring(5, 11) + '-' + date.substring(0, 4));
console.log(formattedDate, 'formatted date')
submitFormData.tabs[i].elements[j].value = formattedDate;
}
}
}
}
Sample of Object
I see that in the loop you manipulate the list which you iterate over.
submitFormData.tabs[i].elements
It would be better to make a copy of it and iterate over it.
const newSubmitFormData = [...submitFormData.tabs[i].elements]
for (let j = 0; j < newSubmitFormData .length; j++) { /* your code */ }

How to check javascript nodelist if it's contents are either all empty or all have values?

I'm fairly new to javascript and looking at checking some fields with dynamic ID's at the end of the ID to see if they've either had values entered in all of them or none of them at all. The user shouldn't be allowed to only enter values in some of them and leave others blank.
I've wrote the below, which works, but I feel there must be a better way of doing this?:
var x = document.querySelectorAll('[id^="entryField"]');
for (var i = 0; i < x.length; ++i) {
if (x[i].value == "") {
for (var i = 0; i < x.length; ++i) {
if (x[i].value != "") {
alert("Please enter a value");
}
}
}
}
One loop should work with a counter for empty (or filled) fields. If the counter is not zero and does not have the length of the object, then some fields have a value.
var x = document.querySelectorAll('[id^="entryField"]'),
empty = 0;
for (var i = 0; i < x.length; ++i) {
if (x[i].value == "") {
++empty;
}
}
if (empty !== 0 && empty !== x.length) {
alert("Please enter a value");
}
This will be a simpler version:
var x = document.querySelectorAll('[id^="entryField"]');
const inputs = Array.from(x);
const allInput = inputs.every(input => {
return (input.value != "");
});
const allEmpty = inputs.every(input => {
return (input.value == "");
});
if (allInput || allEmpty) {
alert('xxxxxx');
}
ES5 implementation:
var x = document.querySelectorAll('[id^="entryField"]');
var inputs = Array.from(x);
var allInput = inputs.every(function(input) {
return (input.value != "");
});
var allEmpty = inputs.every(function(input) {
return (input.value == "");
});
if (allInput || allEmpty) {
alert('xxxxxx');
}
EDIT: Support allInput or allEmpty. Overlooked at the beginning.
You can check with two every calls, below will be true if all elements are filled or none of the elements are filled - every other case will be false:
var x = document.querySelectorAll('[id^="entryField"]');
var allowed = function allOrNone(elements) {
return Array.prototype.every.call(x, function(v) {
return v.value && v.value != "";
}) || Array.prototype.every.call(x, function(v) {
return !v.value || v.value == "";
});
}
console.log(allowed(x));
<input id="entryFieldFoo">
<input id="entryFieldBar">

Why doesn't this .push work? (javascript)

var text = "some text jjke kjerk jker helmi kjekjr helmi ekjrkje helmi";
var myName = "helmi";
var hits = [];
for (var i = 0; i < text.length; i++) {
if (text[i] === 'h') {
for (var j = i; j < text[i] + myName.length; j+=1) {
}
hits.push('text[j]');
}
};
if (hits.length === 0) {
console.log("Your name wasn't found!");
}
else {
console.log(hits);
}
I want it to find "myName" in the "text", and push it. But it only pushes whatever I put in the parenthesis after hits.push. What is wrong with this code?
But it only pushes whatever I put in the parenthesis after hits.push
Exactly, which is why you don't want to put a string in there:
hits.push('text[j]');
but a variable value:
hits.push(text[j]);
for (var i = 0; i < text.length; i++) {
if (text[i] === 'h') {
for (var j = i; j < text[i] + myName.length; j+=1) {
hits.push(text[j]);
}
}
your code has bracket problem and in some case you're doing wrong .
You can use split function. It gives you an opportunity to check your name word by word instead of checking your name character by character.
var text = "some text jjke kjerk jker helmi kjekjr helmi ekjrkje helmi";
var myName = "helmi";
var hits = [];
var texts = text.split(" ");
for (var i = 0; i < texts.length; i++) {
if (texts[i] === myName) {
hits.push(texts[i]);
}
}
if (hits.length === 0) {
console.log("Your name wasn't found!");
}
else {
console.log(hits);
}
Simple example for what you are trying to do is
if(text.indexOf(myName)!=-1)
console.log(myName);
else
console.log("Your name wasn't found");

use one() within a for loop jquery

for (var i = 0; i < res.length; i++) {
if (res[i] != 'a' && res[i] != '-b') {
} else {
// alert will triger multiple times here
alert();
}
}
I loop through an array to check something, how can I run once in the else statement? if I put a function there, it will trigger multiple times.
You need to break; after your else-action.
Try this:
for (var i = 0; i < res.length; i++) {
if (res[i] != 'a' && res[i] != '-b') {
} else {
// alert will triger multiple times here
alert();
break;
}
}
You can use a flag to indicate whether the else block was executed, if so don't execute it again
var run = true;
for (var i = 0; i < res.length; i++) {
if (res[i] != 'a' && res[i] != '-b') {
} else if (run) {
// alert will triger multiple times here
alert();
run = false;
}
}
You could use a simple boolean flag:
// Introduce the flag before your for loop
var process = true;
for (var i = 0; i < res.length; i++) {
if (res[i] != 'a' && res[i] != '-b') {
} else if(process) {
// alert will triger multiple times here
alert();
process = false; // Reset the process flag
}
}

Trying to add and remove items from an array

The script works by asking user for add or remove an item in the array. Then asks to continue this loop. The problem here is that my script doesn't seem to match my user's input (removeItem) to the item in the list (myList[i]). I'm at a lost as to why this is failing to match.
// new method for removing specific items from a list
Array.prototype.remove = function(from,to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
printList = function() {
var listLength = myList.length;
for (i = 0; i < listLength; i++) {
document.write(i + ":");
document.write(myList[i] + "<br/>");
};
document.write("<br/><br/>");
};
// initial list
var myList = new Array ();
if (myList.length === 0) {
document.write("I have " + myList.length + " item in my list. It is: <br/>");
}
else {
document.write("I have " + myList.length + " items in my list. They are: <br/>");
}
printList();
var continueAdding = "yes";
var askToContinue = "";
while (continueAdding === "yes") {
// loop
var askUser = prompt("What do you want to [A]dd or [R]emove an item to your inventory?").toUpperCase();
switch (askUser) {
case "A": { // add an user specified item to the list
var addItem = prompt("Add something to the list");
myList.push(addItem);
printList();
break;
}
case "R": { // remove an user specified item from the list
var removeItem = prompt("what do you want to remove?");
var listLength = myList.length;
for (i = 0; i < listLength; i++) {
if (removeItem === myList[i]) {
document.write("I found your " + removeItem + " and removed it.<br/>");
myList.remove(i);
}
else {
document.write(removeItem + " does not exist in this list.<br/>");
break;
}
if (myList.length === 0) {
myList[0] = "Nada";
}
};
printList();
break;
}
default: {
document.write("That is not a proper choice.");
}
};
askToContinue = prompt("Do you wish to continue? [Y]es or [N]o?").toUpperCase(); // ask to continue
if (askToContinue === "Y") {
continueAdding = "yes";
}
else {
continueAdding = "no";
}
}
Your loop never allows it to loop through all the items, because it breaks on the first iteration if the item doesn't match.
The break statement should be in the if block, not in the else block - use this instead:
for (i = 0; i < listLength; i++) {
if (removeItem === myList[i]) {
document.write("I found your " + removeItem + " and removed it.<br/>");
myList.remove(i);
break;
}
else {
document.write(removeItem + " does not exist in this list.<br/>");
}
};
if (myList.length === 0) {
myList[0] = "Nada";
}
Also, note that it's looking for an exact match, case sensitive, same punctuation, and everything. If you want it to be a little more lenient you'll need to modify the script to convert both strings to lowercase and strip punctuation before comparing them.
Edit: Just noticed something else -- testing for an empty list needs to be done outside the loop. I updated the above code to reflect this.

Categories