Getting undefined result from array query

I’m just beginning my journey with Javascript and have been playing about with a deck of cards.

I have an array set with a standard 52 card deck, and my aim with the code is to display a random card each time, taking the drawn cards out of the array (so they can’t be drawn again, and the deck will eventually run down to 0).

Testing this in the console worked, but now that I’ve put it on to an external JS sheet for a webpage, I’m occasionally getting an error of “undefined” when the random card is being generated.

Any help is gratefully appreciated!

Here’s my Javascript code – there’s no consistency in the error for which card is causing the error, or for number of occurrences – I’ve seen runs with one, two, or three errors, and with different selections each time.

var deck = ['ace_of_clubs',

'2_of_clubs',

'3_of_clubs',

'4_of_clubs',

'5_of_clubs',

'6_of_clubs',

'7_of_clubs',

'8_of_clubs',

'9_of_clubs',

'10_of_clubs',

'jack_of_clubs2',

'queen_of_clubs2',

'king_of_clubs2',

'ace_of_diamonds',

'2_of_diamonds',

'3_of_diamonds',

'4_of_diamonds',

'5_of_diamonds',

'6_of_diamonds',

'7_of_diamonds',

'8_of_diamonds',

'9_of_diamonds',

'10_of_diamonds',

'jack_of_diamonds2',

'queen_of_diamonds2',

'king_of_diamonds2',

'ace_of_hearts',

'2_of_hearts',

'3_of_hearts',

'4_of_hearts',

'5_of_hearts',

'6_of_hearts',

'7_of_hearts',

'8_of_hearts',

'9_of_hearts',

'10_of_hearts',

'jack_of_hearts2',

'queen_of_hearts2',

'king_of_hearts2',

'ace_of_spades',

'2_of_spades',

'3_of_spades',

'4_of_spades',

'5_of_spades',

'6_of_spades',

'7_of_spades',

'8_of_spades',

'9_of_spades',

'10_of_spades',

'jack_of_spades2',

'queen_of_spades2',

'king_of_spades2',

];

 

function pickACard(){

    if (deck.length > 0) {

        let card = Math.round(Math.random()*deck.length);
        console.log(deck[card]);
        document.querySelector("img").setAttribute("src", "./images/" + (deck[card]) + ".png");
        
        let remove = deck.indexOf(deck[card]);

        deck.splice(remove,1);

    }    else {

        alert("Please start a new game!")

    }

}

Always getting `Document with the requested ID already exists.’ in Appwrite

I’m getting a persistent “Document with the requested ID already exists” error when trying to create documents in my users_profiles collection, even though:
strong text

  • No duplicate document IDs exist – I’ve verified this in the Appwrite console

  • Only one user exists with ID 685950f30003536bbc8b

  • Only one user_profile exists with ID 685950f400010a5d1ee1

  • This error only occurs with the users_profiles collection – other collections work fine
    Collection Schema
    My users_profiles collection has:

  • Two one-to-one relationships pointing TO it (not FROM it):
    users_preferencesusers_profiles (one-way relationship)
    librariesusers_profiles (one-way relationship)
    Document security disabled
    Unique indexes on email and username fields

The request’s body

{
    "documentId": "685952b90030c6eb42be",
    "data": {
        "userId": "685952b80036637183cd",
        "name": "Walid Zakan",
        "email": "[email protected]",
        "username": "waliddasdas2_mc949ak0",
        "avatarUrl": "https://api.dicebear.com/9.x/fun-emoji/svg?seed=Walid%20Zakan",
        "mediaPreference": "both"
    },
    "permissions": [
        "read("user:685952b80036637183cd")",
        "update("user:685952b80036637183cd")",
        "delete("user:685952b80036637183cd")"
    ]
}

Formatting textarea’s value on each user input [closed]

I have a textarea where when the user writes text the content must be automatically formatted following these criterias:

  • the maximum number of characters per row must be for example 60 characters
  • if the row ends with a break line the line must end (even if the row has less than 60 characters)
  • if the user edits a word in one of the previous lines the overflowing characters of the row must be attached at the beginning of the next line

This is the algorithm I have implemented:

function format(event) {
  const textarea = document.getElementById("textarea");
  const start = textarea.selectionStart;
  const end = textarea.selectionEnd;
  textarea.value = formatText(event.target.value, 35);
  textarea.setSelectionRange(start,end);
}

function formatText(value, maxLength = 60) {
    let text = '';
    const subtexts = [];
    for (let i = 0; i < value.length; i++) {
        if (value.charAt(i) === 'n' || text.length >= maxLength) {
            subtexts.push(text);
            text = '';
        } else {
            text += value.charAt(i);
        }
    }
    if (text !== '' && subtexts[subtexts.length - 1] !== text) {
        subtexts.push(text);
    }
    return subtexts.join('n');
}
<textarea id="textarea" oninput="format(event)"></textarea>

This code presents one bug lets consider the following text:

test test test test test test test 

The bugs:

  • When I try to edit one of the previous rows the overflowing characters disappear and a new line is added after the row I am editing

Unfortunately I cannot use any libraries to achieve this solution.

GitHub Pages returns 404 for subfolder HTML pages loaded via iframe, but works locally

I’m hosting my games website on GitHub Pages at https://username.github.io. My homepage (index.html) works perfectly, and I’ve structured my project to load different HTML games using an iframe inside a popup.

Each game is in its own folder with its own index.html, CSS, and JS files.

Folder Structure

/
├── index.html
├── game1/
│   ├── game1.html
│   ├── css/
│   └── js/
├── game2/
│   ├── game2.html
│   ├── css/
│   └── js/

Code in index.html

<body>

  <h1>Select a Game</h1>

  <button onclick="openGame('game1/game1.html')">Open Game 1</button>
  <button onclick="openGame('game2/game2.html')">Open Game 2</button>

  <dialog id="gameDialog">
    <button class="close-btn" onclick="closeGame()">✕</button>
    <iframe id="gameFrame"></iframe>
  </dialog>

  <script>
    function openGame(url) {
      const dialog = document.getElementById("gameDialog");
      const frame = document.getElementById("gameFrame");
      frame.src = url;
      dialog.showModal();
    }

    function closeGame() {
      const dialog = document.getElementById("gameDialog");
      const frame = document.getElementById("gameFrame");
      frame.src = "";
      dialog.close();
    }
  </script>

</body>

When I test this locally (opening index.html directly), the games load inside the iframe just fine.

But after pushing to GitHub Pages, clicking the buttons shows a 404 error in the iframe — the subpages like game1/game1.html or game2/game2.html aren’t found, even though they exist and are in the repo. Even in developer options, the games folders are not loaded from start and even after clicking button it isn’t getting loaded.

I have checked the folder and file names, they match and their casing as well.

Any advice would be greatly appreciated!

The fixedColumn feature not being applied in the datatable

I am trying to freeze the first four columns of this datatable when a user is scrolling it. But the style “dtfc-has-left” style=”position: relative;”” is not applied when I inspect the datatable in the browser, and the feature is not working. In case I miss something, I am adding almost all the code here. Please let me know if anyone can see the reason why the frozen columns is not applied.

<head>
    <link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" />
    <link rel="stylesheet" href="https://cdn.datatables.net/fixedcolumns/4.2.2/css/fixedColumns.dataTables.min.css" />
    <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.1/css/buttons.dataTables.min.css" />

</head>
<!-- Tender Selection Dropdown -->
<div class="mb-3">
    <p class="important-note">
        <i class="fas fa-file-contract me-2"></i>Select a tender to add a new estimation. Only eligible tenders are shown in the dropdown below.
    </p>
    <select id="tenderSelect" name="TenderID" class="form-select" size="6">
        <option value="0" selected="@(ViewBag.SelectedTenderID == 0 ? "selected" : null)">
            All Tenders' Estimations
        </option>

        @foreach (var item in ViewBag.Tenders as List<SelectListItem>)
        {
            <option value="@item.Value" selected="@(ViewBag.SelectedTenderID?.ToString() == item.Value ? "selected" : null)">
                @item.Text
            </option>
        }
    </select>
</div>


@if (Model == null || !Model.Any())
{
    <p>No Estimations Available At this Time.</p>
}
else
{
    <div class="dropdown mb-3">
        <button class="btn btn-secondary dropdown-toggle" type="button" id="columnToggleDropdown" data-bs-toggle="dropdown" aria-expanded="false" title="Add/ Remove columns from the view and exports.">
            <i class="fas fa-table-columns me-1"></i> Toggle Columns
        </button>
        @* <button class="btn btn-secondary dropdown-toggle" type="button" id="columnToggleDropdown" data-bs-toggle="dropdown" aria-expanded="false">
            Toggle Columns
        </button> *@
        <ul class="dropdown-menu" aria-labelledby="columnToggleDropdown" id="columnVisibilityOptions">
            <li>
                <label class="dropdown-item">
                    <input type="checkbox" id="selectAllColumns" checked> Select All
                </label>
            </li>
            <li><hr class="dropdown-divider" /></li>
            <!-- Column checkboxes will be added dynamically -->
        </ul>
    </div>

    @* class="table-responsive mx-auto" style="overflow-x: auto; width: 100%;" *@
    <div class="div1">
        <table class="table table-bordered display nowrap" style="width:100%" id="estimationTable">
            <thead>
                <tr>
                </tr>
            </thead>
            <tbody>
                @foreach (var estimation in Model)
                {
                    <tr>
                        <td>
                            @{
                                var status1 = (EstimationStatusEnum)estimation.EstimationStepStatus;

                                string actionName = status1 switch
                                {
                                    EstimationStatusEnum.PileSetupPending => "EstimationPileWizard",
                                    EstimationStatusEnum.ValuationPending => "EstimationValWizard",
                                    EstimationStatusEnum.SubmissionPending => "EstimationSubmissionWizard",
                                    EstimationStatusEnum.ResultPending => "EstimationResultWizard",
                                    EstimationStatusEnum.ResultSubmitted => "EstimationResultWizard",
                                    _ => null
                                };

                                bool isReview = status1 == EstimationStatusEnum.ResultSubmitted;
                                if (!string.IsNullOrEmpty(actionName))
                                {
                                    if (isReview || estimation.EstimationStatus == false)
                                    {
                                        <a href="@Url.Action(actionName, "Estimation", new { estID = estimation.EstID, tenderID = ViewBag.SelectedTenderID })"
                                           class="btn btn-sm"
                                           title="Review or update completed estimation"
                                           style="background-color: yellow; color: black; border: 1px solid #ccc;">
                                            <i class="fas fa-eye me-1"></i> Review
                                        </a>
                                    }
                                    else
                                    {
                                        <a href="@Url.Action(actionName, "Estimation", new { estID = estimation.EstID, tenderID = ViewBag.SelectedTenderID })"
                                           class="btn btn-primary btn-sm"
                                           title="Proceed or update incomplete estimation record">
                                            <i class="fas fa-step-forward me-1"></i> Proceed
                                        </a>
                                    }
                                }
                            }
                        </td>
                        <td>@estimation.EstID</td>
                        <td>@estimation.EstRefID</td>
                        <td>@estimation.TenderProjName</td>
                        <td>
                            @{
                                var status = (EstimationStatusEnum)estimation.EstimationStepStatus;
                                var stepLabels = new Dictionary<EstimationStatusEnum, (string Text, string Badge)>
                                {
                                { EstimationStatusEnum.PileSetupPending, ("Pile Setup Pending", "info") },
                                { EstimationStatusEnum.ValuationPending, ("Valuation Pending", "primary") },
                                { EstimationStatusEnum.SubmissionPending, ("Submission Pending", "success") },
                                { EstimationStatusEnum.ResultPending, ("Result Pending", "secondary") },
                                { EstimationStatusEnum.ResultSubmitted, ("Completed", "dark") }
                                };

                                var (label, badgeClass) = stepLabels[status];
                            }
                            <span class="badge bg-@badgeClass">@label</span>
                        </td>
                        <td>
                            @{
                                string result = estimation.Result?.ToString() ?? "";
                                string displayText = result;
                                string resultBadgeClass = result switch
                                {
                                    "Won" => "success",
                                    "Lost" => "danger",
                                    "In Abeyance" => "warning",
                                    "Cancelled" => "secondary",
                                    _ => "info"
                                };

                                if (string.IsNullOrWhiteSpace(result) || !new[] { "Won", "Lost", "In Abeyance", "Cancelled" }.Contains(result))
                                {
                                    displayText = "NAY";
                                }
                            }
                            <span class="badge bg-@resultBadgeClass">@displayText</span>
                        </td>
                        <td>
                            @if (estimation.EstimationStatus == true)
                            {
                                <a asp-controller="ChangeRequest" asp-action="ChangeRequest" asp-route-estID="@estimation.EstID" asp-route-tenderID="@estimation.TenderID"
                                   class="btn btn-sm btn-outline-secondary change-request-link"
                                   title="Access Change Requests for this Estimation">
                                    <i class="fas fa-exchange-alt me-1"></i> @estimation.ChangeRequestCount
                                </a>
                            }
                            else
                            {
                                @estimation.ChangeRequestCount
                            }
                        </td>
                        <td>@estimation.CompanyName</td>
                        <td>@($"{estimation.CompPhoneCode} {estimation.CompPhone}")</td>
                        <td>@estimation.CompEmail</td>
                        <td>@estimation.RepFirstName @estimation.RepLastName</td>
                        <td>@($"{estimation.RepPhoneCode} {estimation.RepPhone}")</td>
                        <td>@estimation.RepEmail</td>
                        <td style="text-align: right; color:@(estimation.ClientBudget == 0.00M ? "red" : "black")">
                            @(estimation.ClientBudget == 0.00M ? "Not Provided" : estimation.ClientBudget.ToString("#,0.00"))
                        </td>
                        <td style="text-align: right; color:@((estimation.MaterialValue == null || estimation.MaterialValue == 0.00M) ? "red" : "black")">
                            @((estimation.MaterialValue == null || estimation.MaterialValue == 0.00M)
                                                ? "NAY"
                                                : estimation.MaterialValue?.ToString("#,0.00"))
                        </td>
                        <td style="text-align: right; color:@((estimation.TenderValue == null || estimation.TenderValue == 0.00M) ? "red" : "black")">
                            @((estimation.TenderValue == null || estimation.TenderValue == 0.00M)
                                                ? "NAY"
                                                : estimation.TenderValue?.ToString("#,0.00"))
                        </td>
                        <td style="text-align: right; color:@((estimation.MarkUpPercentage == null || estimation.MarkUpPercentage == 0.00M) ? "red" : "black")">
                            @((estimation.MarkUpPercentage == null || estimation.MarkUpPercentage == 0.00M)
                                                ? "NAY"
                                                : estimation.MarkUpPercentage?.ToString("F2"))
                        </td>
                        <td style="text-align: right; color:@((estimation.EstimatedDurationDays == null || estimation.EstimatedDurationDays == 0.00M) ? "red" : "black")">
                            @((estimation.EstimatedDurationDays == null || estimation.EstimatedDurationDays == 0.00M)
                                                ? "NAY"
                                                : estimation.EstimatedDurationDays?.ToString("F2"))
                        </td>
                        <td>@estimation.TenderReceiptDate.ToShortDateString()</td>
                        <td>@estimation.TenderDueDate.ToShortDateString()</td>
                        <td>@(estimation.SubmissionDate?.ToShortDateString() ?? "-")</td>
                        <td>@estimation.EstFirstName @estimation.EstLastName</td>
                        <td>@estimation.TLFirstName @estimation.TLLastName</td>
                        <td>@(estimation.EstResReceivedDate?.ToShortDateString() ?? "-")</td>
                        <td>@estimation.WonCompName</td>
                        <td>@estimation.SuccessPrice?.ToString("#,0.00")</td>
                        <td>
                            <span title="@estimation.EstFeedback" style="max-width:200px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display: inline-block;">
                                @estimation.EstFeedback
                            </span>
                        </td>
                        <td>@estimation.EstContractRefID</td>
                        <td data-status="@(estimation.EstimationStatus ? "Active" : "Inactive")">
                            @if (estimation.EstimationStatus == true)
                            {
                                <span class="badge bg-success">Active</span>
                            }
                            else
                            {
                                <span class="badge bg-secondary">Inactive</span>
                            }
                        </td>

                        <td>
                            @if (estimation.HasSoilProfile)
                            {
                                <button type="button" title="View soil profile for this estimation based tender"
                                class="btn btn-info btn-sm view-soil-btn"
                                style="background-color: darkgrey; color: black; border: 1px solid #ccc;"
                                data-tender-id="@estimation.TenderID">
                                    <i class="fas fa-seedling me-1"></i> View Soil Profile
                                </button>
                            }
                        </td>
                        <td>
                            @if (estimation.HasPileReq)
                            {
                                <button type="button" title="View a comparison of client requested and estimation suggested pile"
                                        class="btn btn-info btn-sm view-pile-btn"
                                        style="background-color: darkgrey; color: black; border: 1px solid #ccc;"
                                        data-tender-id="@estimation.EstID">
                                    <i class="fas fa-hammer me-1"></i> View Pile Setup
                                </button>
                            }
                        </td>
                        

                        
                    </tr>
                }
            </tbody>
        </table>
    </div>

    @* Modal to view soil profile *@

    <div class="modal fade" id="soilProfileModal" tabindex="-1" role="dialog" aria-labelledby="soilProfileModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content" id="soilProfileContent">
                <!-- Partial View here -->
            </div>

        </div>
    </div>

    @* Modal to view requested pile *@
    <div class="modal fade" id="pileReqModal" tabindex="-1" role="dialog" aria-labelledby="pileReqModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content" id="pileReqContent">
                <!-- Partial View here -->
            </div>

        </div>
    </div>

}

<style>
    .dataTables_wrapper .dataTables_scroll {
        overflow: auto;
    }

    th, td {
        white-space: nowrap;
    }

    .dt-button {
        margin-right: 5px;
    }

    .estimation-link:hover {
        background-color: lightgreen !important;
        color: black !important;
    }

    .change-request-link:hover {
        background-color: #e91e63 !important;
        color: black !important;
    }

    /* Initially hide optional columns */
    th.toggle-optional,
    td.toggle-optional {
        display: none;
    }

    /* Add here */
    #columnVisibilityOptions {
        max-height: 250px;
        overflow-y: auto;
        overflow-x: hidden;
        padding-right: 10px;
    }

    .div1 th {
        background: #198754 !important;
    }
</style>

@section Scripts {
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
    <script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/fixedcolumns/4.2.2/js/fixedColumns.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/2.4.1/js/dataTables.buttons.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/2.4.1/js/buttons.html5.min.js"></script>

    <script>
        $(document).ready(function () {

            // Setup filter for Active Inactive Status
            let statusFilterValue = '';

            $.fn.dataTable.ext.search.push(function (settings, data, dataIndex) {
                if (!statusFilterValue) return true;

                const row = settings.aoData[dataIndex].nTr;
                const status = $('td:eq(28)', row).data('status');
                return status === statusFilterValue;
            });

            // Export file title setup
            var now = new Date();
            var formattedDateTime = now.toLocaleString('en-GB', {
                day: '2-digit', month: '2-digit', year: 'numeric',
                hour: '2-digit', minute: '2-digit', second: '2-digit',
                hour12: false
            }).replace(/[/:]/g, '-').replace(',', '');

            var exportTitle = 'Estimation Master List - Exported Date Time: ' + formattedDateTime;
            var exportFileName = 'Estimation_Master_Export_ ' + formattedDateTime;

            // Tender status dictionary
            const tenderStatuses = @Html.Raw(Json.Serialize(ViewBag.TenderStatuses));

            function updateAddEstimationButtonVisibility() {
                const selectedTenderId = $('#tenderSelect').val();
                const addBtn = $('#addEstimationBtn');

                // If "All Tenders" (value 0) is selected, hide the button
                if (selectedTenderId === "0") {
                    addBtn.hide();
                    return;
                }

                // Convert selectedTenderId to a number for lookup
                const tenderIdNum = parseInt(selectedTenderId, 10);
                const status = tenderStatuses[tenderIdNum]; // Look up using the numeric ID

                if (status === true) {
                    addBtn.show();
                } else {
                    addBtn.hide();
                }
            }

            // --- Event Handlers ---

            // Handle Tender Dropdown Change
            $('#tenderSelect').on('change', function () {
                const selectedValue = $(this).val();
                const url = selectedValue === "0"
                    ? "/Estimation/Index"
                    : `/Estimation/Index?tenderID=${selectedValue}`;
                window.location.href = url;
            });

            // Handle Add Estimation Button Click
            $('#addEstimationBtn').on('click', function () {
                const selectedTenderId = $('#tenderSelect').val();
                if (!selectedTenderId || selectedTenderId === "0") {
                    alert("Please select a valid Tender to create an estimation.");
                    return;
                }
                window.location.href = `/Estimation/EstimationCreateWizard?tenderID=${selectedTenderId}&estID=0`;
            });

            // --- Initializations ---

            // Initial check on page load to set button visibility
            updateAddEstimationButtonVisibility();

            // Initialize DataTable if table exists
            if ($('#estimationTable').length > 0) {
                let $filterRow = $('<tr class="filters"></tr>');
                $('#estimationTable thead tr:eq(0) th').each(function () {
                    $filterRow.append('<th><input type="text" placeholder="Search" style="width: 100%;" /></th>');
                });
                $('#estimationTable thead').append($filterRow);

                var table = $('#estimationTable').DataTable({
                    dom: 'lfrtipB',
                    buttons: [
                        {
                            extend: 'csvHtml5',
                            text: '<i class="fas fa-file-csv me-1"></i> Export CSV',
                            className: 'btn btn-sm btn-secondary export-btn',
                            title: exportTitle,
                            filename: exportFileName,
                            exportOptions: {
                                columns: function (idx, data, node) {
                                    var columnCount = table.columns().count();
                                    return $(node).is(':visible') && idx !== 0 && idx !== columnCount - 2 && idx !== columnCount - 1;
                                },
                                    modifier: { search: 'applied', order: 'current' }
                                }
                        },
                        {
                            extend: 'excelHtml5',
                            text: '<i class="fas fa-file-excel me-1"></i> Export Excel',
                            className: 'btn btn-sm btn-secondary export-btn',
                            title: exportTitle,
                            filename: exportFileName,
                            exportOptions: {
                                columns: function (idx, data, node) {
                                    var columnCount = table.columns().count();
                                    return $(node).is(':visible') && idx !== 0 && idx !== columnCount - 2 && idx !== columnCount - 1;
                                },
                                modifier: { search: 'applied', order: 'current' }
                            }
                        }
                    ],
                    scrollX: true,
                    scrollY: '500px',
                    fixedColumns: {
                        leftColumns: 4 
                    },
                    scrollCollapse: true,
                    paging: true,
                    //fixedHeader: true,
                    orderCellsTop: true,
                    order: [[1, 'asc']],
                    columnDefs: [
                        {
                            targets: [13, 14, 15, 16, 17, 25], // Client Budget, Material Value, Tender Value, MarkUp %, Estimated Duration (Days), Success Price
                    render: function (data, type, row) {

                        if (type === 'filter' || type === 'sort') {
                            let cleanData = data.toString().replace(/£/g, '').replace(/,/g, '');
                            if (cleanData === "NAY" || cleanData === "Not Provided" || cleanData.trim() === "" || isNaN(parseFloat(cleanData))) {
                                return -Infinity;
                            }
                            return parseFloat(cleanData);
                        }
                        // For display, return the data as is (with commas)
                        return data;
                    },
                    type: 'num-fmt'
                            // targets: [12,13,14,24],
                            // createdCell: function (td, cellData) {
                            //     var plainText = cellData ? cellData.toString().trim() : "";
                            //     $(td).html('<span class="d-none">' + plainText + '</span>' + plainText);
                            // }
                        },
                        { orderable: false, targets: 0 }
                    ],
                    initComplete: function () {
                        var api = this.api();

                        api.columns().eq(0).each(function (colIdx) {
                            var cell = $('.filters th').eq(colIdx);
                            var colHeader = $('#estimationTable thead tr:eq(0) th').eq(colIdx).text().trim(); // For debugging

        //console.log(`Column Index: ${colIdx}, Header: "${colHeader}"`);
                            if (colIdx === 4) { 
                                $(cell).html(`
                                    <select class="form-select form-select-sm" style="width: 100%;">
                                        <option value="">All</option>
                                        <option value="Pile Setup Pending">Pile Setup Pending</option>
                                        <option value="Valuation Pending">Valuation Pending</option>
                                        <option value="Submission Pending">Submission Pending</option>
                                        <option value="Result Pending">Result Pending</option>
                                        <option value="Completed">Completed</option>
                                    </select>`);
                            }
                            else if (colIdx === 5) { // Column index for "Result"
                                $(cell).html(`
                                    <select class="form-select form-select-sm" style="width: 100%;">
                                        <option value="">All</option>
                                        <option value="Won">Won</option>
                                        <option value="Lost">Lost</option>
                                        <option value="In Abeyance">In Abeyance</option>
                                        <option value="Cancelled">Cancelled</option>
                                        <option value="NAY">NAY</option>
                                    </select>
                                `);
                            }
                            // Active/ Inactive filter
                            else if (colIdx === 28) {
                                $(cell).html(`
                                    <select class="form-select form-select-sm" style="width: 100%;">
                                        <option value="">All</option>
                                        <option>Active</option>
                                        <option>Inactive</option>
                                    </select>`);

                                    $('select', cell).on('change', function () {
                                        statusFilterValue = this.value;
                                        api.draw(); // ⬅ trigger redraw with updated filter
                                    });
                            }
                            else if (colIdx !== 0 && colIdx !== 29 && colIdx !== 30 ) { // Not the 'Action' column
                                $(cell).html('<input type="text" placeholder="Search" style="width: 100%;" />');
                            } 
                            else { // 'Action' column
                                $(cell).html('');
                            }

                            $('input, select', cell).on('keyup change', function () {
                                api.column(colIdx).search(this.value).draw();
                            });
                        });

                       
                        
                    }
                });
            }
        });
    </script>
}

Change Multiselect With Group Options Based On Input Of Another Select Option

I have Two Select Options in that Based on first select options i need to load second select options values. Second select option having multiselect option The HTML code is below.

<div>
  <select name="Control" id="ctrl_typ" onchange="Control_change()">
    <option selected="selected" disabled="disabled">COMMAND</option> 
    <option  disabled="disabled"></option>
    <option  value="1">First</option>
    <option  value="2">Second</option>                  
  </select> 
  <select name="Names[]" multiple id="nameid" size="30">
  </select>
</div>

JS part is below.

var maxSelect=1000;
$( document ).ready(function()
   {
    $('#nameid').multiselect({
    columns: 1,
    texts: {
        placeholder: 'Name',
        search     : 'Search Names'      
       },
    search: true,
    maxWidth:467,
    maxHeight:400, 
    selectAll: true,
    selectGroup: true,
    onOptionClick: function( element, option ) 
       {
         if( $(element).val().length > maxSelect ) {
                    if( $(option).is(':checked') ) {
                        var thisVals = $(element).val();

                        thisVals.splice(
                            thisVals.indexOf( $(option).val() ), 1
                        );

                        $(element).val( thisVals );

                        $(option).prop( 'checked', false ).closest('li')
                            .toggleClass('selected');
                    }
                }
           else if( $(element).val().length == maxSelect ) 
                {
                    $(element).next('.ms-options-wrap')
                        .find('li:not(.selected)').addClass('disabled')
                        .find('input[type="checkbox"]')
                            .attr( 'disabled', 'disabled' );
                }
                // max select not reached, make sure any disabled
                // checkboxes are available
                else {
                    $(element).next('.ms-options-wrap')
                        .find('li.disabled').removeClass('disabled')
                        .find('input[type="checkbox"]')
                            .removeAttr( 'disabled' );
                }
            }
 });

function Control_change()
   {
    var ctrlval=$("#ctrl_typ option:selected").val();
    var Gload="";
    if(ctrlval==1)
       {
        Gload="<select name="Names[]" multiple id="nameid" size="30">
                 <optgroup label='Label 1'>
                   <option value='1'>One</option>
                   <option value'2'>Two</option>
                   <option value='3'>Three</option>
                 </optgroup>
                 <optgroup label='Label 2'>
                   <option value='4'>Four</option>
                   <option value'5'>Five</option>
                   <option value='6'>Six</option>
                 </optgroup>
              </select>"; 
        $('#nameid').replaceWith(Gload);
       }
    else if(ctrlval==2)
       {
        Gload="<select name="Names[]" multiple id="nameid" size="30">
                 <optgroup label='Label 3'>
                   <option value='1'>One</option>
                   <option value'2'>Two</option>
                   <option value='3'>Three</option>
                 </optgroup>
                 <optgroup label='Label 4'>
                   <option value='4'>Four</option>
                   <option value'5'>Five</option>
                   <option value='6'>Six</option>
                 </optgroup>
              </select>";
        $('#nameid').replaceWith(Gload);
       }

   }

I am tried the above code but is not working well while select multiselect dropdown it giving error guide me to resolve the issue. I want to load the multiselect dropdown with group values.

Postgres.js problem with double quotes when creating an Enum

So I’m using Postgres.js to build an application and I’m creating an Enum for user roles like the following

import { PostgresError } from 'postgres';
import sql from './database/index.js';


const RolesEnum = {
    user : 'user',
    moderator : 'moderator',
    admin : 'admin'
} as const;

const Enum = ['user', 'moderator', 'admin'] as const;

async function Build() {
    try {
        await sql`DROP TYPE F_that;`.catch(() => {}); // IF DOESN'T EXIST THEN PASS
        const { statement } = await sql`CREATE TYPE F_that AS ENUM (${sql(
            Enum
        )});`;
        console.log(statement);
    } catch (error) {
        console.error(
            (error as PostgresError).query ?? (error as Error).message ?? error
        );
        /* Logs the following
          CREATE TYPE F_that AS ENUM ( "user", "moderator" , "admin" );*/
    }
}

await Build() // Logs the following: CREATE TYPE F_that AS ENUM ( "user", "moderator" , "admin" );`

as you see the problem is the double quotes in the Enum values which gives an Error in postgres my question is how to make them single quotes in the query

the closest solution I got was adding this to the catch block

if (error instanceof postgres.PostgresError) {
            error.query.replaceAll('"', "'"); // gets query with single quotes for the Enum
   }

which gives the right query but i can’t use it like above
(whenever i try get an error about a positional parameter i guess it runs at run time?)

Search in text only works partially

Need a friendly advise. I have this script to search and filter a list of data.
However, it seems that the search for keyword only works when entering one character.

Try to search for “John” below. It returns hits when hitting “j”, but then nothing when entering “jo”.

What’s the reason for this?

document.addEventListener('DOMContentLoaded', () => {

  'use strict';

  /**
   * Script to handle filtering and pagination out of a list of items 
   */
  const pagination = (el) => {
    const list = el.querySelector('.filter-items');
    const searchinput = el.querySelector('.search-input');
    const pagination = el.querySelector('.pagination-nav');
    const items = Array.from(el.querySelectorAll('.item'));
    const pagesize = parseInt(el.dataset.pagesize, 10) || 10;
    let filteredItems = items;
    let currPage = 1;

    /**
     * Search by keyword
     */
    const searchInput = () => {
      const keyword = el.querySelector('input[name=keyword]').value.trim();
      if (keyword) {
        filteredItems = items.filter(el => {
          return el.innerText.indexOf(keyword) > -1;
        });
      } else {
        filteredItems = items;
      }

      currPage = 1;

      if (filteredItems.length !== 0) {
        pagination.style.display = 'block';
        setHTML(filteredItems);
      } else {
        pagination.style.display = 'none';
        list.innerHTML = 'No data';
      }
    }

    /**
     * Search by input
     */
    searchinput.addEventListener('keyup', e => {
      searchInput();
    })

    const paginate = (totalItems, currentPage = 1, pageSize = 2, maxPages = 3) => {
      let totalPages = Math.ceil(totalItems / pageSize);
      if (currentPage < 1) {
        currentPage = 1;
      } else if (currentPage > totalPages) {
        currentPage = totalPages;
      }

      let startPage, endPage;
      if (totalPages <= maxPages) {
        startPage = 1;
        endPage = totalPages;
      } else {
        let maxPagesBeforeCurrentPage = Math.floor(maxPages / 2);
        let maxPagesAfterCurrentPage = Math.ceil(maxPages / 2) - 1;
        if (currentPage <= maxPagesBeforeCurrentPage) {
          startPage = 1;
          endPage = maxPages;
        } else if (currentPage + maxPagesAfterCurrentPage >= totalPages) {
          startPage = totalPages - maxPages + 1;
          endPage = totalPages;
        } else {
          startPage = currentPage - maxPagesBeforeCurrentPage;
          endPage = currentPage + maxPagesAfterCurrentPage;
        }
      }

      let startIndex = (currentPage - 1) * pageSize;
      let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

      let pages = Array.from(Array((endPage + 1) - startPage).keys()).map(i => startPage + i);

      // Add ellipsis after first page
      if (startPage > 1) {
        pages.unshift(startPage > 1 ? '...' : 2);
        pages.unshift(1);
      }
      // Add ellipsis before last page
      if (endPage < totalPages - 1) {
        pages.push(endPage < totalPages - 1 ? '...' : totalPages - 1);
      }
      if (endPage < totalPages) {
        pages.push(totalPages);
      }

      return {
        totalItems: totalItems,
        currentPage: currentPage,
        pageSize: pageSize,
        totalPages: totalPages,
        startPage: startPage,
        endPage: endPage,
        startIndex: startIndex,
        endIndex: endIndex,
        pages: pages
      };
    }

    const setHTML = (items) => {
      list.innerHTML = '';
      pagination.innerHTML = '';
      const {
        totalItems,
        currentPage,
        pageSize,
        totalPages,
        startPage,
        endPage,
        startIndex,
        endIndex,
        pages
      } = paginate(items.length, currPage, pagesize, 3)

      const ul = document.createElement('ul');
      ul.classList.add('pagination');
      let paginationHTML = '';

      paginationHTML += `<li class='page-item ${currentPage === 1 ? 'd-none' : 'previous'}'><a class='page-link' href='#' title='Previous'>Previous</a></li>`
      pages.forEach(page => {
        if (currentPage === page) {
          paginationHTML += `<li class='page page-item active' data-page='${page}'><a class='page-link' href='#' aria-current='page'>${page}</a></li>`;
        } else if (page === '...') {
          paginationHTML += `<li class='page-item-dots'><div>${page}</div></li>`;
        } else {
          paginationHTML += `<li class='page-item page' data-page='${page}'><a class='page-link' href='#'>${page}</a></li>`;
        }
      })

      paginationHTML += `<li class='page-item ${currentPage === endPage ? 'd-none' : 'next'}'><a class='page-link' href='#' title='Next'>Next</a></li>`

      ul.innerHTML = paginationHTML;
      pagination.append(ul);

      const start = (currentPage - 1) * pageSize,
        end = currentPage * pageSize;
      items.slice(start, end).forEach(el => {
        list.append(el);
      });
    }

    el.addEventListener('click', function(e) {
      e.preventDefault();
      const $this = e.target;

      if ($this.parentNode.classList.contains('page')) {
        currPage = parseInt($this.parentNode.getAttribute('data-page'));
        setHTML(filteredItems);
      }
      if ($this.parentNode.classList.contains('next')) {
        currPage += 1;
        setHTML(filteredItems);
      }
      if ($this.parentNode.classList.contains('previous')) {
        currPage -= 1;
        setHTML(filteredItems);
      }
    });

    setHTML(filteredItems);

  }

  const paginationblock = document.querySelectorAll('.pagination-block');
  if (paginationblock) {
    Array.from(paginationblock).forEach((el) => {
      pagination(el);
    });
  }
});
.items {
  display: flex;
  flex-direction: column;
  row-gap: .5rem;
  width: 100%;
  list-style: none;
  padding-left: 0;
}

.item {
  display: grid;
  grid-auto-rows: 1fr;
  grid-template-columns: 1fr 1fr 1fr;
  column-gap: 1rem;
  padding: .5rem 0;
}

h3 {
  margin: 0;
}

.pagination {
  display: flex;
  list-style-type: none;
  column-gap: 0.5rem;
}

.active .page-link {
  color: red;
}
<div class="pagination-block" data-pagesize="6">
  <form id="filters">
    <input type="search" name="keyword" class="search-input" placeholder="Search by keyword...">
  </form>

  <ul class="items filter-items">
    <li class="item">
      <h3>Jane Smith</h3>
      <div>Software Engineer</div>
      <div>(123) 456-7890</div>
    </li>
    <li class="item">
      <h3>John Doe</h3>
      <div>Project Manager</div>
      <div>(987) 654-3210</div>
    </li>
    <li class="item">
      <h3>John Dough</h3>
      <div>Project Coordinator</div>
      <div>(+45) 6167-3210</div>
    </li>
    <li class="item">
      <h3>John Dubois</h3>
      <div>UI Designer</div>
      <div>(321) 654-0987</div>
    </li>
    <li class="item">
      <h3>Jürgen Müller</h3>
      <div>DevOps Engineer</div>
      <div>(654) 321-7890</div>
    </li>
    <li class="item">
      <h3>Emily Johnson</h3>
      <div>UX Designer</div>
      <div>(555) 123-4567</div>
    </li>
    <li class="item">
      <h3>Michael Brown</h3>
      <div>Data Analyst</div>
      <div>(444) 987-6543</div>
    </li>
    <li class="item">
      <h3>Sarah Lee</h3>
      <div>Marketing Specialist</div>
      <div>(222) 333-4444</div>
    </li>
    <li class="item">
      <h3>David Kim</h3>
      <div>IT Support Technician</div>
      <div>(111) 222-3333</div>
    </li>
    <li class="item">
      <h3>Linda Martínez</h3>
      <div>HR Coordinator</div>
      <div>(777) 888-9999</div>
    </li>
    <li class="item">
      <h3>Renée Faure</h3>
      <div>Legal Advisor</div>
      <div>(888) 777-6666</div>
    </li>
    <li class="item">
      <h3>James Wilson</h3>
      <div>Network Engineer</div>
      <div>(666) 555-4444</div>
    </li>
    <li class="item">
      <h3>Olívia García</h3>
      <div>Financial Analyst</div>
      <div>(999) 888-7777</div>
    </li>
    <li class="item">
      <h3>Robert Patel</h3>
      <div>Product Owner</div>
      <div>(333) 444-5555</div>
    </li>
    <li class="item">
      <h3>Åsa Nordin</h3>
      <div>Cloud Architect</div>
      <div>(212) 343-4545</div>
    </li>
    <li class="item">
      <h3>Søren Kjær</h3>
      <div>AI Researcher</div>
      <div>(565) 787-8989</div>
    </li>
    <li class="item">
      <h3>Chloé Moreau</h3>
      <div>Quality Assurance</div>
      <div>(434) 232-1212</div>
    </li>
    <li class="item">
      <h3>Nikołaj Kowalski</h3>
      <div>Security Specialist</div>
      <div>(555) 666-7777</div>
    </li>
    <li class="item">
      <h3>André Silva</h3>
      <div>Scrum Master</div>
      <div>(888) 222-1111</div>
    </li>
    <li class="item">
      <h3>Zoë Chen</h3>
      <div>Technical Writer</div>
      <div>(999) 111-2222</div>
    </li>
    <li class="item">
      <h3>Frédéric Lemoine</h3>
      <div>Database Administrator</div>
      <div>(444) 123-9876</div>
    </li>
    <li class="item">
      <h3>Lucas Moretti</h3>
      <div>Business Analyst</div>
      <div>(777) 555-8888</div>
    </li>
    <li class="item">
      <h3>Mia Hernández</h3>
      <div>Content Strategist</div>
      <div>(666) 444-2222</div>
    </li>
    <li class="item">
      <h3>Léo Martin</h3>
      <div>Front-End Developer</div>
      <div>(123) 321-1234</div>
    </li>
    <li class="item">
      <h3>Isabella Rossi</h3>
      <div>Graphic Designer</div>
      <div>(432) 234-5432</div>
    </li>
    <li class="item">
      <h3>Olivier Dubois</h3>
      <div>Marketing Manager</div>
      <div>(555) 789-0123</div>
    </li>
    <li class="item">
      <h3>Fatima Al-Hassan</h3>
      <div>HR Manager</div>
      <div>(321) 654-4321</div>
    </li>
    <li class="item">
      <h3>Tomáš Novák</h3>
      <div>Software Tester</div>
      <div>(654) 987-1234</div>
    </li>
    <li class="item">
      <h3>Sophia Becker</h3>
      <div>Customer Success</div>
      <div>(789) 456-0987</div>
    </li>
    <li class="item">
      <h3>Mateo Fernández</h3>
      <div>Operations Manager</div>
      <div>(987) 654-3219</div>
    </li>
    <li class="item">
      <h3>Amélie Laurent</h3>
      <div>Sales Representative</div>
      <div>(123) 456-6789</div>
    </li>
    <li class="item">
      <h3>Jan Kowalski</h3>
      <div>Technical Support</div>
      <div>(321) 654-7890</div>
    </li>
    <li class="item">
      <h3>Yara Haddad</h3>
      <div>Project Coordinator</div>
      <div>(555) 333-2222</div>
    </li>
    <li class="item">
      <h3>Lucas Thompson</h3>
      <div>IT Manager</div>
      <div>(444) 123-4567</div>
    </li>
    <li class="item">
      <h3>Ingrid Svensson</h3>
      <div>Business Development</div>
      <div>(777) 987-6543</div>
    </li>
    <li class="item">
      <h3>Daniela Petrova</h3>
      <div>Data Scientist</div>
      <div>(222) 444-5555</div>
    </li>
    <li class="item">
      <h3>Akira Tanaka</h3>
      <div>Software Architect</div>
      <div>(111) 555-6666</div>
    </li>
    <li class="item">
      <h3>Clara Jensen</h3>
      <div>Content Writer</div>
      <div>(888) 999-0000</div>
    </li>
  </ul>
  <div class="pagination-nav"></div>
</div>

How to check if a class has child classes without loading the whole project?

I’m writing a custom PHPStan rule that suggests marking a class as readonly (introduced in PHP 8.2) when it meets all the necessary conditions.

One of the requirements for safely applying readonly is ensuring that the class has no child classes, because in PHP 8.2, if a parent is readonly, all its child classes must be readonly too.

The problem is, PHPStan doesn’t provide a simple, reliable way to check if a class is extended within the project during static analysis.

I’ve considered the following approaches:

  • Using Composer’s autoload_classmap.php, but with PSR-4 autoloading, it often doesn’t contain project classes.
  • Forcing composer dump-autoload -o --classmap-authoritative, which solves the problem but isn’t always acceptable for development setups.
  • Writing a custom file scanner that parses PHP files to extract namespace and class names to build a class map (either via simple regex or using nikic/php-parser).

Question:
What is the recommended or common approach to reliably detect child classes in a PHPStan custom rule, considering static analysis only?
Are there any best practices for this scenario, or do people generally rely on their own project-specific class scanning logic?

Yoast SEO Stopped Working After I Uploaded My Site To Hosting [closed]

After uploading the site to the hosting, the plugin stopped working correctly. It is impossible to enter the settings page, it is impossible to add meta tags. Please tell me, what could be the reason for this? In the page settings, the SEO block is displayed empty. When clicking on the tabs, nothing happens.

screenshot from the admin panel

AbanteCart 1.4.1 login redirects back to login page — session/cookie not persisting over HTTPS

I’m using AbanteCart v1.4.1 deployed on cPanel hosting under the subdirectory /shop with HTTPS enabled.

After successful login, the customer is immediately redirected back to the login page, and the session data is lost.

Session appears to drop right after the redirect:
Even though login is successful and session data is populated, AbanteCart doesn’t retain the session and goes back to the login screen.

What could cause AbanteCart session or cookies to reset immediately after login?

Are there known issues with secure cookies, session storage, or domain/path mismatch in this version?

Any recommendations for debugging or fixing persistent login sessions in AbanteCart v1.4.1?

Laravel: Google is indexing my site with subdomains, which are now obsolete. How to redirect?

Situateion:
In my app I had c. 20 subdomains. Now they are gone and https certificates with them.
However, Google is indexing my site with use of the subdomains, which was never the intention. EExample:
Google gets to http://booktitle.domainname.com/shop
and the desired URL for the shop should be https://domainname.com/shop

My solution:

now for some URLs I have created a middleware which processes the referer URL and redirects the user to the correct URL.
Note: There is c. 20 subdomains which are involved.

if(str_contains(url()->current(), 'obsoletesubdomain.domainname') {

    return Redirect::away('https://domainname.com'.request()->getPathInfo());
}

My questions

  1. Is there a better solution to handle the issue?
  2. Where should I put the middleware in Laravel 12 in order to handle the obsolete subdomains sitewide?

Thank you.

How to retrieve key backup on matrix-js-sdk?

I’m trying to code a groupchat app with the matrix js sdk. I’m a bit struggling with the keybackup. I create it but when i logout and login again, i have the error below. Idk if the problem comes from how i created it, how i recover it or the secret storage etc …

Here is my function:


    private async bootstrapKeyBackup(): Promise<void> {
        const crypto = this.client.getCrypto();
        if (!crypto) throw new Error('[CryptoService] Crypto API not available!');
    
        console.log('[CryptoService] Vérification du backup de clés...');
    
        const backupInfo = await crypto.checkKeyBackupAndEnable();
    
        if (backupInfo) {
          console.log('[CryptoService] Backup existant détecté : ', backupInfo);
    
          const passphrase = CryptoService.getPassphrase();
    
          const restoreResult = await crypto.restoreKeyBackupWithPassphrase(
            passphrase
          );
          console.log(
            '[CryptoService] Clés restaurées depuis le backup :',
            restoreResult
          );
          return;
        }
    
        console.log('[CryptoService] Aucun backup trouvé, création...');
    
        try {
          await crypto.resetKeyBackup();
          console.log('[CryptoService] Nouveau Key Backup configuré !');
        } catch (err) {
          console.error('[CryptoService] Échec création Key Backup :', err);
        }
      }

logs on the first login

logs after logout+login

Error: Uncaught (in promise) Error: Salt and/or iterations not found: this backup cannot be restored with a passphrase

Thanks a lot !