Get global module variable in vanilla javascript

So i have below module created according to an example i found.

I initialize it with

equipment_booking = new equipment({
    equipment: '#equipment_order',
    type: '#equipment_type_order',
    validation: '#equipment_validation_order',
    submit: "#submit_booking"
});

What I want to do is access the typeVar from outside the module. I found out that I need to use the this. in front of it. And indeed I could access it. However I can’t seem to access it inside the module functions. How would I accomplish this? This is a part of the module I have written. I have tried different ways in the checkInput function. Any help or suggestions are realy appriciated.

var equipment = (function() {
    function equipment(options) {
        // Set the standard options
        var o = {
            equipment: null,
            type: null,
            validation: null,
            submit: null
        };

        // Get some other needed variables
        number = "";
        this.typeVar = 0;
        var error = [{
            code: 0,
            msg: ""
        }];

        // Then we can override the given options to the standard options
        for (var k in options) {
            if (options.hasOwnProperty(k)) {
                o[k] = document.querySelector(options[k]);
            }
        }

        // Add the eventlisteners
        o.equipment.addEventListener('keydown', checkInput);
        o.equipment.addEventListener('blur', validateInput);
        o.type.addEventListener('change', validateInput);

        function checkInput(e) {
            console.log("CheckInput called"); // This console.log is called
            console.log(typeVar);             // Error: typeVar is not defined
            console.log(this.typeVar);        // Undefined
            e.preventDefault();               // The e works
        }

        function validateInput() {
            // Validating input
        }
    }
    return equipment;
})();

Expand only one table row at a time Ant Design React

I’m unable to achieve that, I have attached the code below please let me know what’s wrong here?

before adding expandedRowKeys and onExpand it was expanding all tables rows but after implementing it, it doesn’t even open one row

<Table
    rowkey="id"
    size="small"
    columns={groupsPackageColumns}
    dataSource={roomPackages}
    className="taglist-table"
    expandable={{
        expandedRowRender: (record) => (
            <Table
                rowKey="id"
                columns={nestedTagsColumn}
                dataSource={record.tags}
                className="ant-table-container"
            />
        ),                    
        expandedRowKeys: activeExpRow,
        onExpand: (expanded, record) => {
            const keys = [];
            if (expanded) {
               keys.push(record.id); 
            }
            setActiveExpRow(keys);
        },
    }}
                        
/>

Safari: requestFullscreen is not a function

I have a function that sets a dom node into fullscreen in a React app. It works fine for Chrome, Firefox and Edge. But in Safari, I have the error:

ref.current.requestFullscreen is not a function

The code is (the error happens in openFullscreen()):

import { useCallback, useLayoutEffect, useState } from "react";

function isLeaving() {
  return (
    !document["fullscreenElement"] &&
    !document["webkitFullscreenElement"] &&
    !document["mozFullscreenElement"] &&
    !document["msFullscreenElement"]
  );
}

export default function useFullscreen(
  ref: React.MutableRefObject<HTMLDivElement>
): {
  isFullscreen: boolean;
  openFullscreen: () => void;
  closeFullscreen: () => void;
} {
  const [fullscreen, setFullscreen] = useState(false);
  const [isFullscreenReady, setIsFullscreenReady] = useState(false);

  useLayoutEffect(() => {
    document.onfullscreenchange = () => {
      if (isLeaving()) {
        setFullscreen(false);
        setIsFullscreenReady(false);
      }
    };
    return () => (document.onfullscreenchange = undefined);
  }, [fullscreen, isFullscreenReady, ref]);

  const openFullscreen = useCallback(() => {
    if (ref.current) {
      ref.current
        .requestFullscreen()
        .then(() => setIsFullscreenReady(true))
        .catch(() => setIsFullscreenReady(false));
    }
  }, [ref]);

  const closeFullscreen = useCallback(() => {
    document.exitFullscreen();
    setFullscreen(false);
    setIsFullscreenReady(false);
  }, []);

  return {
    isFullscreen: isFullscreenReady,
    openFullscreen,
    closeFullscreen,
  };
}

How to fix that so I can have fullscreen in every browser?

ps: it doesn’t work in Opera too, but that’s fine with me.

How to set up a PHP Curl POST request which can trigger via a JavaScript onclick event?

I want to track the button click event which is Submit button in javascript to curl PHP side and the url in php file will send the event that I trigger and stored into the database.

Below are 2 files that I make, the 1st part is ajax, and then 2nd part is PHP.

May anyone help me please? Thank you.

(function($){
$("_form_44__submit").on('click', function () {
    // fire the AJAX request on button click
    $.ajax({
       type: "POST",
       url: 'curl.php',
       dataType: 'json',
       headers: {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",},
       data: {actid: "actid",
    key: "key",
    event: "Click_Submit_Button_Event",
    visit: ["email"]
 },
    })
    .done(function (response) {
        console.log(response);
       // if you want to do something on success
    })
    .fail(function (xhr, status, error) {
        console.log('error');
       // if you want to do something on error
    });
  });
})
<?php


$actid = $_POST['actid'];
$key =  $_POST['key'];
$event =  $_POST['event'];
$visit =  $_POST['visit'];

$url = "https://trackcmp.net/event";

    $curl = curl_init(); //open connection /
    // changes the cURL session behavior with options POST
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    //curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_POSTFIELDS, array(
        'actid' => $actid,
        'key' => $key,
        'event' => $event,
        'visit' => $visit,
));
    //execute
    $result = curl_exec($curl); //handle $curl_init
    if ($result !== false) {
        $result = json_decode($result);
        if ($result->success) {
            echo 'Success! ';
        } else {
            echo 'Error! ';
        }

        echo $result->message;
    } else {
        echo 'cURL failed to run: ', curl_error($curl);
    }


?>

Liquid/Shopify – How do I check if a div is out of view?

I’m trying to make a sticky add-to-cart button for my Shopify store without the use of any apps. I have done this so far by duplicating the current add-to-cart button and tweaking the CSS for the second button so it’s displayed at the bottom of my product page on top of all other elements. The only problem remaining is that both buttons are showing at the same time.

Right now I want to write an if-statement to handle which of the 2 buttons to show on the page based on if the default add-to-cart button is in or out of view for the user (so if the user has scrolled down past the button). Preferably I’d like a boolean to check weather the first button is in view so I can write an if/else statement to decide which button should be loaded but I’m not finding any solution for Liquid/Shopify coding.

Any tips on achieving this? I’m okay using JavaScript but having trouble implementing it with the Liquid code for my product page.

I’m using the Prestige theme.

Getting a different output in javascript for a proxy website

Here is my code it is in javascript lang:

 '<script type="text/javascript">
$(document).ready(function(){
  $('#countryz').bind('change', function(){
    var trycountry = $('#countryz').val();

      if(trycountry=="ftl" || trycountry=="mesh1" || trycountry=="mesh2" || trycountry=="courir" 
 || trycountry=="nikena" || trycountry=="nikena" || trycountry=="nikeas"){

        if(trycountry=="us" || trycountry=="mx" || trycountry=="cu" || trycountry=="pr" || 
 trycountry=="gt" || trycountry=="ni" || trycountry=="nikena") {
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }
      
        else if(trycountry=="sg" || trycountry=="id" || trycountry=="my" || trycountry=="ph" || 
 trycountry=="vn" || trycountry=="th" || trycountry=="nikeas"){
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                   $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }

      
        else if(trycountry=="au" || trycountry=="nz" || trycountry=="pg"){
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }
      
        else{
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }
      }
       else{
      $(document).ready(function(){
      $('#citied').bind('change', function(){
        var elements = $('div.citycont');
        var trycity = $(this).val();

        if(trycountry=="us" || trycountry=="mx" || trycountry=="cu" || trycountry=="pr" || 
 trycountry=="gt" || trycountry=="ni" || trycountry=="nikena") {
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }
      
        else if(trycountry=="sg" || trycountry=="id" || trycountry=="my" || trycountry=="ph" || 
 trycountry=="vn" || trycountry=="th" || trycountry=="nikeas"){
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }

        else if(trycountry=="au" || trycountry=="nz" || trycountry=="pg"){
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
          });
        }
      
        else{
          $(document).ready(function(){
          $('#hst').bind('change', function(){
          var iptype = $('#hst').val();
            if(iptype=="dns"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }else if(iptype=="iphst"){
              var setcountry = "";
                $(document).ready(function(){
                  $('#tpz').bind('change', function(){
                  var httptype = $('#tpz').val();
                  if(httptype=="http|https"){
                    var texts = "";
                    $('#foruse').val(trycity);
                  }else if(httptype=="socks5"){
                    var texts = "12325";
                    $('#foruse').val(trycity);
                  }
                  }).trigger('change');
                });
            }
          }).trigger('change');
        });
        }
      }).trigger('change');
      });
      }

  }).trigger('change');
});

Above is my code, what’s weird is I am getting a diff output, I should be getting constantine but durres is coming out:

Am I missing anything? I’m really having some difficulties finishing this proxy reseller website.
Different output

Stackoverflow says it’s mostly code, I’ll be typing this so it doesnt detect it’s all codes………………………………………………………………………………………………………………………………………………………………

React.FC call with multiple parameter

I am trying to call the function with three parameter but its not working.

Here is the React.FC:

const FormStructure: React.FC<{ record: ModelClass, question: Array<ModelClass>, dropdownItems: Array<ModelTypeClass> }> = ({
    record, question, dropdownItems,
}) => {
...
}

and this is the function call:

return (
   <Modal
      visible={this.state.modalVisible}
      onCancel={() => this.setState({ modalVisible: false })}
   >
      {FormStructure(record, this.state.question, this.state.dropdownItems)}
   </Modal>
)

Following Error Message:
“Expected 1-2 arguments, but got 3”

How to inherit slots with svelte components?

There is a component <Bar> that inherits from a component <Foo>.

The <Foo> component defines a slot named content with a fallback content. The <Bar> component also defines a slot named content with a different fallback content.

<!-- Foo.svelte -->
<slot name="content">
  foo fallback
</slot> 

<!-- Bar.svelte -->
<script>import Foo from './Foo.svelte'</script>
<Foo>
    <span slot="content">
        bar fallback
    </span>
</Foo>

The <Bar> component displays the fallback when called with <Foo/> but it does not display the custom content when called with <Bar><span slot="content">bar custom</span></Bar>.

Can you tell me what I am doing wrong?

<Foo/>
<!-- prints 'foo fallback': OK -->

<Foo>
    <span slot="content">foo custom</span>
</Foo>
<!-- prints 'foo custom': OK -->

<Bar/>
<!-- prints 'bar fallback': OK -->

<Bar>
    <span slot="content">bar custom</span>
</Bar>
<!-- prints 'bar fallback': KO - I would have expected 'bar custom' -->

The fiddle: https://svelte.dev/repl/5c525651eb8b4f60a6a696c1bd19f723

Set an element attribute multiple times within a javascript function

im using Vanilla Javascript, and my problem is that i need to render a progress bar in a certain time, but JS only render the final step…

'use strict'
var button = document.getElementById('button');

function sleep(milliseconds) {
    const date = Date.now();
    let currentDate = null;
    do {
      currentDate = Date.now();
    } while (currentDate - date < milliseconds);
  }

function initProgressBar()
{
    let progressBar = document.querySelector('#progress-bar'),
    count = 25,
    total = 64;
    progressBar.style = `width:${count}%;`;

    while (total > 0) {
        sleep(300);
        total = Math.trunc(total/2);
        count = count + total;
        progressBar.style = `width:${count}%;`;
        
    }
}

button.onclick = initProgressBar;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #progress-container {
            height: 4px;
            width: 100%;
        }

        #progress-bar {
            width: 0%;
            height: 100%;
            background-color: blueviolet;
        }


    </style>
</head>
<body>
    <div id="progress-container">
        <div id="progress-bar"></div>
    </div>
    <button id=button>press</button>
    <script src='prueba.js'></script>
</body>
</html>

The idea is that when the user clicks the button, the progress bar automatically jumps to 25% and then progressively goes to ~ 88% (after that I’ll send it to 100% using another function)

The problem is that Javascript only update the element on his last value (88%).

So, is there any way to set the attribute of an element multiple times inside a javasciript function?

Adding input from textarea/form to a list with React

I’m studying to become a Front-End Developer and now react is on the menu. I need to create a react-app that has a grocery list and a shopping cart. I can add Items to the grocery list and eventually I can click on them to transfer them to the shopping cart.

The whole react tree like experience is quitte new and overwhelming. But my question is, I need to add the data that I get from a input field to a UL/LI.

I have a GroceryList component, a InputField component, a List component and a ListItem component.

The code I have now for the InputField works kind of but it displays the information directly on the screen and not on submit.

The code is:

import React, { useState } from "react";
import { ReactDOM } from "react";


function InputField(props) {



    return (

        < div >
            <form>
                <input type="text" onChange={(event) => props.setGroceryName(event.target.value)} />
                <button type="submit" >Add Groceries</button>
            </form>
        </div >
    )
    
}


export default InputField

I defined the setGroceryName in the GroceryList component. Can someone help me how I can change it so it makes an list in the List component. I’m really stuck and can’t seem to find some good help.. Or what do I need to do and where do I need to put it so it takes a ListItem and adds that to the List component.

Thanks in advance. If you guys need more info, let me know.

Regarding Highchart

I want to apply different colors for different columns ,percent values should be displayed on top of respective columns and Help me how can I increase the each column width of Bar chart in this code…Please help me out with this.

const color = {
Online: ‘#800000’,
Chip_PIN: ‘#DB7093’,
Contactless: ‘#FF7F50′,
Transfer:’#008080′,
Cash_out:’#006400’
}

$(document).ready(function() {
var chart = {
type: ‘column’,
showAxes : true,
marginRight : 0,
marginLeft : 10,
};

var legend={ enabled:false };
var title = {
text: ”
};
var subtitle = {
text: ”
};

var xAxis = {
categories: [‘Online’, ‘Chip_PIN’, ‘Contactless’, ‘Transfer’, ‘Cash_out’],
min: 0,
max: 4,
text:null,
visible:true,
linecolor:’transparent’,
labels: {
align:’high’,
formatter () {
return `${this.value}`
}
}

};
var yAxis = {
min: 0,
max:150,
gridLineColor: ‘transparent’,
lineColor: ‘Gray’,
lineWidth: 1,
minorGridLineWidth: 0,
minorTickInterval: ‘auto’,
minorTickColor: ‘Gray’,
minorTickWidth: 1,
minorTickLength:5,
tickInterval:50,
opposite:false,
align:’left’,

//tickAmount:5,

stackLabels: {
style: {
color: ”
},
enabled: false,
verticalAlign: ‘top’,
},

labels: {
enabled: true,
overflow: ‘justify’
},

title: {
text: ”
}
};

var colors =[
‘#800000’,
‘#DB7093’,
‘#FF7F50’,
‘#008080’,
‘#006400’

]
var tooltip = {
pointFormat: ‘{series.name}: {point.y} ({point.percentage:.0f}%)

};
var plotOptions = {
column: {
pointPadding:0,
minPointLength: 50,

stacking: ‘normal’,
dataLabels: {
format: ‘{point.y:.1f}%’,
enabled: true,
style: {
fontWeight: ‘bold’,
fontSize: ’20px’,
color: ‘Yellow’,
textOutline: ‘1px contrast’
}
},

series: {
colorByPoint: true,
borderWidth: 0

}
}
};
var credits = {
enabled: false
};
var series= [
{
name:’HSBC’,
data: [49.9,50,80,35,70],

}

];

var json = {};
json.chart = chart;
json.title = title;
json.subtitle = subtitle;
json.tooltip = tooltip;
json.xAxis = xAxis;
json.legend=legend;
json.yAxis = yAxis;
json.colors=colors;
json.series = series;
json.plotOptions = plotOptions;
json.credits = credits;
$(‘#container’).highcharts(json);

});

How to convert vanilla to react hook toggle menu

I am trying to get a code from vanilla js with bootstrap and use react hooks on yet. I watched some videos on youtube about useState and useReff, however, these concepts still are a bit confusing when I try to apply them in my projects.

I am trying to convert a toggle function in vanilla to react hooks. Can you please guide me on how to start thinking to change this code?

Thanks in advance.

Vanilla:

window.addEventListener("DOMContentLoaded", (event) => {
  // Toggle the side navigation
  const sidebarToggle = document.body.querySelector("#sidebarToggle");

  if (sidebarToggle) {
    if (localStorage.getItem('sb|sidebar-toggle') === 'true') {
        document.body.classList.toggle('sb-sidenav-toggled');
    }
    sidebarToggle.addEventListener("click", (event) => {
      event.preventDefault();
      document.body.classList.toggle("sb-sidenav-toggled");
      localStorage.setItem(
        "sb|sidebar-toggle",
        document.body.classList.contains("sb-sidenav-toggled")
      );
    });
  }
});

React:

const [inactive, setInactive] = useState(false);

  useEffect(() => {

  })


useDispatch() on onChange prop of input field in React form

Let’s say there are 10 input field data. They are required to persist across 3 pages such as form page, preview page and confirmation page.

So I guess the data would definitely to sit in Redux as global data for the 3 pages.
Normally, I would create 10 useState hooks in the form page to store the 10 data/states and assign setState to every onChange prop. Once the submit button is clicked, they will be dispatched as payload and got updated into redux store.

However, one day I came up with an idea why don’t I just assign dispatch to every onChange prop since the 10 data will eventually sit in redux store. With this, I do not need to create 10 useState hooks and feel it is “redundant” to store same data two times ( in both useState hook and redux store).

But this yields another issue, which is frequent call to redux to retrieve newest data using useSelector() and dispatch new action using useDispatch(). But frequent call to redux store should not be a big deal since it is still synchronous right? I got confused and feeling unsure at this point.

Hence, I would like to seek advices from React experts on this…Does that mean in my case, using useDispatch only (not both useState and useDispatch) is better?

//(A) : useState + useDispatch
 //create 10 useState hooks to store data/states. 
 //They are compiled and dispatched as payload to redux on button click

<input type="text" value={value1} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value2} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value3} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value4} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value5} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value6} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value7} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value8} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value9} onChange={()=>setValue(e.target.value)} />
<input type="text" value={value10} onChange={()=>setValue(e.target.value)} />
<button onClick={handleSubmit}>Submit</button>

//(B) useDispatch only
 //valueSelector1 means the value is taken from the useSelector()

<input type="text" value={valueSelector1} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector2} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector3} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector4} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector5} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector6} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector7} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector8} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector9} onChange={()=>dispatch(setValue(e.target.value))} />
<input type="text" value={valueSelector10} onChange={()=>dispatch(setValue(e.target.value))} />
<button onClick={handleSubmit}>Submit</button>

Is there a better way to use Jinja2 items in inline JavaScript?

I’m currently tasked with writing a website using Flask and therefore I’m using Jinja2 templating in my HTML.

I have this inline JavaScript here that would calculate a booking cost and update labels from a previous booking with information pulled from a MySQL database.

<script>
...
{% for booking in future_bookings %}
let futureCost{{ booking.id }} = calculateBookingCosts(
    '{{ booking.price_pn }}',
    '{{ booking.price_pn }}',
    '{{ booking.start_date }}',
    '{{ booking.end_date }}',
    '{{ booking.room_type }}',
    '{{ booking.transaction_date }}'
)
$("#futureBooking{{ booking.id }}Price").text('Total paid: £' + futureCost{{ booking.id }}.totalCost)
{% endfor %}
{% for booking in exp_bookings %}
let expCost{{ booking.id }} = calculateBookingCosts(
    '{{ booking.price_pn }}',
    '{{ booking.price_pn }}',
    '{{ booking.start_date }}',
    '{{ booking.end_date }}',
    '{{ booking.room_type }}',
    '{{ booking.transaction_date }}'
)
$("#expBooking{{ booking.id }}Price").text('Total paid: £' + expCost{{ booking.id }}.totalCost)
{% endfor %}
...
</script>

Now, this code does indeed work, and it feels wrong to do it like this, but I can’t think of a cleaner way to do what I’m trying to do. Maybe there would be a way to pass these Jinja objects in a way that JavaScript can read but I haven’t been able to find a way to do this. If more information is needed on how the code works, I can provide.
Thanks!