Following light animation with mouse position events

I’m trying to create a following light animation with jquery and mouse position events – I am not sure on the formula to use or how to stabilize this type of effect looking for help/improved code attempts.

If I evaluate the size of the box and do math from the center points of the square to calculate the x,y percentages?

enter image description here

https://jsfiddle.net/x40ynof2/7/

$( document ).ready(function() {



var myElement = $("#p1");

function setTranslate(xPos, yPos, zPos, el) {
  console.log("test");
  el.style.transform = `translate3d(${xPos}, ${yPos}, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg)`;
}


myElement.mousemove(function(event) {
  console.log("mousemoveY---", event.clientX, event.clientY);

  let y = event.clientY;
  let x = event.clientX;

  var position = {
    top: myElement[0].offsetTop,
    left: myElement[0].offsetLeft
  };

  console.log("x", x);
  console.log("y", y);

  console.log("position", position);

  let degx = position.left - x;
  let degy = position.top - y;

  console.log("degx", degx);
  console.log("degy", degy);

  setTranslate(-(degx / 20)+"%" , -(degy / 20)+"%", 0, myElement[0]);
});


myElement.mouseleave(function() {
  console.log("mouseleave");
  setTranslate(0, 0, 0, myElement[0]);
});

});
.container {
  padding: 40px;
}

.blockwrapper {
  will-change: transform;
  transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
  margin:10px;
}

.block {
  background-color: skyblue;
  width: 160px;
  height: 160px;
}

.moved {
  background-color: pink;
}


.container {
  padding: 40px;
}

.blockwrapper {
  will-change: transform;
  transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
  margin:10px;
}

.block {
  background-color: #333333;
  width: 260px;
  height: 260px;
}

.moved {
  background-color: pink;
}

.light {
    width: 100%;
    height: 100%;
    opacity: 1;
    border-radius: 110px;
    justify-content: center;
    align-items: center;
    display: flex;
    position: absolute;
  will-change: transform; 
  transform: translate3d(0.01%, 0.01%, 0px) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg); 
  transform-style: preserve-3d;
}

.light-wrapper-in-front {
    z-index: 6;
    width: 100%;
    height: 100%;
    opacity: 1;
    justify-content: center;
    align-items: center;
    display: none;
    position: absolute;
}

.light-wrapper-in-front{
position:relative;
  display: flex; 

}

.light-outside {
    width: 200px;
    height: 200px;
    opacity: .3;
    filter: blur(70px);
    background-color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="container">

  <div class="blockwrapper">
    <div class="block">
     Movable

    <div id="p1" class="light-wrapper-in-front">
      <div class="light">
        <div class="light-outside"></div>
      </div>
    </div>

    </div>
  </div>
</div>

CSP headers required for web worker creation from a different origin?

I’m using a npm package which internally create web workers. I need to send the base URL to the library config, and it uses that URL to fetch the worker files. In our case, it’s a CDN path.

As it’s a different origin from the hosted application, the worker creation is failing with the following error.

Uncaught DOMException: Failed to construct ‘Worker’: Script at
‘cdn.com/worker.js’ cannot be accessed from origin ‘example.com’

I already saw some solutions which suggest to reference a Blob URL while creating a worker.

Something like this: new Worker(blobUrl);

But I don’t want this.

As the worker creation is within the dependency library, we can’t change the way the worker is being initialised. I wanted to know if there’s a way to make it work with a different origin.

While doing some investigation, I’ve read about CSP: worker-src directive. So, I believe we can add this directive to the CSP policies in the gateway and it should work.

So, I’ve tried Burp suite to modify the CSP headers of the hosted application (https://example.com) with the following option:
worker-src 'self' https://cdn.com;

This is how the worker script is invoked:
eg. new Worker('https://cdn.com/worker.js');

Also, Access-Control-Allow-Origin response header is set for the https://cdn.com

Trying these things couldn’t give me any success.

I’m probably still missing something here.

Q1. Does adding “worker-src” directive to the CSP policy alone should solve the issue?

Q2. Is this the correct syntax or whitelisting policy? worker-src 'self' https://cdn.com; or is there something missing here?

Can someone help me out here?

Thanks!

Only first 3 values are insterted from next.js to mysql Workbench

I have this in app.js

app.post('/api/add-order-cui', async (req, res) => {
  const {
    cui,
    email,
    phone,
    billingCUI, // Add other fields if necessary
  } = req.body;

  console.log('Received request body:', req.body); // Log received data

  if (!cui || !email || !phone || !billingCUI) {
    return res.status(400)
      .json({
        error: 'Required fields are missing'
      });
  }

  try {
    const connection = await mysql.createConnection(dbConfig);
    const uuid = uuidv4(); // Generate a new UUID

    const query = `
      INSERT INTO orders (uuid, orderCUI, email, phone, billingCUI)
      VALUES (?, ?, ?, ?, ?)
    `;
    const [result] = await connection.execute(query, [uuid, cui, email, phone, billingCUI]);

    console.log('Database insertion result:', result); // Log insertion result

    await connection.end();

    return res.status(201).json({
      message: 'Order added successfully',
      orderId: result.insertId
    });


  } catch (error) {
    console.error('Database error:', error);
    return res.status(500)
      .json({
        error: 'Database error'
      });
  }
});

and this is the handleSubmit function

const handleSubmit = async (event) => {
  event.preventDefault();

  const formData = {
    cui: 'aaa',
    email: '[email protected]',
    phone: '1234445556',
    billingCUI: 'test-billing-cui',
    // Add other fields if necessary
  };

  console.log('Form data before submission:', formData);

  try {
    const response = await fetch('/api/add-order-cui', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(formData),
    });

    const data = await response.json();
    console.log('Response data:', data);

    if (response.ok) {
      alert(data.message);
    } else {
      alert('Error: ' + data.error);
    }
  } catch (error) {
    console.error('Error:', error);
    alert('There was an error adding the order');
  }
};

If I write the SQL code in workbench

INSERT INTO orders (uuid, orderCUI, email, phone, billingCUI)
VALUES ('test-uuid', 'test-cui', '[email protected]', '1234567890', 'test-billing-cui');

everything works, but when I click on the button handleSubmit, the only values inserted are uuid, email and cui.

How can I fix this?

  • I verified the connection to the database and it works
  • I verified that the data can be inserted with SQL command
  • I checked for triggers
  • I verified the names of the columns, the type of the columns

Simulate a click on a specific node in the visNetwork graph

I need to simulate a click on a specific node in a visNetwork graph in a Shiny application, I tried to use JavaScript within the executeScript function in my Shiny test, but I get error as: “Error in session_makeRequest(self, private, endpoint, data, params, headers): null is not an object (evaluating ‘HTMLWidgets.find(‘#process_genealogy-network_output’).instance’)”

The specific java code is the following:

app$executeScript(
  "
  // Access the visNetwork instance by widget ID
  var network = HTMLWidgets.find('#process_genealogy-network_output').instance;

  // Simulate a click on the node with a specific ID
  network.setSelection({nodes: ['3027356-24']});
  network.emit('click', {
      nodes: ['3027356-24'],
      edges: []
  });
  "
)

Instead, this is the visNetwork line:

output$network_output <- renderVisNetwork({..})

I called process_geneaology-network_output because process_genealogy is the module of my app.
Thank you in advance for your help.

Why is there a delay in hiding drafts?

I’m using this code to add a “Show/Hide Drafts” functionality to the WP Admin area. It works fine, but hiding the drafts takes significantly longer than showing (which is instant).

What could be the issue here?

function hide_drafts_and_add_toggle_button() {
    if ( is_admin() && get_current_screen()->post_type === 'post' ) {
        // Hide drafts by default
        echo '<style>
            .status-draft { display: none; }
            #show-drafts-button { margin-bottom: 10px; cursor: pointer; }
        </style>';

        // Add the button to show/hide drafts
        echo '<button id="show-drafts-button" class="button">Show Drafts</button>';

        // JavaScript to toggle drafts visibility and button text
        echo '<script>
            document.getElementById("show-drafts-button").addEventListener("click", function() {
                var drafts = document.querySelectorAll(".status-draft");
                var draftsAreHidden = drafts[0].style.display === "none";
                
                for (var i = 0; i < drafts.length; i++) {
                    drafts[i].style.display = draftsAreHidden ? "table-row" : "none";
                }
                
                this.textContent = draftsAreHidden ? "Hide Drafts" : "Show Drafts";
            });
        </script>';
    }
}
add_action('manage_posts_extra_tablenav', 'hide_drafts_and_add_toggle_button');

I tried to modify the code myself and with the help of chatgpt but to no avail.

How do you change the title on the tab when using Storybook

For more clarification the title I’m referring to is next on the tab next to the Favicon on a browser, currently mine is like this: Example / Button – Docs ⋅ Storybook, and I can’t seem to get rid of the ⋅ Storybook part or edit it to how I want.

addons.setConfig({
  theme: create({
    brandTitle: "New Title",
    base: "light",
    brandImage: logo,
  })
});

and adding this to main.ts config

managerHead: (head) => 
    `${head}
      <script>
    document.title = 'New Title';
  </script>
      `
  ,

But nothing seems to change it. Does anyone know how I can change this?

EJS loops not rendering html tags

I am a beginner in coding using JS, NODE, and EJS.

I used fs.readdir to get some files as an array then to loop it and display filenames as an html list tag. I can see my files using console log. nothing is showing when I actually included html tags inside the loop.
here is my code for the div where my loop is placed.

<div class="containerAdmin2">
  <h2>UPDATE PAGE</h2>
  <h3>Select a File to update</h3>
  <ul>
    <li>testonly</li>
  <%
    var filePath = locals.path; 
    fs.readdir(filePath, (err, files) => {
    files.forEach(fileName => {
    %>
    /*html tag here, does not render*/
    <%
    console.log(fileName); //This line produces filename results i need
  });
  });
  %>
</ul>
</div>

I tried different EJS tags, nothing worked. thank you in advance.

jQuery set tranform3d effect

enter image description here

Trying to create this mouse tracking effect – which causes a transform3d change on the block and contents – and also adds a flash light where the mouse is.

How would you write this in vanilla js so it’s stable – I am not sure on the formula used to calculate these degree changes – as they seem to go min -8 to max 9 degrees.

https://jsfiddle.net/qzo3ck5m/46/

var myElement = $("#p1");

function setTranslate(xPos, yPos, zPos, el) {
  console.log("test");
  el.style.transform = `translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(${xPos}deg) rotateY(${yPos}deg) rotateZ(0deg) skew(0deg, 0deg)`;
}


myElement.mousemove(function(event) {
  console.log("mousemoveY---", event.clientX, event.clientY);

  let y = event.clientY;
  let x = event.clientX;

  var position = {
    top: myElement[0].offsetTop,
    left: myElement[0].offsetLeft
  };

  console.log("x", x);
  console.log("y", y);

  console.log("position", position);

  let degx = position.left - x;
  let degy = position.top - y;

  console.log("degx", degx);
  console.log("degy", degy);

  let fullDegrees = 8;

  setTranslate(-degx / 20, -degy / 20, 0, myElement[0]);
});


myElement.mouseleave(function() {
  console.log("mouseleave");
  setTranslate(0, 0, 0, myElement[0]);
});
.container {
  padding: 40px;
}

.blockwrapper {
  will-change: transform;
  transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
  margin: 10px;
}

.block {
  background-color: skyblue;
  width: 160px;
  height: 160px;
}

.moved {
  background-color: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="container">
  <div class="blockwrapper">
    <div class="block moved">Moved</div>
  </div>
  <div id="p1" class="blockwrapper">
    <div class="block">Movable</div>
  </div>
</div>

Position an element when the parent div is inside another [closed]

I didn’t know how to summarize my problem in the title.

I have a very simple structure with 3 nested divs and each of these has another div element that is a 20px x 20px square

I want when the divs touch in the top left corner, the square is placed next to the previous one so they don’t overlap

Without absolute position
How I want it

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #grandparent {
            width: 400px;
            height: 400px;
            border: 1px solid orange;
        }

        #parent {
            width: 200px;
            height: 200px;
            border: 1px solid orange;
        }

        #child {
            width: 75px;
            height: 75px;
            border: 1px solid orange;
        }

        .smallDiv {
            width: 30px;
            height: 30px;
            background: blue;
            top: 10px;
            left: 10px;
        }
    </style>
</head>
<body>
    <div id="grandparent">
        <div id="parent">
            <div id="child">
            </div>
        </div>
    </div>

    <script>
        function addSmallDiv(containerId) {
            const container = document.getElementById(containerId);
            const smallDiv = document.createElement('div');
            smallDiv.className = 'smallDiv';
            container.appendChild(smallDiv);
        }

        addSmallDiv('grandparent');
        addSmallDiv('parent');
        addSmallDiv('child');
    </script>
</body>
</html>

Unable to retrieve file type on some devices

I am using antd’s Upload component to take files input in React. My usecase allows only specific types of file to be permitted to upload. I am using beforeUpload prop of Upload component to conditionally check the type of the file before proceeding to upload. The problem is, the file type is empty string on some cases. First I thought it is OS-related issue as it was occuring on Macbook while working fine on Windows. But, it also works fine on some of the Mac devices. I am unable to identify the root cause of the issue. I also thought maybe the issue is with the file itself, but the same file retrieves correct file type on one device while empty string on the other with same browser type and version.

Here’s the code I am using:

export const ATTACHMENT_ALLOWED_FILE_TYPES = [
  "application/x-zip-compressed",
  "application/x-rar-compressed",
  "application/x-compressed",
  "application/zip", // mac format for zip
  "application/x-rar", // mac format for rar
  "application/vnd.rar", // MIME type for .rar files
  "application/x-compressed",
  "image/jpeg",
  "image/png",
  "image/jpg",
  "application/pdf",
  "application/vnd.ms-excel", // Excel 97-2003
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // Excel 2007+
  "application/vnd.ms-powerpoint", // PowerPoint 97-2003
  "application/vnd.openxmlformats-officedocument.presentationml.presentation", // PowerPoint 2007+
  "application/msword", // Word 97-2003
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // Word 2007+
];

export const isFileTypeAllowed = (file) => {
  console.clear();
  console.log("File Type: ", file);
  const isFileTypeSupported = ATTACHMENT_ALLOWED_FILE_TYPES.includes(file.type);
  return isFileTypeSupported;
};

const uploadOptions = (questionId) => ({
    name: "attachments",
    showUploadList: true,
    beforeUpload(file) {
      const isFileTypeSupported = isFileTypeAllowed(file);
      if (!isFileTypeSupported) {
        notification(
          NotificationTypes.ERROR,
          resources_EN.ERROR_LABEL,
          resources_EN.FILE_TYPE_ERROR,
          3
        );
        return Upload.LIST_IGNORE;
      } else {
        const fileSizeLimit = isFileSizeValid(file);
        if (!fileSizeLimit) {
          notification(
            NotificationTypes.ERROR,
            resources_EN.ERROR_LABEL,
            resources_EN.FILE_SIZE_ERROR,
            3
          );
          return Upload.LIST_IGNORE;
        }
      }
      customRequest({ file, questionId });
      return false;
    },
    onRemove: (file) => {
      handleFileRemove(file);
    },
  });


<Form.Item
  name={[index, FORM_VALIDATION_KEYS.ATTACHMENT]}
  valuePropName="fileList"
  getValueFromEvent={normFile}
>
  <Upload {...uploadOptions(question.questionId)}>
    <Button className="submitBtn" title={resources_EN.ADD_ATTACHMENTS} />
  </Upload>
</Form.Item>;

Works correctly on most of the devices: Correct Example – Console logs
But in few cases, doesn’t retrieve file: Example where type = “”

why does it open with any pass after i use the correct password once?

import express from "express";
import { dirname } from "path";
import { fileURLToPath } from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));
import bodyParser from "body-parser";


const app = express();
var userAuthorised = false;

app.use(bodyParser.urlencoded({extended: true}));

function passCheck(req, res, next) {
    
    if (req.body["password"] === "ILoveProgramming"){
        userAuthorised = true;
    }
    next();
}

app.use(passCheck);

app.get("/", (req, res) => {
    res.sendFile(__dirname + "/public/index.html");
});

app.post("/check", (req, res) => {
    console.log(req.body);
    if(userAuthorised){
        res.sendFile(__dirname + "/public/secret.html");
    }
    else {
        res.redirect("/");
    }
});

app.listen(3000, () => {
    console.log("Server Running on port 3000");
});

so i have 2 html files, one with just a form(which takes in a password) and one with secrets. i wrote this js code but when i run it, it refuses every wrong password until i put the correct password once and then when i go back it takes all the incorrect passwords aswell.

where am i going wrong?

Development of an unstuctured supplementary Service Data [closed]

I want to wrap 3 ussd codes,e.g *456#,*567# and *456# that independently allows me to subscribe to a product into one single ussd code.e.g.*3456#.such that when I dial *3456#. it allows me to subscribe to the products offered by the 3 codes at once.please help me through

I tried developing the code and I was expecting a ussd code that could subscribe to the products automatically

why is one of the same items in tandem in an array removed automatically? [duplicate]

Purpose: The function’s purpose is to remove all instances of val in the array nums in-place and return the new length of the array.

let nums= [0, 1, 2, 2, 2, 3, 0, 4, 2];
let val = 2;

I have done this task by filter() method easily, but I’m faced with a problem when I would want to solve with a for loop.

This problem only occurs when we have at least two same items in tandem in an array.
f we have two same items in tandem => only one item is logged. If we have three same items in tandem => only two items is logged

One of the similar item is always deducted in for loop!! why??

I expected : array = [0, 1, 3, 0, 4] => array.length = 5

But I got : array = [0, 1, 2, 3, 0, 4] => array.length = 6

function removeElement(array, val) {
  for (let i = 0; i < array.length; i++) {
    console.log(" array[i]:", array[i]); //only two of three items in tandem with value 2 is counted!!
    if (array[i] === val) {
      array.splice(i, 1);
    }
  }
  return array.length;
}

let nums = [0, 1, 2, 2, 2, 3, 0, 4, 2];
let val = 2;
const numsLength = removeElement(nums, val);
console.log("numsLength:", numsLength);  // The answer must be 5, but the functions gives 6

HTMX Form in Gin Admin Panel Requires Page Reload to Resubmit Changes

I have a form on an admin panel I am working on that doesnt allow me to resubmit changes on it unless I reload the page. I am using HTMX, and GIN primarily:
Form:

<tr data-id="{{ .ID }}">
    <form id="update-vehicle-form-{{ .ID }}" action="/admin/vehicles/{{ .ID }}/update" hx-post="/admin/vehicles/{{ .ID }}/update" hx-target="closest tr" hx-swap="outerHTML">
        <td>{{ .ID }}</td>
        <td><input type="text" name="brand-{{ .ID }}" value="{{ .Brand }}" class="edit-input"></td>
        <td><input type="text" name="model_name-{{ .ID }}" value="{{ .ModelName }}" class="edit-input"></td>
        <td><input type="number" name="year-{{ .ID }}" value="{{ .Year }}" class="edit-input"></td>
        <td><input type="number" name="price-{{ .ID }}" value="{{ .Price }}" class="edit-input"></td>
        <td>
            <select name="condition-{{ .ID }}" class="edit-select">
                <option value="new" {{ if eq .Condition "new" }}selected{{ end }}>New</option>
                <option value="used" {{ if eq .Condition "used" }}selected{{ end }}>Used</option>
            </select>
        </td>
        <td><textarea name="description-{{ .ID }}" class="edit-textarea">{{ .Description }}</textarea></td>
        <td>
            <select name="status-{{ .ID }}" class="edit-select">
                <option value="available" {{ if eq .Status "available" }}selected{{ end }}>Available</option>
                <option value="sold" {{ if eq .Status "sold" }}selected{{ end }}>Sold</option>
                <option value="pending" {{ if eq .Status "pending" }}selected{{ end }}>Pending</option>
            </select>
        </td>
        <td>
            {{ if .Media }}
            {{ range .Media }}
            <div>
                <a href="{{ .FileURL }}" target="_blank">{{ .FileName }}</a>
                <button class="delete-media-btn" hx-delete="/admin/vehicles/media/{{ .ID }}/delete" hx-confirm="Are you sure you want to delete this media?" hx-target="this.parentNode" hx-swap="outerHTML">Delete</button>
            </div>
            {{ end }}
            {{ else }}
            No media available.
            {{ end }}
        </td>
        <td>
            <button type="submit" class="update-btn" >Update</button>
            <button type="button" class="delete-btn" hx-delete="/admin/vehicles/{{ .ID }}/delete" hx-confirm="Are you sure you want to delete this vehicle?" hx-target="closest tr" hx-swap="outerHTML">Delete</button>
        </td>
    </form>
</tr>
{{ end }}

The update Handler:

    fields := map[string]interface{}{
        "Brand":       c.PostForm("brand-" + c.Param("id")),
        "ModelName":   c.PostForm("model_name-" + c.Param("id")),
        "Year":        parseYear(c.PostForm("year-" + c.Param("id"))),
        "Price":       parsePrice(c.PostForm("price-" + c.Param("id"))),
        "Condition":   c.PostForm("condition-" + c.Param("id")),
        "Description": c.PostForm("description-" + c.Param("id")),
        "Status":      c.PostForm("status-" + c.Param("id")),
    }

    for key, value := range fields {
        if value != "" && value != 0.0 && value != nil {
            setField(vehicle, key, value)
        }
    }

    if vehicle.Status == "sold" {
        vehicle.DecisionDate = time.Now()
    } else if vehicle.Status == "available" || vehicle.Status == "pending" {
        vehicle.DecisionDate = time.Time{}
    }
}

func parseYear(yearStr string) int {
    year, _ := strconv.Atoi(yearStr)
    return year
}

func parsePrice(priceStr string) float64 {
    price, _ := strconv.ParseFloat(priceStr, 64)
    return price
}

func setField(vehicle *data.Vehicle, fieldName string, value interface{}) {
    switch fieldName {
    case "Brand":
        vehicle.Brand = value.(string)
    case "ModelName":
        vehicle.ModelName = value.(string)
    case "Year":
        vehicle.Year = value.(int)
    case "Price":
        vehicle.Price = value.(float64)
    case "Condition":
        vehicle.Condition = value.(string)
    case "Description":
        vehicle.Description = value.(string)
    case "Status":
        vehicle.Status = value.(string)
    }
}

func (vs *VehicleService) renderUpdatedVehicleRow(c *gin.Context, vehicle data.Vehicle) {
    var renderedRow bytes.Buffer
    tmpl := template.Must(template.New("vehicle_row").ParseFiles(filepath.Join("templates/admin/partials", "vehicle_row.html")))
    if err := tmpl.ExecuteTemplate(&renderedRow, "carRow", vehicle); err != nil {
        log.Printf("Error executing partial template: %v", err)
        c.String(http.StatusInternalServerError, "Internal Server Error")
        return
    }

    c.Data(http.StatusOK, "text/html; charset=utf-8", renderedRow.Bytes())
}

how can I fix this so that no matter how many times i click update once something has changed on the form the request will be sent to the back end

I tried changing the form like this:

<tr data-id="{{ .ID }}">
    <form id="update-vehicle-form-{{ .ID }}" action="/admin/vehicles/{{ .ID }}/update" hx-post="/admin/vehicles/{{ .ID }}/update" hx-target="closest tr" hx-swap="outerHTML" hx-trigger="my-custom-event from:form">
        <td>{{ .ID }}</td>
        <td><input type="text" name="brand-{{ .ID }}" value="{{ .Brand }}" class="edit-input"></td>
        <td><input type="text" name="model_name-{{ .ID }}" value="{{ .ModelName }}" class="edit-input"></td>
        <td><input type="number" name="year-{{ .ID }}" value="{{ .Year }}" class="edit-input"></td>
        <td><input type="number" name="price-{{ .ID }}" value="{{ .Price }}" class="edit-input"></td>
        <td>
            <select name="condition-{{ .ID }}" class="edit-select">
                <option value="new" {{ if eq .Condition "new" }}selected{{ end }}>New</option>
                <option value="used" {{ if eq .Condition "used" }}selected{{ end }}>Used</option>
            </select>
        </td>
        <td><textarea name="description-{{ .ID }}" class="edit-textarea">{{ .Description }}</textarea></td>
        <td>
            <select name="status-{{ .ID }}" class="edit-select">
                <option value="available" {{ if eq .Status "available" }}selected{{ end }}>Available</option>
                <option value="sold" {{ if eq .Status "sold" }}selected{{ end }}>Sold</option>
                <option value="pending" {{ if eq .Status "pending" }}selected{{ end }}>Pending</option>
            </select>
        </td>
        <td>
            {{ if .Media }}
            {{ range .Media }}
            <div>
                <a href="{{ .FileURL }}" target="_blank">{{ .FileName }}</a>
                <button class="delete-media-btn" hx-delete="/admin/vehicles/media/{{ .ID }}/delete" hx-confirm="Are you sure you want to delete this media?" hx-target="this.parentNode" hx-swap="outerHTML">Delete</button>
            </div>
            {{ end }}
            {{ else }}
            No media available.
            {{ end }}
        </td>
        <td>
            <button type="submit" class="update-btn">Update</button>
            <button type="button" class="delete-btn" hx-delete="/admin/vehicles/{{ .ID }}/delete" hx-confirm="Are you sure you want to delete this vehicle?" hx-target="closest tr" hx-swap="outerHTML">Delete</button>
        </td>
    </form>
</tr>
{{ end }}

and creating new events like this:


function initializeAdminFeatures() {
    console.log("Initializing Admin Features");

    document.querySelectorAll('.collapsible-btn').forEach(button => {
        button.addEventListener('click', toggleCollapsible);
    });

    document.querySelectorAll('form[id^="update-vehicle-form-"]').forEach(form => {
        form.addEventListener('submit', function(event) {
            const customEventName = `my-custom-event-${Date.now()}`;
            setTimeout(() => {
                form.dispatchEvent(new Event(customEventName));
            }, 0);
        });
    });
}

function toggleCollapsible(event) {
    const content = event.target.nextElementSibling;

    document.querySelectorAll('.collapsible-content').forEach(c => {
        c.style.maxHeight = c === content ? (c.style.maxHeight ? null : `${c.scrollHeight}px`) : null;
    });

    console.log("Collapsible section toggled");
}