Make a function that creates a grid

The idea is:

  • a random number, “lets say 4000”
  • I have limited space defined by a function
  • I want to change the properties of a class to fit these parameters
  • i want to make 4000 boxes fit in the parametrized scope
  • and i want to alternate color on click

I’m stuck at generating the ‘div’ boxes. Any help would be greatful;

$(document.body).on('click', 'span', function (e) {

    $(this).addClass('color');

    // 1) squares can be either white, yellow or purple.
    // 2) if a square is yellow and it's clicked on, it turns purple and visa versa
    
    /* 3) there needes to be an enumeration of quadrants
        and there needs to be at least four of them...
    */
    
    // ajecent squares can only be clicked on based on initial pattern... 
    // then 
     
});
div {
}
span {
    height: 2em;
    width: 2em;
    border: solid 1px lightGray;
    display: inline-block;
}
span.color {
    background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!-- code block -->
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<!-- code block -->
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<!-- code block -->
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<!-- code block -->
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div>
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>

How do I call a Function in window2 from the page I opened it from window2?

I and trying to open a window with the window.open code,

var myWindow = window.open(url , name, details);

and then I want to execute a function in that window after it loads.

var myWindow = window.open(url , name, details);
myWindow.doSomething();

The Idea is to have it both triggered by a button, HTML based.

I have just been rewriting it in different ways, and thus far nothing seems to work. Any input would be appreciated.

How to implement a sliding animation for icons in React with Tailwind CSS?

I’m new to React and trying to create a slide effect for ‘Upcoming Icons’ that are stacked at the bottom of the screen. As progress is made and a stage is completed, I want each icon to slide off the screen.

The fade effect and Tailwind CSS are working fine, but the sliding effect isn’t working. I’m used to working with separate CSS files, but this time I have to do it with Tailwind, and I’m not sure how to implement the sliding animation. Can someone help me with this?

here is my progress.jsx

import React from 'react';
import { IdCard, CreditCard, Activity, Info, CheckCircle } from 'lucide-react';

const ProgressBar = ({ step }) => {
  return (
    <div className="flex flex-col items-center relative h-screen py-24 overflow-hidden">
      {/* Title */}
      <h1 className="text-2xl font-bold mb-4 text-center text-purple-600">Your Cards</h1>

      {/* Dots */}
      <div className="flex justify-center space-x-1 mb-4">
        <div className="h-2 w-2 bg-purple-500 rounded-full"></div>
        <div className="h-2 w-2 bg-purple-500 rounded-full"></div>
        <div className="h-2 w-2 bg-purple-500 rounded-full"></div>
        <div className="h-2 w-2 bg-purple-500 rounded-full"></div>        <div className="h-2 w-2 bg-purple-500 rounded-full"></div>
        <div className="h-2 w-2 bg-purple-500 rounded-full"></div>
      </div>

      {/* Progress Bar */}
      <div className="relative h-[90%] w-12">
        <div className="relative w-1 h-full bg-gray-300">
          <div 
            className="absolute w-full bg-gradient-to-t from-red-500 to-fuchsia-600 transition-height ease-in-out duration-500" 
            style={{ height: `${(step / 5) * 100}%`, top: 0 }}  // Ensure gradient fills from top to bottom
          />
        </div>

        {/* Icons along the progress bar */}
        <div className="absolute top-0 flex flex-col items-center h-full space-y-0">
          {[IdCard, CreditCard, Activity, Info, CheckCircle].map((Icon, index) => {
            const isActive = step === index + 1;
            const isCompleted = step > index + 1;
            const isUpcoming = step < index + 1;

            const baseClasses = "flex justify-center items-center relative transition-all ease-in-out duration-500";
            
            // Adjust positions: top for the first icon, bottom stack for the rest
            const iconWrapperClasses = isActive
              ? "z-10 transform translate-y-0"  // Active icon moves to the top
              : isCompleted
              ? "opacity-0 transform -translate-y-full"
              : index === 0
              ? "translate-y-0"  // Keep the first icon at the top
              : "transform translate-y-full";  // Stack other icons at the bottom

            const circleClasses = isActive
              ? "w-12 h-12 border-2 border-purple-600 bg-gradient-to-r from-red-500 to-fuchsia-600"
              : "w-8 h-8 border-2 border-gray-400 bg-black";

            const iconClasses = isActive ? "w-6 h-6 text-white" : "w-4 h-4 text-gray-400";

            return (
              <div key={index} className={`${baseClasses} ${iconWrapperClasses}`}>
                <div className={`${circleClasses} rounded-full flex justify-center items-center`}>
                  <Icon className={iconClasses} />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

export default ProgressBar;

I tried changing every line of my code but nothing worked

How to set testUrl in vitest?

I’m testing mocked api calls in my app but all of these calls are now running from http://localhost

In jest there used to be a testUrl configuration I could set to define my test environment url so that all mocked api calls would come from that url instead. How do I do this in Vitest?

In Jest it looked something like that:

const config = {
  testEnvironment: 'jsdom',
  testEnvironmentOptions: {
    html: '<html lang="zh-cmn-Hant"></html>',
    url: 'https://jestjs.io/',
    userAgent: 'Agent/007',
  },
};

JavaScript methods called from variables of type number

let x=5; // x has type number
alert(x.toString()); // why does this work, since x is a number variable, not an object?

x.toString() should not work, since x is not an object.
Similarly, 10.toString() does not work,
but (10).toString() does work.

I was expecting that the toString() method would not work on any of these cases, since neither x, 10, nor (10) are objects.

I also noticed that x[“toString()”] returns undefined, creating another puzzle.

NW.js Help Needed with nw-builder for macOS ARM64. Error: unknown option ‘–mode=build’

Since nw-builder-phoenix doesn’t support macOS ARM64, I decided to switch to nw-builder.

However, I’m struggling to understand how nw-builder works. I created a simple test project following the README notes, but I’m encountering errors. I might be doing something wrong, but I want to at least run something very simple at first. I’ve tried both the CLI method and the Node manifest method, but neither has worked.

Currently, I’m getting the following error: error: unknown option '--mode=build'

Any help or guidance would be greatly appreciated!

Here’s the code:

index.html

    <!DOCTYPE html>
<html>
  <head>
    <title>NW.js Demo</title>
  </head>
  <body>
    <h1>Hello, NW.js!</h1>
    <button id="myButton">Click Me!</button>
  </body>
  <script src="main.js"></script>
</html>

main.js

document.getElementById("myButton").addEventListener("click", function () {
  alert("Button clicked!");
});

package.json

{
  "name": "nw-builder-demo",
  "version": "0.0.1",
  "description": "A Simple nw-builder DEMO",
  "main": "index.html",
  "volta": {
    "node": "22.7.0"
  },
  "scripts": {
    "start": "nw .",
    "build": "nwbuild --mode=build --glob=false --flavor=normal --arch=arm64 --cacheDir=./node_modules/nw  --outDir=./build ."
  },
  "app": {
    "id": "com.example-demo.nwjs-builder",
    "name": "NW.js Demo",
    "description": "A simple NW.js demo application."
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "base-volta-off-of-nwjs": "^1.0.5",
    "nw": "^0.92.0",
    "nw-builder": "^4.11.4"
  }
}

Add a separator only if there is more than one element

I have a todo list that I made with the help of Pranav Rustagi and Twisty. I still have a problem for which I can’t find a solution.

Between each text added, I want to add a separator (pipe). My problem is that when I delete the first element, the next element, which becomes the first one, has an unwanted pipe.

So how can I add a separator only if there is more than one element, and only if it’s not the first element ?

To reproduce the scenario: add a, b, c, and then delete a. You’ll see the pipe before the b still there. Is it better to imagine a pipe only if there is an element after?

One main issue here is the empty() inside the remove function. It doesn’t delete the span.output from the DOM so I cannot use first() or do something in css like :

.output:not(:first-of-type):before {
  content:'|';
  padding:0 5px;
}

I can’t use remove() instead of empty() either because I won’t be able to add a line again if I delete them all.

Any help would be appreciated.

$(function() {
  $(".container").on('input', 'input[type=text]', function(event) {
    var i = $(this).closest(".flex-row").index();
    var v = (i == 0) ? $(this).val() : "|" + $(this).val();
    $("#custom_wrapper .output").eq(i).html(v);
  });

  $('.add').click(function() {
    var count = $("input").length;
    count++;
    var row = $("<div>", {
      class: "flex-row"
    }).insertBefore(this);
    $("<label>").appendTo(row);
    $("<input>", {
      type: "text",
      class: "input",
      id: "custom-text-" + count,
      placeholder: "custom text " + count,
      tabindex: count
    }).appendTo($("label", row));
    $("<button>", {
      class: "remove"
    }).html("-").appendTo(row);
    $("<span>", {
      class: "output",
      dataid: "custom-text-" + count
    }).insertAfter($("#custom_wrapper .output:last"));
  });

  $('body').on('click', '.remove', function() {
    $(this).parent('.flex-row').remove();
    var j = $(this).parent().find('.input').attr("id");
    $('#custom_wrapper .output[dataid="' + j + '"').empty();
  })
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<div class="container">
  <div class="wrapper">
    <article>
      <section>
        <div class="flex-row">
          <label
            ><input
              class="input"
              type="text"
              name=""
              id="custom-text-1"
              placeholder="custom text"
              tabindex="1" /></label
          ><button class="remove">-</button>
        </div>
        <div class="flex-row">
          <label
            ><input
              class="input"
              type="text"
              name=""
              id="custom-text-2"
              placeholder="custom text 2"
              tabindex="2" /></label
          ><button class="remove">-</button>
        </div>
        <button class="add">+</button>
        <div class="flex-row">
          <div class="token">
            {{customText[<span id="custom_wrapper"><span class="output" dataid="custom-text-1"></span><span class="output" dataid="custom-text-2"></span></span>]}}
          </div>
        </div>
      </section>
    </article>
  </div>
</div>

Item categories filtering with multiple categories – Javascript

I have a question about showing multiple categories on the page by clicking multiple buttons. Codepen:
https://codepen.io/alena-chuyankova/pen/YzmWYKZ

  1. By default all pages are active;
  2. When I click and unclick certain buttons the cards with the same categories should apper and hide (works for one category so far);
  3. When I have multiple buttons it should show and hide cards with according categories. Like if the user wants to see product with Salmon and Shrimp cards that contain Salmon and Shrimp should be shown. Like if some button is active to show everything that contains the button inner text if that makes sense.
    Thank you so much!

let products = {
  data: [
    {
      productName: "Fantasy",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Salmon, Shrimp",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-diego-pontes-901015-2323391.jpg",
    },
    {
      productName: "Spring",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Veggie",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-pixabay-357756.jpg",
    },
    {
      productName: "Rainbow",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Salmon, Tuna, Unagi",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-freestockpro-3147493.jpg",
    },
    {
      productName: "Unique",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Salmon, Tuna, Unagi, Shrimp",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-photo-248444.webp",
    },
    {
      productName: "Perfection",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Salmon",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-isabella-mendes-107313-858501.jpg",
    },
    {
      productName: "Style",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Salmon, Tuna, Unagi, Shrimp",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-rajesh-tp-749235-2098143.jpg",
    },
    {
      productName: "Dreamy",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Salmon",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-viniciusbenedit-3620705.jpg",
    },
    {
      productName: "Spicy",
      heart: "./icons/heart.svg",
      heartCount: 2547,
      category: "Shrimp",
      content:
        "Lorem ipsum dolor sit amet, eu mei posse possim atomorum, vix cu fabellas assueverit. Vel ad option partiendo maiestatis, nec affert appetere te, his.",
      picture: "./images/pexels-catscoming-699544.jpg",
    },
  ],
};

for (let i of products.data) {
  let card = document.createElement("div");
  card.classList.add("card", "i.category");

  //image

  let imgContainer = document.createElement("div");
  imgContainer.classList.add("image-container");
  let image = document.createElement("img");
  image.classList.add("product-img");
  image.setAttribute("src", i.picture);
  imgContainer.appendChild(image);
  card.appendChild(imgContainer);
  document.getElementById("products").appendChild(card);
  card.setAttribute("title", i.category);

  image.addEventListener("error", () => {
    image.style.display = "none"; // Hide the broken image
    image.parentNode.style.backgroundColor = "#d9d9d9"; // Set background color
  });

  //content

  let content = document.createElement("div");
  content.classList.add("content");
  card.appendChild(content);

  //content title and likes section

  let contentHead = document.createElement("div");
  contentHead.classList.add("contentHead");
  let productTitle = document.createElement("h2");
  productTitle.classList.add("productTitle");
  productTitle.innerText = i.productName;

  let likesSection = document.createElement("div");
  likesSection.classList.add("likesSection");
  let likesIcon = document.createElement("img");
  likesIcon.setAttribute("src", "./icons/heart.svg");
  likesIcon.classList.add("likesIcon");
  let likesCount = document.createElement("p");
  likesCount.classList.add("likeCount");
  likesCount.innerText = i.heartCount;

  content.appendChild(contentHead);
  contentHead.appendChild(productTitle);
  contentHead.appendChild(likesSection);
  likesSection.appendChild(likesIcon);
  likesSection.appendChild(likesCount);

  likesIcon.addEventListener("error", () => {
    likesIcon.setAttribute(
      "src",
      "https://upload.wikimedia.org/wikipedia/commons/f/f1/Heart_coraz%C3%B3n.svg"
    );
  });

  //gray line devider
  let line = document.createElement("hr");
  line.classList.add("product-line");
  content.appendChild(line);

  //item category

  let itemCategory = document.createElement("p");
  itemCategory.classList.add("item-category");
  itemCategory.innerText = i.category;
  content.appendChild(itemCategory);

  //description

  let itemDescription = document.createElement("p");
  itemDescription.classList.add("itemDescription");
  itemDescription.innerText = i.content;
  content.appendChild(itemDescription);

  //read more
  let readMore = document.createElement("p");
  readMore.classList.add("readMore");
  readMore.innerText = "Read more >>>";
  content.appendChild(readMore);
}

let buttons = document.querySelectorAll(".category-button");
let cards = document.querySelectorAll(".card");
let buttonArr = [];
let buttonsString;

buttons.forEach((button) => {
  button.addEventListener("click", () => {
    let buttonValue = button.innerText;
    button.classList.toggle("active-button");
    if (button.classList.contains("active-button")) {
      buttonArr.push(buttonValue);
    }
    if (button.classList.contains("active-button") == false) {
      let unwantedButtonValue = buttonValue;
      let index = buttonArr.indexOf(unwantedButtonValue);
      buttonArr.splice(index, 1);
    }
    buttonArr.sort();
    buttonsString = buttonArr.toString();
    console.log(buttonsString);
  });

  buttons.forEach((button) => {
    button.addEventListener("click", () => {
      cards.forEach((card) => {
        let cardCategories;
        cardCategories = card
          .getAttribute("title")
          .split(",")
          .map(function (value) {
            return value.trim();
          })
          .sort()
          .toString();
        console.log(cardCategories);
        if (cardCategories.includes(buttonsString) == false) {
          card.classList.add("inactive-card");
        }
        if (cardCategories.includes(buttonsString)) {
          card.classList.remove("inactive-card");
        }
      });
    });
  });
});

A confirmation popup and Subsequent action

I have a dataTables HTML table on Apache that is generated daily showing all the VMs in a proxmox cluster.

The table is generated dynamically everyday by API calls to Proxmox.
I want to be able to shutdown or reboot a VM by clicking a link, button, image, whatever for that VM in its row in the HTML table.

I am able to do this by creating a link in a cell in each row, pointing to a html page that calls a bash script in cgi-bin,

The link looks like this for reboot, for exanple:

<a href=$VMNAME-reboot.html ><img src="rebootIcon.png"</a>

Basically there is an icon for reboot that you click and it just links to another html page.

So for a VM named MYDC01, the link points to MYDC01-reboot.html.
This html file loads an iframe in which there is a call to a cgi-bin script :

cgi-bin/reboot.sh?MYDC01

The reboot script takes the ${QUERY_STRING} and does an API call to proxmox and reboots the VM.

This works .. but ….. there is no confirmation pop up.

What I want is to click the reboot link, get a pop up that says “are you sure?” OK/Cancel.

I was looking at something like :
https://www.cssscript.com/confirmation-popup-dialog/

I was able to copy the source to my Apache and just create a dummy page, and I get the pop up with OK and Cancel.

But I don’t know enough about Javascript to know how to make the “OK” button actually do something.

And of course I need something dynamic because there is a different VMname in each row of the table and a number of different functions (Reboot, Reset, Start, Shutdown etc).

There could conceivably be custom code for each VM in each row of the table if need be as the table is being created daily.

Currently I get all the VMs into a csv file, then loop through the VMs and build a table row per VM.

# Create html rows
TROW="
<tr><td>$CLUSTER</td>
<td><a href=https://$NODE:8006 target=_blank>$NODE</a></td>
<td>$VMNAME</td>
<td><a href=$VMNAME-reboot.html><img src="rebootIcon.png"></a></td>
</tr>

Thinking about how this would work, I click on a reboot icon in the row for MYDC01, I get a pop up, I choose OK .. and that would then have to know to action on MYDC01.

Alternatively each row, could have a checkbox, I select a row, and then click a reboot icon somewhere on the page, get a pop up and then “OK” would reboot that VM, but I don’t know how to do that.

Any help or ideas would be greatly appreciated.

thanks

import JUST typescript definitions in lazy files for LSP

I am bundling one main_bundle.js file for my web app. And also bundling many smaller lazy files that are separate from main_bundle. Most every view or component in my app is a lazy file that is dynamically imported only as needed. main_bundle contains utility functions (originally as separate ts files that are bundled all up at build time). These utility functions expose functions to a scoped namespace on window. These functions need to be available to every view on the app.

It’s no problem accessing the functions on each lazy view, since it is available in the scoped window namespace. But, I also need to have LSP support in my editor.

I can do this:

import { UtilityFunction, UtilityFunctionReturnType, etc, etc } from "../../utilfunction.js"

That works great for my LSP. But, when compiling and bundling with esbuild, that whole body of js is sucked in to my lazy file … which is very bad.

Is there a way, in esbuild, tsconfig, SWC or any other method, of only pulling in declarations for my LSP and disabling bundling on build?

I can hack it in my build script by removing the import lines, but if there is a more standard way of doing this Id rather go with that, as I want as least custom build tooling as I can get away with.

How do I split a comma separated string into an array and map to multiple HL7 segments using JavaScript?

I am attempting to convert a single JSON field into multiple HL7 NTE segments based on the number of comma separated values.

Example:

JSON Input

"caseComments" : "+ ABC, + CBA, + CAB",

HL7 Output

NTE|1|+ ABC|
NTE|2|+ CBA|
NTE|3|+ CAB|

Number of comma separated values changes per message

Normally the JSON has multiple separate segments with an individual value in each and I can split based on a predetermined number of values.

But, I am unsure how to take the string split it into an array with different amounts each time and map each value to a single NTE each.

Angular – fakeAsync tests fail after switching from es2016 to es2018 or higher

I am working on an upgrade of my project and i wanted to make sure i was using more up to date ECMAScript.

In my tsconfig.spec.json files I had es2016, and i updated it to be 2018, and even tried out es2022.

Most of my tests will pass after changing versions, but I have a small handful that fail now. For example, I have this method that closes and destroys a modal.

  async destroyModal(): Promise<void> {
    const { modalComponentType, modalComponentRef } = this._state$.value;
    document.querySelector('dialog')?.close();
    this.setState({ modalComponentType, modalComponentRef, modalOpen: false }, ModalStateActions.CloseModal);

    // Wait for 300ms for animation before proceeding
    await new Promise(resolve => setTimeout(resolve, 300));

    // Clear the modal container and notify observers
    this.resetModal();
  }

And I test this like so:

  it('should destroy modal on esc press', fakeAsync(() => {
    service.initModalContainer(hostComponent.componentInstance.viewContainerRef);
    service.createModal(DummyComponent).then(() => verifyModalCreated());
    tick();
    dispatchEscPressEvent();
    tick(500);
    verifyModalDestroyed();
  }));

When using es2016, the test correctly simulates the passage of time and then calls verifyModalDestroyed(). However, when using es2018 or es2022, verifyModalDestroyed() will be called and the test will fail before the Promise resolves inside the destroyModal() method. It is as if tick() has no effect anymore after the update.

Can anyone help me understand that the issue is or what has changed between the versions that these kinds of tests would start failing?

line break on text created by createElementNS

I feel like I have a very dumb question: I create a text with the following command:

text = document.createElementNS("http://www.w3.org/2000/svg", "text")
text.textContent = "some very long text"

How can I make the string printed span over many lines? The common 'n' doesn’t work. And I found some solutions for html text using the <br/> command, but I don’t know to convert the text to html. I also tried

text.innerHTML = "some text" + <br/> + "some more text"

but this didn’t work.

Dropdown not only works in Laravel Blade but on any editor it works great

As already described in the header I’m having a problem.

The dropdown doesn’t work in Laravel Blade, but it works on any editor (as you can very well verify below with the code).

I am using Bootstrap 5.0.2

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link href="https://cdn.datatables.net/v/dt/jq-3.7.0/dt-2.1.8/datatables.min.css" rel="stylesheet">
    <script src="https://cdn.datatables.net/v/dt/jq-3.7.0/dt-2.1.8/datatables.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lipis/[email protected]/css/flag-icons.min.css" />

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>

    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

    <title>Project Laravel</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">Navbar</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNavDropdown">
      <ul class="navbar-nav">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Features</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Pricing</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown link
          </a>
          <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <li><a class="dropdown-item" href="#">Action</a></li>
            <li><a class="dropdown-item" href="#">Another action</a></li>
            <li><a class="dropdown-item" href="#">Something else here</a></li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</nav>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
</body>

</html>

After many attempts I saw that to make it work I have to add both the cdn of ‘Bootstrap Bundle with Popper’, that is

<!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

and the cdn of ‘Separate Popper and Bootstrap JS’, that is

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>

(all 3 together, which is not good). (SEE CODE BELOW)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link href="https://cdn.datatables.net/v/dt/jq-3.7.0/dt-2.1.8/datatables.min.css" rel="stylesheet">
    <script src="https://cdn.datatables.net/v/dt/jq-3.7.0/dt-2.1.8/datatables.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

    <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lipis/[email protected]/css/flag-icons.min.css" />

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>

    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

    <title>Project Laravel</title>

    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container-fluid">
            <a class="navbar-brand" href="#">Navbar</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNavDropdown">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link active" aria-current="page" href="#">Home</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Features</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Pricing</a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            Dropdown link
                        </a>
                        <ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
                            <li><a class="dropdown-item" href="#">Action</a></li>
                            <li><a class="dropdown-item" href="#">Another action</a></li>
                            <li><a class="dropdown-item" href="#">Something else here</a></li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>

    <script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/toastify-js"></script>
</body>

</html>

Now it doesn’t work here anymore, while on my Laravel project it works fine.

I know that you don’t have to put both options regarding cdn, but I don’t know what to do anymore.

Can someone please help me?

How to inject HTML into document.documentElement.innerHTML without closing the tag

I have about 100 lines of boilerplate HTML that every file on my site begins with. It contains the following elements:

<!-- START OF BOILERPLATE TEXT -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta ...>
  <link href="..." rel="stylesheet">
  <script src="..."></script>
  <title>MY_TITLE</title>
</head>
<body>
  <div> Page banner ... </div>
  <hr>
<!-- END OF BOILERPLATE TEXT -->

I’d like to minimize the actual amount of boilerplate code needed for each page, and I’ve come up with the following solution:

<!-- Line 1 of actual code will load external script:

     <script src="/test/scripts/boot.js"></script> 

     For this demo I'm inlining it.   -->

<script>
  async function boot(title) {

    // Will insert header boilerplate in document.documentElement.
    // Actual code will fetch boilerplate code from server.

    const my_demo = `
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- ****************** page-specific <head> stuff ***************** -->
    <title>${title}</title>
  <!-- ****************** end page-specific stuff    ***************** -->
</head>
<body>
    <h1>Injected by boot.js</h1>
    <hr> <!-- end of page header -->
    <!-- ****************** begin page content ***************** -->
`;

    try {
      document.documentElement.innerHTML = my_demo;
    } catch (my_error) {
      document.write('Error: ', my_error);
    }
  }
</script>

<!-- Line 2 of actual code will invoke boot() -->

<script>boot("Test Title")</script>

<!-- Now we begin adding our body html -->

<p>
  This is the actual content of the page. It should appear under the injected H1 and HR.
</p>

When I browse it, the boot() script appears to correctly insert my <head> and banner html, but my “actual content” doesn’t appear underneath. According to the Safari debugger, there was a </body> tag inserted after the last line inserted by boot(). How can I prevent that?