Reputation: 1
So im making a software for a customer to manage products for a machine with 20 lanes but where i've gotten stuck is that i had it working for a while then i did something that i dont remember and now i cant click the lanes anymore. i've tried multiple things like making a new site and i get it to work but something with this piece of code has got me stumped haha okay so i think i've tracked down the problem to these lines
// Function to fetch lanes and their active-products from server
function fetchLanes() {
fetch('fetch_activeproduct.php')
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch lanes');
}
return response.json();
})
.then(data => {
if (data.success) {
const lanes = data.lanes;
updateLanesUI(lanes);
} else {
console.error('Error fetching lanes:', data.error);
alert('Failed to fetch lanes. Please try again later.');
}
})
.catch(error => {
console.error('Error fetching lanes:', error);
alert('Failed to fetch lanes. Please try again later.');
});
}
// Function to update UI with lanes and their active-products
function updateLanesUI(lanes) {
const lanesContainer = document.getElementById('lanes');
lanesContainer.innerHTML = ''; // Clear existing content
lanes.forEach(lane => {
const laneElement = document.createElement('div');
laneElement.classList.add('lane');
laneElement.textContent = `${lane['active-product']}`;
lanesContainer.appendChild(laneElement);
});
}
More specifly the Lanes.forEach(lane=>......
part
Here is the full script so you can understand the code a bit more
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Panel</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
}
.container {
width: 50%; /* Adjusted width for better layout */
height: 100vh;
overflow-y: auto;
padding: 20px;
box-sizing: border-box; /* Ensure padding is included in width calculation */
}
.lanes-container {
border-right: 1px solid #ccc;
}
h2 {
margin-top: 0;
}
.lane {
border: 1px solid #000;
padding: 10px;
margin-bottom: 10px;
cursor: pointer;
position: relative;
z-index: 1; /* Ensure lanes are above overlays */
}
.product {
padding: 10px;
margin-bottom: 10px;
border: 1px solid blue;
cursor: pointer;
}
.search-bar {
margin-bottom: 10px;
}
.add-product-form,
.product-form {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
z-index: 1000; /* Ensure forms are above other elements */
}
.add-product-form input,
.product-form input[type="number"] {
display: block;
margin-bottom: 10px;
width: calc(100% - 40px); /* Adjusted width for input fields */
padding: 5px;
}
.add-product-form button,
.product-form button {
background-color: #007bff;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}
.add-product-form button:hover,
.product-form button:hover {
background-color: #0056b3; /* Darker shade on hover */
}
#close-btn,
#close-product-form {
position: absolute;
top: 10px;
right: 20px;
color: #555;
font-size: 20px;
cursor: pointer;
}
#close-btn:hover,
#close-product-form:hover {
color: #333; /* Darker color on hover */
}
</style>
</head>
<body>
<div class="container lanes-container">
<h2>Lanes</h2>
<div id="lanes"></div>
</div>
<div class="container products-container">
<h2>Products</h2>
<div class="search-bar">
<input type="text" id="searchInput" placeholder="Search products...">
<button onclick="searchProducts()">Search</button>
</div>
<div>
<label for="filterType">Filter Type:</label>
<select id="filterType">
<option value="all">All</option>
<option value="ute">Ute</option>
<option value="inne">Inne</option>
<option value="krav">Krav</option>
</select>
<label for="filterBrand">Filter Brand:</label>
<select id="filterBrand">
<option value="all">All</option>
<option value="garant">Garant</option>
<option value="stjarnagg">Stjarnagg</option>
<option value="coop">Coop</option>
<option value="menigo">Menigo</option>
</select>
<button onclick="filterProducts()">Apply Filter</button>
</div>
<div id="productsList"></div>
<button onclick="toggleAddProductForm()">Add Product</button>
<button id="refresh-list" onclick="fetchProducts()">Refresh List</button>
</div>
<div class="add-product-form">
<h2>Add Product</h2>
<span id="close-btn" onclick="closeForm()">X</span>
<input type="text" id="productBrand" placeholder="Product Brand">
<input type="text" id="productType" placeholder="Product Type">
<input type="text" id="productAmount" placeholder="Product Amount">
<input type="text" id="productEggs" placeholder="Product Eggs">
<button onclick="addProduct()">Add Product</button>
</div>
<div class="product-form" id="productSelectionForm">
<h2>Product Selection</h2>
<span id="close-product-form" onclick="closeProductForm()">X</span>
<form id="productSelection" name="productSelection">
<label for="quantity">Quantity:</label>
<input type="number" id="quantity" min="1" value="1">
<br>
<label for="packaging">Packaging:</label>
<select id="packaging">
<option value="Kartong">Cartons</option>
<option value="HP">HP</option>
<option value="PALL">HP</option>
</select>
<br>
<button type="button" onclick="selectProduct()">Select</button>
</form>
</div>
<script>
// Global variables
let selectedProductId = null;
// Function to generate lanes dynamically
function generateLanes() {
const lanesContainer = document.getElementById('lanes');
lanesContainer.innerHTML = ''; // Clear existing content
for (let i = 1; i <= 20; i++) {
const lane = document.createElement('div');
lane.classList.add('lane');
lane.textContent = `Lane ${i}`;
lane.addEventListener('click', (event) => {
event.stopPropagation(); // Ensure the event doesn't bubble up
console.log('Lane clicked:', i);
assignProductToLane(i);
});
lanesContainer.appendChild(lane);
}
}
// Function to assign selected product to a lane
function assignProductToLane(laneNumber) {
if (selectedProductId) {
const selectedProduct = document.querySelector(`.product[data-id="${selectedProductId}"]`);
if (selectedProduct) {
const productBrand = selectedProduct.dataset.brand;
const productType = selectedProduct.dataset.type;
const productAmount = selectedProduct.dataset.amount;
const productEggs = selectedProduct.dataset.eggs;
// Prepare data for AJAX request
const data = {
laneId: laneNumber,
activeProduct: `${productBrand} ${productType} ${productAmount} ${productEggs}`
};
// Perform AJAX request to update database
fetch('update_lane.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to update lane');
}
return response.json();
})
.then(responseData => {
if (responseData.success) {
// Update lane text on UI
const lane = document.querySelector(`.lane:nth-child(${laneNumber})`);
if (lane) {
lane.textContent = `Lane ${laneNumber}: ${data.activeProduct}`;
console.log('Lane updated successfully:', responseData);
} else {
console.error('Lane element not found');
}
} else {
throw new Error('Failed to update lane: ' + responseData.error);
}
})
.catch(error => {
console.error('Error updating lane:', error);
alert('Failed to update lane. Please try again later.');
});
}
}
}
// Function to toggle the visibility of the add product form
function toggleAddProductForm() {
const addProductForm = document.querySelector('.add-product-form');
addProductForm.style.display = addProductForm.style.display === 'block' ? 'none' : 'block';
}
// Function to close the Add Product form
function closeForm() {
const addProductForm = document.querySelector('.add-product-form');
addProductForm.style.display = 'none';
}
// Function to add a new product
function addProduct() {
const productBrand = document.getElementById('productBrand').value.trim();
const productType = document.getElementById('productType').value.trim();
const productAmount = document.getElementById('productAmount').value.trim();
const productEggs = document.getElementById('productEggs').value.trim();
// Validate inputs
if (productBrand && productType && productAmount && productEggs) {
const product = {
brand: productBrand,
type: productType,
amount: productAmount,
eggs: productEggs
};
// Perform AJAX request to add the product using the PHP script
fetch('add_test.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(product)
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to add product');
}
return response.json();
})
.then(data => {
alert('Product added successfully');
// Reset the form inputs
document.getElementById('productBrand').value = '';
document.getElementById('productType').value = '';
document.getElementById('productAmount').value = '';
document.getElementById('productEggs').value = '';
fetchProducts(); // Refresh products list
toggleAddProductForm(); // Close the add product form
})
.catch(error => {
console.error('Error adding product:', error);
alert('Failed to add product: ' + error.message);
});
} else {
alert('Please fill out all fields');
}
}
// Function to fetch and display products
function fetchProducts() {
fetch('fetch_products.php')
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch products');
}
return response.json();
})
.then(products => {
const productsList = document.getElementById('productsList');
productsList.innerHTML = ''; // Clear the list
products.forEach(product => {
const productDiv = document.createElement('div');
productDiv.classList.add('product');
productDiv.dataset.id = product.id; // Set product ID as dataset
productDiv.dataset.type = product.type;
productDiv.dataset.brand = product.brand;
productDiv.dataset.amount = product.amount;
productDiv.dataset.eggs = product.eggs;
productDiv.textContent = `${product.brand} ${product.type} ${product.amount} ${product.eggs}`;
productDiv.addEventListener('click', openProductForm); // Add click event listener
productsList.appendChild(productDiv);
// Check if this product was previously selected
if (product.id === selectedProductId) {
productDiv.classList.add('selected');
}
});
})
.catch(error => {
console.error('Error fetching products:', error);
alert('Failed to fetch products. Please try again later.');
});
}
// Function to open the product selection form
function openProductForm(event) {
const productId = event.currentTarget.dataset.id;
const productType = event.currentTarget.dataset.type;
const productBrand = event.currentTarget.dataset.brand;
const productAmount = event.currentTarget.dataset.amount;
const productEggs = event.currentTarget.dataset.eggs;
const form = document.getElementById('productSelection');
form.dataset.productId = productId; // Set the product ID on the form
form.elements['quantity'].value = 1; // Reset quantity to default
const productForm = document.getElementById('productSelectionForm');
productForm.style.display = 'block';
}
// Function to close the product selection form
function closeProductForm() {
const productForm = document.getElementById('productSelectionForm');
productForm.style.display = 'none';
}
// Function to select the product and close the form
function selectProduct() {
const form = document.getElementById('productSelection');
const productId = form.dataset.productId;
// Highlight the selected product
const selectedProduct = document.querySelector(`.product[data-id="${productId}"]`);
if (selectedProduct) {
// Toggle 'selected' class
if (selectedProduct.classList.contains('selected')) {
selectedProduct.classList.remove('selected');
selectedProductId = null; // Clear selectedProductId if deselected
} else {
// Remove 'selected' class from previously selected product if any
const previouslySelected = document.querySelector('.product.selected');
if (previouslySelected) {
previouslySelected.classList.remove('selected');
}
// Add 'selected' class to the current selected product
selectedProduct.classList.add('selected');
selectedProductId = productId; // Update selected product ID
}
}
// Close the form after selecting
closeProductForm();
}
// Function to search for products
function searchProducts() {
const searchInput = document.getElementById('searchInput').value.toLowerCase();
const products = document.getElementsByClassName('product');
Array.from(products).forEach(product => {
const productName = product.textContent.toLowerCase();
if (productName.includes(searchInput)) {
product.style.display = 'block';
} else {
product.style.display = 'none';
}
});
}
// Function to apply filter on products
function filterProducts() {
const filterType = document.getElementById('filterType').value.toLowerCase();
const filterBrand = document.getElementById('filterBrand').value.toLowerCase();
const products = document.getElementsByClassName('product');
Array.from(products).forEach(product => {
const productType = product.dataset.type.toLowerCase();
const productBrand = product.dataset.brand.toLowerCase();
if ((filterType === 'all' || productType === filterType) && (filterBrand === 'all' || productBrand === filterBrand)) {
product.style.display = 'block';
} else {
product.style.display = 'none';
}
});
}
// Function to fetch lanes and their active-products from server
function fetchLanes() {
fetch('fetch_activeproduct.php')
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch lanes');
}
return response.json();
})
.then(data => {
if (data.success) {
const lanes = data.lanes;
updateLanesUI(lanes);
} else {
console.error('Error fetching lanes:', data.error);
alert('Failed to fetch lanes. Please try again later.');
}
})
.catch(error => {
console.error('Error fetching lanes:', error);
alert('Failed to fetch lanes. Please try again later.');
});
}
// Function to update UI with lanes and their active-products
function updateLanesUI(lanes) {
const lanesContainer = document.getElementById('lanes');
lanesContainer.innerHTML = ''; // Clear existing content
lanes.forEach(lane => {
const laneElement = document.createElement('div');
laneElement.classList.add('lane');
laneElement.textContent = `${lane['active-product']}`;
lanesContainer.appendChild(laneElement);
});
}
// Initialize products and lanes on page load
window.onload = function () {
generateLanes(); // Generate lanes when the page loads
fetchProducts(); // Fetch products when the page loads
fetchLanes(); // Fetch lanes and their active-products upon page load
};
</script>
</body>
</html>
Thanks in advance Best regards, Kevin
My expected resault is that after selecting a product to the right i can click a lane and the product inside that lane should change with the selected product.
Upvotes: 0
Views: 42