|
Server IP : 217.21.85.138 / Your IP : 216.73.216.103 Web Server : LiteSpeed System : Linux in-mum-web906.main-hosting.eu 4.18.0-553.37.1.lve.el8.x86_64 #1 SMP Mon Feb 10 22:45:17 UTC 2025 x86_64 User : u915722082 ( 915722082) PHP Version : 7.4.33 Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail MySQL : OFF | cURL : ON | WGET : ON | Perl : OFF | Python : OFF Directory (0755) : /home/u915722082/.nvm/../public_html/invoice/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
<?php
require "db.php";
function getVariations($con) {
$variations = [];
$result = $con->query("SELECT DISTINCT VARIATION, VARIATION_VAL FROM attributes");
if (!$result) {
error_log("MySQL Error: " . $con->error);
return [];
}
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
// Check if VARIATION_VAL contains multiple values (comma-separated)
$isMultiple = strpos($row['VARIATION_VAL'], ',') !== false;
$variations[] = [
'name' => $row['VARIATION'],
'is_multiple' => $isMultiple
];
}
return $variations;
}
function getVariationValues($con, $variation) {
$stmt = $con->prepare("SELECT VARIATION_VAL FROM attributes WHERE VARIATION = ?");
if (!$stmt) {
error_log("MySQL Prepare Error: " . $con->error);
return [];
}
$stmt->bind_param("s", $variation);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_array(MYSQLI_NUM);
if ($row) {
return array_map('trim', explode(',', $row[0]));
}
return [];
}
// Get all variations and their values
$variations = getVariations($con);
$variationData = [];
foreach ($variations as $variation) {
$variationData[$variation['name']] = [
'values' => getVariationValues($con, $variation['name']),
'is_multiple' => $variation['is_multiple']
];
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Product Variations</title>
<link href="assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css" />
<link href="assets/css/style.bundle.css" rel="stylesheet" type="text/css" />
<style>
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #f3f6f9;
border: none;
padding: 5px 10px;
margin: 2px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
margin-right: 5px;
color: #7e8299;
}
.selected-value {
padding: 2px 5px;
}
</style>
</head>
<body>
<div class="card">
<div class="card-body">
<h3 class="card-title">Variations</h3>
<div class="mb-5">
<label class="form-label">Add Product Variations</label>
<div id="variation-container">
<!-- Initial row will be added by JavaScript -->
</div>
<button type="button" class="btn btn-light-primary btn-sm mt-3" onclick="addRow()">
<i class="ki-duotone ki-plus fs-2"></i>Add another variation
</button>
</div>
</div>
</div>
<script src="assets/plugins/global/plugins.bundle.js"></script>
<script src="assets/js/scripts.bundle.js"></script>
<script>
const variationData = <?= json_encode($variationData) ?>;
// Function to check if variation exists in database
function variationExists(variationName) {
return variationData.hasOwnProperty(variationName);
}
function updateValues(selectElement) {
const row = selectElement.closest('.variation-row');
const valueSelect = row.querySelector('.variation-value-select');
const selectedVariation = selectElement.value;
// Clear and disable value select if no variation is selected
if (!selectedVariation || !variationExists(selectedVariation)) {
valueSelect.disabled = true;
$(valueSelect).select2('destroy');
$(valueSelect).select2({
placeholder: 'Select value',
allowClear: true,
tags: false,
createTag: null,
data: [] // Empty data to prevent any default options
});
return;
}
// Enable value select
valueSelect.disabled = false;
const isMultiple = selectElement.options[selectElement.selectedIndex].dataset.multiple === '1';
// Prepare data for Select2
const selectData = [];
if (variationData[selectedVariation]) {
variationData[selectedVariation].values.forEach(value => {
selectData.push({
id: value.trim(),
text: value.trim()
});
});
}
// Destroy existing Select2 instance
$(valueSelect).select2('destroy');
// Reinitialize Select2 with cleaned up configuration
$(valueSelect).select2({
placeholder: 'Select value',
multiple: isMultiple,
tags: false,
allowClear: true,
createTag: null,
data: selectData,
templateSelection: function(data) {
if (!data.id) return data.text; // Handle placeholder
return data.text ? data.text.trim() : data.text;
},
templateResult: function(data) {
if (!data.id) return data.text; // Handle placeholder
return data.text ? data.text.trim() : data.text;
}
}).on('select2:select', function(e) {
const validValues = variationData[selectedVariation].values;
const selectedValue = e.params.data.text.trim();
if (!validValues.includes(selectedValue)) {
$(valueSelect).val(null).trigger('change');
}
});
// Clear any existing selections
$(valueSelect).val(null).trigger('change');
// Update available options in other dropdowns
updateAvailableOptions();
}
function createFreshRow() {
const row = document.createElement('div');
row.className = 'row mb-2 variation-row';
row.innerHTML = `
<div class="col-md-5">
<select class="form-select variation-select" onchange="updateValues(this)">
<option value="">Select a variation</option>
${Object.keys(variationData).map(variation =>
`<option value="${variation}"
data-multiple="${variationData[variation].is_multiple ? '1' : '0'}">
${variation}
</option>`
).join('')}
</select>
</div>
<div class="col-md-5">
<select class="form-select variation-value-select" disabled>
<option value="" disabled >Select value</option>
</select>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-icon btn-light-danger delete-btn" onclick="removeRow(this)" style="display: none;">
<i class="ki-duotone ki-cross fs-1"></i>
</button>
</div>
`;
return row;
}
function addRow() {
if (!validateRows()) {
toastr.error('Please fill in all existing variations before adding a new one.');
return;
}
const container = document.getElementById('variation-container');
const newRow = createFreshRow();
// Initialize Select2 on the new row's selects
const variationSelect = newRow.querySelector('.variation-select');
const variationValueSelect = newRow.querySelector('.variation-value-select');
// Append the new row
container.appendChild(newRow);
// Initialize Select2
$(variationSelect).select2({
placeholder: 'Select a variation',
allowClear: true
});
$(variationValueSelect).select2({
placeholder: 'Variation',
allowClear: true
});
// Update available options and delete buttons
updateAvailableOptions();
updateDeleteButtons();
}
function updateAvailableOptions() {
const selectedVariations = new Set();
// Collect all selected variations
document.querySelectorAll('.variation-select').forEach(select => {
if (select.value && variationExists(select.value)) {
selectedVariations.add(select.value);
}
});
// Update available options in all dropdowns
document.querySelectorAll('.variation-select').forEach(select => {
const currentValue = select.value;
select.querySelectorAll('option').forEach(option => {
if (option.value && option.value !== currentValue) {
option.disabled = selectedVariations.has(option.value);
}
});
// Reinitialize Select2 to reflect changes
$(select).select2({
placeholder: 'Select a variation',
allowClear: true
});
});
}
function removeRow(button) {
const container = document.getElementById('variation-container');
if (container.children.length > 1) {
const row = button.closest('.variation-row');
// Destroy Select2 instances before removing
$(row).find('select').each(function() {
if ($(this).hasClass('select2-hidden-accessible')) {
$(this).select2('destroy');
}
});
row.remove();
updateAvailableOptions();
updateDeleteButtons();
} else {
toastr.warning('At least one variation is required.');
}
}
function updateDeleteButtons() {
const rows = document.querySelectorAll('.variation-row');
rows.forEach((row, index) => {
const deleteBtn = row.querySelector('.delete-btn');
deleteBtn.style.display = rows.length > 1 ? 'block' : 'none';
});
}
function validateRows() {
const rows = document.querySelectorAll('.variation-row');
for (let row of rows) {
const variationSelect = row.querySelector('.variation-select');
const valueSelect = row.querySelector('.variation-value-select');
if (!variationSelect.value || !valueSelect.value || !variationExists(variationSelect.value)) {
return false;
}
}
return true;
}
// Modified initialization for the first row
document.addEventListener('DOMContentLoaded', () => {
const container = document.getElementById('variation-container');
const firstRow = createFreshRow();
container.innerHTML = '';
container.appendChild(firstRow);
// Initialize variation select
$(firstRow.querySelector('.variation-select')).select2({
placeholder: 'Select a variation',
allowClear: true,
tags: false,
createTag: null
});
// Initialize value select with empty data
$(firstRow.querySelector('.variation-value-select')).select2({
placeholder: 'Select value',
allowClear: true,
tags: false,
createTag: null,
data: [], // Start with empty data
templateSelection: function(data) {
if (!data.id) return data.text; // Handle placeholder
return data.text ? data.text.trim() : data.text;
}
});
});
</script>
</body>
</html>