Counter not Resetting – Javascript

I currently have a program with some teams that are in pairs. Clicking on a team increases the Wins of the team being clicked, and increases the Losses of the pair it is linked to. A team with two losses is disabled and changes their text to “Eliminated”.

I have a reset button that is supposed to clear all of the counters and, in theory, by clearing the counters the disabled buttons should be reenabled again. However, this is not the case. Looking at the console you can see the buttons don’t restart their count until you press them, meaning the disabled buttons stay disabled, but what puzzles me is that their text switches back to the team name. How do I get the counter to reset completely after I press the reset button?

Any input would be greatly appreciated 🙂

let groups = [{
    name: "Chaos Coordinators",
    wins: 0,
    losses: 0
  },
  {
    name: "Sofa King Awesome",
    wins: 0,
    losses: 0
  },
  {
    name: "The Nerd Herd",
    wins: 0,
    losses: 0
  },
  {
    name: "The Laughing Stock",
    wins: 0,
    losses: 0
  },
  {
    name: "Brainy Bunch Gone Wild",
    wins: 0,
    losses: 0
  },
  {
    name: "Cereal Killers",
    wins: 0,
    losses: 0
  },
  {
    name: "The Mismatched Socks",
    wins: 0,
    losses: 0
  },
  {
    name: "The Awkward Turtles",
    wins: 0,
    losses: 0
  }
];


// Create pairs from the groups
function makeMatches(array) {
  return array.map((_, i) => (i % 2 === 0) ? [array[i], array[i + 1]] : []).filter(v => v.length === 2);
}

let matches = makeMatches(groups);

// Create a map of team names to their index
const groupIndexMap = {};
groups.forEach((group, index) => {
  groupIndexMap[group.name] = index;
});

// Function to handle button clicks
function handleButtonClick(groupName) {
  const matchIndex = groupIndexMap[groupName];
  const match = matches.find(match => match.some(group => group.name === groupName));


  if (!match) return;

  match.forEach((group, button) => {
    if (group.name === groupName) {
      group.wins += 1;
    } else if (group.losses < 2) {
      group.losses += 1;
    }
  });

  updateButtonTexts();
  console.log(groups);
}

// Function to update button texts
function updateButtonTexts() {
  groups.forEach((group, index) => {
    const button = document.getElementById(`button${index + 1}`);
    if (button) {
      button.textContent = `${group.name} - Wins: ${group.wins} - Losses: ${group.losses}`;
    }
    if (group.losses == 2) {
      button.textContent = 'Eliminated';
      button.disabled = true;
    }
  });
}

// Function to reset all counters
function resetCounters() {
  groups.forEach(group => {
    group.wins = 0;
    group.losses = 0;
  });
  updateButtonTexts();
}


// Initialize button click handlers
function initializeButtons() {
  groups.forEach((group) => {
    const button = document.querySelector(`[data-team-name='${group.name}']`);
    if (button) {
      button.onclick = () => handleButtonClick(group.name);
    }
  });

  // Initialize reset button handler
  document.getElementById('resetButton').onclick = resetCounters;

  // Initial update of button texts
  updateButtonTexts();
}

// Initial render and setup
initializeButtons();
#group-buttons {
  position: relative;
  /* Container should be relative for positioning buttons absolutely */
  width: 100%;
  height: 500px;
  /* Adjust height as needed */
  border: 1px solid #ccc;
}

.group-button {
  position: absolute;
  /* Allows for free positioning */
  cursor: pointer;
  /* Indicates the element is clickable */
  padding: 10px;
  background: #f0f0f0;
  border: 1px solid #ddd;
  border-radius: 5px;
}


/* Example styles for individual buttons */

#button1 {
  top: 50px;
  left: 50px;
}

#button2 {
  top: 50px;
  left: 200px;
}

#button3 {
  top: 150px;
  left: 50px;
}

#button4 {
  top: 150px;
  left: 200px;
}

#button5 {
  top: 250px;
  left: 50px;
}

#button6 {
  top: 250px;
  left: 200px;
}

#button7 {
  top: 350px;
  left: 50px;
}

#button8 {
  top: 350px;
  left: 200px;
}
<button id="resetButton">Reset All Counters</button>
<div id="group-buttons">
  <button id="button1" class="group-button" data-team-name="Chaos Coordinators">Chaos Coordinators - Wins: 0 - Losses: 0</button>
  <button id="button2" class="group-button" data-team-name="Sofa King Awesome">Sofa King Awesome - Wins: 0 - Losses: 0</button>
  <button id="button3" class="group-button" data-team-name="The Nerd Herd">The Nerd Herd - Wins: 0 - Losses: 0</button>
  <button id="button4" class="group-button" data-team-name="The Laughing Stock">The Laughing Stock - Wins: 0 - Losses: 0</button>
  <button id="button5" class="group-button" data-team-name="Brainy Bunch Gone Wild">Brainy Bunch Gone Wild - Wins: 0 - Losses: 0</button>
  <button id="button6" class="group-button" data-team-name="Cereal Killers">Cereal Killers - Wins: 0 - Losses: 0</button>
  <button id="button7" class="group-button" data-team-name="The Mismatched Socks">The Mismatched Socks - Wins: 0 - Losses: 0</button>
  <button id="button8" class="group-button" data-team-name="The Awkward Turtles">The Awkward Turtles - Wins: 0 - Losses: 0</button>
</div>

Calling a javaScript function in a php echo dosnt work [duplicate]

I have a website where, under certain conditions, a PHP file is executed. Within this PHP function, an if statement includes an echo that is supposed to call a JavaScript function. However, instead of executing the JavaScript, it simply displays the code as text. I’ve also tried using a simple alert, but it still doesn’t work. Interestingly, when I access the PHP file directly, without invoking it through the HTML page via a button, it works perfectly fine. What could be causing this issue?

here is some code:

call in html:

<form id="form" action="assets/php/file.php" method="POST" onsubmit="submitEditForm(event)">

the echo in the php file:

echo '<script type="text/javascript">', 'alert("hello world!");', '</script>';

result: (the text that is displayed on the website through the echo):

<script type="text/javascript">alert("hello world!");</script>

I hope we can find the problem or, alternatively, a way to implement it.your text

JSON Response having count not getting in each loop using JQUERY

I have a JSON response where I have count of 3 records like below

(3) [{…}, {…}, {…}] 0 : {IMG_TYPE: 'Panaromic', IMAGES: '120.jpg,150.jpg,180.jpg,210.jpg,240.jpg,270.jpg,90.jpg,90270.jpg'} 1 : {IMG_TYPE: 'Satellite', IMAGES: '4819.jpg,5520.jpg,7411.jpeg,935.jpg,O3B.jpg'} 2 : {IMG_TYPE: 'SitePlot', IMAGES: 'Anti Bribery & Anti Corruption Policy (2021 - 22).pdf'}

With above JSON Response I want to bind the data in my control in front. But in below $.each(JsonObject, function (index, Value) it’s not getting inside that each loop and getting outside the loop.

Below is the Jquery for the same

function getImages(JsonObject, SAPID, CANDIDATEID) {
    try {
        var SapID_CandidateID = SAPID + "_" + CANDIDATEID;
        var ImagePath = SapID_CandidateID + "/";
        $.each(JsonObject, function (index, Value) {
            if (Value["IMG_TYPE"] == EnumImageType.PanaromicImage) {

                var PanaromicImages = Value["IMAGES"].split(',');

                for (i = 0; i < PanaromicImages.length; i++) {
                    var ImgNameID = PanaromicImages[i].split('.');
                    var ImgID = "Img" + Value["IMG_TYPE"] + ImgNameID[0];
                    var ImgObj = document.getElementById(ImgID);

                    ImgObj.src = SharedFilePath + ImagePath + Value["IMG_TYPE"] + "/" + PanaromicImages[i];
                    $(ImgObj).attr("data-imagename", PanaromicImages[i]);
                }
            }
            else if (Value["IMG_TYPE"] == EnumImageType.SatalliteImage) {
                var SatelliteImages = Value["IMAGES"].split(',');
                for (i = 0; i < SatelliteImages.length; i++) {
                    var ImgNameID = SatelliteImages[i].split('.');
                    var ImgID = "Img" + Value["IMG_TYPE"] + ImgNameID[0];
                    var ImgObj = document.getElementById(ImgID);

                    ImgObj.src = SharedFilePath + ImagePath + Value["IMG_TYPE"] + "/" + SatelliteImages[i];
                    $(ImgObj).attr("data-imagename", SatelliteImages[i]);
                }
            }
            else if (Value["IMG_TYPE"] == EnumImageType.SitePlotImage) {
                var SitePlotImages = Value["IMAGES"];

                var pdfImage = SitePlotImages.split('.');

                if (pdfImage[1] == 'pdf') {
                    parent.document.getElementById('PdfPathLink').style.display = 'block';
                    parent.document.getElementById('PdfPathLink').href = SharedFilePath + ImagePath + Value["IMG_TYPE"] + "/" + SitePlotImages;
                    parent.document.getElementById('PdfPathLink').innerText = SitePlotImages;
                    document.getElementById('ImgSitePlotManual').style.display = 'none';
                }
                else {
                    parent.document.getElementById('PdfPathLink').style.display = 'none';
                    var ImgID = "ImgSitePlotManual";
                    var ImgObj = document.getElementById(ImgID);

                    ImgObj.src = SharedFilePath + ImagePath + Value["IMG_TYPE"] + "/" + SitePlotImages;
                    $(ImgObj).attr("data-imagename", SitePlotImages);
                }
            }
        });

    } catch (e) {

    }
}

UPDATE

The above JSON comes from the below code :-

function BindDataTableToJSON(strVal) {
            try {

                var VSATData = JSON.parse(strVal);
                var getJSONValue = VSATData.Table[0];
                var getJSONImageData = VSATData.Table1;

    getImages(getJSONImageData, getJSONValue.SAP_ID, getJSONValue.CANDIDATE_ID);

}

Also the strVal json is something like below

'{"Table":[{"SAP_ID":"I-HP-PARK-ENB-9005","CANDIDATE_ID":"C1","STATE":"Himachal Pradesh","SITETYPE":"eNodeB","SITE_NAME":"Thandal","CANDIDATESTATUS":"Vendor Survey Form Filled","SITEID":null,"PRIORITYSITE":"P1","CIRCLE":"HIMACHAL PRADESH","VSATSTATUS":"Save As Draft","LATITUDE":32.9185,"LONGITUDE":76.4676,"SITE_ID":null,"PRIORITY_SITE":null,"SITE_NAME1":"Thandal","LATITUDE1":null,"LONGITUDE1":null,"CONTACT_DETAILS":null,"SURVEY_LATITUDE":null,"SURVEY_LONGITUDE":null,"VENDOR_SITE_CODE":null,"SITE_TYPE":"OWN BUILD","SITE_PLOT_DIMENSION":"12*12","SITE_TECHNOLOGY":"TDMA","SITE_MOUNT_TYPE":"PM","SITE_ANTENNA_SIZE":"1.2","SITE_AMSL":12.0,"SPACE_AVAILABLE_12YESNO":"YES","SPACE_AVAILABLE_24YESNO":"YES","SPACE_AVAILABLE_38YESNO":"YES","SPACE_AVAILABLE_46YESNO":"YES","SPACE_AVAILABLE_105YESNO":"YES","SITE_IDENTIFIER_POPULATION":"Religious Place","SITE_IDENTIFIER_POP_DESC":"sewww","ROOFTOP_SITE":"YES","NO_OF_BUILDINGS":13.0,"STANDARD_SPACE_REQ":"12","STRUCTURAL_STABILITY_CERT":"NA","HEIGHT_OF_ANTENNA":12.0,"SATELLITE_BAND":"KU","VENDOR_TO_BE_ADDED":"NELCO","VENDOR_TO_BE_ADDED_OTHERS":null,"SCOPE_TO_BE_ADDED":"PARAKRAM","AZIMUTH_60_E":0.0,"AZIMUTH_95_E":0.0,"AZIMUTH_83_E":0.0,"AZIMUTH_935_E":0.0,"AZIMUTH_74_E":0.0,"AZIMUTH_48_E":0.0,"AZIMUTH_55_20_E":0.0,"AZIMUTH_55_29_E":0.0,"ELEVATION_60_E":0.0,"ELEVATION_95_E":0.0,"ELEVATION_83_E":0.0,"ELEVATION_935_E":0.0,"ELEVATION_74_E":0.0,"ELEVATION_48_E":0.0,"ELEVATION_55_20_E":0.0,"ELEVATION_55_29_E":0.0,"ANTENNA_DISTANCE_NEAR_AIRPORT":233.0,"AIRPORT_NAME":"Pune airport","GSAT_LOS_12_83E":"NO","GSAT_LOS_E_60E":"NO","GSAT_LOS_17_935E":"NO","GSAT_LOS_12_95E":"NO","GSAT_LOS_11_74E":"NO","GSAT_LOS_19_48E":"NO","GSAT_LOS_20_55E":"NO","GSAT_LOS_29_55E":"NO","O3BCLASSIC":"NO","O3BMPOWER":"YES","GSAT_LOS_12_83_OBS":"NO","GSAT_LOS_60E_OBS":"NO","GSAT_LOS_17_935E_OBS":"NO","GSAT_LOS_12_95_OBS":"NO","GSAT_LOS_11_74_OBS":"NO","GSAT_LOS_19_48_OBS":"NO","GSAT_LOS_20_55_OBS":"NO","GSAT_LOS_29_55_OBS":"NO","O3BCLASSIC_OBS":null,"O3BMPOWER_OBS":"YES","GSAT_LOS_12_83_AZM_ELE":"NO","GSAT_LOS_60_AZM_ELE":"NO","GSAT_LOS_17_935_AZM_ELE":"NO","GSAT_LOS_12_95_AZM_ELE":"NO","GSAT_LOS_11_74_AZM_ELE":"NO","GSAT_LOS_19_48_AZM_ELE":"NO","GSAT_LOS_20_55_AZM_ELE":"NO","GSAT_LOS_29_55_AZM_ELE":"NO","GSAT_LOS_03B_CLASSIC_AZM":"NO","GSAT_LOS_03B_MPOWER_AZM":"YES","CIRCLE1":"HIMACHAL PRADESH","PDF_PATH":"https://nvmbd1bkh150v02.rjil.ril.com/VSAT/NESSPATH/VSAT/I-HP-PARK-ENB-9005_C1//SignedDoc//Anti Bribery & Anti Corruption Policy (2021 - 22).pdf","SITE_APPROVED_NOTAPPROVED":null,"GSAT_12_83_OBSTYPE":null,"GSAT_12_83_OBSTYPE_OTH":null,"GSAT_E_60_OBSTYPE":null,"GSAT_E_60_OBSTYPE_OTH":null,"GSAT_17_935_OBSTYPE":null,"GSAT_17_935_OBSTYPE_OTH":null,"GSAT_12_95_OBSTYPE":null,"GSAT_12_95_OBSTYPE_OTH":null,"GSAT_11_74_OBSTYPE":null,"GSAT_11_74_OBSTYPE_OTH":null,"GSAT_19_48_OBSTYPE":null,"GSAT_19_48_OBSTYPE_OTH":null,"GSAT_20_25_OBSTYPE":null,"GSAT_20_25_OBSTYPE_OTH":null,"GSAT_29_55_OBSTYPE":null,"GSAT_29_55_OBSTYPE_OTH":null,"GSAT_03BCLASSIC_OBSTYPE":null,"GSAT_03BCLASSIC_OBSTYPE_OTH":null,"GSAT_03BMPOWER_OBSTYPE":"Building","GSAT_03BMPOWER_OBSTYPE_OTH":null,"GSAT_HEIGHT_OBS_1283":0.0,"GSAT_HEIGHT_OBS_E60":0.0,"GSAT_HEIGHT_OBS_17935":0.0,"GSAT_HEIGHT_OBS_1295":0.0,"GSAT_HEIGHT_OBS_1174":0.0,"GSAT_HEIGHT_OBS_1948":0.0,"GSAT_HEIGHT_OBS_2055":0.0,"GSAT_HEIGHT_OBS_2955":0.0,"GSAT_HEIGHT_OBS_O3BCLASS":0.0,"GSAT_HEIGHT_OBS_O3BMPOWER":12.0,"GSAT_DIST_OBS_12_83":0.0,"GSAT_DIST_OBS_E_60":0.0,"GSAT_DIST_OBS_17_935":0.0,"GSAT_DIST_OBS_12_95":0.0,"GSAT_DIST_OBS_11_74":0.0,"GSAT_DIST_OBS_19_48":0.0,"GSAT_DIST_OBS_20_55":0.0,"GSAT_DIST_OBS_29_55":0.0,"GSAT_DIST_OBS_O3CLASS":0.0,"GSAT_DIST_OBS_O3BMPOWER":24.0,"CAN_LOS_GSAT_1283":"NO","CAN_LOS_GSAT_E_60":"NO","CAN_LOS_GSAT_17_935":"NO","CAN_LOS_GSAT_12_95":"NO","CAN_LOS_GSAT_11_74":"NO","CAN_LOS_GSAT_19_48":"NO","CAN_LOS_GSAT_20_55":"NO","CAN_LOS_GSAT_29_55":"NO","CAN_LOS_GSAT_O3B_CLASS":"NO","CAN_LOS_GSAT_O3B_MPOWER":"YES","CABLE_LENGTH_IFL":"23","CABLE_LENGTH_DC":"23","CABLE_LENGTH_ETHERNET":"23","ANY_CABLE_DIGGING_LAN_DC":"YES","DETAILED_SITE_LAYOUT":"test","CABLE_LEN_EARTH_ANTENNA":"12","CABLE_LEN_EARTH_ODU":"12","NEAREST_ELEC_TAPPING":"12","AC_POWER_SOCKET_3NOS_5AMP":"12","MONKEY_CAGE_REQ":"YES","ACCESS_TO_SITE":"YES","SITE_TRANSPORATION_MODE_CITY":null,"SITE_TRANSPORATION_MODE_TOWN":null,"SITE_TRANSPORATION_MODE_VILLAGE":null,"SITE_TRANSPORATION_MODE_PANCHAYAT":null,"DISTANCE_KM_CITY":0.0,"DISTANCE_KM_TOWN":0.0,"DISTANCE_KM_VILLAGE":0.0,"DISTANCE_KM_PANCHAYAT":0.0,"MODE_OF_TRANSPORTATION":"Air","HIGH_FLOOD_LEVEL":"23","PRESENCE_MOBILE_OPERATOR":"No","OPERATOR_NAME":null,"BACKHAUL":"MW","NEAREST_ACC_TRANSPORT_POINT":"test on 01-Aug2024","SITE_APPROVED_NOT_APPROVED":"Site Not Approved","VENDOR_REMARKS":"test","COMPANY1":null,"COMPANY2":null,"COMPANY3":null,"COMPANY4":null,"NAME1":null,"NAME2":null,"NAME3":null,"NAME4":null,"DESIGNATION1":null,"DESIGNATION2":null,"DESIGNATION3":null,"DESIGNATION4":null,"SURVEY_DATE1":null,"SURVEY_DATE2":null,"SURVEY_DATE3":null,"SURVEY_DATE4":null,"REMARKS1":null,"REMARKS2":null,"REMARKS3":null,"REMARKS4":null}],"Table1":[{"IMG_TYPE":"Panaromic","IMAGES":"120.jpg,150.jpg,180.jpg,210.jpg,240.jpg,270.jpg,90.jpg,90270.jpg"},{"IMG_TYPE":"Satellite","IMAGES":"4819.jpg,5520.jpg,7411.jpeg,935.jpg,O3B.jpg"},{"IMG_TYPE":"SitePlot","IMAGES":"Anti Bribery & Anti Corruption Policy (2021 - 22).pdf"}]}'

Can’t use throw HttpException inside a map making an axios request

I’m trying to make an axios request inside a array.map , for each map item i need to make a axios request and save some response info. When i’m using my code logic all errors handled in my catch block can’t make a throw HttpException inside my catch block since it doesn’t send my error back to my nestjs filter.

I’m using a axios interceptor in my main.ts file, the error goes to my interceptor in main.ts and my code breaksService example code and result(postman don’t receive nothing)

code example and result without the map function

axios interceptor in main.ts
my httpException filter (default filter from nestjs docs)

I’m expecting to throw an httpException and my filter handles the error

CSS resize property is not working with the sidebar that I created

Description

I am developing a website that has a button on the top right side and if the user clicks this button, the sidebar with a chatbot shows up. I want to make this chatbot sidebar resizable by using the resize property to allow the user to resize the sidebar with their mouse.

img1

Current Behavior

Even though I have added the resize property to .sidebar-content, I can’t resize the chatbot sidebar.

/* Side bar */
.sidebar {
    position: fixed;
    top: 10px;
    right: 10px;
    height: 100%;
    width: 100%;
    max-width: 500px;
    background-color: none;
    overflow-x: hidden;
    transition: 0.5s;
    padding-top: 60px;
    color: white;
}

.sidebar-content {
    resize: both;
    display: none;
}

const promptInput = document.getElementById("userInput");
const chatContainer = document.getElementById("chatContainer");
const typingIndicator = document.getElementById("typingIndicator");
const sidebar = document.getElementById("sidebar");
const sidebarContent = document.getElementById("sidebarContent");
const imageContainer = document.getElementById("imageContainer");

async function sendMessage() {
  const prompt = promptInput.value.trim();
  if (!prompt && imageContainer.children.length === 0) {
    alert("Please enter a message or add an image.");  // Browser pop up message
    return;
  }

  // Collect image data
  const images = Array.from(imageContainer.querySelectorAll('.img-preview'))
    .map(img => img.src.split(',')[1]); // Extract base64 data

  addMessage(prompt, 'user', images);
  promptInput.value = "";

  showTypingIndicator();

  const generatedText = await generateText(prompt, images);
  addMessage(generatedText, 'bot');

  hideTypingIndicator();
  //clearImagePreviews(); Add this code if you want the image in the imageContainer disappear if the user sends the image.
}

async function generateText(prompt, images) {
  try {
    const response = await fetch("https://idx-polapo-invest-test-6163648-nylaufaarq-uc.a.run.app/generate_text_stream", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ prompt, images }),
    });

    if (!response.ok) {
      console.error("Error:", response.statusText);
      return "Error occurred while generating response.";
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let isFinished = false;
    let generatedTextContent = "";

    while (!isFinished) {
      const { done, value } = await reader.read();
      if (done) {
        isFinished = true;
        break;
      }
      generatedTextContent += decoder.decode(value, { stream: true });
    }

    return generatedTextContent;
  } catch (error) {
    console.error("Error:", error);
    return "An error occurred.";
  }
}

function addMessage(text, type, images = []) {

  let md = window.markdownit();

  const messageDiv = document.createElement("div");
  messageDiv.className = `message ${type}`;

  const messageContent = document.createElement("div");
  messageContent.className = "message-bubble fadeIn";
  const render = () => {
    messageContent.innerHTML = md.render(text);
  }
  render()

  images.forEach(src => {
    const img = document.createElement("img");
    img.src = `data:image/png;base64,${src}`;
    img.classList.add("message-image");
    messageContent.appendChild(img);
  });

  messageDiv.appendChild(messageContent);
  chatContainer.appendChild(messageDiv);
  chatContainer.scrollTop = chatContainer.scrollHeight;
}

function clearImagePreviews() {
  while (imageContainer.firstChild) {
    imageContainer.removeChild(imageContainer.firstChild);
  }
  checkImageContainerVisibility();
}

let typingTimeout;

function showTypingIndicator() {
  clearTimeout(typingTimeout);
  typingIndicator.style.display = "inline-block";
}

function hideTypingIndicator() {
  typingTimeout = setTimeout(() => {
    typingIndicator.style.display = "none";
  }, 1000);
}

function handleKeyPress(event) {
  if (event.key === "Enter") {
    sendMessage();
  }
}

function toggleSidebar() {
  if (sidebar.style.width === "500px") {
    sidebar.style.width = "0";
    sidebarContent.style.display = "none";
  } else {
    sidebar.style.width = "500px";
    sidebarContent.style.display = "block";
  }
}

window.onload = () => addMessage("Hello! How can I assist you today?", 'bot');

document.addEventListener('DOMContentLoaded', () => {
  const textInput = document.getElementById('userInput');

  textInput.addEventListener('paste', (event) => {
    const items = (event.clipboardData || window.clipboardData).items;
    for (const item of items) {
      if (item.type.indexOf('image') !== -1) {
        const file = item.getAsFile();
        const reader = new FileReader();
        reader.onload = (event) => {
          displayImage(event.target.result);
        };
        reader.readAsDataURL(file);
        event.preventDefault();
      }
    }
  });

  function displayImage(src) {
    const imgContainer = document.createElement('div');
    imgContainer.classList.add('img-preview-container');

    const img = document.createElement('img');
    img.src = src;
    img.classList.add('img-preview');

    const removeButton = document.createElement('button');
    removeButton.classList.add('remove-button');
    removeButton.textContent = '✖';
    removeButton.addEventListener('click', () => {
      imgContainer.remove();
      checkImageContainerVisibility();
    });

    imgContainer.appendChild(img);
    imgContainer.appendChild(removeButton);
    imageContainer.appendChild(imgContainer);
    checkImageContainerVisibility();

    const all_images = imageContainer.querySelectorAll('.img-preview-container');
    all_images.forEach(img => img.style.width = `${100 / all_images.length - 10}%`);
  }

  function checkImageContainerVisibility() {
    if (imageContainer.children.length > 0) {
      imageContainer.classList.remove('hidden');
    } else {
      imageContainer.classList.add('hidden');
    }
  }

  // Initial check to hide image container if empty
  checkImageContainerVisibility();
});

// Backtest Result and Detailed Report buttons
document.getElementById('backtestResultButton').addEventListener('click', function() {
  const cs_model = document.getElementById('cs_model').value;
  const ts_model = document.getElementById('ts_model').value;

  fetch('/Backtest_result', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ cs_model: cs_model, ts_model: ts_model }),
  })
    .then(response => response.json())
    .then(data => {
      if (data.error) {
        console.error('Error:', data.error);
        return;
      }
      document.getElementById('backtestResult').innerHTML = `
        <div class="image" id="image1">
          <img src="data:image/png;base64,${data.port_weights_img}" alt="Portfolio Weights" style="width: 80%; height: auto;">
        </div>
        <div class="image" id="image2">
          <img src="data:image/png;base64,${data.asset_performance_img}" alt="Asset Performance" style="width: 80%; height: auto;">
        </div>
        <div class="image" id="image3">
          <img src="data:image/png;base64,${data.portfolio_performance_img}" alt="Portfolio Performance" style="width: 80%; height: auto;">
        </div>
      `;
      document.getElementById('backtestResult').classList.add('active');
      document.getElementById('detailedReport').classList.remove('active');
    })
    .catch(error => {
      console.error('Error:', error);
    });
});

document.getElementById('detailedReportButton').addEventListener('click', function() {
  const cs_model = document.getElementById('cs_model').value;
  const ts_model = document.getElementById('ts_model').value;

  fetch('/generate_html_report', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ cs_model: cs_model, ts_model: ts_model }),
  })
    .then(response => response.json())
    .then(data => {
      if (data.error) {
        console.error('Error:', data.error);
        return;
      }
      document.getElementById('detailedReport').innerHTML = data.report_html;
      document.getElementById('detailedReport').classList.add('active');
      document.getElementById('backtestResult').classList.remove('active');
    })
    .catch(error => {
      console.error('Error:', error);
    });
});
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f0f2f5;
    color: #333;
    margin: 0;
    padding: 0;
    text-align: center;
}

h1 {
    color: #333;
    text-align: center;
    margin: 20px 0;
}

/* Generate report button styling */
button, input[type="submit"] {
    padding: 12px 24px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 16px;
    transition: background-color 0.3s, transform 0.3s;
}

button:hover, input[type="submit"]:hover {
    background-color: #0056b3;
    transform: translateY(-2px);
}

/* Form styling */
form {
    background: #fff;
    border-radius: 8px;
    padding: 20px;
    max-width: 600px;
    margin: 20px auto;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

label {
    display: block;
    margin-bottom: 8px;
    font-weight: 600;
    font-size: 16px;
}

select, input[type="submit"] {
    width: calc(100% - 22px);
    padding: 12px;
    margin-bottom: 20px;
    border-radius: 6px;
    border: 1px solid #ddd;
    font-size: 16px;
}

select {
    background-color: #f9f9f9;
}

/* Report page styling */
.report-container {
    background: #fff;
    border-radius: 8px;
    padding: 20px;
    max-width: 1200px;
    margin: 20px auto;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    overflow: auto;
}

a {
    color: #007bff;
    text-decoration: none;
    font-weight: 500;
}

a:hover {
    text-decoration: underline;
}

/* Section that will show report content */
.report-content {
    margin-top: 20px;
}

.report-content iframe {
    width: 100%;
    border: none;
    height: 600px;
}



/* Side bar */
.sidebar {
    position: fixed;
    top: 10px;
    right: 10px;
    height: 100%;
    width: 100%;
    max-width: 500px;
    background-color: none;
    overflow-x: hidden;
    transition: 0.5s;
    padding-top: 60px;
    color: white;
}

.sidebar-content {
    resize: both;
    display: none;
}

.sidebar-content h2 {
    text-align: center;
}

.sidebar-content p {
    padding: 10px;
}

.toggle-button {
    position: fixed;
    top: 10px;
    right: 10px;
    padding: 15px;
    background-color: #3182ce;
    color: white;
    border: none;
    cursor: pointer;
}

.toggle-button:hover {
    background-color: #2c5282;
}

img {
    max-width: 90%;
    margin: 20px 0;
    border: 1px solid #ddd;
    border-radius: 10px;
}

.image-container {
    width: 100%;
    /*padding: 12px 18px;*/
    overflow: hidden;

    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    background-color: #fff;
    /*border: 1px solid #444;*/
    min-height: 50px;
    max-height: 70px;
    margin-bottom: 10px;

    border: 2px solid #e2e2e2;
    border-radius: 8px 8px 8px 8px;
}

.hidden {
    display: none;
}

.img-preview-container {
    position: relative;
    display: inline-block;
    max-width: 15%;
}

.img-preview {
    max-width: 100%;
    border-radius: 5px;
}


.remove-button:hover {
    background-color: #45a049;
}

.remove-button {
    position: absolute;
    top: 5px;
    right: 5px;
    background-color: #ff4d4d;
    border: none;
    border-radius: 50%;
    color: white;
    cursor: pointer;
    width: 20px;
    height: 20px;
    font-size: 12px;
    line-height: 20px;
    text-align: center;
    padding: 0;
}



/* Chat Bot */
.container {
    margin-top: 0;
    width: 90%;
    max-width: 450px;
    margin: 10px auto 0;
    background-color: #fff;
    border-radius: 12px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
    padding: 20px;
    transition: all 0.3s;
}

.chat {
    overflow-y: auto;
    height: 400px;
    margin-bottom: 20px;
    border-bottom: 2px solid #e2e2e2;
}

.message {
    display: flex;
    margin-bottom: 12px;
}

.message.user {
    justify-content: flex-end;
}

.message-bubble {
    padding: 12px 18px;
    max-width: 70%;
    border-radius: 20px;
    line-height: 1.6;
    font-size: 0.95rem;
}

.message.user .message-bubble {
    background-color: #3182ce;
    color: white;
}

.message.bot .message-bubble {
    background-color: #e2e2e2;
    color: #333;
}


.message-image {
    max-width: 100px; /* Set the maximum width for the image */
    max-height: 100px; /* Set the maximum height for the image */
    margin: 5px;
    display: inline-block;
    object-fit: cover; /* Ensures the image retains its aspect ratio */
}


input[type="text"] {
    flex: 1;
    padding: 12px 18px;
    border: 2px solid #e2e2e2;
    border-radius: 8px 0 0 8px;
    font-size: 1rem;
    outline: none;
    color: black;
}

.send-button {
    width: 110px;
    background-color: #3182ce;
    color: white;
    padding: 12px 18px;
    border: none;
    border-radius: 0 8px 8px 0;
    cursor: pointer;
    transition: background-color 0.3s;
}

.send-button:hover {
    background-color: #2c5282;
}

.footer {
    text-align: center;
    padding: 15px 0;
    font-size: 0.9rem;
    color: #666;
    position: static;
    border-top: 1px solid #e2e2e2;
    background-color: #fff;
    position: fixed;
    bottom: 0;
    width: 100%;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.fadeIn {
    animation: fadeIn 1s;
}

@media (max-width: 600px) {
    .container {
        width: 95%;
        margin: 10px auto 0;
    }

    .chat {
        height: 300px;
    }

    .input-container {
        max-width: 95%;
    }

    input[type="text"],
    .send-button {
        padding: 10px 14px;
        font-size: 0.9rem;
    }

    .footer {
        font-size: 0.8rem;
        margin-top: 30px;
    }
}

.typing-indicator {
    display: none;
    align-items: center;
    justify-content: flex-end;
    margin-top: 8px;
    width: 10px;
    height: 10px;
    background-color: #333;
    border-radius: 50%;
    margin-left: 4px;
    animation: typing 1s infinite;
}

@keyframes typing {
    0%,
    100% {
        transform: scale(1);
        opacity: 1;
    }

    50% {
        transform: scale(1.2);
        opacity: 0.7;
    }
}


/*the backtest result and detailed report buttons */
.button-container {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin: 20px 0;
}

.content {
    display: flex;
    justify-content: center;
    margin-top: 20px;
}

.content-box {
    display: none;
    flex-direction: row;
}

.content-box.active {
    display: flex;
}

/*Backtest_result style*/
.image img {
    width: auto;
    height: auto; 
    margin: 10px auto; 
    display: block; 
    cursor: pointer; 
}

#detailedReport {
    width: 90%; 
    margin: 0 auto; 
  }
  
/*image modal style*/
.modal {
    display: none; 
    position: fixed;
    z-index: 1;
    padding-top: 100px;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgb(0,0,0);
    background-color: rgba(0,0,0,0.9);
  }

.modal-content {
    margin: auto;
    display: block;
    width: 80%;
    max-width: 700px;
  }

.modal-content, #caption {
    -webkit-animation-name: zoom;
    -webkit-animation-duration: 0.6s;
    animation-name: zoom;
    animation-duration: 0.6s;
  }

@-webkit-keyframes zoom {
    from { -webkit-transform: scale(0) } 
    to { -webkit-transform: scale(1) }
  }
@keyframes zoom {
    from { transform: scale(0) } 
    to { transform: scale(1) }
  }

.close {
    position: absolute;
    top: 50px;
    right: 50px;
    color: #f1f1f1;
    font-size: 40px;
    font-weight: bold;
    transition: 0.3s;
  }
  
.close:hover,
.close:focus {
    color: #bbb;
    text-decoration: none;
    cursor: pointer;
  }
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Portfolio Backtesting</title>
    <link
      rel="stylesheet"
      href="{{ url_for('static', filename='css/style.css') }}"
    />
  </head>
  <body>
    <h1>Portfolio Backtesting</h1>
    <form id="reportForm" method="post" action="/">
      <label for="cs_model">Choose Cross-Sectional Model:</label>
      <select id="cs_model" name="cs_model">
        <option value="EW">Equal Weight (EW)</option>
        <option value="MSR">Maximum Sharpe Ratio (MSR)</option>
        <option value="GMV">Global Minimum Variance (GMV)</option>
        <option value="MDP">Minimum Drawdown Risk (MDP)</option>
        <option value="EMV">Equal Risk Contribution (EMV)</option>
        <option value="RP">Risk Parity (RP)</option>
      </select>

      <label for="ts_model">Choose Time-Series Model:</label>
      <select id="ts_model" name="ts_model">
        <option value="VT">Volatility Targeting (VT)</option>
        <option value="CVT">Conditional Value at Risk Targeting (CVT)</option>
        <option value="KL">Kelly Criterion (KL)</option>
        <option value="CPPI">
          Constant Proportion Portfolio Insurance (CPPI)
        </option>
      </select>

      <button type="submit" class="button">Generate Report</button>
    </form>

    <div class="button-container">
      <button type="button" id="backtestResultButton" class="button">
        Backtest Result
      </button>
      <button type="button" id="detailedReportButton" class="button">
        Detailed Report
      </button>
    </div>

    <div class="content">
      <div id="backtestResult" class="content-box"></div>
      <div id="detailedReport" class="content-box"></div>
    </div>

    <div class="sidebar" id="sidebar">
      <button class="toggle-button" onclick="toggleSidebar()">☰</button>
      <div class="sidebar-content" id="sidebarContent">
        <div class="container bg-white rounded-lg shadow-md">
          <h1 class="text-3xl font-bold mb-4 text-center">ChatBot</h1>
          <div class="chat" id="chatContainer"></div>
          <div class="image-container hidden" id="imageContainer"></div>
          <div class="flex">
            <input
              type="text"
              id="userInput"
              placeholder="Type your message here..."
              class="outline-none"
              onkeyup="handleKeyPress(event)"
            />
            <button class="send-button" onclick="sendMessage()">Send</button>
          </div>
          <div class="typing-indicator" id="typingIndicator"></div>
        </div>
      </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/markdown-it.min.js"></script>
    <script src="{{ url_for('static', filename='js/script.js') }}"></script>
    <!-- image moddal -->
    <div id="myModal" class="modal">
      <span class="close">&times;</span>
      <img class="modal-content" id="img01" />
      <div id="caption"></div>
    </div>

    <script src="{{ url_for('static', filename='js/script.js') }}"></script>
    <script>
      document
        .getElementById("backtestResultButton")
        .addEventListener("click", function () {
          const cs_model = document.getElementById("cs_model").value;
          const ts_model = document.getElementById("ts_model").value;

          fetch("/Backtest_result", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({ cs_model: cs_model, ts_model: ts_model }),
          })
            .then((response) => response.json())
            .then((data) => {
              if (data.error) {
                console.error("Error:", data.error);
                return;
              }
              document.getElementById("backtestResult").innerHTML = `
          <div class="image" id="image1">
            <img src="data:image/png;base64,${data.port_weights_img}" alt="Portfolio Weights">
          </div>
          <div class="image" id="image2">
            <img src="data:image/png;base64,${data.asset_performance_img}" alt="Asset Performance">
          </div>
          <div class="image" id="image3">
            <img src="data:image/png;base64,${data.portfolio_performance_img}" alt="Portfolio Performance">
          </div>
        `;
              document.getElementById("backtestResult").classList.add("active");
              document
                .getElementById("detailedReport")
                .classList.remove("active");

              // image click event
              const images = document.querySelectorAll(".image img");
              images.forEach((img) => {
                img.addEventListener("click", function () {
                  const modal = document.getElementById("myModal");
                  const modalImg = document.getElementById("img01");
                  const captionText = document.getElementById("caption");
                  modal.style.display = "block";
                  modalImg.src = this.src;
                  captionText.innerHTML = this.alt;
                });
              });
            })
            .catch((error) => {
              console.error("Error:", error);
            });
        });

      document
        .getElementById("detailedReportButton")
        .addEventListener("click", function () {
          const cs_model = document.getElementById("cs_model").value;
          const ts_model = document.getElementById("ts_model").value;

          fetch("/generate_html_report", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({ cs_model: cs_model, ts_model: ts_model }),
          })
            .then((response) => response.json())
            .then((data) => {
              if (data.error) {
                console.error("Error:", data.error);
                return;
              }
              document.getElementById("detailedReport").innerHTML =
                data.report_html;
              document.getElementById("detailedReport").classList.add("active");
              document
                .getElementById("backtestResult")
                .classList.remove("active");
            })
            .catch((error) => {
              console.error("Error:", error);
            });
        });

      // modal close
      const modal = document.getElementById("myModal");
      const span = document.getElementsByClassName("close")[0];
      span.onclick = function () {
        modal.style.display = "none";
      };
    </script>
  </body>
</html>

Strapi error while installing dependencies (windows)

I was about to start strapi project by “npx create-strapi-app backend-strapi –quickstart” and “npx create-strapi-app@latest backend-strapi”, but while installing dependencies, i have an error.

PS D:ProgramowanieProjektyczar-ognia> npx create-strapi-app@latest backend-strapi
? Choose your installation type Quickstart (recommended)

We can't find any auth credentials in your Strapi config.

Create a free account on Strapi Cloud and benefit from:

- ✦ Blazing-fast ✦ deployment for your projects
- ✦ Exclusive ✦ access to resources to make your project successful
- An ✦ Awesome ✦ community and full enjoyment of Strapi's ecosystem

Start your 14-day free trial now!


? Please log in or sign up. Skip
Creating a quickstart project.
Creating a new Strapi application at D:ProgramowanieProjektyczar-ogniabackend-strapi.
Creating files.
Error while installing dependencies:
npm warn config production Use `--omit=dev` instead.
npm warn config optional Use `--omit=optional` to exclude optional dependencies, or
npm warn config `--include=optional` to include them.
npm warn config
npm warn config       Default value does install optional deps unless otherwise omitted.
npm warn deprecated [email protected]: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated [email protected]: See https://github.com/lydell/source-map-url#deprecated
npm warn deprecated [email protected]: Rimraf versions prior to v4 are no longer supported
npm warn deprecated [email protected]: Please see https://github.com/lydell/urix#deprecated
npm warn deprecated [email protected]: Rimraf versions prior to v4 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: Glob versions prior to v9 are no longer supported
npm warn deprecated [email protected]: This project is unmaintained
npm warn deprecated @koa/[email protected]: **IMPORTANT 10x+ PERFORMANCE UPGRADE**: Please upgrade to v12.0.1+ as we have fixed an issue with debuglog causing 10x slower router benchmark performance, see https://github.com/koajs/router/pull/173
npm warn deprecated [email protected]: See https://github.com/lydell/source-map-resolve#deprecated
npm warn deprecated [email protected]: https://github.com/lydell/resolve-url#deprecated
npm warn deprecated [email protected]: Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://github.com/node-formidable/formidable/blob/master/VERSION_NOTES.md
npm warn deprecated [email protected]: This project is unmaintained
npm warn cleanup Failed to remove some directories [
npm warn cleanup   [
npm warn cleanup     'D:\Programowanie\Projekty\czar-ognia\backend-strapi\node_modules\@swc\core',
npm warn cleanup     [Error: EBUSY: resource busy or locked, rmdir 'D:ProgramowanieProjektyczar-ogniabackend-strapinode_modules@swccore'] {
npm warn cleanup       errno: -4082,
npm warn cleanup       code: 'EBUSY',
npm warn cleanup       syscall: 'rmdir',
npm warn cleanup       path: 'D:\Programowanie\Projekty\czar-ognia\backend-strapi\node_modules\@swc\core'
npm warn cleanup     }
npm warn cleanup   ],
npm warn cleanup   [
npm warn cleanup     'D:\Programowanie\Projekty\czar-ognia\backend-strapi\node_modules\@swc',
npm warn cleanup     [Error: ENOTEMPTY: directory not empty, rmdir 'D:ProgramowanieProjektyczar-ogniabackend-strapinode_modules@swc'] {
npm warn cleanup       errno: -4051,
npm warn cleanup       code: 'ENOTEMPTY',
npm warn cleanup       syscall: 'rmdir',
npm warn cleanup       path: 'D:\Programowanie\Projekty\czar-ognia\backend-strapi\node_modules\@swc'
npm warn cleanup     }
npm warn cleanup   ],
npm warn cleanup   [
npm warn cleanup     'D:\Programowanie\Projekty\czar-ognia\backend-strapi\node_modules\@strapi',
npm warn cleanup     [Error: EPERM: operation not permitted, rmdir 'D:ProgramowanieProjektyczar-ogniabackend-strapinode_modules@strapiadmindistee'] {
npm warn cleanup       errno: -4048,
npm warn cleanup       code: 'EPERM',
npm warn cleanup       syscall: 'rmdir',
npm warn cleanup       path: 'D:\Programowanie\Projekty\czar-ognia\backend-strapi\node_modules\@strapi\admin\dist\ee'
npm warn cleanup     }
npm warn cleanup   ]
npm warn cleanup ]
npm error code 1
npm error path D:ProgramowanieProjektyczar-ogniabackend-strapinode_modulesesbuild
npm error command failed
npm error command C:WINDOWSsystem32cmd.exe /d /s /c node install.js
npm error D:ProgramowanieProjektyczar-ogniabackend-strapinode_modulesesbuildinstall.js:133
npm error     throw new Error(`Expected ${JSON.stringify(versionFromPackageJSON)} but got ${JSON.stringify(stdout)}`);
npm error           ^
npm error
npm error Error: Expected "0.19.11" but got "0.21.5"
npm error     at validateBinaryVersion (D:ProgramowanieProjektyczar-ogniabackend-strapinode_modulesesbuildinstall.js:133:11)
npm error     at D:ProgramowanieProjektyczar-ogniabackend-strapinode_modulesesbuildinstall.js:284:5
npm error
npm error Node.js v18.20.4
npm error A complete log of this run can be found in: C:UsersplekuAppDataLocalnpm-cache_logs2024-08-01T18_41_39_276Z-debug-0.log
TypeError: Cannot read properties of undefined (reading 'addBreadcrumb')
    at C:UsersplekuAppDataLocalnpm-cache_npx2d56dd13733e9da7node_modules@strapigenerate-newdistutilsusage.js:36:31
    at Array.forEach (<anonymous>)
    at Module.captureStderr (C:UsersplekuAppDataLocalnpm-cache_npx2d56dd13733e9da7node_modules@strapigenerate-newdistutilsusage.js:35:37)
    at createProject (C:UsersplekuAppDataLocalnpm-cache_npx2d56dd13733e9da7node_modules@strapigenerate-newdistcreate-project.js:133:17)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async createQuickStartProject (C:UsersplekuAppDataLocalnpm-cache_npx2d56dd13733e9da7node_modules@strapigenerate-newdistcreate-quickstart-project.js:18:3)
    at async initProject (C:UsersplekuAppDataLocalnpm-cache_npx2d56dd13733e9da7node_modulescreate-strapi-appdistcreate-strapi-app.js:172:3)

If anyone knows what can cause this, please let me know,

I tried changing Node version to 22, 20 and 14 (with NPM v6.14.18)

How to remove the active state on a button when clicking on an input

I am building a component with 4 preset buttons and a custom range input. I am able to toggle the active state on the buttons when clicking them but I want to remove the active state from all the buttons when I click into the input. I also want to clear the input field when I click out of the input.

HTML code:

<div class="row selectors d-flex justify-content-center" id="rc-button-bar">
        <div class="col-xs-6 col-sm-6 col-md-2 mb-2">
          <button id="btn-25" class="btn-primary ce-button" data-value="25">25%</button>
        </div>
        <div class="col-xs-6 col-sm-6 col-md-2 mb-2">
           <button id="btn-50" class="btn-primary ce-button" data-value="50">50%</button>
          </div>
        <div class="col-xs-6 col-sm-6 col-md-2 mb-2">
            <button id="btn-85" class="btn-primary ce-button is-active" data-value="85">85%</button>
          </div>
        <div class="col-xs-6 col-sm-6 col-md-2 mb-2">
            <button id="btn-100" class="btn-primary ce-button" data-value="100">100%</button>
          </div>
        <div class="col-sm-12 col-md-2 mb-2 d-flex align-items-center">
          <input id="customPercent" class="numbers" type="text" placeholder="ex: 80"></input>&nbsp;<span>%</span>
        </div>
      </div>

CSS:

.btn-primary.ce-button {
  width: 100%;
  height: 48px;
  padding: auto;
  border: 4px solid #0079c1;
  border-radius: 5px;
  background: transparent;
  color: #0079c1;
  font-weight: bold;
  cursor: pointer;
}
.btn-primary.ce-button:hover,
.btn-primary.ce-button:active {
  background: #0079c1;
  border-radius: 5px;
  color: #ffffff;
  font-weight: bold;
  cursor: pointer !important;
}
.is-active {
  background: #0079c1 !important;
  border-radius: 5px !important;
  color: #ffffff !important;
  font-weight: bold !important;
}

JavaScript:

let btnContainer = document.getElementById("rc-button-bar");
let btns = btnContainer.getElementsByClassName("ce-button");
let input = document.getElementById("customPercent");

for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function() {
    (document.querySelector('.is-active')) ? document.querySelector('.is-active').classList.remove('is-active') : '';
    this.classList.add('is-active');
  });
}

Here is a link to my codepen so you can see it in full https://codepen.io/RECopeland/pen/rNEMMYZ

How to load cookies in PHP on firstpage load [duplicate]

I cannot read and load non-HttpOnly non-Session cookies via $_COOKIES[‘mycookie’] in PHP on initial page load.

I’ve read through numerous Google SERPs and and SO Q&As and nothing works.

I even tried reloading the web page (on first page load) simply to have the request go from server to client back to server in order to get the cookies in Safari on my iPhone.

Any help?

I even tried reloading the web page (on first page load) simply to have the request go from server to client back to server in order to get the cookies in Safari on my iPhone.

I’m expecting and needing to get the cookies on initial page load in PHP.

Not able to download a web page that uses javascript

I have been trying to download a web page that I ultimately intend to scrape. The page uses Javascript, and has in their code a catch to test if javascript is enabled, and I keep getting it is not enabled.

I am trying to do it under wsl2 (ubuntu) on a windows 10 machine. I have tried with selenium, headless chrome, and axios, and am unable to figure out how to get it to execute the javascript.

As I want to put this into my crontab, I am not using any gui.

The website is

https://app.aquahawkami.tech/nfc?imei=359986122021410

Before I start to scrape the output, I figure I have to first get a good download, and that is where I am stuck.

Here is the javascript:

// index.js

const axios = require('axios');
const fs = require('fs');
axios.get('https://app.aquahawkami.tech/nfc?imei=359986122021410', {responseType: 'document'}).then(response => {
  fs.writeFile('./wm.html', response.data, (err) => {
        if (err) throw err;
        console.log('The file has been saved!');
    });
});

Selenium

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

driver.get("https://app.aquahawkami.tech/nfc?imei=359986122021410")

page_source = driver.page_source
print(page_source)
fileToWrite = open("aquahawk_source.html", "w")
fileToWrite.write(page_source)
fileToWrite.close()
driver.close()

finally headless chrome:

`google-chrome –headless –disable-gpu –dump-dom https://app.aquahawkami.tech/nfc?imei=359986122021410

`

React Animated Cursor – Update Cursor With State

I am trying to utilize the npm package react-animated-cursor to make a custom cursor that changes when it is hovered over certain items.

From what I can tell, it seems like that package is set up to allow custom cursor html, however it’s not updating the cursor html when the state is changed.

Am I doing something wrong or is there another way I can accomplish what I need?

import AnimatedCursor from "react-animated-cursor";
const [value, setValue] = useState("default");

<AnimatedCursor> {value} </AnimatedCursor>
<div
  style={{
          backgroundColor: "blue",
          color: "white",
          textAlign: "center",
          width: "100%",
          height: 300,
   }}
   onMouseOver={() => setValue("in")}
   onMouseOut={() => setValue("out")}
>
   {value}
</div>

CodeSandbox

Expected Behavoir: When hovered on the blue background the cursor should have the text “in”. When the cursor leaves the color section it should have the text “out”

React video restarts on every re-render in functional components with additional return values

This one stumped me for a bit, but I have a wrapper around an html tag which handles the reference to the video element and provides some functions (play/pause, skip forward/back, etc). I wanted to create a hook that could send back those functions and the way to actually render the wrapped video component:

function useVideo() {
  const videoRef = useRef(null);

  function playPause() {
    if (videoRef.current.paused) {
      videoRef.current.play();
    } else {
      videoRef.current.pause();
    }
  }

  function Video() {
    return <video ref={ videoRef } ...etc />
  }

  return { playPause, Video };
}

And then use that hook like so:

function App() {
  const { playPause, Video } = useVideo();

  ...

  return <Video key="key" />;
}

But every time I did anything that would cause App to re-render, the html video would restart. I believe the issue is that the Video function changes every time useVideo is run, so even though I have a key on the component, react treats it as a different component.

Fix for background images not loading until rendered on screen?

I’m building a (mostly static) SPA that has a lot of animations and transitions between views (it’s a kiosk).

It’s working great except…the very first time it runs. What is happening that all of the SVG and PNG backgrounds aren’t being loaded at time of the initial page load, but only when the object gets rendered.

Given most of the SPA is ‘display: none’ until it’s needed, that means the very first time you run through the app, each transition comes in, and then the SVGs slowly pop into place everywhere.

After that, since they are now cached, it’s fine. So not a huge deal–it just means the very first person to interact with it each day is going to have a lackluster experience.

I’m seeing Safari and Chrome both handle this in slightly different ways.

Viewing the network tabs in dev tools, I see the following behavior:

  • Safari: Immediately requests all images being used (which makes sense) but only fully loads the ones immediately being displayed. The rest are ‘stuck’ in a loading state until either a) the containers that they belong to are set to display: block or b) I simply wait several minutes (at which point I guess it just decides to load them all anyways?)

  • Chrome: Immediately requests only the images needed. The rest aren’t even requested until they need to be rendered on screen.

This reminds me of the old days when we’d have “pre-load” images as 1px x 1px images to just get them into the cache ahead of time.

So that’s what I’m doing. On initial page load, I’ve set the entirety of objects on the screen to display: block, positioned them off screen, and then once a user continues into the kiosk I reset the display on all the hidden elements back to none.

This works, but feels clunky. Is there a more elegant way to go about this? Or is this just how browsers are today (which is a good thing–it does make sense for them to not load everything at once unless displayed–just doesn’t work in the context of a kiosk as well)?

How do I use Electron app environment variables

I am creating a Point of Sale using electron js. I want to use environment variables for the source of the API where the backend is coming from. I installed the environment variables using the command npm install dotenv and Im am using .env as the source of environment variables. The following is my folder structure.Folders Structure.
My main window is the login page which is here. Its working well with the .env Login Page Folder.Use of .env on login. When I try to use the environment variables within other pages which are in the pages folder I am getting the error.Add warehouse page error. The following is how the code is structured.add warehouse page Is there a way to fix this or any alternative methods?

I tried to do webpack configurations but maybe I couldn’t do them right.

In playwright using JS, need to add product to cart from list of product

exports.ProductListing = class ProductListing {
constructor(page) {

            this.page = page;
            this.productLocator = page.locator("xpath=(//*[@class='inventory_item'])");
            this.addToCartButton = page.getByRole("button", {name: "Add to cart"})
        }
    
        async addProductToCart(productName) {
            await this.productLocator
                .filter({ hasText: productName })
                .locator(await this.addToCartButton)
                .click();
        }
    }
    

what is wrong with this code?, I’m getting timeout error everytime

Test timeout of 90000ms exceeded.
Error: locator.click: Test timeout of 90000ms exceeded.
Call log:

  • waiting for locator(‘xpath=(//*[@class=’inventory_item’])’).filter({ hasText: ‘Sauce Labs Onesie’ }).locator(getByRole(‘button’, { name: ‘Add to cart’ }))

at ..Pagesproductspage.js:13

11 | .filter({ hasText: productName })
12 | .locator(await this.addToCartButton)

13 | .click();
| ^
14 | }
15 | }
16 |