How to open JQuery modal dialog popup with WKWebView

I have a WKWebview to open the client’s website. In the website, there is a “Cancel” button that will open a popup for confirmation. In Safari or other web clients, it works and it will open a popup. But in my iOS app, it didn’t. When I ask the web FE developer, he said that he is using JQuery modal dialog for the popup. I tried using this, but doesn’t work:

class WebsiteViewController: UIViewController {
    var urlRequest: URLRequest?

    @IBOutlet weak private var ibWebView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        ibWebView.configuration.websiteDataStore = .nonPersistent()
        ibWebView.configuration.preferences.javaScriptEnabled = true
        ibWebView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true
        ibWebView.navigationDelegate = self
        ibWebView.uiDelegate = self

        loadInternetBanking()

     }

    private func loadInternetBanking() {
        guard let urlRequest = urlRequest else {
            return
        }
        ibWebView.load(urlRequest)
    }
}

extension InternetBankingViewController: WKUIDelegate {
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        print(":::::::: createWebViewWith!!!!") <== this doesn't get called
        let popupWebView = WKWebView(frame: view.bounds, configuration: configuration)
        popupWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        return popupWebView
    }
    
    func webViewDidClose(_ webView: WKWebView) {
        
    }
}

The createWebViewWith callback is not being called. Can you help me with this?

Thank you.

light theme to dark theme

Im trying to use a icon to change the theme of my layout from a light theme to a dark theme using themeContext, useState but its not working for some reason. I checked it earlier by going to my scss and making the background red and it worked, but when I clicked the icon the background would’t change and I used console log on the function to check if it was doing anything but nothing came.

My layout component

import React, {createContext, useContext, useState} from 'react'
import { Outlet } from 'react-router-dom';
import { Sidebar } from '../Sidebar/Sidebar';
import './Layout.scss';

export const ThemeContext = createContext();

export const Layout = ({children}) => {
  const [theme, setTheme] = useState ('light');
  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark': 'light');
    console.log("yo")
  }

 return (
  <ThemeContext.Provider value={{theme, toggleTheme}}>
    <div className={`App ${theme}`}>
      <Sidebar/>
      <div className='page'>
        <span className='tags top-tags'>&lt;body&gt;</span>
        <Outlet />
        <span className='tags bottom-tags'>
        &lt;body&gt;
        <br />
        <span className='bottom-tag-html'>&lt;/html&gt;</span>
        </span>
      </div>
    </div>
   </ThemeContext.Provider>
 )
}

My scss for my layout

.App {
  .page {
      width: 100%;
      height: 100%;
      position: absolute;
  }

  .top-tags {
      bottom: auto;
      top: 35px;
  }

  .tags {
      color: rgb(0, 102, 255);
      opacity: 0.6;
      position: absolute;
      bottom: 0;
      left: 120px;
      font-size: 18px;
      font-family: 'La Belle Aurore', cursive;
  }

  .bottom-tag-html {
      margin-left: -20px;
  }
  & .light {
    background-color: rgb(255, 255, 255);
    color: black;
  }

  & .dark {
    background-color: black;
    color: white;
  }
}
 
.container {
    width: 100%;
    will-change: contents;
    height: 90%;
    min-height: 566px;
    position: absolute;
    opacity: 0;
    top: 5%;
    margin: 0 auto;
    z-index: 1;
    transform-style: preserve-3d;
    animation: fadeIn 1s forwards;
    animation-delay: 1s;
}

.contact-page,
.about-page {
    .text-zone {
        position: absolute;
        left: 10%;
        top: 50%;
        transform: translateY(-50%);
        width: 35%;
        vertical-align: middle;
        display: table-cell;
        max-height: 90%;

        h1 {
            font-size: 53px;
            font-family: 'Coolvetica';
            color: rgb(0, 102, 255);
            font-weight: 400;
            margin-top: 0;
            position: relative;
            margin-bottom: 40px;
            left: 10px;
      
            &:before {
              content: '<h1>';
              font-family: 'La Belle Aurore';
              font-size: 18px;
              position: absolute;
              margin-top: -10px;
              left: -10px;
              opacity: 0.6;
              line-height: 18px;
            }
      
            &:after {
              content: '<h1/>';
              font-family: 'La Belle Aurore';
              font-size: 18px;
              line-height: 18px;
              position: absolute;
              left: -30px;
              bottom: -20px;
              margin-left: 20px;
              opacity: 0.6;
            }
          }
      
          p {
            font-size: 13px;
            color: #000000;
            font-family: sans-serif;
            font-weight: 300;
            max-width: fit-content;
            animation: pulse 1s;
            &:nth-of-type(1) {
              animation-delay: 1.1s;
            }
            &:nth-of-type(2) {
              animation-delay: 1.2s;
            }
            &:nth-of-type(3) {
              animation-delay: 1.3s;
            }
        }
    }

    .text-animate-hover {
        &:hover {
          color: #000000;
        }
    }
}

My sidebar component

import React, {useContext, useState} from 'react'
import './Sidebar.scss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLinkedin, faGithub} from '@fortawesome/free-brands-svg-icons'
import { faHome, faUser, faEnvelope, faSuitcase, faBars, faClose, faSun} from '@fortawesome/free-solid-svg-icons'
import { Link, NavLink } from 'react-router-dom'
import {ThemeContext} from '../Layout/Layout'

export const Sidebar = () => {
  const [isNavVisible, setIsNavVisible] = useState(false);

  const {toggleTheme} = useContext(ThemeContext);

  const toggleNav = () => {
    setIsNavVisible(!isNavVisible);
  };

 return (
  <div>
    <FontAwesomeIcon icon={faBars} color="#4d4d4e" onClick={toggleNav} className="hamburger-icon" />
    <FontAwesomeIcon icon={faSun} color='#4d4d4e' onClick={toggleTheme} className='theme-toggle-icon'/>
    <div className={`nav-bar ${isNavVisible ? 'visible' : ''}`}>
          <nav className={isNavVisible ? 'show':'hide'}>
            <NavLink exact="true" activeclassname="active" to="/" >
              <FontAwesomeIcon icon={faHome} color="#4d4d4e" />
            </NavLink>
            <NavLink exact="true" activeclassname="active" className='about-link' to="/about" >
              <FontAwesomeIcon icon={faUser} color="#4d4d4e" />
            </NavLink>
            <NavLink exact="true" activeclassname="active" className='portfolio-link' to="/portfolio" >
              <FontAwesomeIcon icon={faSuitcase} color="#4d4d4e" />
            </NavLink>
            <NavLink exact="true" activeclassname="active" className='contact-link' to="/contact" >
              <FontAwesomeIcon icon={faEnvelope} color="#4d4d4e" />
            </NavLink>
          </nav>
          <ul>
            <li>
              <a href="#" target="_blank" rel="noreferrer">
                <FontAwesomeIcon icon={faLinkedin} color="#4d4d4e" className="anchor-icon"/>
              </a>
            </li>
            <li>
              <a href="#" target="_blank" rel="noreferrer">
                <FontAwesomeIcon icon={faGithub} color="#4d4d4e" className="anchor-icon"/>
              </a>
            </li>
          </ul>
    </div>
  </div>
 )
}

I’ve been using ChatGBT to troubleshoot

Route error after making http request (get)

I have a component which has a button. An api endpoint is called (GET request) when user clicked a button. There is no issue in this step as I got data from the endpoint. But, when I change to another component(page), I got “history.ts697 Uncaught TypeError: URL is not a constructor”, when I move to another page. BTW, I use react router dom v6. What could triggered that issue?

  const clickHandler =async (e) => {
      setSelectedEvent(e)
      const { event_type } = e
      
      if([0,3].includes(event_type) ){
          if(allAlarms && allAlarms == true || allAlarms == false){
                  try{ 
                  
                      URL = baseURL + `/e/register/read`
                      const res = await axios.post(URL, {
                                  userId: currentActiveUser['id'], 
                                  eventId: e['id'],                                
                              }, {
                                          withCredentials: true, 
                                          headers: {                    
                                                  Authorization: `Bearer ${jwtToken}`  
                                          }
                                      })
                                      

                              }catch(err){                        
                                  console.log(err)
                              }
              }
                 
              setShowDetailBox1(true)



      }else{
              setShowDetailBox1(false)
      }        
  }

Also “showDetailsBox1” will trigger a dialog box. I believe the issue is not related to that.

I tried to delete the node_module folder and start from scratch I got the same error. I got the same error when I tried on various browser (Chrome, Firefox and others).

The following is how I setup my react router

ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
  <QueryClientProvider client={queryClient}>
    <BrowserRouter>
          <Routes>
          <Route path='/users' element={<Users />}></Route>
            .....
           </Routes>     
    {/*   </ThemeProvider>  */}
    </BrowserRouter>

How to decipher a word contained in a string, if the string has a random character after each letter of the word in js? [closed]

I want to make a JS function which takes a string(i.e, ‘hsedlflgoh’),

and takes a word(i.e, hello),

and finds the word in the string

(decipher)

*(the string: ‘hsedlflgoh’ is just the word: ‘hello’ with a random letter in front of each character)

(the string can have any number of random letters after each letter in the word, but they have the same amount of characters after every letter, so (hfe, ohj, ejk, lji, lji, ops,)-
is a valid string because they all have the same amount of letters after each character (4 letters),

but the string (hfe, oj, ejgnk, li, l, opsh,)-
is invalid because they don’t have the same amount of letters after each character (some have 3 letters while some have 6))*

then after it finds the word it logs to the console how many letters it had to skip to get the word

the functions structure should be something like this:

function decipher(string, word) {
//i couldn't find something right to go here.
console.log(//how many skips it took to find the word);
}

and to run the function:

decipher('hsedlflgoh', hello)

I tried this:

var string = 'hsedlflgoh';
var word = 'hello';
string.contains(word);

//false

(it didn’t work)

i don’t know how to tell it to skip so please help me.

Filtering select field options in Django Rest Framework

How can brand and type fields filter options based from the existing asset category chosen, and unit model filtering options based from the selected brand? This is my JS:

$(document).ready(function() {

    const assetId = $('#asset_id').val();

    axios({
        method: 'get', 
        url: `/api/assets/assets/${assetId}`, 
    }).then(function(res) {
        let data = res.data;
        $('#id_name').val(data.name);
        $('#id_property_number').val(data.property_number);
        $('#id_serial_number').val(data.serial_number);
        $('#id_date_acquired').val(data.date_acquired);
        getAllBrand(data.brand)
        getAllUnitModel(data.unit_model)
        getAllStatus(data.status)
        getAllType(data.type)
        getAllUser(data.user)
        getAllDepartment(data.department)
        getAllArea(data.area)
        
        axios.get(`/api/assets/asset_details/`,{
            params:{
                asset: data.id
            }
        }).then(function(res) {
            const dataObj = res.data;
            const $formWrapper = $('#form_field_wrapper').empty();

            dataObj.forEach(obj => {
                const assetObj = obj.asset_field;
                const fieldId = `id_${assetObj.field_name}`;
                const feedbackId = `feedback_${assetObj.field_name}`;
                const requiredInfo = obj.asset_form.is_required ? '<span class="text-danger">*</span>' : '';
                const requiredClass = obj.asset_form.is_required ? 'form-required' : '';


                switch(assetObj.field_type) {
                    case 'radio':
                        break;
                    case 'checkbox':
                        break;
                    case 'text':
                        var fieldData = new Object();
                        fieldData.assetFormId = obj.asset_form.id; // form id
                        fieldData.assetFieldId = assetObj.id; // asset field id
                        fieldData.assetDetailId = obj.id; // asset field id

                        
                        $formWrapper.append(`
                            <div class="col-6 m-0">
                                <div class="form-floating mb-3">
                                    <input type="text" class="form-control asset-form-field ${requiredClass}" id="${fieldId}" placeholder="${assetObj.field_label}" value="${obj.value}">
                                    <label for="${fieldId}">${assetObj.field_label} ${requiredInfo}</label>
                                    <div class="invalid-feedback" id="${feedbackId}"></div>
                                </div>
                            </div>
                        `);

                        $(`#${fieldId}`).data(fieldData);
                        break;
                    case 'select':
                        let fieldOptions = JSON.parse(assetObj.field_option);
                        var fieldData = new Object();
                        fieldData.assetFormId = obj.asset_form.id; // form id
                        fieldData.assetFieldId = assetObj.id; // asset field id
                        fieldData.assetDetailId = obj.id; // asset field id

                        $formWrapper.append(`
                            <div class="col-6 m-0">
                                <div class="form-floating-selectize mb-3">
                                    <select class="form-selectize asset-form-field ${requiredClass}" id="${fieldId}" placeholder="${assetObj.field_label}" value="${obj.value}"></select>
                                    <label for="${fieldId}">${assetObj.field_label} ${requiredInfo}</label>
                                    <div class="invalid-feedback" id="${feedbackId}"></div>
                                </div>
                            </div>
                        `);

                        const $selectField = $(`#${fieldId}`);
                        $selectField.selectize({
                            persist: false,
                            maxItems: 1,
                            valueField: "id",
                            labelField: "title",
                            searchField: "title",
                            closeAfterSelect: true,
                            options: fieldOptions,
                        });
                        if (obj.value) {
                            $selectField[0].selectize.setValue(obj.value);
                        }

                        $(`#${fieldId}`).data(fieldData);
                        break;
                    // }

                }
            });

           
        }).catch(function(err){
            console.log(err)
        })
      
    }).catch(function(err){
        console.log(err)
    })

    let getAllBrand = function(values) {
        axios({
            method: 'get', 
            url: `/api/assets/brand/names`, 
        }).then(function(res) {
            let data = res.data;
            let select = $("#id_brand").selectize({
                // plugins: ["clear_button", "remove_button"],
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "name",
                searchField: "name",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };
    let getAllUnitModel = function(values) {
        axios({
            method: 'get', 
            url: `/api/assets/unit_models/names`, 
        }).then(function(res) {
            let data = res.data;
            let select = $("#id_unit_model").selectize({
                // plugins: ["clear_button", "remove_button"],
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "name",
                searchField: "name",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };
    let getAllStatus = function(values) {
        axios({
            method: 'get', 
            url: `/api/assets/statuses/names`, 
        }).then(function(res) {
            let data = res.data;
            let select = $("#id_status").selectize({
                // plugins: ["clear_button", "remove_button"],
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "name",
                searchField: "name",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };
    let getAllType = function(values) {
        axios({
            method: 'get', 
            url: `/api/assets/types/names`, 
        }).then(function(res) {
            let data = res.data;
            let select = $("#id_type").selectize({
                // plugins: ["clear_button", "remove_button"],
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "name",
                searchField: "name",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };
    let getAllUser = function(values) {
        axios({
            method: 'get', 
            url: `/api/core/user/names`, 
        }).then(function(res) {
            
            let data = res.data;
            let select = $("#id_user").selectize({
                // plugins: ["clear_button", "remove_button"],
                
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "fullname",
                searchField: "fullname",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };
    let getAllDepartment = function(values) {
        axios({
            method: 'get', 
            url: `/api/core/department/names`, 
        }).then(function(res) {
            let data = res.data;
            let select = $("#id_department").selectize({
                // plugins: ["clear_button", "remove_button"],
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "name",
                searchField: "name",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };
    let getAllArea = function(values) {
        axios({
            method: 'get', 
            url: `/api/core/area/names`, 
        }).then(function(res) {
            let data = res.data;
            let select = $("#id_area").selectize({
                // plugins: ["clear_button", "remove_button"],
                persist: false,
                maxItems: 1,
                valueField: "id",
                labelField: "name",
                searchField: "name",
                closeAfterSelect: true,
                options: data, 
            });
            if (values) select[0].selectize.setValue(values, false);
        }).catch(function(err) {
            alert(err.message)            
        });
    };

    getAllBrand()
    getAllUnitModel()
    getAllStatus()
    getAllType()
    getAllUser()
    getAllDepartment()
    getAllArea()


    $("#btn-save-asset_update").click(function() { 
        const assetId = $('#asset_id').val();

        const formFields = $('#form_field_wrapper').find('.asset-form-field').filter(function() {
            const tagName = $(this).prop('tagName').toLowerCase();
            return tagName === 'input' || tagName === 'select';
        });
        const formFieldArr = new Array(); // []
        const assetObj = new Object();

        // iterate values of form fields 
        formFields.each(function(index, element) {
            const $element = $(element);
            const fieldObj = new Object() // {}
            fieldObj.asset_field = $element.data().assetFieldId;
            fieldObj.asset_form = $element.data().assetFormId;
            fieldObj.detail_id = $element.data().assetDetailId;
            fieldObj.value = $element.val();
            formFieldArr.push(fieldObj);
        });

        assetObj.name = $('#id_name').val();
        assetObj.asset_category = $('#asset_category').val();
        assetObj.brand = $('#id_brand').val();
        assetObj.unit_model = $('#id_unit_model').val();
        assetObj.status = $('#id_status').val();
        assetObj.type = $('#id_type').val();
        assetObj.user = $('#id_user').val();
        assetObj.department = $('#id_department').val(); 
        assetObj.area = $('#id_area').val(); 
        assetObj.serial_number = $('#id_serial_number').val(); 
        assetObj.property_number = $('#id_property_number').val(); 
        assetObj.date_acquired = $('#id_date_acquired').val(); 
        assetObj.asset_details = formFieldArr;

        axios({
            method: 'put',
            url: `/api/assets/assets/${assetId}/`,
            data: assetObj,
            headers: axiosConfig
        }).then(function(res){
            const redirectUrl = '/asset/asset_list';         
            window.location.href = redirectUrl;
            
        }).catch(function(err){
             let errorText = err.response.request.statusText;
            let errObj = err.response.data;

            errObj.name ? showFieldErrors('name', errObj.name) : removeFieldErrors('name');
            errObj.asset_category ? showFieldErrors('asset_category', errObj.asset_category) : removeFieldErrors('asset_category');
            errObj.brand ? showFieldErrors('brand', errObj.brand) : removeFieldErrors('brand');
            errObj.unit_model ? showFieldErrors('unit_model', errObj.unit_model) : removeFieldErrors('unit_model');
            errObj.status ? showFieldErrors('status', errObj.status) : removeFieldErrors('status');
            errObj.type ? showFieldErrors('type', errObj.type) : removeFieldErrors('type');
            errObj.user ? showFieldErrors('user', errObj.user) : removeFieldErrors('user');
            errObj.area ? showFieldErrors('area', errObj.area) : removeFieldErrors('area');
            errObj.department ? showFieldErrors('department', errObj.department) : removeFieldErrors('department');
            errObj.serial_number ? showFieldErrors('serial_number', errObj.serial_number) : removeFieldErrors('serial_number');
            errObj.property_number ? showFieldErrors('property_number', errObj.property_number) : removeFieldErrors('property_number');     
            errObj.date_acquired ? showFieldErrors('date_acquired', errObj.date_acquired) : removeFieldErrors('date_acquired');
            errObj.non_field_errors ? showFieldErrors('non_field_errors', errObj.non_field_errors) : removeFieldErrors('non_field_errors');
            toastAlert('danger', errorText);
        })
    });
});



I did tried eventlisteners but still it wont work. I’m expecting to filter options of brand and type fields based from the existing asset category and, filtering option of the unit model based from the selected brand field.

React window virtualization – Starting from the bottom of a list

I’m currently using react-virtualized to render a large list which starts at the bottom, and performs the virtualization logic as the user scrolls up. Here is the code for this:

<List scrollToAlignment='end'  scrollToIndex={people.length} />

These two props scrollToAlignment and scrollToIndex are what allow this functionality to occur. I am wanting to switch to react-window, however FixedSizeList and VariableSizeList don’t have these props, therefore I cannot replicate the same functionality.

I tried the following code to fix the problem:

  const scrollToBottom = () => {
    container.current?.scrollIntoView({ behavior: "smooth" })
  }

  useEffect(() => {
    scrollToBottom()
  }, []);

However, this didn’t fix the issue, as the list still was rendering, as the page is scrolling down. Is there any built in methods in react-window to help me replicate this functionality, or any alternative solutions to address this issue? Thanks.

Modal didn’t show up in python

I’m new to python. I’m trying to create a simple chatbot in python where click on avatar to show the modal where User asked to enter Name. Not sure what I’m doing wrong here but modal is never displayed. below is the HTML and script code

// JavaScript to handle showing the name modal
function showNameModal() {
  // Introduce a delay to ensure modal elements are ready
  setTimeout(function() {
    $('#nameModal').modal('show');
  }, 100);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Chat Page</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>

<body>
  <div class="container">
    <p>This is created by Shah.</p>
  </div>

  <div id="avatar-container" class="fixed-bottom fixed-right">
    <!-- Message above chatbot avatar -->
    <p class="text-muted mb-1" id="chatMessage">Click to chat</p>

    <!-- Clickable avatar using Font Awesome icon -->
    <form onsubmit="showNameModal(); return false;">
      <button type="submit" id="avatar" class="fas fa-robot fa-3x rounded-circle bg-primary text-white p-2"></button>
    </form>
  </div>
  <!-- Bootstrap CSS -->
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">

  <!-- Bootstrap JS, Popper.js, and Modal components -->
  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

</body>

</html>

How to address multiple tooltips from SVG

I have an SVG with a title element, as well as polygons with their own empty titles in the hopes of preventing the parent title from appearing when hovering over the polygons because I have a custom JavaScript tooltip for the polygons. So something like

<svg aria-labelledby="title1">
<title id = "title1">My big title</title>
<polygon aria-labelledby="title2"></polygon>
// this title element is dynamically generated by JS after the rest of the SVG is added to page
<title id="title2"></title>
</svg>

The SVG is generated dynamically from a library and I use JavaScript to append the blank title to remove the main title tooltip from polygons, but after running the JavaScript the tooltip still appears even though the new blank titles are in the DOM.

If I go into the developer tools and edit HTML, but make no changes and then hover over the polygons only the custom tooltip displays as expected. It seems that the JavaScript code adds the blank titles but the browser is cacheing the previous aria data state. Is there any way to use JavaScript to force the browser to reevaluate the aria metadata? I’ve tried basic things like adding and removing classes

addEventListener not working. Help me to correct an JS

why that is not working ?

var headerBanner= $(".header-banner");
var closeBtn = $('closeBtn');

closeBtn.addEventListener('click', function () {
  headerBanner.classList.add('IsClose');
}, false);

.closeBtn {
  position: relative;
  display: inline-block;
  width: 20px;
  height: 20px;
  overflow: hidden;
  opacity: 0.8; 
  float: right;
  cursor: pointer;

}


I want to make custom button to close.
in f12 can’t see “IsClose”. Do I make any mistake in js ?

Javascript scrollIntoView within a Scroll event

The goal is to create a full page scroll without using any libraries.

I’ve tried using the css scroll-snap-type: y mandatory; wich actually works fine on desktop.

HTML:

  <div id="scroll_snap_container">
    <section id="section-1">
      content 
    </section>
    <section id="section-2">
      content
    </section>
    .
    .
    .
  </div>

SCSS:

  #scroll_snap_container {
    height: 100vh;
    width: 100%;
    overflow-y: scroll;
    scroll-snap-type: y mandatory;
    section {
      position: relative;
      height: 100vh;
   }
 }

However on IOS mobile devices it triggers multiple issues.

  1. The scrolling often get’s stuck once the user reaches the bottom of the page. As the browser acts as if the window would be scrolled but in reality the user tries to scroll the #scroll_snap_container.
  2. The second major issue is safari’s (browser) searchbar wich is located at the bottom of the page. This searchbar usually disappears on scroll down. Wich again, because we are not actually scrolling the window but a container, is not triggered. This reduces availible space and breaks the 100vh calculation as the searchbar overlaps with the content.

Workaround (not working):
using Javascript.
Javascript has a scrollIntoView event. Wich works prefectly when triggered on click. As you might have guessed. I do not want the user to click every time to move on. The idea is to use the

      element.addEventListener('scroll', function() {
          const section2 = document.getElementById("section-2");
          if ((window.scrollY > 100) && !this.isScrollingState) {
             section2.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"});
             this.isScrollingState = true;
          }
      });

(Yes this needs to be more dynamic)
I figured that using some kind of verifier / state in this case is necessary as the event will trigger a trillion times as soon as the window is scrolled more than 100 causing the animation to be really slow.
But as soon as there is only one trigger it is ignored as soon as the user scrolls on.
Simply put, the scrollIntoViewis only triggered if the user let’s go of the scrolling at exactly window.scrollY > 100. if you scroll let’s say 104 the event is already ignored.

I’m using Vue3 (for the first time) and can’t trigger the update method wich might be another option I can imagine it working in a componentDidUpdate in react.

Also how would you make this more dynamic? Scroll up, Scroll down -> next section accordingly.

Updating AWS DynamoDB from version 2 to version 3 using KeyConditionExpression?

I’m updating my AWS DynamoDB code from version 2 to version 3 and I’m having trouble understanding how to change my use of KeyConditionExpression.

Here is my original code that uses version 2:


const getUsoAXIS = async (cuse) => {
    const query = {
        TableName: TABLE_NAME,
        KeyConditionExpression: "#cuse = :cuse AND #entity = :entity",
        ScanIndexForward: false,
        ExpressionAttributeNames: {
            "#cuse": "cuse",
            "#entity": "entity",
        },
        ExpressionAttributeValues: {
            ":cuse": cuse,
            ":entity": "USOAXIS",
        },
    };
    logger.info("Getting dynamo data in (getUsoAXIS) function", { info: { TableName: TABLE_NAME } });
    const dynamodbRecord = await getDynamodbItem(query);
    if ("Items" in dynamodbRecord && dynamodbRecord.Items.length > 0) {
        const data = dynamodbRecord.Items[0];
        logger.info("Dynamo data obtained");
        return data.data;
    } else {
        return undefined;
    }
};

And here is my updated code that uses version 3:

const getUsoAXIS = async (cuse) => {
    const params = {
        tableName: TABLE_NAME,
        key: {
            "cuse": cuse,
            "entity": "USOAXIS",
        },
    };
    logger.info("Getting dynamo data in (getUsoAXIS) function", { info: { TableName: TABLE_NAME } });
    const dynamodbRecord = await getDynamodbItem(params);
    if (dynamodbRecord) {
        logger.info("Dynamo data obtained");
        return dynamodbRecord.data;
    } else {
        return undefined;
    }
};

//fuction 
const getDynamodbItem = async (params) => {
       try {
        logger.info("Get item dynamo");
        console.log(params);
        const { tableName, key } = params;
        const command = new GetCommand({
            TableName: tableName,
            Key: key,
        });
        const response = await docClient.send(command);
        logger.info("Get item dynamo response", { info: { response } });
        return response?.Item ? response.Item : null;
    } catch (error) {
        logger.error("Error getting item dynamo", error);
    }
};

I’m having trouble understanding how KeyConditionExpression translates into DynamoDB version 3. Please, Could someone explain how this works?

regex statement parsing a custom html template for bracketed vars and conditions

I have a regex statement which I have gotten to work in testers online as well as in local code and PHP and Python. For some reason though I cannot get it to work in Javascript which is what I need it to work in. I have tried many different options and some of them work online within the testing site environment but when I try to use them in real life it just doesn’t work.

My template code is something like this.

<div></div>

{if(action == 'fill'){
    <form-input value="{{value.path}}" >
    <select name="value[path]">
        <option value="identity" >Identity</option> 
        <option value="global">Global</option>
    </select>
    </form-input>
}}

<div class="row">
    <div id="target-picker" class="icon sm">
    <div class="icon:target"></div>
</div>

I’m trying to parse the conditional block above and for some reason I either cannot get it to parse the whole block returning the condition statement as well as the inner content of the handlebars. I appreciate anyone’s time answering the question but please do not add Jquery answers i’m not interested.

I have functions that work correctly for parsing variables as well as nested variables within the handlebar syntax of double curly brackets. I’m trying to parse the conditional block above and for some reason I either cannot get it to parse the whole block returning the condition statement as well as the inner content of the handlebars. This is what I am currently using which works fine online but in real life it doesn’t Any help would be greatly appreciated.

here is my regex which is current working online.

const regex = /{if(([^{]+)){([sS]*)}}/gm;

In real life the result I get is either it stops at the first inner variable or it continues on to the whole template file to the last variable.

And here is the implementation of this within an online testing environment that works as I want it to only issue is in real life on node.js it doesn’t work.

regexr.com/7nkr2

How to avoid sending third-party requests to my serverless function on vercel?

I have a game made in React and JS, and a server running serverles on Vercel.

When you authenticate to my game (for now, all you need is a username), the server checks if the user already exists, and if not, creates a new one. Then it creates a JWT token that it sends back to the frontend thanks to an httpOnly cookie.

When you play my game, you get a score, which is sent after the game to the DB via a POST request to /api/(my function). In the body of the request, I return the score and the name, and in the header I return the cookie we received earlier when we connected.

My problem is that when a user logs in and then retrieves the token in the header of the browser console, he can then go to postman and make a POST request to mondomaine/api/(ma fonction) and thus add a score that he didn’t obtain while playing.

I’ve looked everywhere on the Internet and I can’t find a way to avoid this.

Maybe I need to rethink my connection logic? If you have any ideas, I’d love to hear from you.

filter operator in rxjs and subscribe

i am working in an Angular Material Dialog, what i want to do is a patch request when i close the Dialog.

In my component i have a property that like this, with a certain data i receive with @input

  public stat:Stat = {
    id: "",
    _id: "",
    name: "",
    bithplace: "",
    institution: "",
    topics: [],
    maininterest: "",
    img: "",
    index: ''
  }

I want to filter the data so i can get only the properties that changed and the index to make the patch request.

    const dialogRef = this.dialog.open(DialogUpdateComponent, dialogConfig)
    dialogRef.afterClosed()
    .pipe(
      filter( (resp) => Object.values(resp) !== Object.values(this.stat) && resp.index)
    )
    .subscribe
    (resp => this.statService.editStat(resp, resp.index))
  }

At this point i think i should have the data i want, but when i execute the code nothing happens.

This is the editStat method:

  editStat(stat: Stat, index:string):Observable<Stat>{
    return this.http.patch<Stat>(`${this.basic_URL}/${index}`,stat)
  }

When i make the patch request in Postman, changing a property in the body it works, but this doesnt happen in my app when i close the dialog.

Why don’t my cards go to the correct places with this animation?

I am trying to create a card game in HTML, CSS and JavaScript and I’m currently working on the dealing. I’ve been trying to create an animation where the cards go from the deck to 3 different sections on the page but I can’t get it to work properly. The cards are very close to each other, so their values are hardly visible, but the main issue is their positioning, since they don’t move into their respective containers. (computer cards should go to 'computer-pos' and so on). I am a begginer with animations and i’ve been trying to use anime.js. Does anyone have a fix on how to make the animation cleaner and more accurate?

This is how my html is set up:

`<div class="computer-hand">
 <div class="computer-pos" id="cpu-pos-a"></div>
 ...
 </div>
 div class="middle-section">
 <div class="table">
 <div class="table-pos" id="tab-pos-a"></div>
 ...
 </div>
 <div class="deck"></div>
 </div>
 <div class="player-hand">
 <div class="player-pos" id="player-pos-a"></div>
 ...
 </div>`

For now, i’m working on the first 10 cards being dealt because that’s how the game starts, with 3-3 going go the player and the cpu, and 4 on the table. I create my cards dinamically with Javascript, and i append them to the deck and try to deal the cards from there. Here’s part of the code for that:

`function createCard(parent, toHand, faceCard) {
 let card = deck.pop(deck.length - 1)
 ...
 const cardElement = createElement('div')
 addClass(cardElement, 'card')

const cardInner = createElement('div')
addClass(cardInner, 'card-inner')

appendChild(cardElement, cardInner)
...
parent.appendChild(cardElement)
toHand.push(card);
}`

This is how I deal the cards, same for all 3 sections:

`function dealToTable() {
 const table = document.querySelectorAll('.table-pos');
 table.forEach((position, index) => {
    const cardElement = createCard(deckPosition, tableCards, true);
    animateCard(cardElement, position, index);
 });
}`

And this is the animation I’ve been trying to get to work:

`function animateCard(cardElement, targetPosition, index) {
    anime({
    targets: cardElement,
    translateX: targetPosition.offsetLeft - deckPosition.offsetLeft,
    translateY: targetPosition.offsetTop - deckPosition.offsetTop,
    easing: 'easeInOutQuad',
    duration: 1000,
    delay: index * 200,
});
}`