use one() within a for loop jquery - javascript

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
}
}

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 */ }

Pop up a warning when the same item is entered twice on a sales order when the order is created/edited

I am trying to do a pop-up warning before the sales order is saved if the exact same item is entered twice when the order is created/modified on Netsuite. However, there is no window popping up and I am not sure what is wrong with the script. Here is what I got:
function validateitem (type){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (type == 'item' && numLine > 0) {
for(var i = 0; i < numLine; i++) {
var itemSO = {};
itemSO.id = nlapiGetLineValue('item','item',i);
if (itemSO.id != null && itemSO.id !=''){
for (var j = 0; j < numLine; j++){
if(itenArr.indexOf(itemSO[i].id) === -1) {
itemArr.push(itemSO[i].id);}
else{
if (!confirm('You have entered a duplicate item for this sales order. Continue?'))
{
flag = false;
}
}
}
}
}
}
return flag;
}
Can somebody help, please?
Here is a slightly edited version:
function validateitem (){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (numLine > 0) {
for(var i = 1; i <= numLine; i++) {
var itemSO = nlapiGetLineItemValue('item','item',i);
if (itemSO != null && itemSO !=''){
for (var j = 1; j <= numLine; j++){
if(itemArr.indexOf(itemSO[i]) === -1) {
itemArr.push(itemSO[i]);}
else{
flag = false;
}
}
}
}
}
if (flag == false){
alert('You have entered the same item twice.Continue?');
}
return flag;
}
This is the complete after-edit code that works:
function validateitem (){
var flag = true;
var numLine = nlapiGetLineItemCount('item');
itemArr = [];
if (numLine > 0) {
for(var i = 1; i <= numLine; i++) {
var itemSO = nlapiGetLineItemValue('item','item',i);
if (itemSO != null && itemSO !=''){
for (var j = i+1; j <= numLine; j++){
var itemSOplus = nlapiGetLineItemValue('item','item',j);
if(itemSO === itemSOplus) {
flag = false;
}
}
}
}
}
if (flag == false){
alert('You have entered the same item twice.Continue?');
}
return flag;
}
Thanks to Krypton!!
As per SuiteAnswers ID 10579, there are no paramters passed to the saveRecord client event. Therefore when your code checks the following:
if (type == 'item' && numLine > 0)
it finds that type equals undefined, so the condition is not met and the code will jump straight down to return flag which has been set to true.
Also note that in SuiteScript 1.0, line indexes start from 1 - not 0 as your code seems to assume.
EDIT - adding comment to form part of this answer:
I'd like to understand your logic behind itemSO[i] - as itemSO is not an array. Why not just compare the item from the current line of the inner loop with the current line of the outer loop and set the flag false if they match? Also, the inner loop need only start from j = i + 1 as the previous lines would have already been compared.

scrollIntoView first found element within loop

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;
}
}
}
}

Submit form only if all required fields are full?

I want to do form.submit() but only if all form items with the required attribute are full.
I was thinking on simpy iterating through the form children in search for the attribute, but I'm not sure how to do it since there might be nested elements and such. And probably there is an easier way to do it.
this.form_is_full = function(form){
for (var i = 0; i < form.elements.length; i++){
if(form.elements[i].getAttribute("required") && form.elements[i].value=="")
{
// If has attribute required and is blank return false
}
}
return true;
}
How can I do this?
function Validate()
{
// create array containing textbox elements
//for example:
var inputs = [document.getElementById('fname'),
document.getElementById('lname'), document.getElementById('email'),
document.getElementById('messagetxt')];
var error;
for(var i = 0; i<inputs.length; i++)
// loop through each element to see if value is empty
{
if(inputs[i].value == '')
{
error = 'Please complete all fields.';
alert(error);
return false;
}
}
}
Try this:
$('#YourFormId').submit(function(e) {
if ($.trim($("#YourFormId input").val()) === "") {
e.preventDefault();
alert('you did not fill out one of the fields');
}
});
This is what I did:
this.validate_form = function(form){
for (var i = 0; i < form.elements.length; i++){
if(form.elements[i].value == "" && form.elements[i].getAttribute("name") && form.elements[i].hasAttribute("required"))
{
return false;
}
}
return true;
}

Boolean's value is acting as true but is listed as false?

I'm creating a simple tic-tac-toe game and I have a boolean called winAlert that if it is true it should alert the player that they have won. This works correctly for the most part, but there is one instance where it does not. If the game is won and all of the cells are filled, the console logs that winAlert's value is false, but it still alerts the player that they have won, as if it were true. Could someone look over this code and see why this is behaving in this way? http://jsfiddle.net/Z5c9P/3/
This function is where I think the problem lies, but I don't know for sure.
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
for (var j = 0; j < winConditions[i].length; j++) {
winAlert = false;
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
winAlert = true;
break;
}
}
if (!winAlert) break;
}
if (winAlert) {
alert(currentPlayer + " wins!");
break;
}
}
};
Here's the code that calls this function:
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
This is happening because your code does the following:
storeMoves();
determineWin(xMoves);
determineWin(oMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
So if X ever wins the game, determineWin(xMoves) will set the variable to true, and determinWin(oMoves) will set it back to false, all before the console.log()
One way to solve this would be to only check for a win for the current player's moves:
storeMoves();
determineWin(currentPlayer == 'X' ? xMoves : yMoves);
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
You have called determineWin on each player. so if x wins, determineWin(oMoves); will make winAlert false. Is this the problem?
Maybe you should create a new determineWin which only called once to determine who is the winner.
this code will just skip another user(so winAlert is still true) when his cell is less than 3, so this problem doesn't need fill all cells but just each player has more than 3 cells.
if (winConditions[i].length > pMoves.length) {
continue;
}
i change a little your code Fiddle
var determineWin = function (pMoves) {
for (var i = 0; i < winConditions.length; i++) {
if (winConditions[i].length > pMoves.length) {
continue;
}
winAlert = false;
matches = 0;
for (var j = 0; j < winConditions[i].length; j++) {
for (var k = 0; k < pMoves.length; k++) {
if (pMoves[k] === winConditions[i][j]) {
matches++;
}
}
}
if (matches == 3) return true;
}
return false;
};
and then
$('td').one('click', function () {
turnCount += 1;
setCurrentPlayer();
$(this).text(currentPlayer);
cellTracker = $(this).attr('id');
storeMoves();
if (determineWin(xMoves)){ // this is changed
alert("X Win")
return;
};
if (determineWin(oMoves)){
alert("O Win")
return;
};
if(turnCount === 9 && winAlert === false) {
alert("Tie game!");
}
console.log(turnCount, xMoves, oMoves, winAlert);
});
** Updated to clarify

Categories