Catching screen keyboard entries in javascript on Android webview

In my (old but needed) webapp, I registered a keydown event on document (using jquery) to get which keys were pressed:

$(window).on('keydown', function(e) {
     console.log('e.key: ' + e.key);
     console.log('e.keyCode: ' + e.keyCode)
}

I need to bind it to the window because the mobile devices I use have a barcode scanner that emulate key presses. I want the barcode to be catched no matter where the cursor currently is. If the user needed to focus a special field before performing a barcode scan, usability would be ruined. This is why I cannot use the “input” event. “Keydown” worked for years.

Suddenly the scanners stopped working. Here I found why:

The W3C decided that virtual keyboards for whatever reason should fire keydown events, but should no longer submit the e.key or e.keyCode variables. By standard they should now send
keycode 229 and key “Unidentified”.

I haven’t found any way how to get my old usage case done. Any ideas how to catch a virtual keyboard press and get the code of the key pressed?

React project deployment on Vercel

I’m trying to deploy my React project on Vercel, these are the errors I’m getting. I’ve tried installing the same versions and it’s still not working.

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: @material-ui/[email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"^18.2.0" from the root project
npm ERR!   peer react@"^18.0.0" from @testing-library/[email protected]
npm ERR!   node_modules/@testing-library/react
npm ERR!     @testing-library/react@"^13.4.0" from the root project
npm ERR!   10 more (framer-motion, mdb-react-ui-kit, react-dom, react-icons, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0 || ^17.0.0" from @material-ui/[email protected]
npm ERR! node_modules/@material-ui/core
npm ERR!   @material-ui/core@"^4.12.4" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR!   peer react@"^16.8.0 || ^17.0.0" from @material-ui/[email protected]
npm ERR!   node_modules/@material-ui/core
npm ERR!     @material-ui/core@"^4.12.4" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! 
npm ERR! For a full report see:
npm ERR! /vercel/.npm/_logs/2024-03-26T06_42_43_667Z-eresolve-report.txt
npm ERR! A complete log of this run can be found in: /vercel/.npm/_logs/2024-03-26T06_42_43_667Z-debug-0.log
Error: Command "npm install" exited with 1

I’ve tried installing the same versions. I’ve also uninstalled Node and reinstalled it.

Javascript can’t connect to python secure websockets

I have a python websockets since a year or two, i usually have two clients connecting, one using C# and one using python.

I recently started working on a web client and try to use JS Websocket and it’s throwing an error :
Firefox can’t establish a connection to the server at wss://*url removed for privacy*/.
Same with Chrome :
WebSocket connection to 'wss://*url removed for privacy*/' failed

This is what i have server side :

ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_cert = "*path to cert*"
ssl_key = "*path to key*"

ssl_context.load_cert_chain(ssl_cert, keyfile=ssl_key)
async def main():
    async with websockets.serve(echo, "0.0.0.0", 465, ssl=ssl_context):
        print(f'Listening on port 465')
        await asyncio.Future()

I can share the echo function if needed

This is my python code for connecting :

async with websockets.connect("wss://*URL removed for privacy*") as websocket:
            await websocket.send('*data sent*')
            response = await websocket.recv()

Working fine

On my C# client :

wsc = new WebsocketClient('wss://*URL Removed for privacy*');
wsc.ReconnectTimeout = TimeSpan.FromSeconds(15);
wsc.ReconnectionHappened.Subscribe(info => Console.WriteLine($"Reconnection happened, type: {info.Type}"));
await wsc.Start();

Working fine

And JS client :

const socket = new WebSocket("wss://*URL Removed for privacy*");
socket.addEventListener("open", (event) => {
    socket.send("*data sent*");
});

Throwing an error

I don’t even know why it doesn’t connect as there’s no details on what’s going on with the connexion try.

Thanks for your help

How to deactivate a function when a focusOut event happens?

Goal

I want to have two search bars, and each of them can:

  • Display suggestions as typing
  • Use arrow keys to select item
  • Each item can be customized

Because of the last bullet I don’t want to use <datalist> tag as it’s limited in style. I also use Deno Fresh, which is based on Preact, which is based on React. At the time I wasn’t aware of guides on navigate through list by arrow keys in React, but in vanilla JS, and I think using the vanilla version will be simpler, so currently I’m using it.

Problem

When a list is navigated by keyboard, the other is also triggered. My idea is to have the script targets different lists, and when users unfocus an input field it will be deactivated. I try having this on the script:

if (list === 'deactivate') return

And on each handler I have:

onBlur={(e) => script('deactivate')}

But it still doesn’t work. Do you have any suggestion?

Code

search.jsx:

export default function SearchBar() {
  const [keyword1, setKeyword1] = useState("");
  const [keyword2, setKeyword2] = useState("");
  
  const list1 = [ 'rabbits', 'raccoons', 'reindeer', 'red pandas', 'rhinoceroses', 'river otters', 'rattlesnakes', 'roosters' ] 
  const list2 = [ 'jacaranda', 'jacarta', 'jack-o-lantern orange', 'jackpot', 'jade', 'jade green', 'jade rosin', 'jaffa' ]

  return (
    <div className="search-bar-container">
      <input
        type="text"
        placeholder={'Search list 1'}
        value={keyword1}
        onInput={(e) => {
          setKeyword1(e.target.value);
          script('1');
        }}
        onBlur={(e) => script('deactivate')}
        />
      <br />
      <ul id={'Suggested list 1'}>
        {keyword1 !== '' ? list1.filter(keyword => keyword.includes(keyword1)).map(
          (item) => <li>{item}</li>,
        ) : ''}
      </ul>
      <div>
        Your selected item is :<span id="Item 1"></span>
      </div>
      <div className="search-bar-container">
        <input
          type="text"
          placeholder={'Search list 2'}
          value={keyword2}
          onInput={(e) => {
            setKeyword2(e.target.value);
            script('2');
          }}
          onBlur={(e) => script('deactivate') }
        />
        <br />
        <ul id={'Suggested list 2'}>
          {keyword2 !== '' ? list2.filter(keyword => keyword.includes(keyword2)).map(
            (item) => <li>{item}</li>,
          ): ''}
        </ul>
        <div>
          Your selected item is :<span id="Item 2"></span>
        </div>
      </div>
    </div>
  );
}

script.ts:

export function script(list: "1" | "2" | 'deactivate') {
  if (list === 'deactivate') return
  if (window !== undefined) {
      const ul = document.getElementById(`Suggested list ${list}`);
      const result = document.getElementById(`Item ${list}`);
//the rest of the script

Full code. Somehow CodeSandbox keeps having twind error even when I don’t. This does run in my machine.

Screenshot (GIF)

Unable to get updated values in form textfields using innerHTML in angular

I’m binding for using innerHTML

    this.html = this.sanitizer.bypassSecurityTrustHtml(
          '<iframe width="100%" height="800" src="assets/template_forms/registration_form.html"></iframe>',
        );

<div [innerHtml]="html"></div>

the form is rendered like this

enter image description here

if i entered some test in input fiekd thennot getting updated value in form input value when accessed html variable.

Any solution Thanks

contentEditable – how to force to write after tag, not inside

I have div with contentEditable and when I add an element into it via JS, like: <span>text</span> I am not able to move cursor after – so when user input something it is going into the span. Is there any way how to prevent that?

<p class="line">Some text <span>text</span>[write_here]</p>

I want to force it to write into [write_here] position.

Here is an example, when you just add element and write it is going into the span – red. You are not able to write out of it after.

const input = document.querySelector('div.content');
const result = document.querySelector('div.result');
const addBtn = document.querySelector('button.addbtn');

input.addEventListener('input', () => {
  result.innerText = input.outerHTML;
});

const createElement = (content) => {
  const element = document.createElement('span');

  element.classList.add('mention');
  element.innerText = `@${content}`;

  return element;
};


addBtn.addEventListener('mousedown', () => {
  const element = createElement('test');
  
  const selection = window.getSelection();
  const selectedRange = selection.getRangeAt(0);
  
  selectedRange.deleteContents();
  selectedRange.insertNode(element);
  
  selectedRange.setStart(element, element.length);
  selectedRange.collapse(true);

  selection.removeAllRanges();
  selection.addRange(selectedRange);
  
  // How to properly move cursor after the `span` to write outside of the span. Even solve when user writes something and delete text right next to the end of the span. 
});
.content {
  width: 350px;
  height: 20px;
  background: lightblue;
}

span.mention {
  background: red;
}
<div class="content" contentEditable="true"><br/></div>
<button class="addbtn">Add element</button>
HTML:
<div class="result"></div>

FlatList inside ScrollView in React-Native?

I’m learning to use react-native by creating an application, so I’m creating a scrollable homepage and inside it 10 rectangle with different names. If I understand correctly, you need to use flatlist to manage the scrolling of these rectangles, but I already have a scrollview within the same page. I have something like this:

<ScrollView> 
  <Image/>
  <Text/>
  <RectangleComponents/>
</ScrollView>

Inside RectanglesComponent is the code that creates the 10 rectangles. I’m currently using a ScrollView here too because I couldn’t use FlatList inside a ScrollView. Example of RectanglesComponent:

    return (
    <SafeAreaView style={styles.container}>
        {Array.from(Array(10).keys()).map(i => ( 
            <SafeAreaView key={i} style={styles.rectangle}/>
    </SafeAreaView>
    );

In this case i need to use FlatList or ScrollView is good?

how to solve an error in console using reactjs

So i have a component in react that I have created. When it’s rendering it showing this error.

 Warning: Cannot update a component (`Inweight`) while rendering a different component (`StackPlan`). To locate the bad setState() call inside `StackPlan`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
StackPlan@http://localhost:3000/static/js/bundle.js:11659:19
TemplateWrapper@http://localhost:3000/static/js/bundle.js:97205:24
TemplatesRenderer@http://localhost:3000/static/js/bundle.js:97526:43
div
Form@http://localhost:3000/static/js/bundle.js:102599:43
VisibilityPlan@http://localhost:3000/static/js/bundle.js:13176:24
TemplateWrapper@http://localhost:3000/static/js/bundle.js:97205:24
TemplatesRenderer@http://localhost:3000/static/js/bundle.js:97526:43
div
Form@http://localhost:3000/static/js/bundle.js:102599:43
form
div
div
Inweight@http://localhost:3000/static/js/bundle.js:8449:92
WrappedComponent@http://localhost:3000/static/js/bundle.js:5657:9
RenderedRoute@http://localhost:3000/static/js/bundle.js:424426:7
Routes@http://localhost:3000/static/js/bundle.js:425042:7
div
div
ScrollView@http://localhost:3000/static/js/bundle.js:113534:43
div
div
Drawer@http://localhost:3000/static/js/bundle.js:101149:43
div
SideNavOuterToolbar@http://localhost:3000/static/js/bundle.js:6355:29
Content
App@http://localhost:3000/static/js/bundle.js:2126:62
div
NavigationProvider@http://localhost:3000/static/js/bundle.js:5634:94
AuthProvider@http://localhost:3000/static/js/bundle.js:5520:74
ThemeProvider@http://localhost:3000/static/js/bundle.js:5767:23
Router@http://localhost:3000/static/js/bundle.js:424984:7
HashRouter@http://localhost:3000/static/js/bundle.js:423134:7
Root@http://localhost:3000/static/js/bundle.js:2160:97
Provider@http://localhost:3000/static/js/bundle.js:420294:18 react-dom.development.js:74
    React 5
        printWarning
        error
        warnAboutRenderPhaseUpdatesInDEV
        scheduleUpdateOnFiber
        dispatchSetState
    handleStackData in-weight.js:49
    temporaryStacksJSON stackplan.js:289
    React 5
        basicStateReducer
        updateReducer
        updateState
        useState
        useState
    StackPlan stackplan.js:14
    React 9
        renderWithHooks
        updateFunctionComponent
        updateSimpleMemoComponent
        beginWork
        beginWork$1
        performUnitOfWork
        workLoopSync
        renderRootSync
        performConcurrentWorkOnRoot
    workLoop scheduler.development.js:227
    flushWork scheduler.development.js:205
    performWorkUntilDeadline scheduler.development.js:442
    <anonymous> task.js:57
    run task.js:34
    eventListener task.js:43

here inweight is my component that I want to use those props. I pass them through several components as props With out any change that has seen in the stack flow.
I want to solve this error.
this is my code

import React, { useEffect, useState } from 'react';
import useGetAPI from '../getAPIS';
import apis from '../api-constants';
import { DataGrid, Column, Paging, Summary, SearchPanel, TotalItem, Pager } from 'devextreme-react/data-grid';
import 'devextreme/data/array_store';
import { CheckBox, SelectBox, Button, Popup } from 'devextreme-react';
import Form, { GroupItem, SimpleItem, ButtonItem } from 'devextreme-react/form';
import './stackplan.scss';
import { formatMessage } from 'devextreme/localization';
import TemporaryStack from './temporarystack';

function StackPlan({ tokenDetails, operation, updateDumpingAreaDetails, onRowSelect }) {

  const [stackData, setStackData] = useState([]);

  const [initialValues, setInitialValues] = useState({
    selectedGodown: "0",
    popupVisible: false,
    isAllBagTypeStacks: false,
    isCheckboxVisible: true,
    isReadOnly: true
  })

  const [otherStackValues, setOtherStackValues] = useState({
    godownList: [],
    stackList: [],
    selectedShedValue: "",
    selectedStackValue: "",
  })

  const allowedPageSizes = [10, 25, 50, formatMessage('All')];

  useEffect(() => {
    FetchStackData();
    async function FetchStackData() {
      const response = await useGetAPI(
        apis.GET_STACK_PLANS(tokenDetails.genericid, tokenDetails.tokenid, tokenDetails.truckNum, initialValues.isAllBagTypeStacks, operation)
      );
      if (response) {
        const processedStackData = response.data.map((item, index) => ({
          ...item,
          continuousIndex: index + 1,
          flag: item.flagRecordExists ? true : null
        }));
        setStackData(processedStackData);
        setInitialValues(previousValues => ({
          ...previousValues,
          isCheckboxVisible: !processedStackData.some((stack) => stack.readOnlyTable),
          isReadOnly: processedStackData.some((stack) => stack.readOnlyTable)
        }))
        processedStackData.filter((stack) => stack.flagRecordExists === true).forEach((stack) => {
          if (
            tokenDetails.transactiontype === "CMR" ||
            tokenDetails.transactiontype === "LEVY" ||
            tokenDetails.transactiontype === "BRL_CMR"
          ) {
            GetDumpingAreaDetails(stack.mappedGodownUnitId);
          }
        });
        onRowSelect(processedStackData);
      }
    }
  }, [tokenDetails, initialValues.isAllBagTypeStacks]);


  const GetDumpingAreaDetails = async (godownId) => {
    try {
      let dumpingAreaData = await useGetAPI(apis.GET_DUMPINGAREA_ASSOCIATED_WITH_GODOWN(godownId, tokenDetails.genericid));
      if (dumpingAreaData && dumpingAreaData.data) {
        dumpingAreaData.data.readOnly = initialValues.isReadOnly;
        updateDumpingAreaDetails(dumpingAreaData.data);
      } else {
        console.error("Invalid or null data received from the API:");
      }
    } catch (error) {
      console.error('Error fetching RO Details:', error);
    }
  };

  const handleCheckBox = (checkboxvalue, rowData) => {

    const stackId = rowData.data.mappedStacksId;
    const assignedBags = rowData.data.assignedBags;

    setStackData(prevData => {
      const updatedStackData = prevData.map(stack => {
        if (stack.mappedStacksId === stackId) {
          return {
            ...stack,
            flagRecordExists: checkboxvalue,
            assignedBags: checkboxvalue ? assignedBags : null,
            flag: checkboxvalue ? true : null
          };
        }
        return stack;
      });


      if (tokenDetails.transactiontype === "CMR" || tokenDetails.transactiontype === "LEVY" || tokenDetails.transactiontype === "BRL_CMR") {
        GetDumpingAreaDetails(rowData.data.mappedGodownUnitId)
      }
      onRowSelect(updatedStackData);
      return updatedStackData;
    });
  };



  const getUniqueGodowns = () => {
    const godownArray = [{ value: "0", text: formatMessage('AllSheds') }];

    stackData.map((godown) => {
      if (!godownArray.some(option => option.value === godown.godownName)) {
        godownArray.push({ value: godown.godownName, text: godown.godownName });
      }
    });

    return godownArray;
  };


  const renderSelectBox = () => {
    const uniqueGodowns = getUniqueGodowns();
    return (
      <div>
        <SelectBox dataSource={uniqueGodowns} displayExpr="text" valueExpr="value" value={initialValues.selectedGodown} placeholder="select Depot"
          onSelectionChanged={(data) => (setInitialValues(previousValues => ({ ...previousValues, selectedGodown: data.selectedItem.value })))} />

      </div>
    );
  };

  const GetAllShed2 = async () => {
    try {
      const godownListResponse = await useGetAPI(apis.GET_DEPOT_GODOWN_LIST(true));

      if (godownListResponse && godownListResponse.data) {
        const jsonResponse = godownListResponse.data;
        const jsonData = JSON.parse(jsonResponse.substring(jsonResponse.indexOf('(') + 1, jsonResponse.lastIndexOf(')')));
        setOtherStackValues(previousValues => ({ ...previousValues, godownList: jsonData }))
      }

    } catch (error) {
      console.error('Error fetching godown list:', error);
    }
  };

  const HandleSelectChangeGoDown = async (goDownId) => {
    try {
      let stackOptions = await useGetAPI(
        apis.GET_STACKS_FOR_MULTIPLESTACKING_BY_UNITID(
          goDownId,
          tokenDetails.tokenid,
          tokenDetails.genericid,
          '',
          'Gatepass'
        )
      );

      if (stackOptions && stackOptions.data) {
        const existingStacksOptions = stackData.map((stack) => stack.mappedStacksId);
        const transformedStackList = stackOptions.data
          .filter((stack) => !existingStacksOptions.includes(stack.Stacks_ID))
          .map((stack) => ({
            value: `${stack.Stacks_ID}$${stack.Capacity}$${stack.Gunnycode}`,

            text: stack.Stacks_Name,
          }));

        setOtherStackValues(previousValues => ({ ...previousValues, stackList: transformedStackList }))
      }
    } catch (error) {
      console.log("Error fetching the stack options", error);
    }
  };

  const addOtherStack = () => {
    setOtherStackValues((prevValues) => ({
      ...prevValues,
      selectedShedValue: "",
      selectedStackValue: "",
      godownList: [],
      stackList: []
    }));
    setInitialValues(previousValues => ({ ...previousValues, popupVisible: true }));
    GetAllShed2();
  };

  const handlePopupClose = () => {
    setInitialValues(previousValues => ({ ...previousValues, popupVisible: false }));
  };

  const clearAssignedBagsAndCheckboxValue = () => {
    setStackData((prevData) =>
      prevData.map((stack) => ({
        ...stack,
        flagRecordExists: false,
        assignedBags: null,
      }))
    );
  };

  const handleAddStackClick = () => {
    if (!otherStackValues.selectedShedValue || otherStackValues.selectedShedValue.length === 0) {
      alert(formatMessage('Please_Select_Stack_And_Shed'));
      return;
    }

    if (!otherStackValues.selectedStackValue || otherStackValues.selectedStackValue.length === 0) {
      alert(formatMessage('Please_Select_Stack'));
      return;
    }

    const selectedShedName = otherStackValues.godownList.find((godown) => godown.id === otherStackValues.selectedShedValue)?.value;
    const selectedStackName = otherStackValues.stackList.find((stack) => stack.value === otherStackValues.selectedStackValue)?.text;
    const [stackId, capacity, bagType] = otherStackValues.selectedStackValue.split('$');

    setStackData((prevData) => [
      ...prevData,
      {
        mappedStacksId: parseInt(stackId, 10),
        currentNoOfBags: parseInt(capacity, 10),
        bagtype: bagType,
        mappedGodownUnitId: otherStackValues.selectedShedValue,
        godownName: otherStackValues.selectedShedValue ? selectedShedName : null,
        stackName: selectedStackName ? selectedStackName : null,
        flagRecordExists: false,
        continuousIndex: stackData.length + 1,
      },
    ]);

    // Clear checkbox selection after adding a new stack
    clearAssignedBagsAndCheckboxValue();
    setInitialValues(previousValues => ({ ...previousValues, selectedGodown: selectedShedName }));

    // Close the popup
    handlePopupClose();
  };

  const handleAssignedBagsChange = (e, stackId) => {
    setStackData((prevData) => {
      const updatedStackData = prevData.map((stack) => {
        if (stack.mappedStacksId === stackId) {
          return {
            ...stack,
            assignedBags: e.target.value,
          };
        }
        return stack;
      });
      onRowSelect(updatedStackData);
      return updatedStackData;
    });
  };

  const handleRowPrepared = (e) => {
    if (e.rowType === 'data' && e.data && e.data.flagRecordExists) {
      e.rowElement.classList.add('highlighted-row');
    }
  };

  const isTemporarystackused = (data) => {
    setStackData((prevData) => {
      const updatedStackData = prevData.map((stack) => {
        if (stack.isTemporaryStackUsed !== data) {
          return {
            ...stack,
            isTemporaryStackUsed: data,
          };
        }
        return stack;
      });
      onRowSelect(updatedStackData);
      return updatedStackData;
    });
  }

  const temporaryStacksJSON = (data) => {
    setStackData((prevData) => {
      const updatedStackData = prevData.map((stack) => {
        if (stack.temporaryStacksJSON !== data) {
          return {
            ...stack,
            temporaryStacksJSON: data,
          };
        }
        return stack;
      });
      onRowSelect(updatedStackData);
      return updatedStackData;
    });
  }
  return (
    <>
      <div className="toolbar-container">
        <CheckBox
          text={formatMessage('AllBagTypeStacks')}
          onValueChanged={(e) => {
            setInitialValues(previousValues => ({ ...previousValues, isAllBagTypeStacks: e.value, selectedGodown: "0" }))
          }}
          value={initialValues.isAllBagTypeStacks}
          style={{ zIndex: 1 }}
        />
        <Button
          icon='plus'
          text={formatMessage('AddOtherStack')}
          onClick={addOtherStack}
          className='button-style'
        />
      </div>

      <Popup
        visible={initialValues.popupVisible}
        onHiding={handlePopupClose}
        dragEnabled={true}
        showTitle={true}
        title={formatMessage('AddStack')}
        width="30vw"
        height="25vh"
      >
        <Form>
          <GroupItem colCount={2} >
            <SimpleItem
              dataField={formatMessage('Shed')}
              editorType="dxSelectBox"
              editorOptions={{
                dataSource: otherStackValues.godownList,
                valueExpr: "id",
                displayExpr: "value",
                value: otherStackValues.selectedShedValue,
                onValueChanged: (e) => {
                  setOtherStackValues(previousValues => ({ ...previousValues, selectedShedValue: e.value }))
                  HandleSelectChangeGoDown(e.value);
                },
              }}
            />

            <SimpleItem
              dataField={formatMessage('Stack')}
              editorType="dxSelectBox"
              editorOptions={{
                dataSource: otherStackValues.stackList,
                valueExpr: "value",
                displayExpr: "text",
                value: otherStackValues.selectedStackValue,
                onValueChanged: (e) => {
                  setOtherStackValues(previousValues => ({ ...previousValues, selectedStackValue: e.value }))
                }

              }}
            />
          </GroupItem>
          <ButtonItem horizontalAlignment="right" buttonOptions={{
            text: formatMessage('AddStack'), type: 'default', useSubmitBehavior: true,
            onClick: handleAddStackClick
          }} />
        </Form>
      </Popup>

      <div className='datagrid-container'>
        <DataGrid dataSource={parseInt(initialValues.selectedGodown) === 0 ? stackData : stackData.filter(stack => (parseInt(stack.godownName) === parseInt(initialValues.selectedGodown)))}
          showBorders={true}
          onRowPrepared={(e) => handleRowPrepared(e)}
        >
          <SearchPanel
            visible={true}
            width={240}
            placeholder={formatMessage('Search')}
          />
          <Paging defaultPageSize={10} />
          <Pager
            visible={true}
            allowedPageSizes={allowedPageSizes}
            displayMode="full"
            showInfo={true}
            showPageSizeSelector={true} />
          <Column dataField="continuousIndex" caption={formatMessage('SNo')} allowEditing={false} alignment='left' />
          <Column dataField="godownName" caption={formatMessage('Godown')} width={200} allowSorting={false} alignment='left'
          //headerCellRender={renderSelectBox}
          />
          <Column dataField="stackName" caption={formatMessage('StackName')} allowEditing={false} alignment='left' />
          <Column dataField="bagtype" caption={formatMessage('BagType')} allowEditing={false} alignment='left' />
          <Column dataField="currentNoOfBags" caption={formatMessage('AvailableSpace')} allowEditing={false} alignment='left' />
          <Column
            caption={formatMessage('AssignedBags')}
            dataField="assignedBags"
            alignment='left'
            cellRender={(rowData) => (
              <input
                type="number"
                readOnly={initialValues.isReadOnly || !rowData.data.flagRecordExists}
                defaultValue={rowData.data.assignedBags || ''}
                onBlur={(e) => handleAssignedBagsChange(e, rowData.data.mappedStacksId)}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    e.preventDefault();
                  }
                }}
              />
            )}
          />
          <Column
            allowEditing={false}
            caption="#"
            cellRender={(rowData) => (

              <CheckBox value={rowData.data.flagRecordExists} visible={initialValues.isCheckboxVisible} onValueChanged={(e) => handleCheckBox(e.value, rowData)} />)}
          />
          <Summary>

            <TotalItem
              column="assignedBags"
              summaryType="sum"
              customizeText={(itemInfo) => `Total Bags : ${itemInfo.value}`}
            />
          </Summary>

        </DataGrid>
        <br />

        <TemporaryStack
          tokenDetails={tokenDetails}
          operation={operation}
          isTempUsed={isTemporarystackused}
          temporaryStacksJSON={temporaryStacksJSON}
        />

      </div>
    </>
  );
}

export default React.memo(StackPlan);

I had noticed that the error might be caused by isTemporarystackused,temporaryStacksJSON. if not please let me know.
this is my inweight component that i have using props from stackplan throught VisibilityPlan’s handleStackData

import React, { useEffect, useState, useCallback } from 'react';
import Form, { GroupItem, SimpleItem, ButtonItem } from 'devextreme-react/form';
import apis from '../../../utilities/api-constants';
import TokenSelection from '../../../utilities/token-selection';
import { formatMessage } from 'devextreme/localization';
import PostAPI from '../../../utilities/postAPIS';
import GetAPI from '../../../utilities/getAPIS';
import VisibilityPlan from '../../../utilities/visibilityPlan';
import { DataGrid, Column } from 'devextreme-react/data-grid';
import { Button, RadioGroup, SelectBox } from 'devextreme-react';

export default function Inweight() {
  const [initialValues, setInitialValues] = useState({
    tokenDetails: '',
    aplStackplans: '',
    operation: 'Inweight',
    selectedOptions: '',
    dumpingAreaDetails: [],
    selectedDumpingArea: '0',
    Pvdata: '',
    temporaryStacksJSON: null
  })

  const handleTokenChanges = (tokenDetails, selectedOptions) => {
    setInitialValues(previousValues => ({ ...previousValues, selectedOptions: selectedOptions, tokenDetails: tokenDetails }))
  }
  const handleStackData = (selectedStackData) => {
    const arrangedData = selectedStackData.map(row => ({
      bagtype: row.bagtype,
      isPriorityOverride: row.isPriorityOverride,
      issilo: row.issilo,
      isTemporaryStackUsed: row.isTemporaryStackUsed,
      flagRecordExists: row.flagRecordExists,
      mappedGenericId: initialValues.tokenDetails.genericid,
      mappedGodownUnitId: row.mappedGodownUnitId,
      tokenId: initialValues.tokenDetails.tokenid,
      mappedStacksId: row.mappedStacksId,
      assignedBags: row.assignedBags,
      truckNum: initialValues.tokenDetails.truckNum,
      priority: row.priority,
      cropyear: row.cropyear,
      specificationId: row.specificationId,
      tareweight: row.tareweight,
      specification: row.specification,
      bagCapacity: row.bagCapacity,
      category: row.category,
    }));
    const filteredStackplans = arrangedData.filter(plan => plan.flagRecordExists === true);
    setInitialValues(previousValues => ({ ...previousValues, aplStackplans: filteredStackplans }))
    const tempstackdata = selectedStackData[0]?.temporaryStacksJSON
    setInitialValues(previous => ({ ...previous, temporaryStacksJSON: tempstackdata }))
  };
  function scanWeight() {
    if (!initialValues.inweight) {
      const scannedWeight = parseFloat(window.prompt('Enter the weight'));
      if (scannedWeight) {
        setInitialValues((previous) => ({ ...previous, tokenDetails: { ...previous.tokenDetails, inweight: scannedWeight } }))
      }
    }
  }

  function handleScanAgain() {
    setInitialValues((previous) => ({ ...previous, tokenDetails: { ...previous.tokenDetails, inweight: 0 } }))
  }

  const handlerforPVtype = (gathereddata) => {
    setInitialValues((prevValues) => {
      if (prevValues.Pvdata !== gathereddata) {
        return { ...prevValues, Pvdata: gathereddata };
      } else {
        return prevValues;
      }
    });
  };

  const updateDumpingAreaDetails = (value) => {
    setInitialValues((prevValues) => ({ ...prevValues, dumpingAreaDetails: value }));
  }

  const updateSelectedDumpingArea = (newSelectedDumpingArea) => {
    setInitialValues((prevValues) => ({
      ...prevValues,
      selectedDumpingArea: newSelectedDumpingArea,
    }))
  };

  const HandleSubmit = async (e) => {
    e.preventDefault();
    let formatDataforapi
    if (initialValues.tokenDetails.transactiontype === 'PHYSICAL_VERIFICATION') {
      formatDataforapi = {
        wbweight: {
          inweight: initialValues.tokenDetails.inweight,
          mappedStackhistoryId: initialValues.Pvdata.stackHistoryId,
          trucknum: initialValues.tokenDetails.truckNum,
        },
        generic: {
          issilo: false,
          isbagtypemix: false,
          transactiontype: initialValues.tokenDetails.transactiontype,
          noofbags: 0,
        },
        tokenId: initialValues.tokenDetails.tokenid,

      }
    } else if (['MANDI', 'BRL_CMR', 'CMR', 'TRUCKSHIPMENTINWARD'].includes(initialValues.tokenDetails.transactiontype)) {
      formatDataforapi = {
        wbweight: {
          inweight: initialValues.tokenDetails.inweight,
          trucknum: initialValues.tokenDetails.truckNum,
        },
        generic: {
          aplStackplans: initialValues.aplStackplans,
          issilo: false,
          isbagtypemix: false,
          tempStackplans: initialValues.temporaryStacksJSON,
        },
        tokenId: initialValues.tokenDetails.tokenid,
      }
    } else {
      formatDataforapi = {
        wbweight: {
          inweight: initialValues.tokenDetails.inweight,
          trucknum: initialValues.tokenDetails.truckNum,
        },
        generic: {
          aplStackplans: initialValues.aplStackplans,
        },
        tokenId: initialValues.tokenDetails.tokenid,
      }
    }

    let apiResult = await PostAPI(apis.ADD_INWEIGHT(initialValues.tokenDetails.transactiontype), formatDataforapi);
    if (apiResult.status === 200) {
      alert(apiResult.data)
    }

    setInitialValues({
      tokenDetails: '',
      aplStackplans: '',
      operation: 'Inweight',
      selectedOptions: '',
      dumpingAreaDetails: [],
      selectedDumpingArea: '0',
      Pvdata: '',
      temporaryStacksJSON: null
    });
  };

  return (
    <div className={'content-block'}>
      <div className={'dx-card responsive-paddings'}>
        <form onSubmit={HandleSubmit}>
          <Form id="form">
            <GroupItem caption={formatMessage('InWeight')}>
              <GroupItem colCount={2}>
                <GroupItem colSpan={2}>
                  {/* token select part */}
                  <TokenSelection
                    selectedOptions={initialValues.selectedOptions}
                    operation='Inweight'
                    handleTokenChanges={handleTokenChanges}
                    Url={apis.GET_TOKENS_FOR_INWEIGHT}
                  />
                </GroupItem>
              </GroupItem>

            </GroupItem>

            {initialValues.tokenDetails.processType !== 'OTHERS' && (
              <GroupItem>
                <VisibilityPlan
                  tokenDetails={initialValues.tokenDetails}
                  handleStackData={handleStackData}
                  dumpingAreaDetails={initialValues.dumpingAreaDetails}
                  updateDumpingAreaDetails={updateDumpingAreaDetails}
                  updateSelectedDumpingArea={updateSelectedDumpingArea}
                  operation='Inweight'
                />
              </GroupItem>)}

            <GroupItem>
              {initialValues.tokenDetails.transactiontype === 'PHYSICAL_VERIFICATION' &&
                <PHYSICAL_VERIFICATION
                  tokenDetails={initialValues.tokenDetails}
                  exitdata={handlerforPVtype} />}
            </GroupItem>

            {initialValues.tokenDetails && <GroupItem>
              <div style={{ display: 'flex', alignItems: 'center' }}>
                {<label style={{ marginRight: '10px' }}>{['ISSUE', 'PHYSICAL_VERIFICATION'].includes(initialValues.tokenDetails.transactiontype) ? formatMessage("Tare_Weight_in_Qtls") : formatMessage("Gross_Weight_in_Qtls")}</label>}
                {!initialValues.tokenDetails.inweight ? <Button onClick={scanWeight} text={formatMessage('Capture_Weight')} /> : ''}
                {initialValues.tokenDetails.inweight ? (
                  <div>
                    <input type='text' value={initialValues.tokenDetails.inweight} readOnly style={{ marginRight: '10px' }} />
                    <Button onClick={handleScanAgain} icon='refresh' />
                  </div>
                ) : ''}
              </div>
            </GroupItem>}
            <ButtonItem horizontalAlignment="left" buttonOptions={{ text: formatMessage('Save'), type: 'success', useSubmitBehavior: true }} />
          </Form>
        </form>
      </div>
    </div>
  )
}

How to display the custom created tooltip always on the right side of the element or next to the element?

I am developing a Nuxt 3-based application where creating a reusable custom tooltip menu bar which can display some information on hovering over the vee-validate Field that I want to reuse for various other components. For some reason the tooltip menu displays below the Field instead of displaying next to the Field on the right side.

How to fix the styles using the tailwind CSS to ensure that the tooltip menu always appears on the right side next to the Field? I have added the sample code in my CodeSandbox for reference.

Following are my Nuxt 3 application codes:

components/CustomToolTip.vue:

<template>
  <div>
    <div
      class="focus:outline-none mr-2"
      @mouseenter="hoverPopover($event)"
      @mouseleave="closePopover($event)"
    >
      <slot />
    </div>

    <div
      class="absolute mt-3 z-50 dark:bg-gray-700 bg-gray-300 dark:text-white text-black rounded-lg p-2 inline-block after:absolute after:border-4 dark:after:border-gray-700 after:border-gray-300 after:-left-0 after:top-1/3 after:-translate-x-1/2 after:rotate-45 transform -translate-y-[30%]"
      v-show="showTooltip"
    >
      <div class="max-w-xs max-h-20 overflow-auto">{{ tooltipInfo }}</div>
    </div>
  </div>
</template>
     
  <script setup>
import { ref } from "vue";

const props = defineProps({
  name: {
    type: String, // name associated with the field
    required: false,
  },
  fieldName: {
    type: String, //name associated with HoverIcon
    required: false,
    default: "",
  },
  fieldValue: {
    type: [String, Boolean, Number], //value associated with hoverIcon
    required: false,
    default: "",
  },
});

// Reactive state
const showTooltip = ref(false);
const tooltipInfo = ref("");

// Methods
const hoverPopover = () => {
  setTimeout(() => {
    showTooltip.value = true;
    showToolTipInfo();
  }, 500);
};

const closePopover = () => {
  showTooltip.value = false;
};

const showToolTipInfo = async () => {
  console.log(" Name : " + props.fieldName + " -- Value : " + props.fieldValue);
  tooltipInfo.value = "Custom CSS Tooltip Hello From The ToolTIp Menu Bar";
};
</script>

Following is my usage to wrap the other components to CustomTooltip.vue:
components/HoverMenuTest2.vue:

<template>
  <div class="flex flex-col items-center w-full">
    <CustomToolTip :name="name" :fieldName="name" :fieldValue="''">
      <div
        class="relative w-full h-full bg-gray-50 dark:text-white dark:bg-gray-700 dark:border-gray-600 border-gray-300 border rounded text-center block overflow-hidden"
      >
        <Field
          as="select"
          :name="name"
          v-model="item"
          class="w-full h-full bg-transparent p-2 outline-none dark:bg-gray-700"
        >
          <option
            v-for="option in options"
            :value="option.value"
            :key="option.value"
            :selected="option.selected"
          >
            {{ option.text }}
          </option>
        </Field>

        <Icon
          icon="iconamoon:arrow-down-2-bold"
          class="absolute right-2 top-1/2 transform -translate-y-1/2"
        />
      </div>
    </CustomToolTip>
  </div>
</template>
  
<script setup>
import { Icon } from "@iconify/vue";
import { Field } from "vee-validate";

const props = defineProps({
  options: {
    type: Array,
    required: false,
  },
  name: {
    type: String,
    required: false,
  },
});

const item = ref(props.options[0].value);
</script>
  
<style>
select {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: none;
}
</style>

Following is my usage in pages/Test.vue:

<template>
  <HoverMenuTest2 v-model="type" :name="'eventType'" :options="options" />
</template>

<script setup>
const type = useState("type", () => ({}));
const options = [
  { value: "value1", text: "Option 1", selected: true },
  { value: "value2", text: "Option 2" },
  { value: "value3", text: "Option 3" },
];
</script>

Currently when I hover over the Select dropdown then I get the tooltip as this:
enter image description here

I want it to be displayed next to the field something like this:
enter image description here

I tried with few styles etc but that does not seem to work and it modified the tooltip menu itself by striking its size and all, I want to ensure that the tooltip info bar is of the same size as expected but only need to move to the right side instead of displaying below the Field.

AnyChart Treemap with context menu – make data node accessible to action handler

I have an AnyChart Treemap. Its nodes contain (besides their natural value) also additional attribute. I want to show (ultimately perform action upon) the value of that attribute on click on rectangle.

Example: assume tree map with data of population of countries where additional attribute contains URL shortcut to map of state or continent:

var dataSet = [
  {name: "Europe", url: "https://maps.google.com/europemap", children: [
    {name: "Czechia", value: 10600000, url: "https://maps.google.com/czechiamap"},
    ...
  ]}
];

Since clicking on rectangle is currently reserved to drilling down to deeper level, I started experimenting with context menu with custom action, which would suffice my needs. The example of context menu shows how to implement action handler to serve click on menu item. Unfortunately I cannot figure out how to see the corresponding data set node from within the body of action handler.

I tried to inspect the this object in action handler which seems to be an uncomprehensible internals of minified library or may be parts of generated SVG.

Is there any way to identify data the concrete rectangle has been built from? (I suspect the original data set is completely lost after SVG has been generated – if I am right, some advice how to append dataset to generated SVG as a metadata would be helpful too.)

onkeypressed focus to the next textbox

This is my code:

for($i=0;$i<5;$i++)
{
     echo"<input type='text' autocomplete='off' class='form-control text-center fw-bold mx-auto text-uppercase align-top mr-1' name=$count maxlength='1' style='font-size: 40px;height: 75px;width: 75px' required>";
     $count++;
}

I would like it to take you to the textbox as soon as you click a button, I’ve tried many ways but none of them worked.
Thanks in advance for the advice <3

I tried to modify an example where when you press a button an alert appears but nothing.

I tried with this but without the control for the enter key but nothing

Electron.js App Fails to Generate PDF with jsPDF on Button Click

Body:

I’m working on an Electron.js application that should generate a PDF using jsPDF when a button is clicked. The application runs without issues until I attempt to generate the PDF, at which point nothing happens. Additionally, I’m seeing error messages in the console related to Vulkan driver compatibility and VSync parameters.

Issue:

The ‘Generate PDF’ button click does not trigger the PDF generation as expected, and the following errors are logged in the console:

TU: error: ../src/freedreno/vulkan/tu_knl.cc:232: device /dev/dri/renderD128 (i915) is not compatible with turnip (VK_ERROR_INCOMPATIBLE_DRIVER)
[ERROR:gl_surface_presentation_helper.cc(260)] GetVSyncParametersIfAvailable() failed for 1 times!

These errors suggest a potential issue with the Vulkan driver and Electron’s display synchronization.

Code Snippet:

Here’s the relevant part of my renderer.js:

const { ipcRenderer } = require('electron');
const jsPDF = require('jspdf');


const generatePDF = () => {
  // ... code to collect form data ...
  const pdf = new jsPDF();
  // ... code to add content to PDF ...
  pdf.save('output.pdf');
};

document.getElementById('generatePdf').addEventListener('click', generatePDF);

What I’ve Tried:

  • Ensuring that the paths to assets and save locations are correct.
  • Checking permissions for file system access.

Question:

What could be causing the PDF generation to fail upon button click within an Electron.js environment, and how can I resolve the Vulkan driver and VSync parameter errors that appear in the console?

Any insights or suggestions would be greatly appreciated!

Firebase getDoc function not resolving or throwing errors

I’m facing an issue with the getDoc function in Firebase Firestore. When I try to use getDoc to retrieve a document from the Firestore database in my web application, it neither resolves nor throws any errors.

Here’s my code snippet in js:


import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.1.1/firebase-app.js';
import { getFirestore, collection, addDoc, doc, setDoc, getDoc, query, getDocs, onSnapshot, updateDoc, where } from 'https://www.gstatic.com/firebasejs/9.1.1/firebase-firestore.js';

const firebaseConfig = {
  apiKey: "API_KEY",
  authDomain: "AUTH_DOMAIN",
  projectId: "PROJECT_ID",
  storageBucket: "STORAGE_BUCKET",
  messagingSenderId: "MESSAGING_SENDER_ID",
  appId: "APP_ID",
  measurementId: "MEASUREMENT_ID"
};

const app = initializeApp(config);
const db = getFirestore(app);


[... other functions]


async function cropImage() {
    if (!selectedUser) {
        return;
    }

    try {
   
        const imageDataURL = croppedCanvas.toDataURL();
        const cleanedURL = cleanAndValidateUrl(imageDataURL);

        if (!cleanedURL) {
            console.error('Invalid image URL');
            return;
        }
        const userDocRef = doc(db, 'character_sheet', selectedUser);
        const imagesCollectionRef = collection(userDocRef, 'images');         
        
        try {
            const imagesCollectionSnapshot = await getDocs(imagesCollectionRef); //HERE THE CODE STOPS, RETURNING NOTHING
   
            if (!imagesCollectionSnapshot.empty) {
                // If the collection doesn't exist, create it
                await addDoc(imagesCollectionRef, {});
            }
        } catch (error) {
            console.error("Error retrieving images collection:", error);
        }
        
        // Get a reference to a new document in the images collection
        var newImageRef = doc(imagesCollectionRef);

        // Clean and validate the image URL
        const cleanedImageUrl = cleanAndValidateUrl($('#previewImage').attr('src'));
        if (typeof cleanedImageUrl !== 'string') {
            console.error('Cleaned image URL is not a string:', cleanedImageUrl);
            return;
        }
        
        // Set the document data (image)
        await setDoc(newImageRef, {
            imageUrl: cleanedImageUrl,
            cropData: {
                x: croppedData.x,
                y: croppedData.y,
                width: croppedData.width,
                height: croppedData.height,
                rotate: croppedData.rotate,
                scaleX: croppedData.scaleX,
                scaleY: croppedData.scaleY
            }
        });

        // Display success message
        alert("Image uploaded successfully.");

        // Clear the preview
        $('#previewImage').attr('src', '');
        cropper.destroy();
        console.log('Image uploaded successfully');
    } catch (error) {
        console.error('Error uploading image:', error);
    }
}

When I run this code, the error block inside the catch statement is not executed. However, I can confirm that the document exists in the Firestore database, and the Firebase configuration is correct.

Interestingly, when I try to access the same collection and document from another page using getDoc, it works perfectly fine.

Could anyone provide insights into why getDoc might not be resolving or throwing errors in this scenario? Any help would be greatly appreciated. Thank you!