Open PHP without breaking JavaScript loop - javascript

I'm iterating over a table's values to modify them if any changes have been made by the user.
Currently I have something similar to:
for (var i = 0; i < rows.length - 1; i++) {
if (item[5]) {
window.open("modify.php?id=" + id + "&delete=true");
}
}
My question is how I can connect to my modify.php file without breaking the for loop. I tried with
window.location("modify.php?id=" + id + "&delete=true");
too but that's the same story.
I considered using window.open and setting the new windows dimension's to something very small so it appears hidden and closing it again after my PHP has finished executing.
This however seems ridiculously dumb hence why I'm wondering what a/the better approach would be?

It sounds like you want to be using AJAX here. For conciseness, I'll show you what I mean using jQuery.ajax:
for (var i = 0; i < rows.length - 1; i++) {
if (item[5]) {
$.ajax("modify.php?id=" + id + "&delete=true");
}
}
This sends an asynchronous HTTP GET request to the URL provided.
AJAX can be done in vanilla JavaScript too but for reasons of convenience and compatibility I would recommend using a library.

As with any other code, why not simply copy the instructions for later use?
var openItems = [], i;
for (i = 0; i < rows.length - 1; i++) {
if (item[5]) {
openItems.push(id); // Don't open the window just yet, just copy to array
}
}
for (i = 0; i < openItems.length; i++) {
window.open("modify.php?id=" + openItems[i] + "&delete=true");
}
And if you consider that you'd only be opening one window anyway (and you want the first item to be it), then simply do the following:
var openID, i;
for (i = 0; i < rows.length - 1; i++) {
if (item[5]) {
openID = i;
break; // No need to continue iterations
}
}
if (openID) {
window.open("modify.php?id=" + openID + "&delete=true");
}
If you want the last item to be the one you open, simply remove the break; statement.

Related

Code is getting stuck somewhere in a succession of for-loops and I'm not sure why

EDIT - I changed the code to correctly declare variables below but nothing seems to have changed
I've written code using a for-loop that has to satisfy a number of criteria before executing what's within it. The problem is that, somewhere along the way, the code is getting stuck inside one of the loops, causing the computer to crash.
I've tried breaking the loop but this doesn't seem to help.
function compareKeypoints(varifiedKeypoints) {
outer_loop: for (i = 0; i < varifiedKeypoints.length; i++) {
let initialKeypoint = varifiedKeypoints[i];
for (j = 0; j < varifiedKeypoints.length; j++) {
let comparisonKeypoint = varifiedKeypoints[j];
if (initialKeypoint.part != comparisonKeypoint.part) {
if (Math.abs(comparisonKeypoint.position.x - initialKeypoint.position.x) <= 20
&& Math.abs(comparisonKeypoint.position.y - initialKeypoint.position.y) <= 20) {
if (keypointsCompatible(initialKeypoint.part, comparisonKeypoint.part)) {
console.log("Activating part: " + initialKeypoint.part);
console.log("Activated part: " + comparisonKeypoint.part);
let keypointPair = {
point_1: initialKeypoint.part,
point_2: comparisonKeypoint.part
}
console.log("Pushing parts!");
activeParts.push(keypointPair);
console.log("breaking loop!");
break outer_loop;
console.log("Loop NOT broken!!");
}
}
}
}
}
if (activeParts.length > 0) {
console.log(activeParts);
}
}
function keypointsCompatible(keypoint_1, keypoint_2) {
var outcome = true;
if (activeParts.length > 0) {
compatibility_loop: for (i = 0; i < activeParts.length; i++) {
if (Object.values(activeParts[i]).includes(keypoint_1) && Object.values(activeParts[i]).includes(keypoint_2)) {
console.log(keypoint_1 + " and " + keypoint_2 + " are not compatible because they already exist as " + activeParts[i].point_1 + " and " + activeParts[i].point_2 + " respectively");
outcome = false;
break compatibility_loop;
console.log("Compatibility NOT broken!!");
}
}
}
console.log("Compatibility outcome is " + outcome);
return outcome;
}
The code is suppose to take two values in the same array and compare them. If a number of conditions are met, including if they're a certain distance apart from one another, they will be pushed into a secondary array. If the values already appear in the secondary array, which the keypointCompatible function is suppose to determine, the loop should either continue looking for other candidates or stop before being called again. For some reason, however, the code is getting stuck within the keypointCompatible function when it detects that the values have already appeared in the secondary array and the console will repeatedly print "Compatibility is false" until the browser crashes.
Working Solution
Use let or const instead of var or nothing. Your issue may be related to closures and variables reused between loops. Make sure you use let or const in your loops too. for (let i=0).
When you use let or const, the runtime will create a new instance every time the block or loop iterates. However, using var will reuse the internal allocation.
So what happens with the standard var is the multiple closures or loops each use the same instance of the variable.
Unless you want the var behavior, always use let or const.
Another Solution
Put a newline after the label compatibility_loop
Still Another Solution
The first function is pushing into activeParts. The second function is looping activeParts. This can go on forever, or longer than expected. Pushing into the array could possibly make the loop limit never reached.
Put a log on the length of activeParts in the second function to see if it is growing out of control.
Your code should be OK if varifiedKeypoints.length has reasonable value. And all internal variables are declared properly!
You have two loops (this inner can start at j=i+1 to save time and multiple calculations) with few conditions inside.
function compareKeypoints(varifiedKeypoints) {
outer_loop: for (let i = 0; i < varifiedKeypoints.length; i++) {
let initialKeypoint = varifiedKeypoints[i];
for (let j = i+1; j < varifiedKeypoints.length; j++) {
let comparisonKeypoint = varifiedKeypoints[j];

Javascript Performance improvement

I am Using Jquery plugin to show a dropdown which looks like this
Now in the edit page, this drop-down opens with checked checkboxes, I do this with the help of Javascript which is as below
var setValues = $("#SelectedFrameworks").val().split(",");
for (var i = 0; i < setValues.length; i++) {
var selectedElement = $("#frameworksDropDown").find('*[data-id="' + setValues[i] + '"]');
selectedElement.find("i").addClass("fa-check-square-o").removeClass("fa-square-o");
SelectParent(selectedElement);
}
function SelectParent(_element) {
var count = 0;
for (var i = 0; i < $(_element).parent().children().length; i++) {
if ($(_element).parent().children().eq(i).find("i").attr("class") == "fa select-box fa-check-square-o") {
count++;
}
}
if (count == $(_element).parent().children().length) {
$(_element).closest("ul").siblings("i").click();
}
}
I store this value first in the hidden field then use it to Check the checkboxes. (as shown in the code)
Now the problem is, it takes too much time when data is a lot. this causes the page to hang.
I found that operation
selectedElement.find("i").addClass("fa-check-square-o").removeClass("fa-square-o");
takes too much time. how can I optimize this code to have a better result
EDIT
Here is the HTML for this dropdown.
Note: this HTML is autogenarated.
Thanks.
So one of the big issues with this code is the amount of times you're calling the DOM. Everytime you do $(el) you're calling document.getElementByClassName or id etc. Which is gonna be slow and is unnecessary to make that many calls.
So you can change
function SelectParent(_element) {
var count = 0;
for (var i = 0; i < $(_element).parent().children().length; i++) {
if ($(_element).parent().children().eq(i).find("i").attr("class") == "fa select-box fa-check-square-o") {
count++;
}
}
if (count == $(_element).parent().children().length) {
$(_element).closest("ul").siblings("i").click();
}
}
To this, which accesses the DOM once, stores a reference to the element. This will cut down on the amount of DOM calls you make. The biggest advantage to this is of course, speed. I always make a point of naming jquery variables beginning with $ so that it's much easier and quicker to tell what that variable is in the future, or if someone else comes to work on your code.
function SelectParent(_element) {
var count = 0;
var $element = $(_element);
var $children = $element.parent().children();
for (var i = 0, length = $children.length; i < length; i++) {
if ($children.eq(i).find("i").attr("class") == "fa select-box fa-check-square-o") {
count++;
}
}
if (count == $children.length) {
$element.closest("ul").siblings("i").click();
}
}
Now of course you can refactor the rest to speed it up ;)

Using .push stops for loop from executing

I have a for loop that suddenly stops working when I try to push to an array. The best way to describe what's going on is just to show my code and try an explain what's going on.
for (var i = 0; i < childs.length; i++) {
if (childs[i].length > 0) {
for (var j = 0; j < amountsValue[i].options.custValues.length; j++) {
var label = amountsValue[i].options.custValues[j].label;
var value = amountsValue[i].options.custValues[j].value;
for (var k = childs[i].length - 1; k >= 0; k--) {
if (childs[i][k].attributes[label] != value) {
childBackup.push(childs[i][k]);
childs[i].splice(k, 1);
}
}
}
amountsValue[i].id = childs[i][0].attributes.internalid;
childs.push(childBackup);
}
}
What's happening is I am looping through an array of items which may or may not have custom options available such as different sizes or colours. The loop will check to see if there are any then get the value and label from the array.
After this, we then loop again to try and match up the values with option values stored within a separate model. The plan is to check if the value is the same as the one stored and if not then splice it from the array. The process of elimination should eventually leave only one option left and that will be used to get the internalid.
During this a back up of the spliced objects is kept so that they can be appended to the array again so that the user can change the option they want. The problem is using childs.push(childBackup) stops the browser form reading the options on amountsValue. This works if the code is removed or it is pushed into another index so I'm really not sure why it isn't working.
Does anyone have any suggestions on how to get this working? I'm sorry if this doesn't make much sense, I've tried to explain it as best I can but let me know if anything needs to be cleared up.
EDIT: I have fixed the issue. Thank you to everyone who suggested ways to solve the problem. As others said, I was trying to manipulate the array I was looping through and changing the length on it. So that part of the code was taken outside the loop and after the initial loop another loop was set up which contained the following code:
for (var i = 0; i < childBackup.length; i++) {
childs[0].push(childBackup[i]);
}
It now works as intended. Thank you.
You are manipulating the array you are looping through.
var count = childs.length;
for (var i = 0; i < count; i++) {
if (childs[i].length > 0) {
for (var j = 0; j < amountsValue[i].options.custValues.length; j++) {
var label = amountsValue[i].options.custValues[j].label;
var value = amountsValue[i].options.custValues[j].value;
for (var k = childs[i].length - 1; k >= 0; k--) {
if (childs[i][k].attributes[label] != value) {
childBackup.push(childs[i][k]);
childs[i].splice(k, 1);
}
}
}
amountsValue[i].id = childs[i][0].attributes.internalid;
childs.push(childBackup);
}
}

Having trouble with jQuery's click() method. and event.data

I'm building small script that lets you change the background image of a page on the fly for design comparisons.
I have a hacky version up and running, but I'm trying to solve this small issue just so I can improve my JS/jQuery skills.
Please look at the jsfiddle here: http://jsfiddle.net/misteroh/Yh22B/6/
The part of the code I'm trying to fix is here:
var clickBind = function() {
for (var j = 0; j < background.length; j++) {
background[j].css({'background': 'url("' + directory + clickBind.data.value + '.jpg")', 'background-size':'cover', 'background-attachment':'fixed'});
crumbSearch[0].css('background', '#F8F8F8');
crumbSearch[1].css({'background': '#F8F8F8'});
if (homepage) {
$('.flexslider').css({'margin-top': '25px'});
}
}
};
for (i = 1; i <= bgOptions; i++) {
bgSwitch.append('<li id="image'+ i + '"></li>');
button.push($('li:last', bgSwitch));
button[button.length - 1]
.css({'background': 'url("' + directory + i + '.jpg")', 'background-size':'cover'})
.click({ value: i }, clickBind);
}
You see that for loop on the bottom? How can I pass the current iteration's value of "i" to the function at the top? I'm assuming the answer is something along the lines of this: http://api.jquery.com/event.data/
My logic behind the code is that in each iteration of the bottom for loop, button[button.length - 1] will be bound with the click event and the clickBind function would use the value of "i" to complete the url of the background image.
Obviously that's not happening. If I simply use "i" in the clickBind's for loop, console.log shows that the value of "i" is always 8.
Please help!
There are a few things you should do to hopefully fix this:
First, your for-loop should look like below.
for (i = 1; i <= bgOptions; i++) {
bgSwitch.append('<li id="image'+ i + '"></li>');
button.push($('li:last', bgSwitch));
button[button.length - 1]
.css({'background': 'url("' + directory + i + '.jpg")', 'background-size':'cover'})
// CHANGED:
.click({value:i},function(event) {
clickBind(event.data.value);
});
}
Next (probably obvious step) is to tell your clickBind function to use this i instead of clickBind.data.value:
var clickBind = function(i) {
for (var j = 0; j < background.length; j++) {
// Replace clickBind.data.value with i:
background[j].css({'background': 'url("' + directory + i + '.jpg")', 'background-size':'cover', 'background-attachment':'fixed'});
crumbSearch[0].css('background', '#F8F8F8');
crumbSearch[1].css({'background': '#F8F8F8'});
if (homepage) {
$('.flexslider').css({'margin-top': '25px'});
}
}
};
Here is a fiddle that works for me
Let me know if this works for you!
Edit: I changed some stuff around in your last for-loop. I am not used to strict mode, so hopefully this method will work for you. If not, we can pursue other options!

Javascript Wait for Ajax Content Load

I am newbie to javascript and am writing to traverse a DOM . The page uses Checkboxes to filter results. Results are displayed using Ajax. There are 4 level of checkboxes.
Grand Parent
Parent
Child
Grand Child .
For each level, I want the javascript to click the checkbox and WAIT for the content to load.
Right now it checks and traverses the whole DOM , but does not wait .
What I want is , that when the element is CLICKED , next function decideread() should be called only when Ajax results have been refreshed.
I have tried using setTimeOut and other delay methods, but they say it's single threaded so that won't work. Any ideas ?
for (i = 0; i < mgtNode.length; i++) {
mgtNode[i].click();
for (j = 1; j < stateNode.length; j++)
{
stateNode[j].click();
var read = decideRead();
if (read)
{
alert('we have read the data, now skip further reading below');
stateNode[j].click(); // we have read the data, now skip further reading below.
continue;
}
for (k = 0; k < inTypeNode.length; k++) {
inTypeNode[k].click();
var read = decideRead();
if (read)
{
alert('we have read the data, now skip further reading below');
inTypeNode[k].click();
continue;
}
for (l = 0; l < jobNode.length; l++)
{
jobNode[l].click();
while (true) {
if (new Date() - startTime >= 5000) {
break;
}
}
saveData();
jobNode[l].click();
}
inTypeNode[k].click();
}
stateNode[j].click();
}
mgtNode[i].click();
}
You should use the onreadystatechange for this. Check this http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp

Categories

Resources