How is the Webuntis Lesson ID generated and does it change with updates?

I’m currently working with WebUntis. I’m building an n8n workflow to detect timetable changes, generate a short notification video, and send it via WhatsApp. The main challenge right now is reliably detecting those changes. I have some questions:

  • When and how is the Lesson ID generated?
  • What happens to the ID if a lesson is changed (e.g., teacher switch, room change, cancellation, etc.)?
  • Can the ID be used reliably to export the timetable once and later compare it with an updated version to detect changes?

Does anyone have experience with how the ID behaves during updates, or any best practices for tracking changes? Maybe even an example workflow design for this?

Thanks in advance for your help!

Question about WebUntis: How is the Lesson ID generated and does it change with updates?

I’m currently working with WebUntis using the WebUntis Library (see API docs: webuntis.noim.me/interfaces/Lesson.html#code).
I have a specific question about the Lesson ID:
When and how is the Lesson ID generated?
What happens to the ID if a lesson is changed (e.g., teacher switch, room change, cancellation, etc.)?
Can the ID be used reliably to export the timetable once and later compare it with an updated version to detect changes?
Background:
I’m building an n8n workflow to detect timetable changes, generate a short notification video, and send it via WhatsApp. The main challenge right now is reliably detecting those changes.
Does anyone have experience with how the ID behaves during updates, or any best practices for tracking changes? Maybe even an example workflow design for this?
Thanks in advance for your help!

How to make element sticky to bottom of window vh but continue to scroll with rest of page when scrolling past its container?

I have a “learn more” button with an arrow that encourages users to scroll down to the next section of a page, and I want it to always appear at the bottom of the window on page load, so that if someone’s window is smaller than the first section they can still see it, but then after scrolling I want it to stop scrolling once the bottom of the first section is on-screen.

So for example

Before Scroll:

  



     Learn More v
---- bottom of VH ----



---- bottom of section one, off-screen ----

after scroll



      Learn More v
---- bottom of section one ----




---- bottom of section two ----

I was trying to figure it out with position: fixed but that obviously keeps it fixed all the way to the bottom of the page. I was trying to fix it to the container but that doesn’t work.

Is there a solution to this without javascript? Or will I need to use javascript to limit the farthest it goes down?

I had tried:

#section-one {
   position: relative;
  
  .learn-more {
    position: fixed;
    bottom: 0;

  }

}

Or alternatively maybe

.learn-more {
    position: absolute;
    bottom: 0vh;
}

My thought there was that using vh for positioning might do it when it’s absolutely positioned to section-one but that’s not a valid option for bottom positioning.

What’s the right way to do it?

#section-one {
    position: relative;
    background: #c3c3c3;
    padding: 40px;
    height: 120vh;
    text-align: center;
    
  .learn-more {
    display: flex;
    flex-direction: column;
    border: none;
    width: 100%;
    transition: all .4s;
    position: absolute;
    bottom: 0;
    text-align: center;

    &:hover {
      color: var(--blue);
      transition: all .4s;
      transform: translateY(-10px);
    }

    .caret {
      transform: scale(2,1);
      margin-top: -10px;
    }
  }
 }
 
 #section-two {
  height: 100vh;
  padding: 40px;
  background: #d3d3d3;
 }
<section id="section-one">
  <h1>Section One</h1>
  <ul>
  <li>"Learn More" below should be visible any time section one is on screen.</li>
  <li>Could be in the middle of the section if the bottom of s1 is off-screen</li>
  <li>or if the bottom is on-screen then it should stop at the bottom of the section.</li>
  </ul>
  <a href="#section-two" class="learn-more">
        <div class="font-bold text-lg">Learn More</div>
        <div class="caret font-bold text-xl">⌄</div>
      </a>

</section>

<section id="section-two">
  <h2>Section Two</h2>
  <p>"Learn More" should never be in this section, and should scroll up with the bottom of section 1 above</p>
</section>

APEX programming to Javascript [closed]

Hello I have a working Apex code but I want it to work Javascript. Is this easy todo and can somebody help me on the way?

Code below

create or replace function f_marcus -- 20250610
( p_volume in number )
return number is
   x_default     number default 439;
   x_bedrag      number default 0;
   x_meer        number default 0;
   x_factor      number default 0;
   x_factor_ceil number default 0;

BEGIN
  x_meer   := p_volume - 400;
  x_factor := x_meer / 100;
  x_factor_ceil := ceil(x_meer / 100);

   if p_volume < 400 then
     x_bedrag := x_default;
   else
     x_bedrag := x_default + x_factor_ceil * 20;
   end if
   ;
   return(x_bedrag)
   ;
END f_marcus;
/

How to use addEventListener on dynamically added elements inside forEach() [closed]

I have a function with another function inside it. It also has an eventListener for some dynamically added elements.
With the pseudo code below, I get multiple listeners – the same for each element.
How do I do it to get one eventListener – and how do get its context?

If I move the eventListener out of functionA(), how can I reach functionB()?

const functionA = (el) => {
    const items = 1;
    console.log('functionA');

    const functionB = (items) => {
        console.log('functionB');
    }

    document.addEventListener('click', function (e) {
        const $this = e.target;
        console.log($this);
        
        functionB(items);
    });
}

Array.from(document.querySelectorAll('.el')).forEach((el) => {
    functionA(el);
});
<div class="el">El 1</div>
<div class="el">El 2</div>
<div class="el">El 3</div>

Sort datatable column so blanks appear last

I’m trying to sort my date column ArrivalDate so that any blanks/null values appear last or at the bottom of the list when sorting by that column. I have found the ‘absolute’ plugin but I don’t understand why I’m having no success in using it. I get no console errors. I have tried using values ‘null’ and ” to pick up blank values but the sort always has the blank showing at the top.

var namesType = $.fn.dataTable.absoluteOrder([
    { value: '', position: 'bottom' }
]);


$('#recoverySMTableMain').dataTable({
    "processing": true,
    "serverSide": true,
    order: [[3, 'desc']],
    "ajax": {
        "url": "?handler=GetPIs",
        headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
        "data": function (d) {
            d.datefrom = "",
                d.dateto = "",
                d.archive = archiveView,
                d.destsearch = $('#destSearchInput').val();
        },
        "type": "POST",
        "ContentType": "json"
    },
    "columns": [
        { "name": "Regnumber", "data": "Regnumber", "autoWidth": false },
        { "name": "Vehicle", "data": "Vehicle", "autoWidth": false },
        { "name": "Colour", "data": "Colour", "autoWidth": false },
        { "name": "JobNumber", "data": "JobNumber", "autoWidth": false },
        { "name": "Site", "data": "Site", "autoWidth": false },
        { "name": "CustomerDeliveryDate", "data": "CustomerDeliveryDate", "autoWidth": false },
        { "name": "ArrivalDate", "data": "ArrivalDate", "autoWidth": false},
        { "name": "Pulled", "data": "Pulled", "autoWidth": false },
        { "name": "Driver", "data": "Driver", "autoWidth": false },
        { "name": "DeliveryDate", "data": "DeliveryDate", "autoWidth": false },
        { "name": "Notes", "data": "Notes", "autoWidth": false },
        { "name": "RecNo", "data": "RecNo", "autoWidth": false }
    ],
    "columnDefs": [
        {
            targets: [5, 6, 9],
            type: 'date'
        },
        { type: namesType, targets: [5, 6, 9] },
    ],
    pageLength: 1000,
    width: "1000px",
    "deferRender": true,
    "bAutoWidth": false,
    scrollY: "402px",
    scrollCollapse: false,
    fixedHeader: true,
    "stateSave": false,
    "bLengthChange": false,
    //Table Status Colours
    "rowCallback": function (row, data) {
        $(row).addClass('row-pointer-no-change');
        row.id = data.RecNo;
        if (data.Status == null) {
            data.Status = "";
        }
        //if (tableType != "ARCHIVE") {
        if (data.Status == "" || data.Status == undefined) {
            $(row).addClass('table-colour-font-settings');
        }
        /*if (data.Status == "PENDING") {
            $(row).addClass('table-lightblue');
            $(row).addClass('table-colour-font-settings');
        }*/
        /*}
        else {
            if (data.Status.includes("CANCELLED") || data.Status == "DELETED") {
                $(row).addClass('table-danger');
                $(row).addClass('table-colour-font-settings');
            }
        }*/
    }
});

PLUGIN: https://datatables.net/plug-ins/sorting/absolute

How to associate CSS with Tailwind/Shadcn?

I am confused on how to configure React/Tailwind/Shadcn to work with CSS. I am trying to make a very minimal example where I can add a button.

I did the minimal:

npm create vite@latest  # (React/TypeScript)
cd project
npm install
npm install tailwindcss @tailwindcss/vite
npm install -D @types/node
npx shadcn@latest init
npx shadcn@latest add Button

I have modified the ts.config.json:

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

The ts.app.json:

{
    "compilerOptions": {
        ...
        "include": ["src"],
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        }
    }
}

The vite.config.ts:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import path from "path"

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
})

Then simplified the App.tsx to the following:

import { Button } from './components/ui/button'

function App() {
   return <Button variant="destructive">Destructive</Button>
}

export default App

No changes in the main.tsx:

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
)

And the last file index.css was edited by Shadcn, but I kept the minimal:

@import "tailwindcss";
@import "tw-animate-css";

:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;

  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  --radius: 0.625rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.129 0.042 264.695);
  ...
  --destructive: oklch(0.577 0.245 27.325);
  ...
}

@theme inline {
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  ...
  --color-destructive: var(--destructive);
  ...
  --color-sidebar-border: var(--sidebar-border);
  --color-sidebar-ring: var(--sidebar-ring);
}

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  body {
    @apply bg-background text-foreground;
  }
}

And here my result:

enter image description here

Here the version used:

[email protected] /home/ycr/shad-anim/prout
├── @eslint/[email protected]
├── @radix-ui/[email protected]
├── @tailwindcss/[email protected]
├── @types/[email protected]
├── @types/[email protected]
├── @types/[email protected]
├── @vitejs/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

Why colors are not available?

Next.js 15 Crash After Build (next start) – $Sreact.fragment, MetadataBoundary, AsyncMetadataOutlet Errors

I’m using Next.js 15 and encountering intermittent crashes when running the built project with next start. The issue does not occur consistently during development (next dev), but sometimes in production after build (next build && next start).

The error output is highly obfuscated and appears to be related to server-side rendering or React component streaming. Here’s a snippet of the error stack:

1: "$Sreact.fragment"
2: I[87555, [], ""]
4: I[32613, ["4345", "static/chunks/app/not-found-62470cef0e8678bf.js"], "default"]
8: I[59665, [], "MetadataBoundary"]
a: I[59665, [], "OutletBoundary"]
d: I[74911, [], "AsyncMetadataOutlet"]
f: I[59665, [], "ViewportBoundary"]
...
12: "$Sreact.suspense"
13: I[74911, [], "AsyncMetadata"]
...

There are also many entries like:

:HL["/_next/static/css/6244d6272a597737.css","style"]

And chunks such as:

I[75042, ["8320", "static/chunks/41ade5dc-1ce412a688519a96.js", ...], "default"]

This looks like an internal serialization format or streaming rendering metadata, but it crashes the page load instead of gracefully rendering or falling back to an error boundary.

What I’ve Tried

  • Clean install (rm -rf .next node_modules && npm install)

Environmentstrong text

  • Next.js: 15.2.0
  • Node.js: 22.6.0
  • React: 18 (Next.js default)

Question

Has anyone encountered a similar error output related to “$Sreact.fragment” or “AsyncMetadataOutlet” after build? How can I debug or resolve this kind of rendering crash in Next.js 15?

Google Analytics not showing real numbers

Google Analytics is not working as it used before, numbers went more than half down suddenly while I am pretty sure that I have more visitors than the actual shown numbers on GA.

Is there any way to track where is the issue and why its not checking the actual visitors?

I tried to change the code, and tested couple months and multiple times but still not solved.

Initializing global variable between re-render and setstate function call breaks UI

Overview

I’ve found that resetting indxg = -1 either before calling setColor(setcol) or after React re-renders keeps everything in sync, but resetting it between setColor(setcol) and the re-render breaks the hook order. I don’t yet understand why resetting before the state update works, yet doing so between the update and the render corrupts the behavior.

Unexpected Output:

After clicking “change color”, the console showed:
[‘blue’, ‘red’, ‘pink’, ‘red’] instead of [‘pink’,’red’]

Minimal Reproducible Example:
Corrupted code:

// Global state management
let m = []; 
let indxg = -1;

function mystate(initial) {
  indxg++;
  const idx = indxg;
  
  if (m[idx] === undefined) {
    m[idx] = initial;
  }

  const setState = (newValue) => {
    m[idx] = newValue;
    
  };
  
  return [m[idx], setState];
}

// Component Implementation (Broken)
function App() {
  const [color1, setColor1] = mystate("blue");
  const [color2, setColor2] = mystate("red");

  const updateColor = () => {
    setColor1("pink");
    // PROBLEM: Reset AFTER state update indxg between setcol and render
    indxg = -1; 
    root.render(<App />); // Re-render on update 
  };

  return (
    <>
      <div style={{ background: color1 }}>Box 1</div>
      <div style={{ background: color2 }}>Box 2</div>
      <button onClick={updateColor}>Update</button>
    </>
  );
}

Working Solution:

// Global state management
let m = []; 
let indxg = -1;

function mystate(initial) {
  indxg++;
  const idx = indxg;
  
  if (m[idx] === undefined) {
    m[idx] = initial;
  }

  const setState = (newValue) => {
    m[idx] = newValue;
    root.render(<App />); // Re-render on update
  };
  
  return [m[idx], setState];
}


function App() {
  indxg = -1; 
  const [color1, setColor1] = mystate("blue");
  const [color2, setColor2] = mystate("red");

  const updateColor = () => {
    setColor1("pink");
      };

  return (
    <>
      <div style={{ background: color1 }}>Box 1</div>
      <div style={{ background: color2 }}>Box 2</div>
      <button onClick={updateColor}>Update</button>
    </>
  );
}

Ai answer that i could not understand:

The root cause is that your custom hook relies on a global indxg to assign each call a unique slot in the m array. React (and your stub) expects hooks to be called in the same order every render. If you reset indxg after calling setState (but before the next render), you shift your hook calls out of sync, so new slots get created and old ones are never reused—hence the extra entries. The fix is to reset indxg to -1 at the very start of your component render, so each call to mystate always increments from zero in the same sequence.

Clarification about reducers

I encountered the following code and I’m trying to make sense of it. When I substitute my simplified version of the code in question, the application doesn’t work.

The original code is:

const state = {count: 0}

const reducers = {
    add: (state) => ({count: state.count + 1}),
    sub: (state) => ({count: state.count - 1}),
}

My dumbed-down version is:

const myReducersAsAnObject = {
    add : function (state) {
        return count = state.count + 1
    },
    sub: function (state){
        return count = state.count - 1
    }
}

Where am I going wrong?

How to Defer JavaScript in WordPress Without Breaking Elementor Widgets? [closed]

I’m working on improving my WordPress website’s performance by deferring JavaScript. I tried using defer or async on my script tags, but this caused some Elementor widgets to stop working properly.

Here’s a simplified example of my current approach:

html
Copy
Edit

Is there a best practice for deferring JavaScript in WordPress while keeping Elementor (or other JS-heavy plugins) working as expected? Should I use specific hooks in functions.php or certain plugins to handle this?

Thanks!

emonkey integration returning NaN despite nearly identical code

I am currently working on formatting dates to some desired formats, and I am using Emonkey to do this using their integrations and some Javascript.

I’ve made two integrations called “Integration Tools” and “DateToTextDDMMYYYY” that convert dates from the internal Date format that Emonkey provides to strings formatted as DDMMYYYY and YYYYMMDD. “Integration Tools” correctly formats the Date to a string in the YYYYMMDD format, but the “DateToTextDDMMYYYY” integration returns NaNNaNNaN (NaN is short for Not a number).

The only difference between these integrations is the Javascript functions that they use. The only difference between the Javascript functions is that they concatenate the day, month and year variables in a different order, everything else is exactly the same.

function DateConverter1(date) {

  // control flow
  let newDate = new Date(date);

  if (!newDate) {
    throw new Error("the string date is not a formatted date string");
    return;
  }

  let year = newDate.getFullYear().toString();

  // inkrementerer med 1 siden funksjonen defaulter til 0 for januar og søndag
  let month = (newDate.getMonth() + 1).toString();

  if (Number(month) < 10) {
    month = '0' + month;
  }

  let day = (newDate.getDay() + 1).toString();

  if (Number(day) < 10) {
    day = '0' + day;
  }


  let formattedDate = year + month + day;
  return formattedDate;
}

function DateConverter2(date) {

  // control flow
  let newDate = new Date(date);

  if (!newDate) {
    throw new Error("the string date is not a formatted date string");
    return;
  }

  let year = newDate.getFullYear().toString();

  // inkrementerer by 1 since the getMonth() and getDay() functions default to 0 for 
  //sundays and january
  let month = (newDate.getMonth() + 1).toString();

  if (Number(month) < 10) {
    month = '0' + month;
  }

  let day = (newDate.getDay() + 1).toString();

  if (Number(day) < 10) {
    day = '0' + day;
  }


  let formattedDate = year + month + day;
  return formattedDate;
}

console.log(DateConverter1("2025-06-10"))
console.log(DateConverter2("2025-06-10"))

integration implementation