portabletelly Posted yesterday at 09:13 PM Share Posted yesterday at 09:13 PM Ok here goes hope i can explain this correctly. Im building an internal quoting system THE PROBLEM: . These buttons 1, 2, and 3 when code is inspected all have the correct quote_item_id However when you click on any change quantity the javascript brings up the popup with the very last line items quote_item_id every time. THE CODE: This bit of code is whats doing the work // Loop if (count($quoteItems) > 0) { echo "<!-- Entering quoteItems loop -->"; foreach ($quoteItems as $item) { echo "<!-- Looping item: quote_item_id = {$item['quote_item_id']} -->"; echo "<!-- DEBUG quote_item_id: {$item['quote_item_id']} -->"; // 🔍 Debug line $isCustom = $item['is_custom_item'] ?? 0; $productName = $isCustom ? 'Custom Item' : ($item['product_name'] ?? '—'); $description = $isCustom ? ($item['custom_description'] ?? '—') : ($item['description'] ?? '—'); echo "<tr>"; echo "<td>" . htmlspecialchars($productName) . "</td>"; echo "<td>" . htmlspecialchars($description) . "</td>"; // Quantity with 🛠 button $quoteItemId = (int)$item['quote_item_id']; echo "<td>" . htmlspecialchars($item['quantity']) . ""; echo "<button type=\"button\" onclick=\"openEditQuantityPopup(" . (int)$item['quote_item_id'] . ", " . (int)$quoteId . ")\" title=\"Edit Quantity\" style=\"border: none; background: none; cursor: pointer; font-size: 14px;\"> 🛠 </button>"; echo "</td>"; echo "<td>" . number_format((float)$item['WSExPerUnit'], 2) . "</td>"; echo "<td>" . number_format((float)$item['SellExPerUnit'], 2) . "</td>"; echo "<td>" . number_format((float)$item['SellTotalEx'], 2) . "</td>"; echo "<td>" . number_format((float)$item['SellTotalInc'], 2) . "</td>"; echo "<td>" . number_format((float)$item['GSTAmount'], 2) . "</td>"; // Delete button echo "<td style='text-align: center;'> <form method='POST' action='Quotes.php?action=edit_quote&id=" . (int)$quoteId . "' onsubmit=\"return confirm('Are you sure you want to delete this item?');\" style='display:inline;'> <input type='hidden' name='delete_item_id' value='" . (int)$item['quote_item_id'] . "'> <button type='submit' style='border:none; background:none; color:red; font-size:16px;'>❌</button> </form> </td>"; echo "</tr>"; } } else { echo "<tr><td colspan='9' style='text-align:center;'><em>No items added yet.</em></td></tr>"; } And this is the javascript calling the popup window function openEditQuantityPopup(quoteItemId, quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( `Quotes/Edit_Quote_Quantity.php?quote_item_id=${quoteItemId}"e_id=${quoteId}`, "EditQuoteQuantity", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } and this is the Edit_Quote_Quantity.php that run when button is clicked <?php var_dump($_GET); include '../Functions/db_con.php'; $quoteItemId = $_GET['quote_item_id'] ?? null; $quoteId = $_GET['quote_id'] ?? null; if (!$quoteItemId || !$quoteId) { echo "Missing parameters."; exit; } // Get current quantity $stmt = $pdo->prepare("SELECT quantity FROM QuoteItems WHERE quote_item_id = ?"); $stmt->execute([$quoteItemId]); $item = $stmt->fetch(PDO::FETCH_ASSOC); $currentQty = $item['quantity'] ?? 1; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $newQty = (int)$_POST['quantity']; // Update quantity $update = $pdo->prepare("UPDATE QuoteItems SET quantity = ? WHERE quote_item_id = ?"); $update->execute([$newQty, $quoteItemId]); echo "<script>window.opener.location.reload(); window.close();</script>"; exit; } ?> <!DOCTYPE html> <html> <head> <title>Edit Quantity</title> </head> <body style="font-family: Arial; padding: 20px;"> <h3>Edit Quantity</h3> <form method="POST"> <label>New Quantity:</label><br> <input type="number" name="quantity" value="<?= htmlspecialchars($currentQty) ?>" min="1" required><br><br> <button type="submit">Update</button> </form> </body> </html> The process actually works however it always changes the quantity to the last line item called up in the foreach loop. Been racking my brains for a day on this one trying to work it out. Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/ Share on other sites More sharing options...
mac_gyver Posted 22 hours ago Share Posted 22 hours ago (edited) a test page works for me (uses the correct quoteItemId matching the clicked button, both in the javascript and in the php code) in chrome, edge, and firefox, but i don't have all the code on your page. the only changes i made to the //loop code is to add a <table> tag before it and comment out the 5 lines with number_format() calls, since i didn't want to make up fake data to loop over for these. do you have some event listener for 'buttons' that could be affecting this? this is acting like some broken markup is causing all those buttons to call the last openEditQuantityPopup(...), instead of the correct one or all the buttons are being clicked and you are seeing the end result from the last such operation. i would console.log the quoteItemId value inside the openEditQuantityPopup() faction, so that you can see how many times it gets called, and with what value as an input. in the end, you will need to post all the code on that page that's necessary to reproduce the problem. Edited 22 hours ago by mac_gyver Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/#findComment-1653282 Share on other sites More sharing options...
portabletelly Posted 21 hours ago Author Share Posted 21 hours ago <?php function renderQuoteTopButtons() { echo <<<HTML <div style="margin-bottom: 20px;"> <button onclick="startNewQuote()">📝 New Quote</button> <button onclick="loadTemplateQuote()">📄 Quote from Template</button> <button onclick="cloneQuote()">📋 Clone Quote</button> </div> HTML; } function renderNewQuoteFormWithClientSearch() { echo <<<HTML <div id="newQuoteForm" style="display: block; margin-top: 20px;"> <h3>New Quote Details</h3> <form method="POST" action="Quotes.php?action=create_quote"> <label for="clientSearch">Search Customer:</label><br> <input type="text" id="clientSearch" name="clientSearch" oninput="getSuggestions(this.value)" autocomplete="off" required> <input type="hidden" name="selectedCustomerId" id="selectedCustomerId"> <div id="suggestions"></div><br> <label for="quoteTitle">Quote Title:</label><br> <input type="text" id="quoteTitle" name="quoteTitle" required><br><br> <label for="quoteDate">Quote Date:</label><br> <input type="date" id="quoteDate" name="quoteDate" required><br><br> <label for="quoteNotes">Notes (Optional):</label><br> <textarea id="quoteNotes" name="quoteNotes" rows="4" cols="50"></textarea><br><br> <button type="submit">Create Quote</button> </form> </div> HTML; // JavaScript for showing the form and handling customer selection echo <<<JS <script> function startNewQuote() { document.getElementById('newQuoteForm').style.display = 'block'; } function getSuggestions(query) { if (query.length === 0) { document.getElementById("suggestions").innerHTML = ""; return; } var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("suggestions").innerHTML = this.responseText; } }; xhttp.open("GET", "Functions/get_customer_suggestions.php?q=" + encodeURIComponent(query), true); xhttp.send(); } function selectSuggestion(id, name) { document.getElementById("clientSearch").value = name; document.getElementById("selectedCustomerId").value = id; document.getElementById("suggestions").innerHTML = ""; } </script> JS; } function renderEditQuoteForm($pdo, $quoteId) { // Fetch quote and customer data $stmt = $pdo->prepare("SELECT q.*, c.CompanyName FROM Quote q JOIN Customer c ON q.CustomerID = c.CustomerID WHERE q.QuoteID = ?"); $stmt->execute([$quoteId]); $quote = $stmt->fetch(PDO::FETCH_ASSOC); if (!$quote) { echo "<p>❌ Quote not found.</p>"; return; } // 💰 Calculate total profit and margin $totalProfit = $quote['QuoteEXTotal'] - $quote['QuoteOurBuytotalEx']; $profitMargin = $quote['QuoteEXTotal'] > 0 ? round(($totalProfit / $quote['QuoteEXTotal']) * 100, 2) : 0; // Fetch contacts for dropdown $contacts = $pdo->prepare("SELECT ContactID, FirstName, LastName FROM Contact WHERE CustomerID = ?"); $contacts->execute([$quote['CustomerID']]); // Fetch sales people $techs = $pdo->query("SELECT TechnicianID, FirstName, LastName FROM Technician")->fetchAll(PDO::FETCH_ASSOC); // Fetch statuses $statuses = $pdo->query("SELECT QuoteStatusID, StatusDescription FROM QuoteStatus")->fetchAll(PDO::FETCH_ASSOC); echo "<br><br>"; echo "<form method='POST' action='Quotes.php?action=update_quote&id={$quoteId}'>"; // 🌟 Header layout (3 columns) echo <<<HTML <br><br> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;"> <!-- Customer name (left) --> <div style="flex: 1; text-align: left;"> <strong>Customer:</strong> {$quote['CompanyName']} </div> <!-- Quote Title (center-left) --> <div style="flex: 1; text-align: center;"> <span>{$quote['QuoteTitle']}</span> <button type="button" onclick="openQuoteTitlePopup({$quote['QuoteID']})" style="border: none; background: none; cursor: pointer;">✏️</button> </div> <!-- Contact (center-right) --> <div style="flex: 1; text-align: center;"> <label><strong>Contact:</strong></label> <span> HTML; // Close heredoc to insert PHP logic $contactName = ''; $contactStmt = $pdo->prepare("SELECT FirstName, LastName FROM Contact WHERE ContactID = ?"); $contactStmt->execute([$quote['QuotecontactID']]); if ($contactRow = $contactStmt->fetch(PDO::FETCH_ASSOC)) { $contactName = htmlspecialchars($contactRow['FirstName'] . ' ' . $contactRow['LastName']); } echo $contactName ?: "<em>No Contact Selected</em>"; echo " <button type='button' onclick='openContactEditPopup({$quoteId})' title='Edit Contact' style='margin-left: 6px; font-size: 14px; border: none; background: none; cursor: pointer;'>👤</button>"; echo "</span><br><label><strong>Sales Person:</strong></label> <span>"; // Insert PHP logic for Sales Person $salesPersonName = ''; $salesStmt = $pdo->prepare("SELECT FirstName, LastName FROM Technician WHERE TechnicianID = ?"); $salesStmt->execute([$quote['SalesPerson']]); if ($salesRow = $salesStmt->fetch(PDO::FETCH_ASSOC)) { $salesPersonName = htmlspecialchars($salesRow['FirstName'] . ' ' . $salesRow['LastName']); } echo $salesPersonName ?: "<em>Not Assigned</em>"; echo " <button type='button' onclick='openSalesPersonEditPopup({$quoteId})' title='Edit Sales Person' style='margin-left: 6px; font-size: 14px; border: none; background: none; cursor: pointer;'>👤</button>"; echo "</span>"; // Resume heredoc echo <<<HTML </span> HTML; $escapedNotes = htmlspecialchars($quote['Notes']); // Close previous heredoc and resume HTML echo <<<HTML </select> </div> <!-- Quote ID and Date Created (right) --> <div style="flex: 1; text-align: right;"> <strong>Quote #{$quote['QuoteID']}</strong><br> <small> <strong>Date Created:</strong> {$quote['DateCreated']} <button type="button" onclick="openDateEditPopup({$quote['QuoteID']})" style="border: none; background: none; cursor: pointer;"> 📅 </button> </small> <div style="margin-top: 6px;"> <small> <strong>Quote Expiry Date:</strong> {$quote['QuoteExpireyDate']} <button type="button" onclick="openExpiryEditPopup({$quote['QuoteID']})" style="border: none; background: none; cursor: pointer;"> 📅 </button> </small> </div> <div style="margin-top: 8px;"> <label style="font-size: 13px;"><strong>Quote Notes:</strong></label> <button type="button" onclick="openNotesPopup({$quote['QuoteID']})" title="View & Edit Notes" style="border: none; background: none; cursor: pointer;">🔍</button> </div> <!-- Hidden field to keep existing notes in form --> <input type="hidden" name="Notes" value="{$escapedNotes}"> HTML; // ✅ Determine current status text $currentStatusText = ''; foreach ($statuses as $status) { if ($status['QuoteStatusID'] == $quote['StatusID']) { $currentStatusText = htmlspecialchars($status['StatusDescription']); break; } } // ✅ Output status row echo <<<HTML <div style="margin-top: 8px;"> <label style="font-size: 13px;"><strong>Status:</strong></label> <span style="margin-left: 6px; font-weight: bold;">{$currentStatusText}</span> <button type="button" onclick="openStatusEditPopup({$quote['QuoteID']})" title="Edit Status" style="border: none; background: none; cursor: pointer;">✏️</button> </div> </div> </div> HTML; // 🔍 Quote Notes with popup button //$escapedNotes = htmlspecialchars($quote['Notes']); //echo <<<HTML //<div style="margin-bottom: 10px;"> // <label><strong>Quote Notes:</strong></label> // <button type="button" onclick="openNotesPopup({$quote['QuoteID']})" title="View & Edit Notes" style="margin-left: 8px; font-size: 16px;">🔍</button> //</div> //<!-- Hidden field to keep existing notes in form --> //<input type="hidden" name="Notes" value="{$escapedNotes}"> //HTML; // echo "</select><br><br>"; // 🧾 Quote Items Header and Add Button echo <<<HTML <hr style="margin: 20px 0;"> <div style="display: flex; justify-content: space-between; align-items: center;"> <h4 style="margin: 0;">Quote Items</h4> <button type="button" onclick="openAddItemPopup({$quote['QuoteID']})" title="Add Item" style="font-size: 16px; cursor: pointer;"> ➕ Add Item </button> </div> <table border="1" cellpadding="6" cellspacing="0" width="100%" style="margin-top: 10px; text-align: left;"> <thead> <tr> <th>Product Name</th> <th>Description</th> <th>Quantity</th> <th>WS Ex Per Unit</th> <th>Sell Ex Per Unit</th> <th>Sell Tot Ex</th> <th>Sell Tot Inc</th> <th>GST</th> <th>Del</th> </tr> </thead> <tbody> HTML; // Fetch quote items // Fetch quote items $itemsStmt = $pdo->prepare(" SELECT qi.quote_item_id, qi.product_id, qi.service_id, qi.WSExPerUnit, qi.SellExPerUnit, qi.SellTotalEx, qi.SellTotalInc, qi.quantity, qi.discount, qi.GSTAmount, qi.custom_description, qi.is_custom_item, p.product_name, p.description FROM QuoteItems qi LEFT JOIN Products p ON qi.product_id = p.product_id WHERE qi.quote_id = ? "); $itemsStmt->execute([$quoteId]); $quoteItems = $itemsStmt->fetchAll(PDO::FETCH_ASSOC); // Loop if (count($quoteItems) > 0) { echo "<!-- Entering quoteItems loop -->"; foreach ($quoteItems as $item) { echo "<!-- Looping item: quote_item_id = {$item['quote_item_id']} -->"; echo "<!-- DEBUG quote_item_id: {$item['quote_item_id']} -->"; // 🔍 Debug line $isCustom = $item['is_custom_item'] ?? 0; $productName = $isCustom ? 'Custom Item' : ($item['product_name'] ?? '—'); $description = $isCustom ? ($item['custom_description'] ?? '—') : ($item['description'] ?? '—'); echo "<tr>"; echo "<td>" . htmlspecialchars($productName) . "</td>"; echo "<td>" . htmlspecialchars($description) . "</td>"; // Quantity with 🛠 button $quoteItemId = (int)$item['quote_item_id']; echo "<td>" . htmlspecialchars($item['quantity']) . ""; echo "<button type=\"button\" onclick=\"openEditQuantityPopup(" . (int)$item['quote_item_id'] . ", " . (int)$quoteId . ")\" title=\"Edit Quantity\" style=\"border: none; background: none; cursor: pointer; font-size: 14px;\"> 🛠 </button>"; echo "</td>"; echo "<td>" . number_format((float)$item['WSExPerUnit'], 2) . "</td>"; echo "<td>" . number_format((float)$item['SellExPerUnit'], 2) . "</td>"; echo "<td>" . number_format((float)$item['SellTotalEx'], 2) . "</td>"; echo "<td>" . number_format((float)$item['SellTotalInc'], 2) . "</td>"; echo "<td>" . number_format((float)$item['GSTAmount'], 2) . "</td>"; // Delete button echo "<td style='text-align: center;'> <form method='POST' action='Quotes.php?action=edit_quote&id=" . (int)$quoteId . "' onsubmit=\"return confirm('Are you sure you want to delete this item?');\" style='display:inline;'> <input type='hidden' name='delete_item_id' value='" . (int)$item['quote_item_id'] . "'> <button type='submit' style='border:none; background:none; color:red; font-size:16px;'>❌</button> </form> </td>"; echo "</tr>"; } } else { echo "<tr><td colspan='9' style='text-align:center;'><em>No items added yet.</em></td></tr>"; } // Resume heredoc echo <<<HTML </tbody> </table> HTML; // 💰 Totals (read-only) echo "<br><label>Ex. Total:</label> {$quote['QuoteEXTotal']}<br>"; echo "<label>Tax Total:</label> {$quote['QuoteTaxTotal']}<br>"; echo "<label>Inc. Total:</label> {$quote['QuoteIncTotal']}<br>"; echo "<label>Our Buy Total (Ex):</label> {$quote['QuoteOurBuytotalEx']}<br><br>"; //echo "<button type='button' onclick='openUpdateTotalsPopup({$quoteId})'>📊 Update Totals</button>"; echo "<button type=\"button\" onclick=\"openUpdateTotalsPopup({$quoteId})\">📊 Update Totals</button>"; echo "<br><br><label><strong>Total Profit (Ex GST):</strong></label> \$" . number_format($totalProfit, 2) . "<br>"; echo "<label><strong>Profit Margin:</strong></label> {$profitMargin}%<br><br>"; echo "</form>"; echo <<<JS <script> function openNotesPopup(quoteId) { const width = 800; const height = 400; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; const screenHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Quote_Notes.php?id=" + quoteId, "QuoteNotes", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=yes,scrollbars=yes" ); } function openQuoteTitlePopup(quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; const screenHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Edit_Quote_Title.php?id=" + quoteId, "EditQuoteTitle", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openDateEditPopup(quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; const screenHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Edit_Quote_Date.php?id=" + quoteId, "EditQuoteDate", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openStatusEditPopup(quoteId) { const width = 400; const height = 250; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Edit_Quote_Status.php?id=" + quoteId, "EditQuoteStatus", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openExpiryEditPopup(quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Edit_Quote_Expiry.php?id=" + quoteId, "EditQuoteExpiry", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openContactEditPopup(quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Edit_Quote_Contact.php?id=" + quoteId, "EditQuoteContact", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openSalesPersonEditPopup(quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Edit_Quote_SalesPerson.php?id=" + quoteId, "EditQuoteSalesPerson", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openAddItemPopup(quoteId) { const width = 600; const height = 400; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( "Quotes/Add_Quote_Item.php?quoteId=" + quoteId, "AddQuoteItem", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } function openUpdateTotalsPopup(quoteId) { const width = 400; const height = 200; const left = (window.innerWidth - width) / 2; const top = (window.innerHeight - height) / 2; window.open( `Quotes/Update_Quote_Totals.php?quoteId=${quoteId}`, 'UpdateQuoteTotals', `width=${width},height=${height},top=${top},left=${left},resizable=no,scrollbars=no` ); } function openEditQuantityPopup(quoteItemId, quoteId) { const width = 400; const height = 200; const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; const screenWidth = window.innerWidth || document.documentElement.clientWidth || screen.width; const screenHeight = window.innerHeight || document.documentElement.clientHeight || screen.height; const left = dualScreenLeft + (screenWidth - width) / 2; const top = dualScreenTop + (screenHeight - height) / 2; window.open( `Quotes/Edit_Quote_Quantity.php?quote_item_id=${quoteItemId}"e_id=${quoteId}`, "EditQuoteQuantity", "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",resizable=no,scrollbars=no" ); } </script> JS; } ?> This is the full Quote_Functions.php code and this is the Quotes.php below that calls the functions. <?php //ini_set('display_errors', 1); //ini_set('display_startup_errors', 1); //error_reporting(E_ALL); session_start(); // Check if the user is logged in if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) { header("Location: /login.php"); exit(); } // Include necessary files include 'Functions/Common_Functions.php'; include 'Functions/Quote_Functions.php'; include 'Functions/db_con.php'; include 'Functions/Button_Quotes.php'; // Left menu buttons // ✅ Handle Quote Creation BEFORE output // ✅ Handle Quote Creation Before Output if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'create_quote') { $customerId = $_POST['selectedCustomerId'] ?? null; $quoteTitle = $_POST['quoteTitle'] ?? ''; $quoteDate = $_POST['quoteDate'] ?? ''; $quoteNotes = $_POST['quoteNotes'] ?? ''; if ($customerId && $quoteTitle && $quoteDate) { $stmt = $pdo->prepare("INSERT INTO Quote (CustomerID, QuoteTitle, Notes, DateCreated, StatusID, QuoteEXTotal, QuoteIncTotal, QuoteTaxTotal, QuoteOurBuytotalEx) VALUES (?, ?, ?, ?, ?, 0.00, 0.00, 0.00, 0.00)"); $stmt->execute([$customerId, $quoteTitle, $quoteNotes, $quoteDate, 1]); $newQuoteId = $pdo->lastInsertId(); header("Location: Quotes.php?action=edit_quote&id=" . $newQuoteId); exit(); } else { echo "❌ Missing required data."; exit(); } } // ✅ Display main menu func_header(); menu_items(); // ✅ Begin layout echo "<div class='main-container'>"; // ✅ Left-side menu echo "<div class='side-menu'>"; echo "<h4 style='color: white; text-align: center;'>Quotes</h4>"; renderQuotesButtons(); echo "</div>"; // ✅ Right-side content echo "<div class='right-content'>"; // ✅ Routing by action if (isset($_GET['action'])) { switch ($_GET['action']) { case 'new_quote': echo "<h2 style='text-align: left;'>Create New Quote</h2>"; renderQuoteTopButtons(); renderNewQuoteFormWithClientSearch(); break; case 'all_quotes': echo "<h2 style='text-align: left;'>All Quotes</h2>"; break; case 'pending_quotes': echo "<h2 style='text-align: left;'>Pending Quotes</h2>"; break; case 'approved_quotes': echo "<h2 style='text-align: left;'>Approved Quotes</h2>"; break; case 'rejected_quotes': echo "<h2 style='text-align: left;'>Rejected Quotes</h2>"; break; case 'expired_quotes': echo "<h2 style='text-align: left;'>Expired Quotes</h2>"; break; case 'draft_quotes': echo "<h2 style='text-align: left;'>Draft Quotes</h2>"; break; case 'converted_quotes': echo "<h2 style='text-align: left;'>Converted Quotes</h2>"; break; case 'search_quotes': echo "<h2 style='text-align: left;'>Search Quotes</h2>"; break; case 'customer_quotes': echo "<h2 style='text-align: left;'>Customer Quotes</h2>"; break; case 'quote_reports': echo "<h2 style='text-align: left;'>Quote Reports</h2>"; break; case 'quote_settings': echo "<h2 style='text-align: left;'>Quote Settings</h2>"; echo ' <table border="1"> <tr><th>Feature</th><th>Action</th></tr> <tr> <td>Import/Update Products</td> <td><button id="importProducts">Import</button> <span id="syncStatus"></span></td> </tr> <tr> <td>Sync Contacts</td> <td><button id="syncContacts">Sync</button> <span id="syncContactsStatus"></span></td> </tr> <tr> <td>Update Vendors</td> <td><button id="manageVendors">Manage</button></td> </tr> </table> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function () { $("#importProducts").click(function () { $("#syncStatus").text("Importing..."); $.post("Functions/Product_Functions.php", { sync_products: true }, function (response) { $("#syncStatus").text(response); }).fail(function () { $("#syncStatus").text("Error importing products."); }); }); $("#syncContacts").click(function () { $("#syncContactsStatus").text("Syncing contacts..."); $.post("Functions/Syncro_Contact_Sync.php", { sync_contacts: true }, function (response) { $("#syncContactsStatus").text(response); }).fail(function () { $("#syncContactsStatus").text("❌ Error syncing contacts."); }); }); $("#manageVendors").click(function () { window.open("Vendors/Manage_Vendors.php", "ManageVendors", "width=600,height=400"); }); }); </script>'; break; case 'edit_quote': $quoteId = $_GET['id'] ?? null; // 👇 Handle delete quote item if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_item_id'])) { $itemIdToDelete = $_POST['delete_item_id']; $deleteStmt = $pdo->prepare("DELETE FROM QuoteItems WHERE quote_item_id = ?"); $deleteStmt->execute([$itemIdToDelete]); } if ($quoteId) { renderEditQuoteForm($pdo, $quoteId); } else { echo "<p>❌ Quote ID is missing.</p>"; } break; default: echo "<h2>Quotes Dashboard</h2><p>Welcome to the Quotes Dashboard. Choose an option from the left menu.</p>"; break; } } else { echo "<h2>Quotes Dashboard</h2><p>Welcome to the Quotes Dashboard. Choose an option from the left menu.</p>"; } echo "</div>"; // End right-content echo "</div>"; // End main-container ?> Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/#findComment-1653284 Share on other sites More sharing options...
portabletelly Posted 20 hours ago Author Share Posted 20 hours ago Further to this I added the console.log the quoteItemId value inside the openEditQuantityPopup() and got this result. inspect shows correct value however popup is defiantly wrong item. Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/#findComment-1653285 Share on other sites More sharing options...
mac_gyver Posted 20 hours ago Share Posted 20 hours ago i haven't looked that the code yet, but in Quotes/Edit_Quote_Quantity.php, log the $_GET variables so that you can see how many requests are made to it and what the inputs are - file_put_contents('log.txt',print_r($_GET,true),FILE_APPEND); Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/#findComment-1653286 Share on other sites More sharing options...
mac_gyver Posted 18 hours ago Share Posted 18 hours ago so, i found the problem, with the help of php's error reporting, though the problem is in javascript. you are echoing blocks of static html/javescript using php's heredoc syntax. when I made the test page i used, the javascript was simply in-line. you are using template literals with embedded expressions in the javascript, e.g. ${some_var}. however, in php's heredoc syntax, this is the syntax for a php variable. so, php is putting the last value for any of its variables with the some_var name into the echoed javascript. how i found this is that the embedded expressions in the openUpdateTotalsPopup() javascrpt, for ${width}, ... produced undefined php variable errors. the simplest fix would be to use php's nowdoc syntax. the correct solution would be to NOT echo blocks of static html/javascript, which I see i wrote about in one of your previous threads. Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/#findComment-1653287 Share on other sites More sharing options...
portabletelly Posted 18 hours ago Author Share Posted 18 hours ago @mac_gyver champion this fixed it JS; echo <<<'JS' <script> function openEditQuantityPopup(quoteItemId, quoteId) { const width = 400; const height = 200; console.log("Opening popup for quoteItemId:", quoteItemId, "quoteId:", quoteId); const left = (window.innerWidth - width) / 2; const top = (window.innerHeight - height) / 2; window.open( `Quotes/Edit_Quote_Quantity.php?quote_item_id=${quoteItemId}"e_id=${quoteId}`, "EditQuoteQuantity", `width=${width},height=${height},top=${top},left=${left},resizable=no,scrollbars=no` ); } </script> JS; Quote Link to comment https://forums.phpfreaks.com/topic/327462-button-variable-of-foreach-loop-being-set-correct-but-when-passed-to-javascript-it-remains-the-value-of-the-last-button-variable-in-foreach-loop/#findComment-1653290 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.