Capture HTML element and it’s styles for re-rendering

How would you capture a div element and its computed styles so the individual element can be re-rendered in its own html file, so that it displays the same way it would in the original source?

I have written some code that I can use from within the developer console, but the rendered html file looks nothing like the original source.

function captureDivWithStyles(div) {
    div.id = 'captured-div'

    const styles = window.getComputedStyle(div);
    const cssText = Array.from(styles).reduce((str, property) => {
        return `${str}${property}:${styles.getPropertyValue(property)};`;
    }, '');

    return {
        html: div.outerHTML,
        css: cssText
    };
}

function createNewHtml(capturedDiv) {
    return `
<html>
<head>
    <title>Captured Div</title>
    <style>
        #captured-div {
            ${capturedDiv.css}
        }
    </style>
</head>
<body>
    ${capturedDiv.html}
</body>
</html>
    `;
}

function saveToFile(content, filename) {
    const blob = new Blob([content], { type: 'text/html' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();
    URL.revokeObjectURL(link.href);
}

function saveDivAsHtml(div) {
    const capturedDiv = captureDivWithStyles(div);
    const newHtml = createNewHtml(capturedDiv);
    saveToFile(newHtml, 'captured-div.html');

}

Usage via: (Where I am using my own query selector, which varies depeneding on what element I want to capture)

myDiv = document.querySelector()
saveDivAsHtml(myDiv);

Error in a script for Adobe Illustrator in charge of numbering

I’m working on a JavaScript script for Adobe Illustrator that will number multiple text fields in an.ai. The script should increment the numbering in multiple text fields at the same time and generate multiple copies of the document.

The script works well for the first text field, increasing the numbering from 0001 to 0005 as expected. However, for the second field, which must be numbered 0006 to 0010, the script stops at 0008 and continues printing the same number until the prints in the first field are completed. Then, move to the next number for the second field, but still with the same problem.

"use strict";

// Request the number of fields to number
var fieldCount = parseInt(prompt("Enter the number of fields to number:", "4"));
var fields = [];

// Request the number of copies to print
var numberOfCopies = parseInt(prompt("How many copies would you like to print? (e.g., for Original and Copy enter 2):", "2"));

// Configure fields with their numbering range
for (var i = 0; i < fieldCount; i++) {
    var fieldName = prompt("Enter the name of field " + (i + 1) + ":", "field_" + (i + 1)); // Field name
    var initialNumber = parseInt(prompt("Enter the starting number for field " + (i + 1) + ":", "0001"));
    var finalNumber = parseInt(prompt("Enter the final number for field " + (i + 1) + ":", "0005"));

    if (isNaN(initialNumber) || isNaN(finalNumber) || finalNumber < initialNumber) {
        alert("Please enter valid numbers.");
        exit();
    }

    fields.push({
        name: fieldName,
        current: initialNumber,
        last: finalNumber
    });
}

// Select Adobe Illustrator file
var baseFile = File.openDialog("Select the base file (.ai)");
if (baseFile === null) {
    alert("No file was selected.");
    exit();
}
var document = app.open(baseFile);

// Check if there are enough textFrames in the document
if (document.textFrames.length < fieldCount) {
    alert("The document does not have enough text fields. Please check the file.");
    exit();
}

// Loop to number and generate the copies
var continuePrinting = true;
while (continuePrinting) {
    continuePrinting = false;
    for (var i = 0; i < fields.length; i++) {
        // Find the corresponding textFrame by name
        var foundTextFrame = null;
        for (var j = 0; j < document.textFrames.length; j++) {
            if (document.textFrames[j].name === fields[i].name) {
                foundTextFrame = document.textFrames[j];
                break;
            }
        }
        if (foundTextFrame === null) {
            alert("No text field found with the name: " + fields[i].name);
            exit(); 
        }
        if (fields[i].current <= fields[i].last) {
            continuePrinting = true; // There are still fields to number
            var currentNumber = ("0000" + fields[i].current).slice(-4);
            foundTextFrame.contents = "No. " + currentNumber;
        }
    }

    // Print all updated fields before continuing numbering
    if (continuePrinting) {
        for (var copy = 0; copy < numberOfCopies; copy++) {
            document.print();
        }

        // Increment the numbers of all fields after printing
        for (var i = 0; i < fields.length; i++) {
            if (fields[i].current <= fields[i].last) {
                fields[i].current++; // Increment the field at the same time
            }
        }
    }
}
alert("Process completed. The receipts were printed in the specified fields.");

The code’s goal is for text fields in Adobe Illustrator to be numbered synchronously and in parallel. For example, if you have two fields with numbering ranges of 0001-0005 and 0006-0010, both should advance at the same time and in a coordinated way, such as 0001 and 0006, 0002 and 0007, etc. After updating the numbering in all the fields, the document should be printed according to the specified number of copies, so that each copy reflects the current numbering of all fields. Once the copies have been generated, the numbers in all fields must be incremented simultaneously to continue the sequence on the next print cycle.

I need to add a modal on one classic ASP page, but inly if a cookie has not been set. i’d like to avoid javascript

I have a classic ASP page that needs a modal to pop up asking people to sign up to our mailing list. If they sign up, a cookie is set. This page checks for that cookie and doesn’t harass the user if they’ve already signed up (a cookie is set).

I saw a similar routine using a lot of JavaScript, but I couldn’t get it to work. (I’m very weak in JavaScript.)

So I tried the following using classic ASP and the bare minimum of Javascript, which doesn’t display the modal at all.

Here’s the basic code I’m working with.

<code>
<body>
<%
' Get the cookie
KeepInTouch = Request.Cookies("KeepInTouch")

if KeepInTouch <> "Y" then
%>
<script>
    document.getElementById('popup').style.display='block';
</script>
<div id="popup" class="w3-modal">
    <div class="w3-modal-content">
        <div class="w3-container">
            <!-- ... rest of popup ... -->
        </div>
    </div>
</div>
</body>`
</code>
    

I can't get the modal to pop up, even without checking for the cookie.

Paysafe Checkout updates for 3DS compliance

I need to update a Paysafe Checkout integration due to a change in requirements from Visa[1]. From the suggested changes I can see that I have to add email/phone/cellphone values to a profile object on the setup options, but the API documentation does not detail any profile properties, so I’m at a loss as to what to do about this. Has anyone else had to deal with this that could offer some insights?

FWIW here’s a code snippet of the JS code from the place I think I need to add the profile data. Note: the code currently works without the profile data, so I can’t tell if just adding the profile data to paymentData has any effect at all :-/

const paymentData = {
    amount: amount,
    currency: 'GBP',
    accounts:{
        CC: accountNumber
    },
    billingAddress:{
        country: "GB",
        zip: postcode,
        state: state,
        city: city,
        street: address,
    },
    environment: 'TEST',
    companyName: 'myco',
    buttonColor: '#121212',
    imageUrl: 'https://myco.com/img/logo.jpg', 
    holderName: '',
    displayPaymentMethods: ['Cards'],
    threeDS: {
        useThreeDSecureVersion2: true
    }
};
const payeeData={
    amount,
    address,
    city,
    state,
    postcode,
    reference
};
const token = GetToken();
paysafe.checkout.setup(
    token,
    paymentData,
    function (instance, error, result) {
        postPaymentProcessing(payeeData, instance, error, result);
    },
    function(stage){
        console.log('closed at payment stage: ' + stage);
    }
);

[1] https://go.pardot.com/webmail/365931/1644206923/c2913a61471857eeea22a44effc737a3815c5cce267486bd0a60c8173b57b599
[2] https://developer.paysafe.com/en/api-docs/client-side-sdks/paysafe-checkout-powered-by-cards-api/setup-function/

Trying to get total change in value and average change in value for data set with errors, clean up meter raw data

The problem with the code currently, it doesnt properly handle all the errors it seems

what i need as output is

  • Total Change in value
  • Average change in value (based on number of vaild changes)
  • Starting value
  • Ending value (start value + total change in value)

for the most part it works except having a huge problem with one set of raw data, it appears the filtering to ignore bad changes in value is messing up with this data, not sure why.

Script – excert

  // Check if cellValue is a valid number
      if (isNaN(numericValue) || numericValue < 0) {
        numericValue = null; // Invalid data, treat as reset
      }

      if (numericValue !== null) {
        if (startValue === null) {
          startValue = numericValue; // This is the first valid reading
          firstValue = numericValue;
          lastValidValue = numericValue;
        } else {
          if (numericValue >= lastValidValue) {
            // Calculate the change (difference between current and last valid value)
            var change = numericValue - lastValidValue;
            totalUsage += change; // Increment total usage based on valid change
            lastValidValue = numericValue;
            if (change > 0) {
              countValidChanges++; // Increment the count only for valid changes > 0
            }
          } else {
            // If the value resets (lower than previous), ignore it and continue
            lastValidValue = numericValue; // Treat this as a reset point, but continue counting up from    here
          }
        }
      }
    }

    // === NEW LOGIC STARTS HERE ===

    // Calculate the initial average usage (without threshold) only if there are valid changes
    var initialAverageUsage = (countValidChanges > 0) ? (totalUsage / countValidChanges) : 0;

    // Reset totalUsage and countValidChanges to recalculate with threshold
    var threshold = initialAverageUsage + 2000;
    totalUsage = 0;
    countValidChanges = 0;
    lastValidValue = firstValue; // Reset to the first valid reading

    // Re-run the loop to apply the threshold
    for (var row = dataStartRow; row < data.length; row++) {
      var rowData = data[row];
      var cellValue = rowData[colIndex];
      var numericValue = parseFloat(cellValue);

      // Check if cellValue is a valid number
      if (isNaN(numericValue) || numericValue < 0) {
        numericValue = null; // Invalid data, treat as reset
      }

      if (numericValue !== null && numericValue >= lastValidValue) {
        // Calculate the change only if it doesn't exceed the threshold
        var change = numericValue - lastValidValue;
        if (change <= threshold) {
          totalUsage += change; // Increment total usage based on valid change
          lastValidValue = numericValue;
          if (change > 0) {
            countValidChanges++; // Increment the count only for valid changes > 0
          }
        }
      }
    }

    // Recalculate average usage with the threshold applied
    var finalAverageUsage = (countValidChanges > 0) ? (totalUsage / countValidChanges) : 0;

    // Ensure the ending value is never lower than the start value
    var endValue = (firstValue !== null) ? firstValue + totalUsage : 0; // If no valid first value, set to 0
    
    // Ensure that startValue and endValue default to 0 if no valid data was found
    reportData.push([point, totalUsage || 0, finalAverageUsage || 0, startValue || 0, endValue || 0]);
 }

here is the raw data that is causing the problem

66,360
66,360
66360
66360
66360
66360
66360
66360
66360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
66,360
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
66360
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
Data Loss
Data Loss
Data Loss
Data Loss
Data Loss
1.41E+06
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
Data Loss
Data Loss
Data Loss
1.41E+06
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
Data Loss
Data Loss
1.41E+06
1.41E+06
1.41E+06
1.41E+06
1.41E+06
1.41E+06
1.41E+06
1.41E+06
1.41E+06
1.41E+06
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
Data Loss
Data Loss
Data Loss
Data Loss
Data Loss
Data Loss
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
Data Loss
Data Loss
1.41E+06
1.41E+06
1.41E+06
1.41E+06
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
6.64E+04
Data Loss
Data Loss
1.41E+06
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
Data Loss
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0.00E+00
0
0
0
0`

Ive tried updating it and adding threshold to the data, also it should be ignoring same values and improper values, it works great on most of the data, but this one data set is causing it to give absurdly high numbers.

Using Page Function in Apify Puppeteer for scraping articles (using Pagination)

I am trying to scrape news articles from this website using Apify Puppeteer crawler. I am trying to write a page-function in javascript to achieve the same but unable get it to work.
The webpage incorporates pagination so I am trying to navigate through all the relevant pages to extract all articles with publication date since ‘2024-08-15’.

I am new to javascript, so any help is highly appreciated. The page-function code I was trying to write is given below.

Can someone please help me to fix the page-function in javascript to use it in Apify Puppeteer scraper.

async function pageFunction(context) {
    const { request, $, log, jQuery } = context;
    const results = [];
    const url = context.request['url'];
    const pageopt = 'home';
    const pageoption = context.customData.pageopt;
    
    let i = 1;
    
    //Define startDate
    const startDate = new Date('2024-08-15');
    
    //Get the page object from the context
    const { page } = context;
    
    await page.goto(url, { waitUntil: "domcontentloaded" });
    const litags = null;
    
    if ( pageoption === 'True') {
        try {
            await page.waitForSelector('ul.bwNewsList li');
            liTags = await page.$$('ul.bwNewsList li');
        } catch (error) {
            console.error('An error occurred: ', error);
        }
    }
    else {
        try {
            await page.waitForSelector('ul.bwNewsList li');
            liTags = await page.$$('ul.bwNewsList li');
        } catch(error) {
            console.error('An error occurred: ', error);
        }
    }
    
    const urls = [];
    let date = null;
    
    for (let li of liTags) {
        date = new Date(await li.$eval('time', el => el.getAttribute('datetime')));
        
        const aTag = await li.$('a');
        const href = aTag ? await (await aTag.getPropert('href')).jsonValue() : null;
        
        if (date >= startDate) {
            urls.push(href);
        }
    }
    
    console.log(date)
    console.log(startDate)
    
    if (date >= startDate) {
        const nxthref = await page.$eval('div.pagingNext a', element => element.href);
        console.log(nxthref);
        context.customData.pageopt = 'False';
        await context.enqueRequest({ 'url' : nxthref});
    }
    
    for (let url of urls) {
        await page.goto(url, { waitUntil: " domcontentloaded" });
        
        let title = await page.$eval('title', el => el.textContent.replace(/[rns]+/g, " ") );
        const unique_article = url.concat(title);
        
        // Generate the hash of the title
        const titleHash = await page.evaluate(async (unique_article) => {
            const encoder = new TextEncoder();
            const data = encoder.encode(unique_article);
            const hash = await window.crypto.subtle.digest('SHA-256', data);
            const hashArray = Array.from(new Uint8Array(hash) );
            return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
        }, unique_article);
        
        const pgdate = new Date(await page.$eval('div.bw-release-timestamp time', el => el.getAttribute('datetime')));
        const divs = await page.$$('p');
        let text = '';
        for (let div of divs) {
            text += await page.evaluate(el => el.textContent, div);
        }
        text = text.replace(/[rns]+/g, " ");
        
        results.push({
            'article_id': titleHash,
            'url': url,
            'title': title,
            'content': text,
            'published_date': pgdate,
            'publisher': 'BW'
        });
    }
    
    return results;
}

Thanks in advance.

Browser’s tab freezes if i make too many request per second

I have a website that needs the user to make many requests in a very short time on the click of a button.

The problem I’m facing is that my tab freezes or become really slow when I send too many requests in a short time (like 300 requests in 5 seconds).

In each request I just use like void request() (don’t wait for the promise).

What do you think? Any advice?

Thank you in advance

P.S. I can’t send them in batches, each must be handled separately for legal reasons.

Javascript stops responding on postback, DOMContentLoaded no longer responds

I’m not well-versed with Javascript, so please feel free to explain in detail. I’ve got this script that acts as a keystroke counter:

    <script type="text/javascript">

        document.addEventListener('DOMContentLoaded', function () {
            const textArea2 = document.getElementById('TextBox_Follow_Up_Answer2');
            const label1 = document.getElementById('Label_Answer_Char_Count');
            const label2 = document.getElementById('Label_Answer_Char_Count2');
            const labelRemaining1 = document.getElementById('Label_Answer_Char_Remaining');
            const labelRemaining2 = document.getElementById('Label_Answer_Char_Remaining2');

            // Add input event listener for text area
            textArea2.addEventListener('input', function () {
                textCounter(textArea2, 3000, label1, labelRemaining1);
                textCounter2(textArea2, 865, label2, labelRemaining2);
                alert("Event Listener - DOMContentLoaded");
            });
        });

        function textCounter(field, maxlimit, label, label2) {
            if (field.value.length > maxlimit)
                field.value = field.value.substring(0, maxlimit);
            else {

                label.innerHTML = maxlimit - field.value.length;
            }
            if (field.value.length > maxlimit - 500) {
                label.style.color = "#FF0000";
                label2.style.color = "#FF0000";
            }
            else {
                label.style.color = "#000000";
                label2.style.color = "#000000";
            }
            alert("textCounter Fired");
        }

        function textCounter2(field, maxlimit, label, label2) {
            if (field.value.length > maxlimit)
            //  field.value = field.value.substring(0, maxlimit);
            field.value = field.value;
            else {

                label.innerHTML = maxlimit - field.value.length;
            }
            if (field.value.length > maxlimit - 200) {
                label.style.color = "#FF0000";
                label2.style.color = "#FF0000";
            }
            else {
                label.style.color = "#000000";
                label2.style.color = "#000000";
            }
            alert("textCounter2 Fired");
        }

        $(document).ready(function () {
            alert("Page Initial Load");
            textCounter(textArea2, 3000, label1, labelRemaining1); // this works for initial page load only
            textCounter2(textArea2, 865, label2, labelRemaining2);
        });

        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function () {
            alert("Page Reload");
            textCounter(textArea2, 3000, label1, labelRemaining1); // this works after postback         
            textCounter2(textArea2, 865, label2, labelRemaining2);
        });

    </script>

On the same page, I have a button that creates an email based on certain info.

    <td>
        <asp:DropDownList ID="DropDownList_Response_Method" runat="server" Width="200px">
        </asp:DropDownList>
        <asp:Button ID="Button_Create_Email" runat="server" Text="Create Email" CssClass="action_button" Height="22px" Width="200px" OnClick="Button_Create_Email_Click" />
    </td>

The code-behind for this button is:

    protected void Button_Create_Email_Click(object sender, EventArgs e)
    {
        string question;
        string article;
        string section;

        //use question 3 details
        if (Label_Question_3_Text.Text != "")
        {
            question = WebUtility.HtmlDecode(Label_Question_3_Text.Text);
            article = Label_Question_3_Article_Number.Text;
            section = Label_Question_3_Section_Number.Text;
        }

        //use question 2 details
        else if (Label_Question_2_Text.Text != "")
        {
            question = WebUtility.HtmlDecode(Label_Question_2_Text.Text);
            article = Label_Question_2_Article_Number.Text;
            section = Label_Question_2_Section_Number.Text;
        }

        //use question 1 details
        else
        {
            question = WebUtility.HtmlDecode(Label_Question_1_Text.Text);
            article = Label_Question_1_Article_Number.Text;
            section = Label_Question_1_Section_Number.Text;
        }

        string answer = WebUtility.HtmlDecode(TextBox_Follow_Up_Answer2.Value);
        string answer_article = TextBox_Answer_Article_Number.Text;
        string answer_section = TextBox_Answer_Section_Number.Text;

        //remove special characters
        question = question.Replace("'", "");
        question = question.Replace("<", " less than ");
        question = question.Replace(">", " greater than ");
        question = question.Replace(""", "");
        question = question.Replace("&", "and");
        question = question.Replace(";", "");
        question = question.Replace("/", "");
        question = question.Replace("%", " percent");
        question = question.Replace("#", "number");
        question = question.Replace(System.Environment.NewLine, " ");

        answer = answer.Replace("'", "");
        answer = answer.Replace("<", " less than ");
        answer = answer.Replace(">", " greater than ");
        answer = answer.Replace(""", "");
        answer = answer.Replace("&", "and");
        answer = answer.Replace(";", "");
        answer = answer.Replace("/", "");
        answer = answer.Replace("%", " percent");
        answer = answer.Replace("#", "number");
        answer = answer.Replace(System.Environment.NewLine, " ");

        string account_name = Label_Account_Name.Text;
        //string account_number = Label_Account_Number.Text;

        Page.ClientScript.RegisterStartupScript(this.GetType(), "email", "parent.location='mailto:" + Label_Advocate_Name.Text + "?Subject=Coach Response for " + Label_Unique_ID.Text + " " + Label_Escalated.Text + " " + account_name +
            "&body=Analyst Question:  " + question +
            "%0D%0AAnalyst Article Number:  " + article +
            "%0D%0AAnalyst Section Number:  " + section +

            "%0D%0A %0D%0AAnswer:  " + answer +
            "%0D%0AAnswer Article:  " + answer_article +
            "%0D%0AAnswer Section:  " + answer_section +

            "%0D%0A %0D%0AREMINDER: If this answers your question, please accept the answer in the Question Response Page." +

            "'", true);

    }

So, what currently happens with the above code is, when the page loads I get an alert for “Page Initial Load”. I type a letter in the textbox and I get alerts for “textCounter Fired”, “textCounter2 Fired” and “Event Listener – DOMContentLoaded”. The counter decreases by 1. I type the next letter, and I get the same alerts, and again the counter decreases by 1. All is working well.

I click the Email button. It bypasses the “If (!IsPostBack)” block in my code-behind, so I know we’re dealing with a page postback. I continue stepping through the code, keeping an eye on my webpage and so far the character count on the page is fine. When I get to the last closing bracket of Button_Create_Email_Click, the webpage jumps to the top and the counters are reset to their default number.

When I close the email, I get no prompts. The javascript has stopped working. The counter doesn’t move, no alerts appear. I assume the listener has stopped listening? I added that last section of my Javascript because I saw a post that said you needed an add_EndRequest on Postback, but it doesn’t seem to work since I never see the alert inside that function. Related to that, I see this in the Debug window: “Uncaught ReferenceError ReferenceError: Sys is not defined”

Pass additional props to functional component

I have a constellation like this:

<AComponent>
  foo={{bar: AFunctionalComponent}}
</AComponent>
export default function AFunctionalComponent({
  // These are props that will get passed "automatically" by 'AComponent'
  foo, 
  bar, 
  baz
}) 
{...}

Now I want to pass an additional prop to AFunctionalComponent. How do I do that?

Radar Chart Color Transition and Border Smoothing Issue

“I am trying to make smooth color transitions in graphics using Radar Chart. At the same time, I want the lines to be smooth, but I cannot get the results I want. The color transitions are smooth, but the lines do not fit well and the corners look hard. You can find the code I used below. Does anyone have a helpful solution suggestion ?enter image description here

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Radar Chart with Smooth Color Transitions</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <style>
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background-color: #252c37;
      margin: 0;
      font-family: Arial, sans-serif;
    }

    .chart-container {
      position: relative;
      width: 400px;
      height: 400px;
    }

    .center-text {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      text-align: center;
    }

    .main-number {
      font-size: 3em;
      color: #4CAF50;
    }

    .sub-text {
      font-size: 1.2em;
      color: #999;
    }
  </style>
</head>
<body>
  
  <div class="chart-container">
    <canvas id="radarChart"></canvas>
    <div class="center-text">
      <span class="main-number">87</span>
      <br />
      <span class="sub-text">Ad Liked</span>
    </div>
  </div>

  <script>
    // Özel plugin ile segmentleri renklendirme ve geçiş sağlama
    const multiColorPlugin = {
      id: 'multiColorPlugin',
      afterDatasetDraw(chart) {
        const { ctx } = chart;
        const meta = chart.getDatasetMeta(0);
        const points = meta.data;
        const tension = 0.3; // Daha yumuşak geçişler için tension

        const borderColors = [
          'rgba(255, 99, 132, 1)', // Pembe
          'rgba(54, 162, 235, 1)', // Mavi
          'rgba(255, 206, 86, 1)', // Sarı
          'rgba(75, 192, 192, 1)', // Turkuaz
          'rgba(153, 102, 255, 1)', // Mor
          'rgba(255, 159, 64, 1)'   // Turuncu
        ];

        ctx.save();
        for (let i = 0; i < points.length; i++) {
          const currentPoint = points[i];
          const nextPoint = points[(i + 1) % points.length];
          const prevPoint = points[(i - 1 + points.length) % points.length];

          // Kontrol noktaları hesaplanarak daha yumuşak geçiş sağlanıyor
          const cp1x = currentPoint.x + tension * (nextPoint.x - prevPoint.x);
          const cp1y = currentPoint.y + tension * (nextPoint.y - prevPoint.y);

          const gradient = ctx.createLinearGradient(currentPoint.x, currentPoint.y, nextPoint.x, nextPoint.y);
          gradient.addColorStop(0, borderColors[i]);
          gradient.addColorStop(1, borderColors[(i + 1) % points.length]);

          ctx.beginPath();
          ctx.moveTo(currentPoint.x, currentPoint.y);
          ctx.bezierCurveTo(cp1x, cp1y, nextPoint.x, nextPoint.y, nextPoint.x, nextPoint.y); // Daha yumuşak geçiş için bezierCurve
          ctx.strokeStyle = gradient;
          ctx.lineWidth = 3;
          ctx.stroke();
          ctx.closePath();
        }
        ctx.restore();
      }
    };

    // Radar grafiği verileri ve ayarları
    const data = {
      labels: ['Creativity', 'Originality', 'Emotion', 'Believable', 'Uniqueness', 'Different'],
      datasets: [{
        label: 'Ad Liked',
        data: [47, 91, 42, 88, 63, 83],
        fill: true,
        backgroundColor: 'rgba(0, 0, 0, 0.5)', // İç kısım siyah ve şeffaf
        pointBackgroundColor: 'rgba(0, 0, 0, 0)', // Noktaları gizle
        pointBorderColor: 'rgba(0, 0, 0, 0)', // Nokta kenarlarını gizle
        tension: 0.5 // Çizgilerin yumuşaklığı için tension
      }]
    };

    const config = {
      type: 'radar',
      data: data,
      options: {
        elements: {
          line: {
            borderWidth: 0 // Çizgi rengi plugin ile belirlenecek
          }
        },
        scales: {
          r: {
            angleLines: {
              display: false
            },
            suggestedMin: 0,
            suggestedMax: 100,
            ticks: {
              display: false // Etrafındaki sayıları gizler
            }
          }
        }
      },
      plugins: [multiColorPlugin] // Özel plugin kullanımı
    };

    // Radar grafiğini oluştur
    const radarChart = new Chart(
      document.getElementById('radarChart'),
      config
    );
  </script>

</body>
</html> Even though I made the transitions 0.5 to 0.5, it doesn't work.

Map pin background color 1st pin marker dissapears

I have the code below, the moment I place the second marker the 1st one is not rendered – Im stumped – if I remove the content: pinBackground.element both is rendered again

const pinBackground = new PinElement({
background: “#FBBC04”,
});

new google.maps.marker.AdvancedMarkerElement({
map,
title: ‘wittebergstudio’,
content: pinBackground.element,
position: {
lat: -28.507,
lng: 27.933
}
});

new google.maps.marker.AdvancedMarkerElement({
map,
title: ‘rusendalcottages’,
content: pinBackground.element,
position: {
lat: -28.506,
lng: 27.940
}
});

different color pins/marker

Automated Subscription and Rental Management [closed]

I’m managing game subscriptions and rentals manually and looking for an easier and faster way to handle it. I need a system or tool that can help with:

1- Tracking the start and end dates of each subscription.
2- Storing subscription emails and customer contact info like phone numbers or emails.

How would you recommend I go about this?

I hope to find a more automated solution to simplify and streamline the process

Change of property value of an object instance is affecting others objects as well

When I change the values of a property of an instance of an object, I find that the other instances of the object have the value of that specific property changed too. Look at my code and you’ll see.

window.onload = function() {

    function randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1) ) + min;
    }

    let canva1 = document.getElementById("canva1");
    
    let canvaWidth = 600;
    let canvaHeight = 500;

    canva1.width = canvaWidth;
    canva1.height = canvaHeight;
    canva1.style.border = "1px solid black";

    let ctx = canva1.getContext("2d");

    const Bola = {
        x: null,
        y: null,
        raio: randomInt(10, 30),
        direcaoX: null,
        direcaoY: null,
        gerarBola: function() {

            if (this.direcaoX == null) {
                let a = randomInt(0, 1);
                if (a == 0) {
                    this.direcaoX = false;
                }
                else {
                    this.direcaoX = true;
                }
            }
            if (this.direcaoY == null) {
                let a = randomInt(0, 1);
                if (a == 0) {
                    this.direcaoY = false;
                }
                else {
                    this.direcaoY = true;
                }
            }

            if (this.x == null) {
                this.x = randomInt(this.raio, canvaWidth-this.raio);
            }
            if (this.y == null) {
                this.y = randomInt(this.raio, canvaHeight-this.raio);
            }
            
            ctx.clearRect(0, 0, canvaWidth, canvaHeight);

            ctx.beginPath();
            ctx.arc(this.x, this.y, this.raio, 0, 2*Math.PI);
            ctx.fillStyle = "rgb(" + randomInt(0, 255) + "," + randomInt(0, 255) + "," + randomInt(0, 255) + ")";
            ctx.fill();
            ctx.strokeStyle = "rgb(" + randomInt(0, 255) + "," + randomInt(0, 255) + "," + randomInt(0, 255) + ")";
            ctx.stroke();

            if (this.x+this.raio < canvaWidth && this.direcaoX == true) {
                this.x++;
            }
            else if (this.x+this.raio >= canvaWidth && this.direcaoX == true) {
                this.x--;
                this.direcaoX = false;
            }
            else if (this.x-this.raio > 0 && this.direcaoX == false) {
                this.x--;
            }
            else if (this.x-this.raio <= 0 && this.direcaoX == false) {
                this.x++;
                this.direcaoX = true;
            }

            if (this.y+this.raio < canvaHeight && this.direcaoY == true) {
                this.y++;
            }
            else if (this.y+this.raio >= canvaHeight && this.direcaoY == true) {
                this.y--;
                this.direcaoY = false;
            }
            else if (this.y-this.raio > 0 && this.direcaoY == false) {
                this.y--;
            }
            else if (this.y-this.raio <= 0 && this.direcaoY == false) {
                this.y++;
                this.direcaoY = true;
            }
        }
    }

    let bola1 = Bola;
    let bola2 = Bola;
    let bola3 = Bola;
    let bola4 = Bola;
    let bola5 = Bola;

    setInterval(function() {
        bola1.gerarBola();
        bola2.gerarBola();
        bola3.gerarBola();
        bola4.gerarBola();
        bola5.gerarBola();

        console.log("Bola 1: " + bola1.x);
        console.log("Bola 2: " + bola2.x);
        console.log("Bola 3: " + bola3.x);
        console.log("Bola 4: " + bola4.x);
        console.log("Bola 5: " + bola5.x);
        
    }, 500);

}

Now, let me explain. I’m trying to create multiples instances of a moving ball using canvas. 5 of them, to be clear. I’ve created a “Bola” object with its own properties, so it doesn’t affect other instances. Btw, there’s also an index.html, but the only thing it have is a div with a “canva1” id.
I think the code is pretty self-explanatory. Try to execute it, and you’ll see what I’m talking about.
Also, the “500” in the end is how fast the ball is moving. I made it that slow so you can see in the console that all the balls are in the same position (or something like that). And, with every “ball” I add, the only thing happening is the one ball accelerating.
Btw.: Sorry for my bad english :p

I have no idea how to go further. After I created one ball, I tried what you can see in the “setInterval” part. It hasn’t created more ball. It only made x and y go +5 instead of the normal +1 (one per instance). Look at the console log, and try to delete the number of balls in the few last lines, and you’ll see.

Hide iframe in the absence of its stylesheet

I have an iframe with the following element in its header

<link type="text/css" rel="stylesheet" href="/web/assets/report.min.css">

The problem is that this style sheet takes more time to load than the iframe. Because of that, the iframe would show without styling for 2 seconds or so.

What I want to do is to hide the iframe and only show it if this style sheet has fully loaded. How can I do this? Can I maybe listen to the url /web/assets/report.min.css and once it returns status code of 200 I can show the iframe?