DND-KIT unable to make rows of table draggable and droppable

Trying to implement dnd-kit functionality for every row inside a table that is rendered inside of a modal.

I am trying to make the row that is created with map() method draggable and droppable inside the table. I have also created two simple components just to check if the dnd-kit is working at all and it does. But in that example I am just mapping over state that contains strings so the items prop that <SortableContext> is asking for is easy to pass. I am not sure if that is what is causing the problem in my app. If anyone can give me any suggestions or solution I would be very grateful!

This is the sortable item from the simple example that works:

import { useSortable } from "@dnd-kit/sortable";
import {CSS} from "@dnd-kit/utilities";

import Box from '@mui/material/Box';

function SortableItem(props) {

    const { 
      attributes,
      listeners,
      setNodeRef,
      transform,
      transition
    } = useSortable({id: props.id});

    const style = {
        transform: CSS.Transform.toString(transform),
        transition
    }
    return (
      <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
          <Box sx={{margin: "5px", border: "1px solid gray"}}>
          <button>button</button>
              {props.id}
          </Box>
      </div>
        )
};

export default SortableItem;

This is the second piece of code that creates the working example:

import {useState} from 'react';
import Box from '@mui/material/Box';
import { DndContext, closestCenter } from "@dnd-kit/core";
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import SortableItem from "./sortableItem.js";

function DndKitTest() {
    const [people, setPeople] = useState(["Luka Jovicic", "Dejan Markic", "Branko Kovacevic", "Nemanja Djokic"]);

  return (
    <DndContext
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
    >
    <Box sx={{ padding: "5px", witdh: 10, border: "1px solid gray", margin: 5 }}>
      <h3>List of people!</h3>
      <SortableContext
        items={people}
        strategy={verticalListSortingStrategy}
      > 
       {people.map(person => <SortableItem key={person} id={person} />)}
      </SortableContext>
    </Box>
    </DndContext>
    );

    function handleDragEnd(event) {
        console.log("Drag end called");
        const {active, over} = event;
        console.log("ACTIVE: " + active.id);
        console.log("OVER: " + over.id);

        if(active.id !== over.id) {
           setPeople((items) => {
            const activeIndex = items.indexOf(active.id);
            const overIndex = items.indexOf(over.id);

            return arrayMove(items, activeIndex, overIndex)
           });
        }
    }
}

export default DndKitTest;

As for my APP I will provide two pieces of code that are using dnd-kit:

import React, { useMemo, Fragment, useState, useEffect } from 'react';
import TableRow from '@mui/material/TableRow';
import TableCell from '@mui/material/TableCell';
import IconButton from '@mui/material/IconButton';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import CloseOutlinedIcon from '@mui/icons-material/CloseOutlined';
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

function SortingRow({ sortOrder, fields, moveRowUp, moveRowDown, handleOrderChange, resetSingleSort, rowItems, setRowItems, handleRowsChange }) {

     const [idVal, setIdVal] = useState("");

    const rows = sortOrder.map((item, index) => {
    const ID = `sortable-row-${index}`;
    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: ID });
    const style = {
      transform: CSS.Transform.toString(transform),
      transition
    };

    useEffect(() => {
      setIdVal(ID);
    }, [ID]);

    return (
      <TableRow key={index} ref={setNodeRef} style={style} {...attributes} {...listeners}>
        <TableCell>
          {fields.find((f) => f.name === item.field)?.label}
          <IconButton onClick={() => moveRowUp(item.field)}>
            <ArrowUpwardIcon />
          </IconButton>
          <IconButton onClick={() => moveRowDown(item.field)}>
            <ArrowDownwardIcon />
          </IconButton>
        </TableCell>
        <TableCell>
          <Box>
            <Button onClick={() => handleOrderChange(item.field, item.direction)}>
              {item.direction}
            </Button>
            <IconButton onClick={() => resetSingleSort(item.field)}>
              <CloseOutlinedIcon />
            </IconButton>
          </Box>
        </TableCell>
      </TableRow>
    );
  });

useEffect(() => {
handleRowsChange(rows, idVal);
}, []);

// console.log('CEO ROW IZ sortingROW', rows);
// console.log('ID IZ sortingROW', id);
// console.log('STATE ID IZ sortingRow', idVal);

  return <>{rows}</>;
}

export default SortingRow;

And the second one:

import React, { useState, useMemo } from 'react';
import PropTypes from 'prop-types';

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
import IconButton from '@mui/material/IconButton';
import Button from '@mui/material/Button';
import CloseOutlinedIcon from '@mui/icons-material/CloseOutlined';
import Box from '@mui/material/Box';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import { DndContext, closestCenter } from "@dnd-kit/core";
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";

import SortingRow from "./sortingRow.js";

function TableComponent({ sortOrder, setSortOrder, fields, moveRowUp, moveRowDown, handleOrderChange, resetSingleSort, onRowsUpdated, rows, id }) {

 const [rowsVal, setRowsVal] = useState([]);
 const [activeRowId, setActiveRowId] = useState("");
 const [overRowId, setOverRowId] = useState("");

 const handleRowsChange = (rows, idVal) => {
     setRowsVal(rows);
 };
     console.log("rowsVal", rowsVal);

  function handleDragEnd(event) {
    console.log("Drag end called!");
    const { active, over } = event;
    console.log("ACTIVE: " + active.id);
    console.log("OVER: " + over.id);

    setActiveRowId(active.id);
    setOverRowId(over.id);

    if (active.id !== over.id) {
      setSortOrder((items) => {
        const activeIndex = items.indexOf(active.id);
        const overIndex = items.indexOf(over.id);

        return arrayMove(items, activeIndex, overIndex);
      });
    }
  };

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>Field</TableCell>
            <TableCell>Order</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          <SortableContext items={rowsVal} strategy={verticalListSortingStrategy}>
            <SortingRow
              sortOrder={sortOrder}
              fields={fields}
              moveRowUp={moveRowUp}
              moveRowDown={moveRowDown}
              handleOrderChange={handleOrderChange}
              resetSingleSort={resetSingleSort}
              handleRowsChange={handleRowsChange}
              activeRowId={activeRowId}
              overRowId={overRowId}
            />
          </SortableContext>
        </TableBody>
      </Table>
    </DndContext>
  );
}

TableComponent.propTypes = {
  sortOrder: PropTypes.array.isRequired,
  fields: PropTypes.array.isRequired,
  moveRowUp: PropTypes.func.isRequired,
  moveRowDown: PropTypes.func.isRequired,
  handleOrderChange: PropTypes.func.isRequired,
  resetSingleSort: PropTypes.func.isRequired,
};

export default TableComponent;

I think that passing the items prop inside the is being passed the wrong way? Maybe all the different buttons and functions inside the SortingRow are causing the problem? I am pretty sure that ID-s are not the problem, because when I try to drag the row at index 0 over the row that is on index 1 everything console.log-s correctly.

How the value is undefined , when reading from reducer/ store in react redux?

I am working in react redux. I stored the value in reducer and try to retrieve it. Value is undefined? I am getting the sessionId from url. In App.js, sessionId is having value.

http://localhost:3000?SessionId=89e2ff80-c1d7

import * as types from '../lib/store/action';

const App = () => {
  const dispatch = useDispatch();
  useEffect(function () {

    const params = new URLSearchParams(window.location.search);
    const SessionId = params.get('SessionId');

    if (SessionId != null && SessionId.length) {
      console.log("saving SessionId: " + SessionId);
      dispatch(
        types.updateData({
          SessionId: SessionId
        })
      );
    }
 })
}

Reducer.js

import * as types from './action';

export const initialState = {

    recDetails: {
        name: '',
       country: '',
        city: ''
    },
    SessionId: ''
}

const Datareducer = (state = initialState, action) => {

    switch (action.type) {

        case types.UPDATE__DATA:

            const output = action.payload;

            if (output.recDetails) {

                state.recDetails = output.recDetails;

            }

            if (output.SessionId) {

                state.SessionId = output.SessionId;

            }

            return {

                ...state,

            }

            break;

        default:

            return state;

    }

}

 

export default Datareducer;



Component1.js

import * as types from '../../lib/store/action';

const { SessionId } = useSelector(state => state.app.DataReducer.SessionId);

  const uDispatch = useDispatch();

  useEffect(() => {

      alert(SessionId);}

SessionId is undefined.....

http://localhost:3000?SessionId=89e2ff80-c1d7

Hi, I am reading the sessionId from ur paraameter in app.js. SessionId is showing in app.js and then store in reducer. Readming sessionId in component1 is undefined.

How to retrieve profile data and edit data with service and context with react?

I have a react application and I try to retrieve the profile data in the text fields.

So I have a service:

export const AccountRequest = async (token, data) => {
    try {
        const response = await fetch("http://192.168.1.67:8000/api/user/me/", {
            method: "GET",
            headers: {
                Authorization: "Token 5dd44e266bf43435742f587f4d61b04d473d9cec",
                "Content-Type": "application/json",
            },
        });

        
        return response.data;
    } catch (error) {
        throw error;
    }
};

and a context:


import { AccountRequest, loginRequest, registerRequest } from "./authentication.service";
import React, { AsyncStorage, createContext, useState } from "react";

export const AuthContext = createContext();


export const AuthContextProvider = ({ children }) => {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState("");
    const [user, setUser] = useState(null);


    const updateUserProfile = async (data) => {
        try {           
        
            const updateAccount = await AccountRequest(data);
            console.log(updateAccount);

            // Update the user profile in the state
            setUser(updateAccount);
        } catch (error) {
            console.log("Update user profile failed:", error);
        }
    }

and the view:

export const SettingsScreen = ({ navigation }) => {
    const [email, setEmail] = useState("");
    const [username, setUsername] = useState("");
    const { updateUserProfile, user, isLoading } = useContext(AuthContext);

    return (
        <AccountBackground>
            <AccountCover />
            <Title>Instellingen</Title>
            <AccountContainer>
                <AuthInput
                    label="E-mail"
                    value={console.log(user.email)}
                    textContentType="emailAddress"
                    keyboardType="email-address"
                    autoCapitalize="none"
                    onChangeText={(u) => {
                        setEmail(u);
                    }}
                />
                <Spacer size="large">
                    <AuthInput
                        label="username"
                        value={user.username}
                        textContentType="username"
                        keyboardType="username"
                        autoCapitalize="none"
                        onChangeText={(account) => setUsername(account)}
                    />
                </Spacer>

                <Spacer size="large">
                    {!isLoading ? (
                        <AuthButton icon="email" mode="contained" onPress={() => console.log("text")}>
                            Save
                        </AuthButton>
                    ) : (
                        <ActivityIndicator animating={false} />
                    )}
                </Spacer>
            </AccountContainer>
            <Spacer size="large">
                <AuthButton mode="contained" onPress={() => navigation.goBack()}>
                    Back
                </AuthButton>
            </Spacer>
        </AccountBackground>
    );
};

and in swagger I have this api call: http://192.168.1.67:8000/api/user/me/ and it returns the correct object:

{
  "email": "[email protected]",
  "username": "user"
}

But in the view of react I get undefined in the console.log of email

Question: how to retrive the user data from the api call in the view of react?

How do I use Node.JS to run a web application?

I am learning to code and I created an application that can write a simple Human Resources letter to test how to run my Javascript code on a server, using Node. The application works on my desktop, though when using the server on local host 3000, there is no functionality to my application.

My server.js code is as follows:

const express = require("express");
const bodyParser = require("body-parser");

const app = express();

app.use(express.static("Public"));

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

//Route 1
app.get("/test", function(req, res){
res.sendFile(__dirname + "/test.html");
});

app.get("/test", function(req, res){

var submitButton = document.querySelector(".submit");
var statement = document.querySelector(".statement");

submitButton.addEventListener("click", ()=>{
    var nameInput = document.querySelector(".name-input-field").value;
    var letterType = document.querySelector("#letterType").value;


    var textTemplate = `Dear employee, 

    I am writing this letter to you in regards to the outcome of the recent disciplinary 
    meeting that we held. 
    
    replace paragraph
    
    If you have any queries regarding the content of this letter please do not hesitate 
    to contact me.` 
    
  
    var fittedText = textTemplate.replace(/b(employee)b/ig, nameInput)


    if(letterType == "Letter of Concern"){
    fittedText = fittedText.replace(/b(replace paragraph)b/ig, `On this particular 
    occasion I have decided not to proceed with formal disciplinary action. However, 
    this letter is to be treated as confirmation that I have discussed my concerns with 
    you and that you are expected to make every effort to address the shortcomings that 
    have been identified.
  This letter is not intended to be a formal warning and does not form part of the 
  company's disciplinary procedure, however, it will be kept in your personnel file and 
  thus takes the form of what I consider to be a reasonable written management 
  instruction.`)
  }
  if(letterType == "Written Warning"){
  fittedText = fittedText.replace(/b(replace paragraph)b/ig, `At the hearing you gave 
  no satisfactory explanation for your actions. Having carefully reviewed the 
  circumstances, I have decided that a written warning is the appropriate sanction. This 
  written warning will be placed on your personnel file but will be disregarded for 
  disciplinary purposes after six months, provided your conduct improves to a 
  satisfactory level.`)
  }
  if(letterType == "Final Written Warning"){
  fittedText = fittedText.replace(/b(replace paragraph)b/ig, `Having carefully 
  reviewed the circumstances, including the severity of the offence, I have decided that 
  a first and final written warning is the appropriate sanction.
  This first and final written warning will be placed on your personnel file but will be 
  disregarded for disciplinary purposes after twelve months, provided your 
  conduct/performance improves to a satisfactory level.`)
  }
  if(letterType == "Dismissal"){
  fittedText = fittedText.replace(/b(replace paragraph)b/ig, `Having carefully 
  considered all the evidenced presented at the disciplinary hearing, I have decided to 
  terminate your contract with immediate effect.`)
  }
  
    statement.innerText = fittedText

  });

  res.send(statement.innerText);

  });

  app.listen(3000, function(){
  console.log("Server started on port 3000");
  });

And my HTML is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <link rel="stylesheet" href="css/styles.css">-->
</head>
<body>

<div class="test-container">
<h1>Human Resources Letter</h1>
<form> 
  <label>Employee's Name:</label>
  <input class="name-input-field" type="text"></input>
  <br>
  </form>
<br>
<form> 
  <label for="letter">Letter type?</label>  
  <select name="letter" id="letterType">
      <option disabled hidden selected>Select</option>
      <option value="Letter of Concern">Letter of Concern</option>
      <option value="Written Warning">Written Warning</option>
      <option value="Final Written Warning">Final Written Warning</option>
      <option value="Dismissal">Dismissal</option>
  </select>  
  </form>
  <br>
  <button class="submit">Submit</button>
  <br>
  </div>
  <h3 class="statement"></h3>
  <p class="statement"></p>
  <!--<script src="test.js"></script>-->
  </body>
  </html>

With Webpack, can a class import a file that also import the first file

I try to write a class A that instantiate a class B that inherit from A. In JS, this is technically possible as shown on this JSFiddle and with this previous question: In JavaScript, can a class A instantiate an object B that inherit from A

With WebPack, I wrote the following files:

index.js

import A from "./a.js";
let a = new A();
a.fct();

a.js

import B from "./b.js"
    
export default class A {
  constructor() {
    console.log ("a constructor")
  }
  fct() {
    this.b = new B();
  }
}

b.js

import A from "./a.js"
    
export default class B extends A {
  constructor() {
    console.log ("b constructor")
  }
}

When I try to run the above code, I’ve got the following error at runtime:

js:3 Uncaught ReferenceError: Cannot access 'A' before initialization
    at Module.default (a.js:3:56)
    at eval (b.js:3:32)
    at ./src/js/b.js (bundle.425598cf4c8e29cd2b4d.js:723:1)
    at __webpack_require__ (bundle.425598cf4c8e29cd2b4d.js:1278:41)
    at eval (a.js:5:63)
    at ./src/js/a.js (bundle.425598cf4c8e29cd2b4d.js:712:1)
    at __webpack_require__ (bundle.425598cf4c8e29cd2b4d.js:1278:41)
    at eval (index.js:2:63)
    at ./src/js/index.js (bundle.425598cf4c8e29cd2b4d.js:821:1)
    at __webpack_require__ (bundle.425598cf4c8e29cd2b4d.js:1278:41)

Am I doing something wrong or is it an issue with Webpack?

Note that since I’m not sure I also reported an issue on GitHub

How can I use JavaScript to take content from a textarea and print it to a docx file?

I am trying to make a html to take something I have typed in the textarea and print in out in a docx file. Any ideas?

I tried a library DOCX but couldn’t get my hand around it. And I also tried mammoth.js.

import { Document, Packer } from "docx";

function saveToDocx() {
  var content = document.getElementById("content").value;

  // Create a new document
  const doc = new Document();
  doc.addParagraph(content);

  // Generate the DOCX file
  Packer.toBlob(doc).then((blob) => {
    // Create a temporary link to download the DOCX file
    var link = document.createElement("a");
    link.href = URL.createObjectURL(blob);
    link.download = "output.docx";
    link.click();
  });
}

Download an HLS stream with javascript

I’m trying to download an m3u8 live streaming on the browser using JavaScript (all client-side). I found this code from another question posted by @huhngut on Stack Overflow: Hls.js record file.

I wanted to ask how I could merge the audio and video streams so that I can make a single download. I’m not familiar with JavaScript, thank you very much to anyone who will help me.

var arrayRecord = [];

function download(data, filename) {
    console.log('downloading...');
    var blob = new Blob([arrayConcat(data)], {
        type: 'application/octet-stream'
    });
    saveAs(blob, filename);
}

function arrayConcat(inputArray) {
    var totalLength = inputArray.reduce(function (prev, cur) {
        return prev + cur.length
    }, 0);
    var result = new Uint8Array(totalLength);
    var offset = 0;
    inputArray.forEach(function (element) {
        result.set(element, offset);
        offset += element.length;
    });
    return result;
}

function saveAs(blob, filename) {
    var url = URL.createObjectURL(blob);
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    a.href = url;
    a.download = filename;
    a.click();
    window.URL.revokeObjectURL(url);
}

function stopRecord() {
    arrayRecord.forEach(function (item) {
        download(item.data['video'], "video.mp4");
        download(item.data['audio'], "audio.mp4");
        item.hls.destroy();
        return false;
    });
}

function startRecord() {
    var video = document.getElementById('video');
    var dataStream = {
        'video': [],
        'audio': []
    };
    var hls = new Hls();
    hls.loadSource("Your playlist");
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, function () {
        video.play();
        hls.on(Hls.Events.BUFFER_APPENDING, function (event, data) {
            console.log("apending");
            dataStream[data.type].push(data.data);
        });
    });
    arrayRecord.push({
        hls: hls,
        data: dataStream
    });
    video.onended = function (e) {
        stopRecord()
    }

}

Using IntersectionObserver to detect element with 100vh is fully visible

I need to immediately block scroll as soon as a div is fully visible.
The tricky part is that .stopDiv has 100vh height.
I tried using IntersectionObserver to detect it.

    const stopDiv = document.querySelector('.stopDiv');

    const observer = new IntersectionObserver(([e]) => {
        window.addEventListener('mousewheel', defaultScrollHandler, { passive: false });
        window.addEventListener('wheel', defaultScrollHandler, { passive: false });
        window.addEventListener('DOMMouseScroll', defaultScrollHandler, { passive: false });
    },
    {threshold: 1}
    );

    observer.observe(stopDiv);

    function defaultScrollHandler(e) {
        e.preventDefault();

        return false;
    }

The problem is the event is never called, unless the scroll perfectly stop when the div top is exactly on the beginning of the viewport (very low chance). How can I manage it?

Cordova 11.1.0 – Can’t access Cordova hook environment variables using Node.js – returns undefined

I’ve tried running hooks for an old application using Cordova, Node.js and Angular.

It is trying to get an environment variable from process.env like process.env.CORDOVA_CMDLINE but when console logging it returns undefined.

After further investigation, when logging process.env it returns a long text but doesn’t show any of the environment variables that should be there. As they appear on the cordova documentation.

I’ve gone through a bunch of websites and stack overflow threads but I couldn’t find a proper solution, or an example of it working. Maybe a more updated case. I’m currently using Cordova 11.1.0.

The only solution I could find is adding them to a .env file but I feel like that is not the right answer. In the documentation it clearly states that each variable will return a specific value. And the application was working on older versions without a .env file so I don’t think this is the case.

I’m running after_prepare hooks that are clearly stated in the config.xml file. So the program is running and executing the hooks as expected. The only problem is it breaks because it is trying to do things with an undefined value (because it doesn’t exist in process.env).

// Modules
var fs = require('fs');
var path = require('path');

var cliCommand = process.env.CORDOVA_CMDLINE;
var isRelease = (cliCommand.indexOf('--release') > -1);

var rootdir = process.argv[2];

// Exit
if (!isRelease) {
  return;
}

As further clarificaion I’m running the application using the browser platform.

I wonder if any of you have encountered a similar problem and could help. Thanks!

Table keeps jumping back to top after assigning custom scroll position

I’m using Vue 3 with a Vuetify table and whenever I modify data I have to fetch everything again. If you modify a cell inside row 123 and column 456 reconstructing the whole grid is annoying because the table scrollbars jump back to the start. I think a good solution for this would be to

  • store the current scroll position
  • perform the write action
  • reassign the stored scroll position

( any better suggestions are highly appreciated )

As a sidenote: Since Vuetify requires a fixed table height for fixed table headers I’m, calculating the height dynamically ( table should fill the rest of the page ).

I created the following example ( Playground link )

<script setup lang="ts">
import { ref, nextTick, onMounted, watch } from "vue";  

const mainContainerComponent = ref<VMain>();
const tableComponent = ref<VTable>();
const tableHeight: Ref<number | undefined> = ref(undefined);
const tableMatrix = ref([[]]);

onMounted(async () => {
  // we only want to scroll inside the table
  document.documentElement.classList.add("overflow-y-hidden");

  await loadData();
});

watch(tableMatrix, async () => {
  // Unset table height and wait for it to rerender
  tableHeight.value = undefined;

  await nextTick();

  if (!tableComponent.value) {
    return;
  }

  const mainContainerComponentRectangle = mainContainerComponent.value.$el.getBoundingClientRect();
  const tableRectangle = tableComponent.value.$el.getBoundingClientRect();
  const topOffset = tableRectangle.top;
  const bottomOffset = mainContainerComponentRectangle.bottom - tableRectangle.bottom;

  tableHeight.value = window.innerHeight - bottomOffset - topOffset;
});

async function loadData() {
  // destroy table
  tableMatrix.value = [];

  await nextTick();
  
  // fetch data
  const fetchedData = new Array(Math.floor(Math.random() * 300) + 50).fill("data");

  // calculate table matrix
  tableMatrix.value = [...fetchedData.map(x => [x])];
}

async function performWriteAction() {
  // send modify request here

  const { scrollLeft, scrollTop } = getTableScrollPosition();

  await loadData();

  // wait for the DOM to finish
  await nextTick();

  // try to restore the previous scroll position
  setTableScrollPosition(scrollLeft, scrollTop);
}

function getTableDOMElement() {
  return tableComponent.value?.$el.querySelector(".v-table__wrapper");
}

function getTableScrollPosition() {
  const { scrollLeft, scrollTop } = getTableDOMElement();
  
  console.log(`current scroll position => x: ${scrollLeft} | y: ${scrollTop}`);

  return { scrollLeft, scrollTop };
}

function setTableScrollPosition(scrollLeft: number, scrollTop: number) {
  const tableElement = getTableDOMElement();
  
  console.log(`scroll to => x: ${scrollLeft} | y: ${scrollTop}`);

  tableElement.scrollLeft = scrollLeft;
  tableElement.scrollTop = scrollTop;
}
</script>

<template>
  <v-app>
    <v-main ref="mainContainerComponent">
      <v-container>
        <v-btn @click="performWriteAction">Modify data</v-btn>
      </v-container>
      
      <v-table
        ref="tableComponent"
        density="compact"
        fixed-header
        :height="tableHeight"
      >
        <thead>
          <tr>
            <th>Col</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(row, rowIndex) in tableMatrix" :key="rowIndex">
            <template v-for="(cell, columnIndex) in row" :key="columnIndex">
              <td>{{ rowIndex }}</td>
            </template>
          </tr>
        </tbody>
      </v-table>
    </v-main>
  </v-app>
</template>

The problem with this code is that the table always jumps back to the start. If you scroll down to the center of the table and modify some data the scroll position is still wrong.

Do you have any ideas what’s wrong or missing?

How can I keep open my mat dialoge modal if angular route getting change in angular material.?

I am implementing the multiple dialoge modal functionality to open multiple dialoge at a time and not closed untill we closed manually.

In this feature we allow user to opne modal on click of navigation bar and it is draggable and resizeable modal. after open 1st modal user can open other modals by clicking on navigation bar band 1st modal will remain same.

I am facing issue while click on navigation bar it will change the routes and close the 1st modal.

I am able to implement multiple modal at a time functionality for the same route and same page but not able to use it with route change

Can any one help out with this.?

How do I require the examinee to fill in the prompt before exiting the page? [duplicate]

So I have an examination page, and the user cannot leave until it’s over. They can only leave if they know the password or examination ended. However, I don’t know how to do that. I have tried to use Prompt and Do While, but I get nothing. No errors or popups

Here’s what i have tried so far

window.onbeforeunload = (event) => {
    prompt("Enter password before you leave!");
        let confirm;
        while (true) {
            confirm= (prompt("Enter password before you leave!"));
    
            if (confirm != "44344")
                return confirm;
            alert("You can't leave while the examination is still ongoing.");
            event.preventDefault();
        }
}

I’m expecting to loop a prompt until the user gets the correct password or they cancel the prompt.

I have seen others post in stackoverflow but it does only confirm the user if they want to leave or not.

change the return value of a mock function of pinia store inside multiple tests

Problem

Inside a component which should render when getPersons returns with a collection of Persons.

I need to write two tests:

  1. Which asserts x attribute is available in the HTML
  2. Which asserts that x attribute is not in the html

In my current test configurations, I can’t mock out the getPersons return value as an empty [] in order to verify test scenario 2.

Question: How to change the return value from function inside a store?

<div v-if="persons" ref="personList">
 <div data-cy="foo">hello world</div>
</div>

store

export const userStore = defineStore("user", {
state: () => ({
  fooObject: null
}),

actions: {
 async getPersons() {
 // get all person
 }
}})


user module 

import { userStore } from 'somepath'

const  { getPersons } = userStore();

onMounted(async () => {
  const persons = await getPersons()
}) 

Component Test

import { useStore } 'somepath'

vi.mock('somepath', () => ({
  userStore: vi.fn().mockImplementation(() => ({
   getPersons: vi.fn().mockResolvedValue([{name: 'foo'}])
}))
}))

describe("personList Comp", () => {

it("should show all persons", async () => {
    const wrapper = mount(Perons, ...options) // pass in createTestingPinia, router etc

    const comp = wrapper.findComponent(Persons);

   // getPersons will return [{name: 'foo'}]
   // and component can conditionally render
})

it("show not show persons if no data", async () => {

// I've tried the following, but when the test runs it always returns an array of persons
    
 vi.mocked(getPersons).mockResolvedValue([])


 })

How to access files in outside of bin folder in ASP.NET Core?

I am developing a web app in ASP.net Core MVC and am trying to access a TempFile in a folder called TempFile within my project.

MyWebAPP:.
├───TempFiles
     ├─── file.wav

However I cannot access that file, even tho it exists, through JavaScript, like this:

const connection = new signalR.HubConnectionBuilder().withUrl("/SandboxHub").build();

// Start the SignalR connection
connection.start().catch(err => console.error(err));

// Handle textbox change event
$("#sentence-input").on("input", async function () {
    // Get the sentence value
    const sentence = $(this).val();

    // Send the sentence to the Hub
    await connection.invoke("TransformIntoTTS", sentence);

    connection.on("ReceiveFile", function (fileUrl) {
        const relativeFilePath = fileUrl.replace("/LearningWithAI-WebLayer", "");


        // Apply the file URL to the source of the audio controller
        $("#audio-player").attr("src", "../" + relativeFilePath);

    });
});