How to enter enter multiple entries in an array using onclick in HTML/PHP

I’m a junior developer and I wanted to know that how to enter text in multiple entries/fields/indexes in an array. Currently I’m doing a small project. So I am stuck in inputting the text repeatedly. Kindly help me in this regard. I can enter only one entry, i also tried to make use of classes but no luck.

                                    <!-- Tic Tac Toe Game -->

<html>
<head>
    <title>Tic Tac Toe</title>
    <style>
    body {
        background-color: whitesmoke;
        text-align: center;
    }

    #enteries{
        border-radius: 50px;
        border: 2px solid black;
        padding: 50px; 
        width: 200px;
        height: 15px;
        margin-bottom: 20px;
        margin-top: 20px;
        margin-right: 20px;
        font-size: 30px;
    }

    #done{
         
        border-radius: 10px;
        border: 2px solid black;
        padding: 50px; 
        width: 160px;
        height: 15px;
        margin-bottom: 20px;
        margin-top: 20px;
        margin-right: 20px;
        font-size: 15px;
    }
    </style>
</head>

<body>
    <h1>Welcome! X player</h1>

<form name = "ticktactoe" method = "post" action = "practice.php">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<?php

$winner = 'tied';
$x = array('','','','','','','','','');
if (isset($_POST["gobtn"]))
    {
        $x[0] = $_POST["x0"];
        $x[1] = $_POST["x1"];
        $x[2] = $_POST["x2"];
        $x[3] = $_POST["x3"];
        $x[4] = $_POST["x4"];
        $x[5] = $_POST["x5"];
        $x[6] = $_POST["x6"];
        $x[7] = $_POST["x7"];
        $x[8] = $_POST["x8"];

        if(($x[0] == 'x' && $x[1] == 'x' && $x[2] == 'x')  || ($x[3] == 'x' && $x[4] == 'x' && $x[5] == 'x') || ($x[6] == 'x' && $x[7] == 'x' && $x[8] == 'x') || ($x[0] == 'x' && $x[3] == 'x' && $x[6] == 'x')  || ($x[1] == 'x' && $x[4] == 'x' && $x[7] == 'x') || ($x[2] == 'x' && $x[5] == 'x' && $x[8] == 'x') || ($x[0] == 'x' && $x[4] == 'x' && $x[8] == 'x') || ($x[2] == 'x' && $x[4] == 'x' && $x[6] == 'x') )
        {
            $winner = 'x';
            Print "<h1>X Wins!</h1>";
        }

        $blank = 0; //if the field is blank
        for ($i = 0; $i <= 8 ; $i++)
        {
            if($x[$i] == '')
            {
                $blank = 1;
            }
        }
        if($blank == 1) //if the field contains value
        {
            $i = rand() % 8;
            while($x[$i] != '')
            {
                $i = rand() % 8;
            }
            $x[$i] = 'o';
            if(($x[0] == 'o' && $x[1] == 'o' && $x[2] == 'o')  || ($x[3] == 'o' && $x[4] == 'o' && $x[5] == 'o') || ($x[6] == 'o' && $x[7] == 'o' && $x[8] == 'o') || ($x[0] == 'o' && $x[3] == 'o' && $x[6] == 'o')  || ($x[1] == 'o' && $x[4] == 'o' && $x[7] == 'o') || ($x[2] == 'o' && $x[5] == 'o' && $x[8] == 'o') || ($x[0] == 'o' && $x[4] == 'o' && $x[8] == 'o') || ($x[2] == 'o' && $x[4] == 'o' && $x[6] == 'o') )
            {
                $winner = 'o';
                Print "<h1>O Wins!</h1>";
            }
            
        }
        else if ($winner == 'tied')
        {
            $winner = 'draw';
            Print "<h1>Match is tied</h1>";
        }
    }

    
    for($i = 0; $i <=8; $i++)

            {
                printf('<input type="text" id = "enteries" name = "x%s" value = "%s">', $i, $x[$i]);
                printf('<input type="radio" name="x" id="choose" value="x">');
                printf('<button type="button" onclick="getvalue();">click</button>');
    
            if ($i == 2 || $i == 5 || $i == 8){
                print("<br>");
                }
            }

            if($winner == 'tied')
            {
                //submitting
                print('<input type = "submit" name = "gobtn" style="margin-left: 10px" value = "Enter" id = "done">');
                
            }
            else
            {
                //play again when the matched is finished
                print('<input type = "button" name = "newgamebtn" value = "Play Again" id = "done" onclick = "window.location.href='practice.php'">');
            }
    
        ?>

</form>

<script>
    function getvalue(){
            
            var values = document.getElementById("choose").value;
            
            document.getElementById("enteries").value="x";
        }
    
</script>

</body>
</html>

how to get specific json path on onclick event of particular key value pair in json array data using react js?

enter image description here
I m getting json array data as shown in figure I m displaying it with material UI through React js. Now I want specific json path on Onclick event but for same key value pair i m getting all json path present in json data for that all key value, I want json path of only clicked node, how to get that*

for e.g Clicked Node : XPN.1: TEST
Json Path Array : (4) [‘[0].NK1[0].NK1.2.XPN.1’, ‘[0].NK11.NK1.2.XPN.1′, ‘[0].NK1[2].NK1.2.XPN.1’, ‘[0].PV2.PV2.3.CE.1’]
I want specific path instead of array of all same key value pair path .

import React, { useState } from "react";
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { TextField } from "@material-ui/core";
import TreeItem from '@material-ui/lab/TreeItem';
import TreeView from '@material-ui/lab/TreeView';
import axios from "axios";
import copy from "copy-to-clipboard";
import { makeStyles } from '@material-ui/core/styles';    

const useStyles = makeStyles({
  root: {
    height: 700,
    flexGrow: 1,
    maxWidth: 400
  }
});

export const FileUpload3 = (props) => {

  const classes = useStyles();
  const [file, setFile] = useState();
  const [fileName, setFileName] = useState();

  const [data, setData] = useState([]);
  const [key, setKey] = useState();


  const getChildren = obj =>
    Object.keys(obj).map(key => {
      const hasChildren = typeof obj[key] === "object";
      return {
        id: hasChildren ? key : obj[key],
        name: `${key}${hasChildren ? "" : `: ${obj[key]}`}`,
        children: hasChildren ? getChildren(obj[key]) : []
      };
    });

  const getData = objs => {
    return objs.map(obj => ({
      id: "root",
      name: key,
      children: getChildren(obj),    
    }));
  };

  const renderTree = nodes => {
    return (
      <TreeItem value={nodes.parents} nodeId={nodes.id} label={nodes.name}             
        onClick={() => handleClick(nodes)}                
        {Array.isArray(nodes.children)
          ? nodes.children.map(node => renderTree(node))
          : null}
      </TreeItem>

    );
  };
 
  const handleClick = (e) => {

    var mypath = getPath(data, e.id)
    console.log("Json Path : ", mypath);  // JSON PATH
    
  }
  function getPath(object, value) {
    return Object
      .keys(object)
      .reduce((r, k) => {
        var kk = Array.isArray(object) ? `[${k}]` : `${k}`;
        if (object[k] === value) {
          r.push(kk);
        }
        if (object[k] && typeof object[k] === 'object') {
          r.push(...getPath(object[k], value).map(p => kk + (p[0] === '[' ? '' : '.') + p));
        }
        return r;
      }, []);
  }
  
  const saveFile = (e) => {
    console.log(e.target.files[0]);
    setFile(e.target.files[0]);
    setFileName(e.target.files[0].name);
  }
  const UploadFile = async (e) => {

    const bindTree = async (e) => {
      setData(e);
    }

    const setKeyData = async (e) => {
      setKey(e);
    }

    console.log(file);
    const formData = new FormData()

    formData.append("formFile", file);
    formData.append("fileName", fileName);


    try {

      const res = await axios.post("https://localhost:44316/api/TerserExpressionUtility", formData);
      console.log(res.data);

      const keyData = Object.keys(res.data);
      //console.log(keyData);
      setKeyData(keyData);

      //Json object excluding the root node ADT_A01
      const result = Object.keys(res.data).map((key) => res.data[key]);
   ;

      //Convert the result into string array
      const data2 = JSON.stringify(result);
    

      //Parse the string into the object to bind it to TreeView
      const treeObject = JSON.parse(data2);
 
      bindTree(treeObject)
 
    }

    catch (ex) {
      console.log(ex);
    }

  };
 

  return (

    <>

      <input type="file" onChange={saveFile} />
      <input type="button" value="upload" onClick={UploadFile} />
      <br />
      <br />
      <div>

        <TreeView 
          className={classes.root}
          defaultCollapseIcon={<ExpandMoreIcon />}
          defaultExpanded={["root"]}
          defaultExpandIcon={<ChevronRightIcon />}
        >
          {getData(data).map(renderTree)}

        </TreeView>
        
      </div>


    </>

  );

}

Why doesn’t sawtooth allow me to declare exceptions?

When I want to declare an error in my handler, it causes an infinite loop in my processor which displays in the console :

{ InvalidTransaction: InvalidTransaction: Error when initializing the object!
    at VoteHandler.apply (/app/handler.js:79:19)
    at <anonymous> name: 'InvalidTransaction' }

“Error while initializing the object!” being my error message.
IMAGE : Error while initializing the object message error

I develop my processor in JS and I could see code examples in java, js, python, … They always do the same thing, that is to say simply declare the exception by importing it from the sawtooth-sdk package (sawtooth-sdk/processor/exceptions).
En java :
IMAGE : Java exceptions

LINK : Daml Transaction Java

En python :
IMAGE : Python exceptions

LINK : Sawtooth xo pyton

En js :
IMAGE : JS exceptions

LINK : Simple Wallet JS

I also tried to get the exceptions from the package @restroom-mw/sawtooth-sdk/ but the error is still there.
IMAGE : Import exceptions

Normally my error report should return an error code with my error message to my client.

How to apply transition when adding or removing dom?

How to apply transition when adding or removing dom?

If you look at SPA libraries such as Vue, there is a function to apply a transition when conditionally rendering a component.

I would like to implement it in pure JavaScript like this, but I am having a hard time because the related articles are based on jQuery.

How do I implement it? I know that transition is not applied even if I add DOM or change display:none to block.. I want to know how.

I don’t want keyframe animations

Why Electron Remote not working on Electron-Tabs?

I get these errors in my Electron App Project:

webview logged from Dashboard.html(146): Uncaught TypeError: window.require is not a function
webview logged from dashboard.js(7): Uncaught ReferenceError: require is not defined

and further errors in other files that also use the require function.

Edit: To be more explicit: These errors occur in the tab files that should be opened. Not in the main Window.

These errors occured, because i updated my electron version to the latest one (was on 10 or 11 before) – but needed new version for a new npm module.

I already tried to add nodeIntegration: true, contextIsolation: false, enableRemoteModule: true to webpreferences of main browserwindow and also to each tab in electron-tabs and it didnt work.

I will show here only the main files, because showing the whole project is too much for the question text…

Index.html for Electron:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>ExMeX Companion App</title>

  <link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css">
  <style>
    body {
      margin: 0;
    }
  </style>
</head>

<body>
  <div class="etabs-tabgroup">
    <div class="etabs-tabs"></div>
    <div class="etabs-buttons"></div>
  </div>
  <div class="etabs-views"></div>

  <script>
    // 1. Require the module
    const TabGroup = require("electron-tabs");
    // 2. Define the instance of the tab group (container)
    let tabGroup = new TabGroup({});
    let tabDashboard = tabGroup.addTab({
      title: "Dashboard",
      src: "pages/Dashboard.html",
      visible: true,
      active: true,
      webviewAttributes: {
        webSecurity: false,
        plugins: true,
        nodeIntegration: true,
        contextIsolation: false,
        enableRemoteModule: true
      }
    });
    let webviewDashboard = tabDashboard.webview;
    webviewDashboard.addEventListener('console-message', function(e) {
      var srcFile = e.sourceId.replace(/^.*[\/]/, '');
      if (srcFile == 'renderer_init.js') {
        console.log("Electron Security warning hidden from console.");
      } else {
        console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
      }
    });
    //implementation to get messages from other renderer windows
    const {
      remote,
      ipcRenderer
    } = require('electron');
    var ExmexGUITabOpened = 'false';
    var ExmexGUITabID = 0;
    ipcRenderer.on("cardClickedExmexGUI", function(event, arg) {
      if (ExmexGUITabOpened == 'false') {
        //create new tab
        console.log("Tab creation ExmexGUI");
        let tabExmexGUI = tabGroup.addTab({
          title: "Batch Orchestration",
          src: "pages/BatchOrchestration.html",
          visible: true,
          active: true,
          webviewAttributes: {
            webSecurity: false,
            plugins: true,
            nodeIntegration: true,
            contextIsolation: false,
            enableRemoteModule: true
          }
        });
        ExmexGUITabOpened = 'true';
        ExmexGUITabID = tabExmexGUI.id;
        tabExmexGUI.on("close", (tab) => {
          ExmexGUITabOpened = 'false';
          ExmexGUITabID = 0;
        });
        let webview2 = tabExmexGUI.webview;
        webview2.addEventListener('console-message', function(e) {
          var srcFile = e.sourceId.replace(/^.*[\/]/, '');
          if (srcFile == 'renderer_init.js') {
            console.log("Electron Security warning hidden from console.");
          } else {
            console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
          }
        });
      } else {
        let activeExmexTab = tabGroup.getTab(ExmexGUITabID);
        activeExmexTab.activate();
      }
    });
    var ExmexConfigurationTabOpened = 'false';
    var ExmexConfigurationTabID = 0;
    ipcRenderer.on("cardClickedExmexConfiguration", function(event, arg) {
      if (ExmexConfigurationTabOpened == 'false') {
        //create new tab
        console.log("Tab creation ExmexConfiguration");
        let tabExmexConfig = tabGroup.addTab({
          title: "ExMeX Configuration",
          src: "pages/ExmexConfiguration.html",
          visible: true,
          active: true,
          webviewAttributes: {
            webSecurity: false,
            plugins: true,
            nodeIntegration: true,
            contextIsolation: false,
            enableRemoteModule: true
          }
        });
        ExmexConfigurationTabOpened = 'true';
        ExmexConfigurationTabID = tabExmexConfig.id;
        tabExmexConfig.on("close", (tab) => {
          ExmexConfigurationTabOpened = 'false';
          ExmexConfigurationTabID = 0;
        });
        let webview3 = tabExmexConfig.webview;
        webview3.addEventListener('console-message', function(e) {
          var srcFile = e.sourceId.replace(/^.*[\/]/, '');
          if (srcFile == 'renderer_init.js') {
            console.log("Electron Security warning hidden from console.");
          } else {
            console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
          }
        });
      } else {
        let activeExmexConfigTab = tabGroup.getTab(ExmexConfigurationTabID);
        activeExmexConfigTab.activate();
      }
    });

    var ExmexSourceFilterTabOpened = 'false';
    var ExmexSourceFilterTabID = 0;
    ipcRenderer.on("cardClickedSourceFilter", function(event, arg) {
      if (ExmexSourceFilterTabOpened == 'false') {
        //create new tab
        console.log("Tab creation SourceFilter");
        let tabSourceFilter = tabGroup.addTab({
          title: "Filter Configuration",
          src: "pages/FilterConfiguration.html",
          visible: true,
          active: true,
          webviewAttributes: {
            webSecurity: false,
            plugins: true,
            nodeIntegration: true,
            contextIsolation: false,
            enableRemoteModule: true
          }
        });
        ExmexSourceFilterTabOpened = 'true';
        ExmexSourceFilterTabID = tabSourceFilter.id;
        tabSourceFilter.on("close", (tab) => {
          ExmexSourceFilterTabOpened = 'false';
          ExmexSourceFilterTabID = 0;
        });
        let webview4 = tabSourceFilter.webview;
        webview4.addEventListener('console-message', function(e) {
          var srcFile = e.sourceId.replace(/^.*[\/]/, '');
          if (srcFile == 'renderer_init.js') {
            console.log("Electron Security warning hidden from console.");
          } else {
            console.log('webview logged from ' + srcFile + '(' + e.line + '): ' + e.message);
          }
        });
      } else {
        let activeExmexSourceFilterTab = tabGroup.getTab(ExmexSourceFilterTabID);
        activeExmexSourceFilterTab.activate();
      }
    });
  </script>
</body>

</html>

Main.js for electron

/*jshint esversion: 8 */
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

const path = require('path');
const url = require('url');


global.mainWindow = null;

/* Configuration for server is stored in these variables, accessible for all windows or tabs */
/*Test Config*/


const appversion = '0.5.0 Beta';

/*Live Config*/
global.user = 'Not available';
global.password = 'Not Set';
global.server = 'Not available';
global.serverPort = 0;
global.database = 'Not available';
global.serverInfoText = 'Server connection is not configured.';
global.installedExmexVersion = 'ExMeX | Core ? | App ' + appversion + '';
global.trustedConnectionOption = 'no';

global.userDeploy = '';
global.passwordDeploy = '';
global.serverDeploy = '';
global.databaseDeploy = '';

function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1080,
    height: 1000,
    webPreferences: {
      webviewTag: true,
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true
    }
  });

  // Open the DevTools.
  //mainWindow.webContents.openDevTools();

  //remove the top menu from electron
  //mainWindow.removeMenu();

  // load the index.html of the app.
  mainWindow.loadFile('index.html');

}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow);



// Quit when all windows are closed.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});


const {
  ipcMain
} = require('electron'); // include the ipc module to communicate with render process ie to receive the message from render process

ipcMain.on("setUser", function(event, arg) {
  global.user = arg;
});
ipcMain.on("setPassword", function(event, arg) {
  global.password = arg;
});
ipcMain.on("setServer", function(event, arg) {
  global.server = arg;
});
ipcMain.on("setServerPort", function(event, arg) {
  global.serverPort = parseInt(arg, 10);
});
ipcMain.on("setDatabase", function(event, arg) {
  global.database = arg;
});


ipcMain.on("setServerInfoText", function(event, arg) {
  global.serverInfoText = arg;
});
ipcMain.on("setInstalledExmexVersion", function(event, arg) {
  global.installedExmexVersion = 'ExMeX | Core ' + arg + ' | App ' + appversion + '';
});
ipcMain.on("setTrustedConnection", function(event, arg) {
  global.trustedConnectionOption = arg;
});


const Store = require('electron-store');
Store.initRenderer();

Dashboard.html
This is the first Tab that should be opened, here the error occurs at the first time

<!doctype html>
<html lang="en" class="no-js">
<!-- <link rel="stylesheet" href="node_modules/electron-tabs/electron-tabs.css"> -->
<link rel="stylesheet" href="../css/dashboard.css">
<link rel="stylesheet" href="../css/sweetalert.css" />

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ExMeX Dashboard App</title>
</head>

<body>

  <div class="grid-container-dashboard">
    <header class="header">
      <div class="header_server_info">
        <p style="font-size:16px">Server</p>
        <p style="font-size:12px" id="serverInfoText">No server connection.</p>
      </div>
      <!-- Button to open the serverConfigPopupWindow -->
      <div class="header_server_connect">
        <button id="myBtn" class="header_button"> Connect</button>
      </div>
      <div id="serverConfigPopupWindow" class="modal">
        <div class="modal-content">
          <!-- <span class="close">&times;</span> -->
          <p style="font-size:20px ">Configure the server connection</p>
          <br><br>
          <div class="box">
            <p class="item1">Server Name: </p> <input type="text" id="serverInputField" class="item2" placeholder="Server to connect">
          </div>
          <div class="box">
            <p class="item1">Server Port: </p> <input type="text" id="serverPortInputField" class="item2" placeholder="Port to connect" value="1433">
          </div>
          <div class="box">
            <p class="item1">Database Name: </p> <input type="text" id="databaseInputField" class="item2" placeholder="Your ExMeX database name">
          </div>
          <div class="box">
            <p class="item1">Authentication Mode: </p>
            <select class="item2" id="authenticationModeOptionField" onclick="showOrHideUserPWFields()">
              <option>Windows Authentication</option>
              <option>SQL Server Authentication</option>
            </select>
          </div>
          <div class="box" id="userBox" style="visibility: hidden">
            <p class="item1">User: </p> <input type="text" id="userInputField" class="item2" placeholder="Your user login name">
          </div>
          <div class="box" id="passwordBox" style="visibility: hidden">
            <p class="item1">Password: </p> <input type="password" id="passwordInputField" class="item2" placeholder="Your password">
          </div>
          <br><br>
          <textarea type="text" id="OutputTestServerConnection" name="FilterSPOutput" disabled rows="4" cols="70" style="resize: none;">Output will be shown after saving first filter.
                </textarea>
          <button id="testServerConfig" class="blue_button_big" onclick="testServerConfigFunction()">Connect</button>
          <button id="cancelServerConfig" class="blue_button_big" onclick="cancelServerConfigFunction()">Cancel</button>
        </div>
      </div>
    </header>
    <aside class="sidenav">
      <img src="../img/TedamohLogoFull.png" style="  display: block; margin-left: auto; margin-right: auto; width: 90%; height:80px; object-fit: contain;" alt="Logo" id="spin">
      <ul class="sidenav_list">
        <p style="font-size:20px">Quick Links</p>
        <li class="sidenav_list-item" id="sidenav_Tedamoh" onclick="openTedamohHomepageInBrowser()">TEDAMOH</li>
        <li class="sidenav_list-item" id="sidenav_Helpdesk" onclick="openHelpdeskInBrowser()">Helpdesk</li>
        <li class="sidenav_list-item" id="sidenav_FAQ" onclick="openFAQInBrowser()">FAQ</li>
        <li class="sidenav_list-item" id="sidenav_Documentation" onclick="openDocumentationInBrowser()">Documentation</li>
      </ul>
    </aside>
    <main class="main">
      <div class="main-header">
        <div class="main-header_heading">
          <img src="../img/ExMeX_Banner_Dashboard.png" style="width: 100%; height: 100%; " alt="ExMeX Dashboard">
        </div>
        <!-- <div class="main-header_updates">A powerful interface component for the Tedamoh ExMeX Framework. <br />We call it ExMeX Companion App!</div> -->
      </div>
      <div class="main-overview-dashboard">
        <div class="overviewcard" id="cardIDExmexConfiguration">
          <div class="overviewcard_icon"><img src="../img/dashboard_config.png" style="width:70px;height:70px;" alt="ConfigIcon"></div>
          <div class="overviewcard_info">Exmex Configuration</div>
        </div>
        <div class="overviewcard" id="cardIDExmexGUI">
          <div class="overviewcard_icon"><img src="../img/dashboard_threearrows.png" style="width:70px;height:70px;" alt="ThreeArrowIcon"></div>
          <div class="overviewcard_info">Batch Orchestration</div>
        </div>
        <div class="overviewcard" id="cardIDFilterConfig">
          <div class="overviewcard_icon"><img src="../img/dashboard_filter.png" style="width:70px;height:70px;" alt="FilterIcon"></div>
          <div class="overviewcard_info">Filter Configuration</div>
        </div>

        <!-- future -->
        <div class="overviewcard" id="cardIDFuture4" style=" pointer-events: none;">
          <!-- <div class="overviewcard_icon">Icon</div>
            <div class="overviewcard_info">Future feature</div> -->
        </div>
        <div class="overviewcard" id="cardIDFuture5" style=" pointer-events: none;">
          <!-- <div class="overviewcard_icon">Icon</div>
            <div class="overviewcard_info">Future feature</div> -->
        </div>
        <div class="overviewcard" id="cardIDFuture6" style=" pointer-events: none;">
          <!-- <div class="overviewcard_icon">Icon</div>
            <div class="overviewcard_info">Future feature</div> -->
        </div>
        <div class="overviewcard" id="cardIDFuture7" style=" pointer-events: none;">
          <!-- <div class="overviewcard_icon">Icon</div>
            <div class="overviewcard_info">Future feature</div> -->
        </div>
        <div class="overviewcard" id="cardIDFuture8" style=" pointer-events: none;">
          <!-- <div class="overviewcard_icon">Icon</div>
            <div class="overviewcard_info">Future feature</div> -->
        </div>
        <div class="overviewcard" id="cardIDFuture9" style=" pointer-events: none;">
          <!-- <div class="overviewcard_icon">Icon</div> -->
          <!-- <div class="overviewcard_info">Future feature</div> -->
        </div>
        <!-- future end -->
      </div>
    </main>
    <footer class="footer">
      <div class="footer_copyright">&copy; 2019-2022 TEDAMOH GmbH</div>
      <div class="footer_signature" id="footer_signature">ExMeX | Core ? | App ?</div>
    </footer>
  </div>

</body>

<!-- Insert this line above script imports  -->

<script>
  if (typeof module === 'object') {
    window.module = module;
    module = undefined;
  }
</script>

<!-- normal script imports etc  -->

<script src="../js/sweetalert.min.downloaded.js"></script>

<script src="../js/swal-messages.js"></script>
<!-- scripts for opening the links on the dashboard  -->

<script>
  const {
    shell
  } = window.require('electron');

  function openDocumentationInBrowser() {
    shell.openExternal("https://tedamoh.com/de/helpdesk/doc-faq/exmex-framework-book");
  }

  function openFAQInBrowser() {
    shell.openExternal("https://tedamoh.com/de/helpdesk/doc-faq/frequently-asked-questions");
  }

  function openTedamohHomepageInBrowser() {
    shell.openExternal("https://tedamoh.com/de/");
  }

  function openHelpdeskInBrowser() {
    shell.openExternal("https://tedamoh.com/de/helpdesk/my-tickets");
  }
</script>

<script src="../js/SQLConnectAndQuery.js"></script>

<script src="../js/dashboard.js"></script>


<!-- Insert this line after script imports -->

<script>
  if (window.module) module = window.module;
  actualizeVersionInfo('footer_signature');
</script>



</html>

Dashboard.js
This is the javascript for the first tab that should be opened.

/*jshint esversion: 8 */

// include the ipc module to communicate with main process.
const {
  remote,
  ipcRenderer
} = require('electron');


const Store = require('electron-store');
const store = new Store();
//if store file was never initialized, put defaults in it
if (store.get('serverConfigStore') == undefined) {
  store.set('serverConfigStore', {
    serverName: "Server to connect",
    serverPort: 1433,
    databaseName: "Your ExMeX database name",
    authenticationMode: "Windows Authentication",
    user: ""
  });
}
// console.log(store.get('serverConfigStore').serverName);
// console.log(store.get('serverConfigStore').serverPort);
// console.log(store.get('serverConfigStore').databaseName);


let btnclick2 = document.getElementById('cardIDExmexGUI');
btnclick2.addEventListener('click', () => {
  var arg2 = "secondparam";

  //send the info to main process . we can pass any arguments as second param.
  //ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
  let mainWindowTest2 = remote.getGlobal('mainWindow');
  if (mainWindowTest2) mainWindowTest2.webContents.send("cardClickedExmexGUI", arg2);
});

let btnclick3 = document.getElementById('cardIDExmexConfiguration');
btnclick3.addEventListener('click', () => {
  var arg3 = "secondparam";

  //send the info to main process . we can pass any arguments as second param.
  //ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
  let mainWindowTest3 = remote.getGlobal('mainWindow');
  if (mainWindowTest3) mainWindowTest3.webContents.send("cardClickedExmexConfiguration", arg3);
});

let btnclick4 = document.getElementById('cardIDFilterConfig');
btnclick4.addEventListener('click', () => {
  var arg4 = "secondparam";

  //send the info to main process . we can pass any arguments as second param.
  //ipcRenderer.send("btnclick", arg); // ipcRender.send will pass the information to main process
  let mainWindowTest4 = remote.getGlobal('mainWindow');
  if (mainWindowTest4) mainWindowTest4.webContents.send("cardClickedSourceFilter", arg4);

});


// Get the modal
var modal = document.getElementById("serverConfigPopupWindow");
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on the button, open the modal
btn.onclick = function() {

  console.log(store.get('serverConfigStore').serverName);
  console.log(store.get('serverConfigStore').serverPort);
  console.log(store.get('serverConfigStore').databaseName);

  console.log('The connect button clicked and onclickfunction starts');
  modal.style.display = "block";
  document.getElementById('OutputTestServerConnection').innerHTML = '';

  document.getElementById('serverInputField').value = store.get('serverConfigStore').serverName;
  document.getElementById('serverPortInputField').value = store.get('serverConfigStore').serverPort;
  document.getElementById('databaseInputField').value = store.get('serverConfigStore').databaseName;
  document.getElementById('userInputField').value = store.get('serverConfigStore').user;

  //Make sure that authentication mode is one of the two possible values (instead a poweruser changes the config file manually...)
  if (store.get('serverConfigStore').authenticationMode == "Windows Authentication" || store.get('serverConfigStore').authenticationMode == "SQL Server Authentication") {
    document.getElementById('authenticationModeOptionField').value = store.get('serverConfigStore').authenticationMode;
  } else {
    document.getElementById('authenticationModeOptionField').value = "Windows Authentication";
  }

  showOrHideUserPWFields();

};
// When the user clicks on <span> (x), close the modal
// span.onclick = function() {
//  modal.style.display = "none";
// };
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
  if (event.target == modal) {
    modal.style.display = "none";
  }
};

function testServerConfigFunction() {
  console.log("The test server config button was clicked.");
  document.getElementById('OutputTestServerConnection').innerHTML = 'Wait for database response...';

  const sql = require('mssql/msnodesqlv8');

  var authOption = '' + document.getElementById('authenticationModeOptionField').value;
  var trustedAuthBool = false;
  if (authOption == 'Windows Authentication') {
    trustedAuthBool = true;
  }
  var config;

  //if trustedAuthBool is true, then WindowsAuthentification should be used (no User+PW)
  if (trustedAuthBool) {
    config = {
      user: 'Win User',
      password: 'Win User',
      server: '' + document.getElementById('serverInputField').value,
      database: '' + document.getElementById('databaseInputField').value,
      port: parseInt(document.getElementById('serverPortInputField').value, 10),
      options: {
        trustedConnection: "yes"
      }
    };
  }
  //else SQL Server Authentification is available (User+PW needed)
  else {
    config = {
      user: '' + document.getElementById('userInputField').value,
      password: '' + document.getElementById('passwordInputField').value,
      server: '' + document.getElementById('serverInputField').value,
      database: '' + document.getElementById('databaseInputField').value,
      port: parseInt(document.getElementById('serverPortInputField').value, 10)
    };
  }
  // async function invocation - connect to db and try a query
  queryDatabase(config, 'Select TOP(1) ReleaseVersion FROM [MetadataZone].[TEDAMOHExMeXRelease] Order by ReleaseInstalledDate DESC')
    .then(result => {
      var obj = JSON.parse(JSON.stringify(result.recordsets[0]));
      console.log('Connection succesful! Your last installed ExMeX Version is: ' + obj[0].ReleaseVersion);

      const {
        remote,
        ipcRenderer
      } = require('electron');
      ipcRenderer.send('setInstalledExmexVersion', '' + obj[0].ReleaseVersion);
      var s = obj[0].ReleaseVersion;
      if ((s.match(/2.12.*/)) || (s.match(/2.11.*/)) || (s.match(/2.10.*/)) || (s.match(/2.9.*/)) || (s.match(/2.8.*/)) || (s.match(/2.7.*/)) || (s.match(/2.6.*/)) || (s.match(/2.5.*/))) {
        swal('Old ExMeX Version installed', 'On the connected database the latest installed ExMeX Version is lower than 2.13.* ! The companion App will not work stable in all features! Please install the latest ExMeX release.', 'warning');
      }
      //document.getElementById('footer_signature').innerHTML = "ExMeX Version: " + obj[0].ReleaseVersion;
      actualizeVersionInfo('footer_signature');
    })
    .catch(err => {
      sql.close();
      console.log("A connection error happened");
      document.getElementById('OutputTestServerConnection').innerHTML = 'An error occurred while trying to query the database. The detailed error message is: ' + err.message;
    });

  // async function invocation - connect to db and try a query
  queryDatabase(config, 'SELECT SUSER_NAME() as LoggedInUser;')
    .then(result => {
      var obj = JSON.parse(JSON.stringify(result.recordsets[0]));
      console.log('Connection succesful! Your SysUsername is: ' + obj[0].LoggedInUser);
      const {
        remote,
        ipcRenderer
      } = require('electron');
      modal.style.display = "none";
      var sysusername = obj[0].LoggedInUser;
      saveServerConfigFunction(config, sysusername);
    })
    .catch(err => {
      sql.close();
      console.log("A connection error happened");
      document.getElementById('OutputTestServerConnection').innerHTML = 'An error occurred while trying to query the database. The detailed error message is: ' + err.message;
    });
}


//needed to delete some parts here for question length

I hope this is something where you can follow the code and give me an advise, on how to change my electron code to get the require function working on my tabs.

Best wishes!

Socket.io ERR_SSL_PROTOCOL_ERROR

Setup:

  • centOS 7
  • Apache (httpd package)
  • https (letsencrypt)
  • subdomain
  • socket.io running on port 3000, v4
  • connection via socket-admin ui
  • vps

I have checked this question, and it didn’t work for me, and I’ve tried all options: How to connect to socket io via ssl, serving files by apache2

Either my setup is wrong or my apache config. I’m not sure how to setup it well at this point. The SocketIO server should be running on https.

Running DEBUG=socket* node app.js will print out the url of the VPS as a hostname and serverId instead of the domain, which is… a part of the issue? I’m not sure.

app.js (I’ve tried changing https to http and removing the keys from the options of the server).

with https => net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH, with http => net::ERR_SSL_PROTOCOL_ERROR

import express from "express";
const app = express();

import fs from "fs"
import {createServer} from "https";
const httpServer = createServer(app);
import {Server} from "socket.io";
import {instrument} from "@socket.io/admin-ui"

const io = new Server(httpServer, {
  key: fs.readFileSync('/etc/letsencrypt/live/mydomain/privkey.pem'),
  cert: fs.readFileSync('/etc/letsencrypt/live/mydomain/cert.pem'),
  ca: fs.readFileSync('/etc/letsencrypt/live/mydomain/chain.pem'),
  allowRequest: (request, callback) => {
    //let ipAddress = request.connection.remoteAddress
    //let origin = request.headers.origin
    //let userAgent = request.headers['user-agent']

    callback(null, true);
  },
  cors: {
    origin: ["https://admin.socket.io"],
    credentials: true,
  },
  path: "/websocket/socket",
});

httpServer.listen(3000, () => {
  API.initConnection()
})

My Apache conf

<VirtualHost *:80>
    DocumentRoot /var/www/mydomain

    ServerName mydomain

    <Directory "/var/www/mydomain">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    LogLevel debug  ssl:info
        SSLEngine on

        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateFile /etc/letsencrypt/live/mydomain/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/mydomain/privkey.pem

        RewriteEngine On
        #RewriteCond %{SERVER_NAME} =mydomain [OR]
        #RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
        RewriteCond %{REQUEST_URI}  ^/websocket/socket          [NC]
        RewriteCond %{QUERY_STRING} transport=websocket    [NC]
        RewriteCond %{HTTP:Upgrade} websocket              [NC]
        RewriteCond %{HTTP:Connection} upgrade             [NC]
        RewriteRule /(.*)           wss://localhost:3000/$1 [P,L]

        #ProxyPass "/websocket/socket" "http://localhost:3000/websocket/socket"
        #ProxyPassReverse "/websocket/socket  " "http://localhost:3000/websocket/socket"

</VirtualHost>

Your help is much appreciated.

How to prevent click happen on child element?

I have a problem with the click event is being received on the child instead of the parent element. At the moment click event is happening on span element instead of link element.

I’ve searched a few similar SO questions and found out about EventBubling and how to prevent it, but unfortunately, it didn’t work for me.

HTML

        <div class="container">
            <div class="list">
                <a href="#" data="data-1">
                    <span>Text 1</span>
                </a>
            </div>
            <div class="list">
                <a href="#" data="data-2">
                    <span>Text 2</span>
                </a>
            </div>
            <div class="list">
                <a href="#" data="data-3">
                    <span>Text 3</span>
                </a>
            </div>
        </div>

JS

const list = document.querySelectorAll('.list > a');

Array.from(list).forEach((el) =>
    el.addEventListener('click', (e) => {
        //e.preventDefault();
        e.stopPropagation();
        const dataAttr = e.target.getAttribute('data');
        console.log(dataAttr);
    })
);

How to call multiple ID’s in one function?

I’ve found this function that allows me to do what I want, but since I have many inputs, and I don’t want to use this JS on all of them, I would like to call it only on couple of inputs. Can I do that by ID or something?

( I know that this sentence isn’t one of the best, but I’m in a hurry, sorry)

var pastValue, pastSelectionStart, pastSelectionEnd;

$("input").on("keydown", function() {
    pastValue          = this.value;
    pastSelectionStart = this.selectionStart;
    pastSelectionEnd   = this.selectionEnd;
}).on("input propertychange", function() {
    var regex = /^(100|(d|[1-9]d)(.d{0,2})?)$/;
                    
    if (this.value.length > 0 && !regex.test(this.value)) {
        this.value          = pastValue;
        this.selectionStart = pastSelectionStart;
        this.selectionEnd   = pastSelectionEnd;
    }
});

Update a nested JavaScript object with default values

I would like to add some data to a nested javascript object, however I do not know how much of the object tree already exists. I want to add the structure if it is not there, but also keep the same information if it is there tagged with some other default data.

Ideally I don’t want to use a third party library for this.

In my example I have the following object structure, there will be an endless combination of these available, so it needs to generate the structure for me if it does not already exist.

{
  level1: {
    level2: {
      level3: {
        property1: 'test'
      }
    }
  }
}

I want to be able give this some values, create the structure – if the structure is there, add some default values and if not create the structure with defaults.

I have the following, which does the job, but it looks very messy to me, I was wondering if there was a better way to achieve this?

const updateNestedObject = (obj, level1, level2, level3, defaultProps) => {
  if (obj && obj[level1] && obj[level1][level2] && obj[level1][level2][level3]) {
    obj[level1][level2][level3] = { ...defaultProps, ...obj[level1][level2][level3] }
  } else if (obj && obj[level1] && obj[level1][level2] && !obj[level1][level2][level3]) {
    obj[level1][level2][level3] = defaultProps
  } else if (obj && obj[level1] && !obj[level1][level2]) { 
    obj[level1][level2] = { [level3]: defaultProps }
  } else if (obj && !obj[level1]) { 
    obj[level1] = { [level2]: { [level3]: defaultProps } }
  } else {
    obj = { [level1]: { [level2]: { [level3]: defaultProps } } }
  }
  return obj
}

Javascript change style of all buttons with a certain class doesn’t work

I have multiple buttons, some with the same classname. When one button is pushed, I want all the other buttons with the same classname to change with it. I made a loop to calculate the length of the queryselector and make sure it applies is to all buttons, but it doesn’t work.

 let buttons = document.querySelectorAll('.v' + tgt.value);
// when console.log(buttons) the right buttons are shown

            for(let i = 0; i < buttons.length; i++) {
                let btn = buttons[i];
                if (quizUrl.indexOf(tgt.value) === -1) {
                    quizUrl.push(tgt.value);
                    btn.style.backgroundColor = "white";
                    btn.style.color = "black";
                    console.log(btn)
                    // Check if a button is clicked again. If clicked again changes color back and deletes value in the url array
                } else {
                    quizUrl.splice(quizUrl.indexOf(tgt.value), 1);
                    btn.style.backgroundColor = "transparent";
                    btn.style.color = "white";
                }
            }

But with this only one button changes and it won’t even change back.

How To Implement Custom Scroll Buttons In Bootstrap Modal Body

I want to implement a custom scroll up & down button outside the Bootstrap 4 modal but I have no idea how to achieve this functionality. I has hidden the scroll bar using (::-webkit-scrollbar {display:none;}) property to enhance the modal body design.

On PC we can scroll using the mouse but some people may get confused so that’s why I want to add two custom up & down buttons. (Check out the image I attached)

Is it possible to achieve the functionality using javascript?

[![My project website with buttons

.modal-body::-webkit-scrollbar {
  display: none;
}
.modal-body P {
  color: red;
}

.modal.left_modal .modal-dialog {
  position: fixed;
  margin: auto;
  width: 450px;
  max-width: 85%;
  height: 100%;
  -webkit-transform: translate3d(0%, 0, 0);
      -ms-transform: translate3d(0%, 0, 0);
       -o-transform: translate3d(0%, 0, 0);
          transform: translate3d(0%, 0, 0);
}

.modal.left_modal .modal-content {
  height: 100vh !important;
}

.modal.left_modal.fade .modal-dialog{
  left: -50%;
  -webkit-transition: opacity 0.3s linear, left 0.3s ease-out;
  -moz-transition: opacity 0.3s linear, left 0.3s ease-out;
  -o-transition: opacity 0.3s linear, left 0.3s ease-out;
  transition: opacity 0.3s linear, left 0.3s ease-out;
}

.modal.left_modal.fade.show .modal-dialog{
  left: 0;
  box-shadow: 0px 0px 19px rgba(0,0,0,.5);
}

.modal_outer .modal-body {
    overflow-y: auto;
    overflow-x: hidden;
    height: 100vh;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
    
    
    
<button class="btn  btn-primary  mt-3 float-right" id="modal_view_left" data-toggle="modal"  data-target="#get_quote_modal">Open modal</button>


<div class="modal modal_outer left_modal fade" id="get_quote_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2" >
  <div class="modal-dialog" role="document">
      <div class="modal-content">

        <div class="modal-header">
          <h2 class="modal-title">LEFT MODAL</h2>
        </div>
        
        <div class="modal-body">
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni numquam accusantium dolore ipsum! Aut distinctio maxime obcaecati, sapiente nisi laudantium dignissimos optio, ea ex quas laboriosam ab officia odit, sequi.</p><br><br>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni numquam accusantium dolore ipsum! Aut distinctio maxime obcaecati, sapiente nisi laudantium dignissimos optio, ea ex quas laboriosam ab officia odit, sequi.</p><br><br>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni numquam accusantium dolore ipsum! Aut distinctio maxime obcaecati, sapiente nisi laudantium dignissimos optio, ea ex quas laboriosam ab officia odit, sequi.</p><br><br>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni numquam accusantium dolore ipsum! Aut distinctio maxime obcaecati, sapiente nisi laudantium dignissimos optio, ea ex quas laboriosam ab officia odit, sequi.</p><br><br>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni numquam accusantium dolore ipsum! Aut distinctio maxime obcaecati, sapiente nisi laudantium dignissimos optio, ea ex quas laboriosam ab officia odit, sequi.</p>
        </div>

        <div class="modal-footer">
          <button type="reset" class="btn btn-primary ml-auto" data-dismiss="modal">cancel</button>
        </div>

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

]1]1

enter image description here

There is a problem with javascript compiling and running that confuses me

function test1(a = 1) {
  console.log(a);
  var a = 2;
  function a() {}
}
function test2(a = 1) {
  console.log(a);
  function a() {}
}
test1(); // console log  1
test2(); // console log  [Function: a]

According to the understanding of variable hoisting, the variable a in the first function has the same name as the function a, and finally the function a covers the variable a, and there is only the function a in the second function. The output result should be the same.So Why is the function default parameter valid in the test1 function but not in the test2 function?

Sync horizontal scroll between two Tabulator tables (Tabulator 5)

Since the release of Tabulator 5.0 the events and callbacks have been changed.
For the previous releases there was a solution to sync scrolling between two Tabulator tables (https://github.com/olifolkerd/tabulator/issues/203)

My problem is now that these callbacks/events do not exist anymore in Tabulator 5, but I would like to have a similar solution.

I do have two Tabulator 5 tables and do want to sync horizontal scrolling. When I scroll one table the other one should do the same scroll. Both tables do have the same column definition.

Does anyone know how I could solve this in Tabulator 5?

TypeError: undefined is not an object (evaluating ‘_$$_REQUIRE(_dependencyMap[11]

I’m currently building a ecommerce app
while I was running the app suddenly i encounter this error,
I have tried alot of things but nothing seems to work
this is my first ecommerce app so i might have done something wrong, I just want to know what it is.

import * as React from 'react';
import {ThemeProvider} from '@shopify/restyle';
import {NavigationContainer} from '@react-navigation/native';
import {enableScreens} from 'react-native-screens';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {Container} from 'native-base';

/* Utils */
import theme from './src/components/theme';
import {createStackNavigator} from '@react-navigation/stack';

/* Routes */
import {ProductNavigator} from './src/components/Products';
import {AuthNavigator} from './src/components/Authentication';

/* Import Redux */
import {useDispatch} from 'react-redux';
import {useEffect} from 'react';
import {loadUser} from './src/store/actions/authActions';

enableScreens();

type SharedStackParams = {
  Auth: undefined;
  Product: undefined;
};

const AppStack = createStackNavigator<SharedStackParams>();

export default function App() {
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(loadUser());
  }, []);

  return (
    <NavigationContainer>
      <ThemeProvider {...{theme}}>
        <Container style={{flex: 1}}>
          <SafeAreaProvider>
            <AppStack.Navigator headerMode="none" initialRouteName="Auth">
              <AppStack.Screen name="Product" component={ProductNavigator} />
              <AppStack.Screen name="Auth" component={AuthNavigator} />
            </AppStack.Navigator>
          </SafeAreaProvider>
        </Container>
      </ThemeProvider>
    </NavigationContainer>
  );
}