Form dirty does not work properly for combobox – ExtJs

I have an edit form and I’m trying to unlock the Save button only if the form has any changes compared to what data was loaded at the beginning of the form.

It works fine for various input types, but unfortunately it doesn’t work at all for ComboBox. I don’t know what could be wrong here, because formally everything looks fine and works for other input types. Does anyone have any idea why?

https://fiddle.sencha.com/#view/editor&fiddle/3te7

form = Ext.widget('form', {
    id: 'gridPopUpForm',
    cls: 'form form--full-width',
    bodyCls: 'form__body',
    scrollable: true,
    listeners: {
      dirtychange: () => {
        const saveButton = form.up().down('#gridPopUpFormSaveButton')
        console.log('dirtychange')
        console.log(`isDirty: ${form.isDirty()}`)

        saveButton.setDisabled(!form.isDirty())
      },
      change: () => {
        console.log('change')
      },
      validitychange: (_, valid) => {
        const disabled = !valid
        const saveButton = form.up().down('#gridPopUpFormSaveButton')

        saveButton.setDisabled(disabled)
      },
    },
  })

field.listeners = {
        ...field.listeners,
        change: (field, newValue, oldValue) => {
          if (column?.dependants?.length) {
            this.handleDependentFields(column)
          }

          console.log(field, newValue, oldValue)
        },

        afterRender: (field) => {
          if (column?.dependants?.length) {
            this.handleDependentFields(column)
          }
          console.log(field)
        },

        dirtyChange: (field, isDirty) => {
          const formWindow = field?.up('#gridPopUpFormWindow')
          const saveButton = formWindow?.down('#gridPopUpFormSaveButton')

          console.log(`isDirty: ${isDirty}`) // if combobox is true after form render
          saveButton?.setDisabled(!isDirty)
        },
      }

Who uses OOP Javascript and in what circumstance? [closed]

It’s been a long time since I’ve used Javascript heavily. I’m taking a refresher course online and I’m reacquainting myself with OOP Javascript as well as functional. I personally only recall using functional Javascript.

Do you use OOP Javascript? Why do you choose to use that over functional? I’ve read that it’s more typical to use functional, but that OOP can make for cleaner/efficient code. Is it typical in certain jobs to use OOP or is it just a personal preference no matter what you’re coding?

Ckeditor5 with React – Custom Comment View is not working

I am new to Ckeditor5 with React and created sample application where I am trying to create custom comment view where user can view/ edit the comment. (refer below screenshot)

Description – We have a editor with comments. As per our requirement we are trying to customize the Comment view, where user can edit the comment in TextArea (later we will going to add few more controls like Input, Input as File) in comment popup as shown below(View and edit mode). We are using vite.config for bundling.

enter image description here

package.json

 "devDependencies": {
    "@ckeditor/ckeditor5-react": "^9.2.0",
    "@vitejs/plugin-react": "^4.0.0",
    "ckeditor5": "44.3.0",
    "ckeditor5-premium-features": "44.3.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "vite": "^5.0.0"
  },
  "dependencies": {
    "html-to-text": "^9.0.5"
  }
}
import { BaseCommentView, CommentView } from 'ckeditor5-premium-features';
import { View, icons, ButtonView } from "ckeditor5";

export default class CustomCommentView extends BaseCommentView {
    constructor(locale, model, config) {
        super(locale, model,
            {
               ....
            });

        this._model = model;

        this.commentContent = model.content || '';
        this.state = 'view';

        // Define the template
        this._setTemplateBasedOnState();
    }

    // Dynamically update the template based on the state (view/edit)
    _setTemplateBasedOnState() {
        if (this.state === 'edit') {
            // Edit Mode Template
            this.setTemplate({
                tag: 'div',
                attributes: {
                    class: 'custom-comment-view edit-mode'
                },
                children: [
                    {
                        tag: 'textarea',
                        attributes: {
                            class: 'comment-textarea',
                            rows: 3,
                            value: this.commentContent,
                            onchange: this._onContentChange.bind(this)
                        }
                    },
                    {
                        tag: 'button',
                        attributes: {
                            class: 'save-button',
                            onclick: this._onSave.bind(this)
                        },
                        children: [{ text: 'Save' }]
                    },
                    {
                        tag: 'button',
                        attributes: {
                            class: 'cancel-button',
                            onclick: this._onCancel.bind(this)
                        },
                        children: [{ text: 'Cancel' }]
                    }
                ]
            });
        } else {
            // View Mode Template
            this.setTemplate({
                tag: 'div',
                attributes: {
                    class: 'custom-comment-view view-mode'
                },
                children: [
                    {
                        tag: 'p',
                        attributes: {
                            class: 'comment-content'
                        },
                        children: [{ text: this.commentContent }]
                    },
                    {
                        tag: 'button',
                        attributes: {
                            class: 'edit-button',
                            onclick: this._onEdit.bind(this)
                        },
                        children: [{ text: 'Edit' }]
                    },
                    {
                        tag: 'button',
                        attributes: {
                            class: 'delete-button',
                            onclick: this._onDelete.bind(this)
                        },
                        children: [{ text: 'Remove' }]
                    }
                ]
            });
        }
    }

    // Handle content changes in the textarea
    _onContentChange(event) {
        this.commentContent = event.target.value;
    }

    // Switch to edit mode
    _onEdit() {
        this.state = 'edit';
        this._setTemplateBasedOnState(); // Re-render the template
    }

    // Save changes and switch back to view mode
    _onSave() {
        console.log('Saved Comment:', this.commentContent);
        this.state = 'view';
        this._setTemplateBasedOnState();

        // Trigger a save callback if defined
        // if (this._options.onSave) {
        //     this._options.onSave(this.commentContent);
        // }
    }

    // Cancel editing and revert back to the original state
    _onCancel() {
        console.log('Edit cancelled');
        this.state = 'view';
        this._setTemplateBasedOnState();
    }

    _onDelete() {
        console.log('Delete button clicked');
        // if (this._options.onDelete) {
        //     this._options.onDelete(this.commentContent);
        // }
    }
}

Below I have created CustomCommentView and used it in Ckeditor config but after running I am getting “TypeError: Cannot read properties of undefined (reading ‘on’)” error for removebutton. When i checked this error is coming on remove button while creating template. Due to this events are not getting registered on button and also not able to check whether other edit template loading will also work or not.

enter image description here

enter image description here

If someone can help us on this will be appreciated.

How to calculate 3d point on a 2d triangle in a 3d space?

I’m making my own 3D renderer in JS and am trying to create a z-buffer. However, I need to then get the position of each pixel on the triangles being rendered to get the distance from the camera. I can get which pixels I need to measure, but how can I find the cooridnates on the triangle?

To clarify, I’m not trying to render a triangle or find the coordinates of the vertice. I’m trying to find the position of a point on the triangle that is spread through three dimensions.

Mock one function under object instantiated from class in jest

I need to test how my function would respond when only one of the methods under an object instantiated in the function script returns a certain value.

The function’s script:

import TTLCache from '@isaacs/ttlcache';

const DATA_KEY = 'barks';

const dataCache = new TTLCache({ ttl: 100, checkAgeOnGet: true, max: 1 });

export const getCachedData = async (): Promise<string | undefined> => {    
    if (!dataCache.has(DATA_KEY)) {
        dataCache.set(DATA_KEY, 'new-item');
    }

    return dataCache.get(DATA_KEY);
};

My test:

import { getCachedData } from '../functionScript';

const mockGetRemainingTTL = jest.fn();

jest.mock('@isaacs/ttlcache', () => {
    return jest.fn().mockImplementation(() => ({
        ...jest.requireActual('@isaacs/ttlcache'),
        getRemainingTTL: () => mockGetRemainingTTL(),
    }));
})

describe('ttlCaching', () => {
    test('Return undefined when ttl has expired', async () => {
        mockGetRemainingTTL.mockReturnValue(0);
        expect(await getCachedData()).toEqual(undefined);
    });
});

getRemainingTTL is a method under the cache object that gets called internally.

For the above test, I get the error:
“TypeError: dataCache.has is not a function”

I do not understand why the ...jest.requireActual('@isaacs/ttlcache') part did not fill in the original implementations.

How can I create a rotating slider with clickable circles and arrow controls?

I’m developing a rotating slider interface where several circles are arranged in a circular layout. I want the slider to have two main functionalities:

Clickable Circles: When a user clicks on any circle, it should smoothly rotate and reposition so that the clicked circle becomes the central, prominent element.

Arrow Controls: In addition to clicking the circles, I’d like to include left/right arrow buttons that allow the user to rotate through the circles.

I’ve attempted to implement this behavior using HTML/CSS/JavaScript, but I’m encountering issues with the position of circles, rotation animations and ensuring the clicked circle transitions correctly to the main position. Additionally, managing the arrow control rotations has proven challenging.

Could someone provide guidance or examples on how to achieve this functionality? Any suggestions for libraries, frameworks, or code examples that can help me implement a smooth, interactive rotating slider would be greatly appreciated.

Thank you in advance for your help.

Rotating Circles Slider

  // Grab all carousel items and the main circle
  const items = document.querySelectorAll('.carousel-item');
  const mainCircle = document.getElementById('mainCircle');
  const arrowLeft = document.getElementById('arrowLeft');
  const arrowRight = document.getElementById('arrowRight');
  
  // Track which item is "active"
  let activeIndex = 0;

  // Update positions based on the active index
  function updateCarousel() {
    // Update main circle text to match the active item
    mainCircle.textContent = items[activeIndex].textContent;
    
    const totalItems = items.length;
    const angleStep = 360 / totalItems;
    
    // Define ellipse radii (must match the SVG ellipse)
    const radiusX = 250;  // horizontal radius
    const radiusY = 50;   // vertical radius
    
    items.forEach((item, i) => {
      // Calculate angle relative to the active index
      const angle = (i - activeIndex) * angleStep;
      const rad = angle * Math.PI / 180;
      
      // Calculate x/y positions for elliptical orbit
      const x = radiusX * Math.cos(rad);
      const y = radiusY * Math.sin(rad);
      
      // Move each item into position around the main circle
      item.style.transform = `translate(-50%, -50%) translate(${x}px, ${y}px)`;
    });
  }

  // Event listeners for arrow clicks
  arrowLeft.addEventListener('click', () => {
    activeIndex = (activeIndex - 1 + items.length) % items.length;
    updateCarousel();
  });
  
  arrowRight.addEventListener('click', () => {
    activeIndex = (activeIndex + 1) % items.length;
    updateCarousel();
  });

  // Event listener for clicking on an outer item
  items.forEach((item, i) => {
    item.addEventListener('click', () => {
      activeIndex = i;
      updateCarousel();
    });
  });

  // Initialize the carousel on page load
  updateCarousel();
 .carousel-container {
      position: relative;
      width: 900px;
      height: 300px;
      margin:  auto;
      overflow: hidden;
      /* Remove the container border since we use an SVG for the orbit */
    }
    
    /* SVG orbit drawn behind the circles */
    .orbit {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 1;
    }
    
    /* The central circle (the "sun") */
    .carousel-center {
      position: absolute;
      top: 80%; /* Orbit center vertical position */
      left: 50%;
      width: 120px;
      height: 120px;
      background-color: orange;
      border-radius: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      font-weight: bold;
      color: #fff;
      z-index: 10;
      box-shadow: 0 0 8px rgba(0,0,0,0.3);
      cursor: default;
    }
    
    /* Outer circles (the "planets") */
    .carousel-item {
      position: absolute;
      top: 80%; /* Same center as the main circle */
      left: 50%;
      width: 80px;
      height: 80px;
      background-color: #ffe0a2;
      border-radius: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      cursor: pointer;
      transition: transform 0.5s;
      box-shadow: 0 0 5px rgba(0,0,0,0.2);
      z-index: 5;
    }

    /* Arrows for manual sliding */
    .carousel-arrow {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      background-color: #ddd;
      border: none;
      padding: 10px 15px;
      cursor: pointer;
      z-index: 20;
      font-size: 16px;
      border-radius: 4px;
      box-shadow: 0 0 5px rgba(0,0,0,0.2);
    }
    .carousel-arrow.left {
      left: 10px;
    }
    .carousel-arrow.right {
      right: 10px;
    }
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Carousel Orbit</title>
</head>
<body>

<div class="carousel-container">
  <!-- SVG Orbit Path matching the ellipse in JS -->
  <svg class="orbit" width="900" height="300">
    <!-- The ellipse is centered at (450, 240) which is 50% (450px) horizontally and 80% (240px of 300px) vertically -->
    <ellipse cx="450" cy="240" rx="250" ry="50" fill="none" stroke="#ccc" stroke-dasharray="5,5" />
  </svg>

  <!-- Main circle (active item) -->
  <div class="carousel-center" id="mainCircle">API Applications</div>
  
  <!-- Outer circles (planets) -->
  <div class="carousel-item" data-index="0">E2E Testing</div>
  <div class="carousel-item" data-index="1">API Portal</div>
  <div class="carousel-item" data-index="2">API Governance</div>
  <div class="carousel-item" data-index="3">API Navigator</div>
  
  <!-- Navigation arrows -->
  <button class="carousel-arrow left" id="arrowLeft">&lt;</button>
  <button class="carousel-arrow right" id="arrowRight">&gt;</button>
</div>


 
</body>
</html>

JavaScript drop Table row before or after an other row

my script for dragging and dropping table rows inserts the rows always before (in function dropHandler).
This works fine, but I additionally would like to check if I dropped the row AFTER the last existing row and then insert the row at the end of the table body.

Is there a way to do this?

/*** Drag und Drop der Tabellenzeilen */
function dragstartHandler(ev) {
  sourceRow = ev.target;
  sourceTableId = sourceRow.closest("table").id;
}

function dragoverHandler(ev) {
  ev.preventDefault();
}

function dropHandler(ev) {
  ev.preventDefault();
  targetRow = ev.target.closest("tr");
  targetTable = targetRow.closest("table");
  targetTableId = targetRow.closest("table").id;
  if (sourceTableId === targetTableId) {
    //console.log("richtige Tabelle");
    targetTableBody = targetRow.closest("tbody");
    targetTableBody.insertBefore(sourceRow, targetRow);
    rebuildIndex(targetTableBody);
    //sourceRow.classList.remove("dragRow");
  } else {
    console.log("falsche Tabelle")
  }
}
<table id="table2">
  <thead>
    <tr>
      <th>Head1</th>
      <th>Head2</th>
      <th>Head3</th>
      <th>Head4</th>
    </tr>
  </thead>
  <tbody id="tableBody-table2">
    <tr id="table2_row1" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>table 2 values 1</td>
      <td>table 2 values 2</td>
      <td>table 2 values 3</td>
      <td>table 2 values 4</td>
    </tr>
    <tr id="table2_row2" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>table 2 values 5</td>
      <td>table 2 values 6</td>
      <td>table 2 values 7</td>
      <td>table 2 values 8</td>
    </tr>
    <tr id="table2_row3" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>table 2 values 8</td>
      <td>table 2 values 9</td>
      <td>table 2 values 10</td>
      <td>table 2 values 11</td>
    </tr>
  </tbody>
</table>

Can’t change line thickness

I’m creating an axis with circles in it, I need the logic for interpolation, so the solution should work with it. Everything works normally, I just can’t change line thickness, I tried various methods and none work, or they do but I can’t integrate interpolation (or I’m just dumb)
I tried using meshlinematerial with a mesh instead of linebasicmaterial and lineloop but they didn’t even appear (no idea what the problem was and it was the closest to my current logic, so if it does work I think it’s my best bet)

import { MeshLineGeometry, MeshLineMaterial } from "meshline";
import { useRef, useEffect } from "react";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import {
  Line2,
  LineGeometry,
  LineMaterial,
} from "three/examples/jsm/Addons.js";

const Axis = () => {
  const mountRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const mountain = mountRef.current;
    const textureLoader = new THREE.TextureLoader();
    const starTexture = textureLoader.load("star3.png");
    const axisLength = 80;
    //# Scene
    const scene = new THREE.Scene();
    scene.frustumCulled = false;
    scene.background = new THREE.Color("#000");
    scene.fog = new THREE.FogExp2(0x000000, 0.001);

    //# Renderer
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    if (mountRef.current) {
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setPixelRatio(window.devicePixelRatio);
      // Append the renderer's canvas element to our container.
      mountRef.current.appendChild(renderer.domElement);
      console.log(renderer.domElement);
    }
    //# Camera
    const camera = new THREE.PerspectiveCamera(
      50,
      window.innerWidth / window.innerHeight,
      0.5,
      10000
    );
    camera.position.set(200, 100, -30);

    //# OrbitControls
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;

    //# Group
    const objectGroup = new THREE.Group();

    //# Axes
    function createAxis(
      points: THREE.Vector3[],
      color: string,
      thickness: number
    ) {
      const positions = points.flatMap((p) => [p.x, p.y, p.z]);
      const geometry = new LineGeometry();
      geometry.setPositions(positions);

      const material = new LineMaterial({
        color,
        linewidth: thickness, // Now works reliably
        resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
      });

      return new Line2(geometry, material);
    }
    // function createAxis(points: THREE.Vector3[], color: string) {
    //   const segments = 1000;
    //   const newPoints = [];

    //   for (let i = 0; i < segments; i++) {
    //     const t = i / segments; // 0 - 1
    //     const x = (1 - t) * points[0].x + t * points[1].x;
    //     const y = (1 - t) * points[0].y + t * points[1].y;
    //     const z = (1 - t) * points[0].z + t * points[1].z;
    //     newPoints.push(new THREE.Vector3(x, y, z));
    //   }

    //   for (let i = 0; i < segments; i++) {
    //     const t = i / segments;
    //     const x = (1 - t) * points[1].x + t * points[2].x;
    //     const y = (1 - t) * points[1].y + t * points[2].y;
    //     const z = (1 - t) * points[1].z + t * points[2].z;
    //     newPoints.push(new THREE.Vector3(x, y, z));
    //   }

    //   const geometry = new THREE.BufferGeometry().setFromPoints(newPoints);
    //   const material = new THREE.LineBasicMaterial({ color, linewidth: 15 });
    //   const line = new THREE.Line(geometry, material);
    //   line.frustumCulled = false;
    //   return line;
    // }
    // scene.add(
    //   createAxis(
    //     [
    //       new THREE.Vector3(-100, 0, 0),
    //       new THREE.Vector3(0, 0, 0),
    //       new THREE.Vector3(100, 0, 0),
    //     ],
    //     xColor
    //   )
    // ); //x axis

    // scene.add(
    //   createAxis(
    //     [
    //       new THREE.Vector3(0, -100, 0),
    //       new THREE.Vector3(0, 0, 0),
    //       new THREE.Vector3(0, 100, 0),
    //     ],
    //     xColor
    //   )
    // ); //y axis

    // scene.add(
    //   createAxis(
    //     [
    //       new THREE.Vector3(0, 0, -100),
    //       new THREE.Vector3(0, 0, 0),
    //       new THREE.Vector3(0, 0, 100),
    //     ],
    //     xColor
    //   )
    // ); //z axis
    const xColor = "#fff";
    const lineThickness = 3;
    objectGroup.add(
      createAxis(
        [
          new THREE.Vector3(-axisLength, 0, 0),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(axisLength, 0, 0),
        ],
        xColor,
        lineThickness
      ),
      createAxis(
        [
          new THREE.Vector3(0, -axisLength, 0),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(0, axisLength, 0),
        ],
        xColor,
        lineThickness
      ),
      createAxis(
        [
          new THREE.Vector3(0, 0, -axisLength),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(0, 0, axisLength),
        ],
        xColor,
        lineThickness
      )
    );

    //# Arrow
    const arrowLength = 1;
    const headLength = 3;
    const headWidth = 3;
    const arrowColor = "#fff";

    // Positive X
    const posXArrow = new THREE.ArrowHelper(
      new THREE.Vector3(1, 0, 0), // Direction
      new THREE.Vector3(axisLength, 0, 0), // Origin
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(posXArrow);

    // Negative X
    const negXArrow = new THREE.ArrowHelper(
      new THREE.Vector3(-1, 0, 0),
      new THREE.Vector3(-axisLength, 0, 0),
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(negXArrow);
    // Positive Y
    const posYArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, 1, 0), // Direction
      new THREE.Vector3(0, axisLength, 0), // Origin
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(posYArrow);

    // Negative Y
    const negYArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, -1, 0),
      new THREE.Vector3(0, -axisLength, 0),
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(negYArrow);
    // Positive Z
    const posZArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, 0, 1), // Direction
      new THREE.Vector3(0, 0, axisLength), // Origin
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(posZArrow);

    // Negative X
    const negZArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, 0, -1),
      new THREE.Vector3(0, 0, -axisLength),
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(negZArrow);

    //# Circle
    function createOrbitalCircle(
      radius: number,
      color: string,
      rotationAxis: THREE.Vector3,
      rotationAngle: number
    ) {
      const points = [];
      const segments = 128;

      // Base circle
      const baseGeometry = new THREE.CircleGeometry(radius, segments);
      const positions = baseGeometry.getAttribute("position").array;

      // Apply 3D rotation
      const quaternion = new THREE.Quaternion().setFromAxisAngle(
        rotationAxis,
        rotationAngle
      );

      for (let i = 0; i < positions.length; i += 3) {
        const vec = new THREE.Vector3(
          positions[i],
          positions[i + 1],
          positions[i + 2]
        );
        vec.applyQuaternion(quaternion);
        if (i !== 0) {
          points.push(vec);
        }
        // console.log(points);
      }

      const geometry = new MeshLineGeometry().setFromPoints(points);
      const material = new  THREE.LineBasicMaterial({
        color: new THREE.Color(color),
        lineWidth: 0.1,
        resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
        // transparent: true,
        opacity: 0.9,
      });

      return new THREE.LineLoop(geometry, material);
    }
    const outerCircles = 3;
    const radius = 70;
    // const innerCircles = 2;
    for (let i = 0; i < outerCircles; i++) {
      const inter = i / outerCircles;
      objectGroup.add(
        createOrbitalCircle(
          radius,
          "#ffcc00",
          new THREE.Vector3(1, 0, 0),
          Math.PI * inter
        )
      );
    }

    // const sphereGeo = new THREE.BufferGeometry();
    const starPositions = new Float32Array([0, 0, 0]);

    const starGeometry = new THREE.BufferGeometry();
    starGeometry.setAttribute(
      "position",
      new THREE.BufferAttribute(starPositions, 3) // 3 components per vertex
    );
    // const sphereGeometry = new THREE.SphereGeometry(15, 32, 16);
    // const material = new THREE.MeshBasicMaterial({ color: "#fff" });
    const sphereMaterial = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 120,
      sizeAttenuation: true,
      transparent: true,
      opacity: 0.99,
      map: starTexture,
      alphaTest: 0.01,
    });
    const star = new THREE.Points(starGeometry, sphereMaterial);
    objectGroup.add(star);
    scene.add(objectGroup);

    //# Particles
    const particleGeometry = new THREE.BufferGeometry();
    const particleCount = 20000;
    const positions = new Float32Array(particleCount * 3);

    for (let i = 0; i < particleCount; i++) {
      positions[i * 3] = (Math.random() - 0.5) * 2000; // x
      positions[i * 3 + 1] = (Math.random() - 0.5) * 2000; // y
      positions[i * 3 + 2] = (Math.random() - 0.5) * 2000; // z
    }
    particleGeometry.setAttribute(
      "position",
      new THREE.BufferAttribute(positions, 3)
    );

    const particleMaterial = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 8,
      sizeAttenuation: true,
      transparent: true,
      opacity: 0.99,
      map: starTexture,
      alphaTest: 0.01,
    });

    const particles = new THREE.Points(particleGeometry, particleMaterial);
    scene.add(particles);

    //# Animation
    const animate = () => {
      const positions = particleGeometry.attributes.position.array;
      const minXPos = 201;
      const maxXPos = 300;
      const minXNeg = -201;
      const maxXNeg = -300;
      for (let i = 0; i < positions.length; i += 3) {
        const x = positions[i];
        const z = positions[i + 2];

        if (x >= -201 && x <= 0 && z >= -201 && z <= 0) {
          positions[i] = Math.random() * (maxXPos - minXPos) + minXPos;
          positions[i + 2] = Math.random() * (maxXPos - minXPos) + minXPos;
        } else if (x >= 0 && x <= 201 && z >= 0 && z <= 201) {
          positions[i] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
          positions[i + 2] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
        } else if (x >= -201 && x <= 0 && z >= 0 && z <= 201) {
          positions[i] = Math.random() * (maxXPos - minXPos) + minXPos;
          positions[i + 2] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
        } else if (x >= 0 && x <= 201 && z >= -201 && z <= 0) {
          positions[i] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
          positions[i + 2] = Math.random() * (maxXPos - minXPos) + minXPos;
        }
      }
      particleGeometry.attributes.position.needsUpdate = true;
      particles.rotation.y += 0.003;
      objectGroup.rotation.y -= 0.002;
      renderer.render(scene, camera);
      requestAnimationFrame(animate);
    };
    animate();

    //# Window Resize
    const handleResize = () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    };
    window.addEventListener("resize", handleResize);

    // const mountain = mountRef.current;
    //# Cleanup
    return () => {
      window.removeEventListener("resize", handleResize);
      if (mountain) mountain.removeChild(renderer.domElement);
    };
    // console.log(renderer.domElement);
  }, []);

  return <div ref={mountRef} />;
};

export default Axis;

what my current code shows

Invalid content security policy (CSP) header when receiving an Ajax request?

nonce works in the script tag but it doesn’t work when I have a request to another page.

index.php :

<?php
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: script-src 'nonce-$nonce'");
?>
<!DOCTYPE html>
<html>
    <head>
        <title>submit data</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>

        <input type="text" id="username" placeholder="username" autocomplete="off">
        <input type="password" id="password" placeholder="password" autocomplete="off">
        <button id="submitButton">submit data</button>
        <p id="demo"></p>

        <script nonce="<?php echo $nonce; ?>">
            document.getElementById("submitButton").addEventListener("click", function () {
                submitdata(document.getElementById('username').value, document.getElementById('password').value);
            });

            function submitdata(submitdata1, submitdata2) {
                const xhttp = new XMLHttpRequest();
                xhttp.onload = function () {
                    document.getElementById("demo").innerHTML = this.responseText;
                };
                xhttp.onerror = function () {
                    document.getElementById("demo").innerHTML = 'there is a problem!';
                };
                xhttp.open("POST", "./check.php");
                xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                xhttp.send("username=" + encodeURIComponent(submitdata1) + "&password=" + encodeURIComponent(submitdata2));
            }

            document.body.style.background = '#eee';
        </script>

    </body>
</html>

check.php :

<?php

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    if (isset($_POST['username']) && !empty($_POST['username']) && isset($_POST['password']) && !empty($_POST['password'])) {

        if (preg_match('/^[0-9a-z]+$/', $_POST['username'])) {

            echo '<button type="button" onclick="this.innerText = this.value;" value="' . $_POST['username'] . ' : ' . $_POST['password'] . '">' . $_POST['username'] . '</button>';
        } else {
            echo 'Username is invalid!';
        }
    } else {
        echo 'Please complete all fields!';
    }
} else {
    echo 'Your request is not allowed!';
}
?>

I don’t have the option to add a new script to the index file. If there is a script solution, please consider it in the check file ( my problem is exactly here ).

thank you in advance for your guidance and i will appreciate it.

I am a newbie. I have an array of numbers. I want to loop through it to find the maximum consecutive times numbers Less than 3 appear in a row. in JS [closed]

I am a new to Programming. I have an array of numbers. I want to loop through it to find the maximum consecutive times numbers Less than 3 appear in a row. in JS

const Numbers = [
  1.52,
  1.79,
  1.83,
  1.25,
  73.99,
  1.02,
  2.89,
  1.75,
  1.41,
  1.26,
  7.61,
  1.3,
  1.11,
  6.72,
  2.27,
  1.17,
  1.6,
  3.16
];

The answer should be 5

I tried for loop, but I get confused

Javascript find older date and newer date into an array of arrays

I am receiving this JSON structure :

 data[0].json_report.bank_orders[0].itens[23].payment_date

I need to find the first most older, and the last most newer payment_dates. Or just the last most newer payment_date.

There will be always one data element and one json_report but many bank_orders with many itens having payment_date ordered from older first to newer in the last position.

data[0].
  |_json_report.
  |__bank_orders[0].
  |__bank_orders[1].
  |__bank_orders[2].



data[0].
  |_report_json.
  |__bank_orders[0].
  |___itens[0].payment_date
  |___itens[1].payment_date
  |__bank_orders[1].
  |___itens[0].payment_date
  |____payment_date
  |___itens[1].payment_date
  |___itens[2].payment_date
  |__bank_orders[2].
  |___itens[0].payment_date
  |___itens[1].payment_date
  |___itens[2].payment_date
  |___itens[3].payment_date

I Try to iterate but could not enter into the second loop. how can i loop and find the most older date ?

const latestDate = {};
const actualLatestDate = {};


for (let n of response.data[0].report_json.bank_orders) {
        n.itens.forEach( di => {
            
            //latestDate = di.payment_date;
            //if(latestDate >actualLatestDate ){
                console.log("> "+di.payment_date);
            //}
            //actualLatestDate = di.payment_date
        });
    }

Which event should be triggered to accept input?

Background

I am still learning a bit about creating DOM JavaScript methods so I apologize if this is something that is considered straight forward or I am missing something very simple. I have a few automations I am trying to set up to automatically log into online accounts. I am testing my JavaScript within the Chrome browser.

Problem

In this example I am trying to log into Fidelity so using the URL https://digital.fidelity.com/prgw/digital/login/full-page I am presented with a username and password form to fill out. My goal is to programmically fill this out and log in. After inspecting the page I have gathered the username ID name and have the following code:

var username_field = window.document.getElementById("dom-username-input");
username_field.value = "myusername";
username_field.dispatchEvent(new Event("input"));

The issue is that when I click the submit button, it tells me that the username field needs to be filled out and is blank, so for some reason it is not registering what was put in through my JavaScript. On other automations, I have to dispatch the correct event. I have tried using input, change, keydown, and a few others but have not been able to succeed. I believe I do not know the correct event to dispatch or possibly I am missing something else?

HTML used to create the element from Fidelity’s site

<input class="pvd-input__input" required="" aria-describedby="dom-username-error-alert" aria-required="true" id="dom-username-input" type="text" maxlength="50" autocomplete="off" data-gtm-form-interact-field-id="0" aria-invalid="true">

As you can see it is just an input element which is why I don’t know why triggering an input event doesn’t work

How do I apply fabricjs filters to an image loaded to a canvas using ctx.drawimage?

I am using fabricjs version 5.2.1 to layer images on top of each other. At first, the load order was not always correct, because the canvas would load the images before the previous image was completed loading. I found this excellent post on stackoverflow that worked flawlessly to load the images. Fabric.js add images order The only slight change I made to that example was var SelfLoadingImage = fabric.util.createClass(fabric.Image, { instead of var SelfLoadingImage = fabric.util.createClass(fabric.Object, {. I assumed I would need the self-loading image to be of type Image in order to manipulate the image.

However, the object that is created by this method does not appear to be the same as the object that gets created by fabric.Image.fromURL.

When I attempt to applyFilters on any of these images, it returns the error: Uncaught TypeError: Cannot read properties of undefined (reading 'naturalWidth') at klass.applyFilters (fabric.js:23335:36)

Is there a way to force the object that gets created by the ctx.drawImage to be the same as a normal fabric.Image object?

How to fix camera vibrations and unreadable pixels in IFC.js viewer with Three.js and React

I’m developing a React application using IFC.js and Three.js to visualize complex BIM models. However, I’m facing two major issues:

  • Camera vibrations during transitions/selections

    When clicking on an element or transitioning through the model, the camera experiences unpleasant vibrations.

  • A Unreadable pixels on some elements

    Some elements appear with pixelation artifacts, making text and fine details difficult to read.

Here is the useEffect hook that initializes the IFC.js viewer:

useEffect(() => {
  const initViewer = async () => {
    if (!containerRef.current || initializedRef.current) return;
    
    try {
      initializedRef.current = true;

      // Initialize IFC.js Viewer
      const viewer = new IfcViewerAPI({
        container: containerRef.current,
        backgroundColor: new THREE.Color(0xeeeeee),
      });

      // Ensure renderer is ready
      await new Promise<void>((resolve) => {
        const checkReady = () => {
          if (viewer.context?.getRenderer()) {
            const renderer = viewer.context.getRenderer();
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.logarithmicDepthBuffer = true;
            renderer.sortObjects = true;
            resolve();
          } else {
            setTimeout(checkReady, 50);
          }
        };
        checkReady();
      });

      // Set IFC.js configurations
      await viewer.IFC.setWasmPath("wasm/");
      viewer.clipper.active = true;
      viewerRef.current = viewer;
      
      // Handle element selection (causing vibrations)
      containerRef.current.ondblclick = async () => {
         const result = await viewer.IFC.selector.pickIfcItem(false);
         if (!result) {
           viewer.IFC.selector.unpickIfcItems();
         }
      };

      // Handle resizing
      const resizeObserver = new ResizeObserver(() => {
        if (containerRef.current && viewer.context?.getRenderer()) {
          viewer.context.getRenderer().setSize(
            containerRef.current.clientWidth,
            containerRef.current.clientHeight
          );
          viewer.context.ifcCamera?.cameraControls?.update();
        }
      });
      resizeObserver.observe(containerRef.current);

      // Loading IFC models...
    } catch (error) {
      console.error("Initialization error:", error);
    }
  };

  initViewer();
}, [searchParams]);

What I’ve already tried

  • Adjusting pixelRatio (renderer.setPixelRatio(window.devicePixelRatio))
  • Enabling logarithmicDepthBuffer and sortObjects
  • Dynamically resizing the renderer

Questions

  • How can I eliminate vibrations during transitions and element selections?

  • How can I improve the display quality to make unreadable elements sharper?

  • Are there specific Three.js or IFC.js parameters that could solve these issues?

Technical environment

  • React 18

  • Three.js (latest version)

  • IFC.js

  • Tested browsers: Chrome & Firefox (latest versions)