MMCT TEAM
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  ]

Current File : /home/u915722082/.nvm/../public_html/invoice/attr-check.php
<?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>

MMCT - 2023