Image sorting by category

I am trying to make an image gallery that lets the user sort options by category (land, sea, animal, and more). I wrote a small example.

My goal: is that once the user selects (clicks) the category he wishes to sort by, the website will present only pictures from that specific category, while the other “unwanted” pictures will slowly disappear and move downward. Once the user changes selection, the “missing” pictures will reappear from below and go up until they reach their destination.

I did manage to make the in and out animations as well as keep the image hidden after the animation ends, but only after all relevant pictures disappear, the sorted pictures “jump” to their place instead of smoothly sliding toward their expected place.

Now I think my current problem is missing animation, but maybe I wrote something wrong in my css or my JS.

const filterContainer = document.querySelector('.data-filters');
const photoItems = document.querySelectorAll('.photo-item');

filterContainer.addEventListener('click', (event) => {
    
  filterContainer.querySelector('.active-filter').classList.remove('active-filter');
  event.target.classList.add('active-filter');
    
  const filter = event.target.getAttribute('data-filter');
  
  photoItems.forEach((item) => {
  if(item.getAttribute('data-filter') == filter || filter == 'all'){
    item.classList.remove('photo-out')
    item.classList.add('photo-in')
  } else {
    item.classList.remove('photo-in')
    item.classList.add('photo-out')
  }
  })

})
.line-list li {
  display: inline-block;
  margin: 10px;
  cursor:pointer;
}

.active-filter {
  color:blue;
}

@keyframes go-out {
  0%   {top:0px;opacity:1.0}
  100% {top:600px;opacity:0;display:none}
}

@keyframes go-in {
  100%   {top:0px;opacity:1.0}
  0% {top:600px;opacity:0;display:block}
}

.photo-out {
  animation: go-out 1.2s forwards;
}

.photo-in {
  animation: go-in 1.2s forwards;
}
<html>
  <head>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  </head>
  <body>
  <section id='photo_wall'>
    <div class='container'>
      <div class='row'>
        <div class='col-md-12 data-filters'>
          <ul class='line-list'>
            <li class='active-filter' data-filter='all'> All photos </li>
            <li data-filter='land'> Land </li> 
            <li data-filter='sea'> Sea </li> 
            <li data-filter='animals'> Animals </li> 
          </ul>
        </div>
      </div>
      <div class='row'>
        <div class='col-md-3 photo-item p-4 photo-in' data-filter='land'>
          <img src='https://fastly.picsum.photos/id/807/200/200.jpg?hmac=Y8gayvNItiQYxP_Pd-2un9GH09XuyJdIZOQPw6K9QsI'>
        </div>
        <div class='col-md-3 col-sm-6 photo-item p-4 photo-in' data-filter='animals'>
          <img src='https://fastly.picsum.photos/id/659/200/200.jpg?hmac=kFpdD3XTBGwPUAH1tD-AiWigstjIX8WGIcyySuVQIvE' class='animals'>
        </div>
         <div class='col-md-3 col-sm-6 photo-item p-4 photo-in' data-filter='land'>
          <img src='https://fastly.picsum.photos/id/165/200/200.jpg?hmac=tQGrY9pm5ze9soSsZ5CNBt87zqnHfFwdPv_khau12Sw' class='land'>
        </div>
        <div class='col-md-3 photo-item p-4 photo-in' data-filter='sea'>
            <img src='https://fastly.picsum.photos/id/883/200/200.jpg?hmac=evNCTcW3jHI_xOnAn7LKuFH_YkA8r6WdQovmsyoM1IY' class='sea'>
           </div>
          <div class='col-md-3 photo-item p-4 photo-in' data-filter='animals'>
            <img src='https://fastly.picsum.photos/id/237/200/200.jpg?hmac=zHUGikXUDyLCCmvyww1izLK3R3k8oRYBRiTizZEdyfI' class='animals'>
            </div>
          <div class='col-md-3 photo-item p-4 photo-in' data-filter='sea'>
            <img src='https://fastly.picsum.photos/id/653/200/200.jpg?hmac=tZtho3csFdJ2rLHTTlT7WhXtDwbXgJNIIUvOQQb2dIo' class='sea'>
            </div>
      </div>
    </div>
  </section>
  </body>
</html>

Showing icon on results after selection

Am having a script below which is working and outputting results very well.

but my problem is that i wanted to change and output results with icon

i changed from

$("#results").text(firstname + " " + lastname);

to

$("#results").html("<i class='fa fa-user-circle-o'></i>" firstname + " " + lastname);

but its not working

<!DOCTYPE html>
<html>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<body>



  <select id="fname">
   <option value="">Select Firstname</option>
    <option value="jone">jone</option>
  </select>
  
    <select id="lname">
    <option value="">Select Lastname</option>
    <option value="micheal">micheal</option>
  </select>

 <br>
 <br>
 <p>My fullname is:</p>
 <div id="results"></div>
<script>
            $("select").on("change", function (e) {
                var firstname = $("#fname").children("option:selected").val();
                var lastname = $("#lname").children("option:selected").val();
                $("#results").text(firstname + " " + lastname);
            });
            
            </script>

</body>
</html>

R : Re-binding the SelectInput of a DataTable after being updated

So I am currently trying to create a Shiny App that would allow the user to chose the category associated with an entry, change it, and this change being directly written into the corresponding database. For that I used both RMySQL and DT libraries to configure Select Inputs displayed on each row with all the categories to chose from, as well as an “Update Data” button to confirm the changes and execute the SQL queries to write them into the database.

However, the app seems to work only the first time that the “Update Data” button is used after launching the app. From what I noticed, it seems to be related to the Select Input ids : they are first defined when the DataTable is initialized (with “single_input6” being associated with the row “ID : 6” for exemple), and are then recreated the same way when the DataTable is updated after the “Update Data” button has been clicked. However, the value associated with those inputs stay the same as the ones that were selected when the “Update Data” button was clicked the first time.

It could be that the ids are still binded to their initial values, or that the initial DataTable wasn’t replaced by the new one and so still exist. I don’t know however what exactly causes the issue or how to fix it.

Below are the images showing how the App works (1., 2.), where it doesn’t (3.) and what makes me think the ids are not correctly binded (4.) :

1. The App the first time it is launch
1. The App the first time it is launch](https://i.stack.imgur.com/I3DoH.png)

2. The App after selecting "Egyptien" for the row ID : 6 and cliking on "Update Data"
2. The App after selecting “Egyptien” for the row ID : 6 and cliking on “Update Data”

3. The App after then selecting "Grec" for the row ID : 6 and cliking on "Update Data" (nothing has changed)
3. The App after then selecting “Grec” for the row ID : 6 and cliking on “Update Data” (nothing has changed)

4. The console prints used for debug. The first "Egyptien" was displayed during the 2. image update, the second "Egyptien" was displayed during the 3. image update

4. The console prints used for debug. The first “Egyptien” was displayed during the 2. image update, the second “Egyptien” was displayed during the 3. image update


Here is the SQL queries to create the MySQL dummy database used as an exemple :

### Initialize the two MySQL Databases used in the code
# The Databases are not important in themselves but are handy to test and tinker what I need

CREATE TABLE Z_TEST (ID INT PRIMARY KEY NOT NULL, Divinite VARCHAR(20), ID_pantheon INT);
CREATE TABLE Z_TEST2 (id_pantheon INT PRIMARY KEY NOT NULL, nom_pantheon VARCHAR(20));

INSERT INTO Z_TEST VALUES 
(1, "Quetzalcoatl", 5), 
(2, "Odin", 3), 
(3, "Ra", 2),
(4, "Zeus", 1),
(5, "Tiamat", 4),
(6, "Isis", 0),
(7, "Hades", 0),
(8, "Thot", 0),
(9, "Thor", 0),
(10, "Persephone", 0),
(11, "Amatsu", 0);

INSERT INTO Z_TEST2 VALUES 
(1, "Grec"), 
(2, "Egyptien"), 
(3, "Nordique"),
(4, "Sumerien"),
(5, "Azteque"),
(6, "Japonais");


### Display each Database and their join

SELECT * FROM Z_TEST;
SELECT * FROM Z_TEST2;

SELECT ID, Divinite, Z_TEST.ID_pantheon, nom_pantheon FROM Z_TEST LEFT JOIN Z_TEST2 ON Z_TEST.ID_pantheon = Z_TEST2.id_pantheon;

Here is the R code used for the Shiny App :

### Libraries

{
  library(shiny)            # used to create the Shiny App
  library(bslib)            # used to create the Shiny App
  
  library(RMySQL)           # used to access the Database
  library(lares)            # used to import logins for the Database
  
  library(tidyverse)        # used for many things (mainly data manipulation)
  library(DT)               # used for creating interactive DataTable
  # library(DTedit)           # used for better editing of DataTable (judged not enought intuitive for the user)
}


### JS Module for keyboard shortcut (Not Important)
# Allows the use of arrow keys to move from cell to celle and the Enter key to confirm an edit

js <- c(
  "table.on('key', function(e, datatable, key, cell, originalEvent){",
  "  var targetName = originalEvent.target.localName;",
  "  if(key == 13 && targetName == 'body'){",
  "    $(cell.node()).trigger('dblclick.dt');",
  "  }",
  "});",
  "table.on('keydown', function(e){",
  "  var keys = [9,13,37,38,39,40];",
  "  if(e.target.localName == 'input' && keys.indexOf(e.keyCode) > -1){",
  "    $(e.target).trigger('blur');",
  "  }",
  "});",
  "table.on('key-focus', function(e, datatable, cell, originalEvent){",
  "  var targetName = originalEvent.target.localName;",
  "  var type = originalEvent.type;",
  "  if(type == 'keydown' && targetName == 'input'){",
  "    if([9,37,38,39,40].indexOf(originalEvent.keyCode) > -1){",
  "      $(cell.node()).trigger('dblclick.dt');",
  "    }",
  "  }",
  "});"
)


### Queries (Not Important)

QDisplay <- "
  SELECT ID, Divinite, Z_TEST.ID_pantheon, nom_pantheon 
  FROM Z_TEST LEFT JOIN Z_TEST2 ON Z_TEST.ID_pantheon = Z_TEST2.id_pantheon
"

QEdit <- "
  UPDATE Z_TEST
  SET %s = '%s'
  WHERE ID = %d
"

QRef <- "
  SELECT nom_pantheon FROM Z_TEST2
"

### --- YOU MUST EDIT THE FOLLOWING PART BEFORE RUNNING THE CODE --- ###

### Database Connection (Important)

# Connect to a MySQL Database using appropriate credentials, then close the connection
# IMPORTANT : Requires a config.yml file to be setup with corresponding credentials if you want to use the get_creds function as is
# Otherwise, you can simply replace the get_creds("cirrina_as")$[...] by putting the plain-text credentials in their place

mydbGetQuery <- function(Query) {
  
  DB <- dbConnect (
    MySQL(),
    dbname = get_creds("dummy_db")$dbname,
    host = get_creds("dummy_db")$host,
    user = get_creds("dummy_db")$user,
    password = get_creds("dummy_db")$password
  )
  data <- dbGetQuery(DB, Query)
  dbDisconnect(DB)
  
  return(data)
}


### Automatic generation of row Select Input (somewhat Important)

# Create levels to choose from in the Select Input
factorOptions <- function(select_factors) {
  a <- ""
  for (i in select_factors) {
    a <- paste0(a, '<option value="', i, '">', i, '</option>n')}
  
  return(a)
}

# Create the Select Input with ID and corresponding entry from the joined table
mySelectInput <- function(selected_factor, select_factors) {
  b <- c()
  
  for (j in 1:length(selected_factor)) {
    b <- c(b, paste0('<select id="single_select', j, '"style="width: 100%;">n', 
                     sprintf('<option value="%s" selected>%s</option>n', selected_factor[j], selected_factor[j]), 
                     factorOptions(select_factors), '</select>'))
  }
  return(b)
}

# Get the reference levels for the Select Input 
panth_level <- mydbGetQuery(QRef) %>% as_tibble() %>% pull(nom_pantheon)


### Shiny App (Important)

shinyApp(
  ui = fluidPage(
    DTOutput('interactiveTable'),
    actionButton("updateButton", "Update Data")
  ),
  
  server = function(input, output, session) {
    
    # Fetch the underlying data
    panth_data <- reactiveVal()
    observe(panth_data(mydbGetQuery(QDisplay) %>% as_tibble()))
    
    # Initialize the DataTable
    output$interactiveTable <- renderDT({
      datatable(data = bind_cols(panth_data(), tibble(Test = mySelectInput(panth_data()$nom_pantheon, panth_level))), 
                selection = 'none', escape = FALSE, rownames = FALSE, editable = list(target = 'cell', disable = list(columns = c(0, 2))),
                callback = JS(js), extensions = "KeyTable", 
                options = list(
                  keys = TRUE,
                  preDrawCallback = JS('function(){Shiny.unbindAll(this.api().table().node());}'),
                  drawCallback = JS('function(){Shiny.bindAll(this.api().table().node());}')
                )
      )
    })
    
    # If the button is clicked, apply the changes made with the Select Input directly to the database
    # Note : for now, only the sixth row (ID : 6, Divinite : Isis) is made responsive to any change done with selectors
    # Changing the "6" of "single_select6" and "sprintf(QEdit, "ID_pantheon", i, 6)" for another number will make another entry
    # responsive instead
    
    observeEvent(input$updateButton, {
      # for debug
      print(input$single_select6)
      
      # Fetch the corresponding ID of the selected pantheon and update the database
      i <- mydbGetQuery(sprintf("SELECT id_pantheon FROM Z_TEST2 WHERE nom_pantheon = '%s'", as.character(input$single_select6)))$id_pantheon
      mydbGetQuery(sprintf(QEdit, "ID_pantheon", i, 6))
      
      # Update the Datable
      output$interactiveTable <- renderDT({
        updated_data <- mydbGetQuery(QDisplay) %>% as_tibble()
        datatable(data = bind_cols(updated_data, tibble(Test = mySelectInput(updated_data$nom_pantheon, panth_level))),
                  selection = 'none', escape = FALSE, rownames = FALSE, editable = list(target = 'cell', disable = list(columns = c(0, 2))),
                  callback = JS(js), extensions = "KeyTable", options = list(
                    keys = TRUE,
                    preDrawCallback = JS('function(){Shiny.unbindAll(this.api().table().node());}'),
                    drawCallback = JS('function(){Shiny.bindAll(this.api().table().node());}'))
        )
      })
    })
    
    
    ### Attempt to edit the Data everytime the input is modified rather than waiting for a Button input
    
    # observeEvent(input$single_select6, {
    #   print(input$single_select6)
    #   
    #   i <- mydbGetQuery(sprintf("SELECT id_pantheon FROM Z_TEST2 WHERE nom_pantheon = '%s'", as.character(input$single_select6)))$id_pantheon
    #   mydbGetQuery(sprintf(QEdit, "ID_pantheon", i,
    #                        # d6()[input$x6_cell_edit$row,]$ID
    #                        6
    #   ))
    #   
    #   output$x6 <- renderDT({
    #     updated_data <- mydbGetQuery(QDisplay) %>% as_tibble()
    #     datatable(data = bind_cols(updated_data, tibble(Test = test2(updated_data$nom_pantheon, d))),
    #               selection = 'none', escape = FALSE, rownames = FALSE, editable = list(target = 'cell', disable = list(columns = c(0, 2))),
    #               callback = JS(js), extensions = "KeyTable", options = list(keys = TRUE))
    #   })
    #   
    #   reset("single_select6")
    # })
  }
)

Important Notes :

  • The SQL dummy database must first be created for the code to work properly as is
  • You must edit the “mydbGetQuery” function by replacing the credentials inside with either the one associated with your MySQL database in your config.yml file (if you intend to use lares) or directly with the plain-text credentials (simplest option)
  • Only the row ID : 6, Divinite : Isis can be updated by changing the Select Input Value and then clicking on “Update Data”. This is by design as to debug a single row first.
  • Closing and launching the App again will make the first new update work, before returning the same result again

Web-scraping: GET request returns a string – how can I read/process it in R?

I’m sending a GET request to an governmental page in India with the following URL:
https://pmfby.gov.in/landingPage/districtState?stateID=2F3DE245-46E6-4C4D-9297-C0B23C803B15&sssyID=02012223

What this basically does on their webpage (https://pmfby.gov.in/ -> “Insurance Premium Calculator”) is returning all districts for a specific state selected (with JavaScript).

I used the following R code to reproduce this:

content(httr::GET("https://pmfby.gov.in/landingPage/districtState?stateID=2F3DE245-46E6-4C4D-9297-C0B23C803B15&sssyID=02012223"))

I somehow expected to get a HTML or JSON structured return with a list of those districts. What I actually get back however is a string that starts with “09f2ba53495a95c8d6189182d996252553a088b548d4f3c7caf1e195ff….”.

I don’t even know what format this is and I’m unable to convert/process this is R.
Is there any solution to my problem?

javascript having problem in handling codes from html [closed]

There’s this code that can be applicable to html since it is from server side.

but in script, it cannot.

this is the code at html where the code works:

<span id="lang">#(main.language.toUpperCase())</span>

and this is the code in script that doesn’t work:

$('#lang').html(`<span>${main.language.toUpperCase}</span>`);

What do you think is the issue in js code?

Optional capturing in any order for values only

I have the following group of text:

name:   something
type:   another value
color:  red

I need to capture only the values to the right, in any order. Keeping in mind that any of the values above may be missing in other instances, or in a different order, such as:

color:  red
type:   value

On top of that, it being able to ignore quotation marks " and ' in case the values are wrapped in them, and ignoring the spaces between the proper and value. Which means that it would be able to still pull the values from the below example:

color:  "red"
type:   'value'
name:             'something'

Here is the JavaScript regex I’ve tried to pull together:

(?=[^`]*?name:? +(?<name>[^`n]*))(?=[^`]*?value:? +(?<value>[^`n]*))(?=[^`]*?color:? +(?<color>[^`n]*))(?=[^`]*?file:? +(?<file>[^`n]*))(?=[^`]*?type:? +(?<type>[^`n]*))

Regex101

The issue at the moment is:

  1. All values are required, if I remove any from the list, none of them capture. I’ve attempted adding optional ? syntax, but I can’t seem to place it in the right spot.
  2. The quotations are being captured with the value.

I have looked at examples online which mention using a ? between each group, but that results in the regex101 error: ? The preceding token is not quantifiable

Django-React not staying logged in

I have a React JS – Django site and I implemented the login functionality. But I have seen that the user does not stay logged in even though it authenticates and moves to the home page after log in. I tried displaying the username once it navigates to the home page and it returns empty.

Views.py

class Login(APIView):
    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')

        # Authenticate user
        user = authenticate(request, username=username, password=password)

        if user is not None:
            # If authentication succeeds, log in the user
            login(request, user)
            return JsonResponse({"message": "Login successful"})
        else:
            # If authentication fails, return error response
            return JsonResponse({"error": "Invalid username or password"}, status=status.HTTP_400_BAD_REQUEST)

Login.js

const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      const response = await fetch("http://localhost:8000/login/", {
        method: 'POST',
        withCredentials: true,
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ username, password })
      });
      
      const data = await response.json();

      if (response.ok && data.message === "Login successful") {
        // Redirect to the home page upon successful login
        navigate('/');
      } else {
        // Set error state with the error message
        setError(data.error);
      }
    } catch (error) {
      // Handle network or server errors
      setError("An error occurred during login. Please try again later.");
    }

I have the necessary session middleware in my settings.py as well.

I tried adding middleware to settings.py and session cookie age but it didnt work either

What is the equivalent of sinonStub.callsArg(2).returns({}) in jest?

Some code we’ve inherited from a supplier is using uploadStub.callsArg(2).returns({}) in Sinon to mock out the callback to a stubbed function. We’re migrating to jest and I’m struggling to find an equivalent.

The original function call being Upload(req, res, async function (error) { ... }). It’s this 3rd arg which is a callback that I want to become a mock so the test can check it was called.

jestcodemods has this PR https://github.com/skovhus/jest-codemods/pull/357 which suggests apiStub.mockImplementation((...args) => args[2]()) which would call the callback but not create a mocked version of it.

Link de redicionamento [closed]

Será que alguém podia me ajudar, quando faço uma chamada ao api da microsoft recebo um link de autenticação no console, mas surge um problema ao fazer um redicionamento automático meu link muda para http://localhost:5173/’https://login.microsoftonline.com/…. ,o que causa um erro pois inves do link ser substituido é concateado com o link atual.
O problema e o link de redicionamento?

Meu codico:

function ObterOken() {
  axios
    .get(
      `'https://login.microsoftonline.com/${settings.tenantId}/oauth2/v2.0/authorize?client_id=${settings.clientId}&response_type=token&redirect_uri=http://localhost:5173/Home&response_mode=fragment&scope=offline_access%20User.Read%20Mail.Read%20Mail.Send&state=12345'`
    )
    .then((response) => {
      const url = response?.config?.url;
   window.location.href=url;
  
    })   .catch((error) => console.log("erro na solicitação de acesso", error));
}
export { ObterOken };

How to migrate to standalone in angular

I have question how to migrate to standalone if I want that:

  1. In ApplicationConfigService I want use httpclient How I can do it?
  2. After Init app I want use load function

export function initializeFn(jsonAppConfiguration: ApplicationConfigService){
  return () =>{
    return jsonAppConfiguration.load();
  };
}

Please check following codes

export abstract class AppConfiguration{
    baseUrl:string = '';
    connectionName:string = '';
}

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AppConfiguration } from './app-config'
import { DOCUMENT } from '@angular/common';
import { Inject } from '@angular/core';

@Injectable({providedIn: 'root'})
export class ApplicationConfigService extends AppConfiguration{

  constructor(@Inject(DOCUMENT) private document: Document, private http: HttpClient) { 
    super();
  }


  load(){
    try{
    
      this.connectionName = (this.document.getElementsByName("connectionName")[0] as any).value;
      this.baseUrl = (this.document.getElementsByName("baseUrl")[0] as any).value;
    }
    catch{}
  }
}


import { APP_INITIALIZER, Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ApplicationConfigService } from './config/application-config.service';
import { HttpClientModule } from '@angular/common/http';


export function initializeFn(jsonAppConfiguration: ApplicationConfigService){
  return () =>{
    return jsonAppConfiguration.load();
  };
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [
    RouterOutlet,
    HttpClientModule
  ],
  providers: [
    ApplicationConfigService,
    {
      provide:APP_INITIALIZER,
      multi:true,
      deps:[ApplicationConfigService],
      useFactory:initializeFn
    }
  ],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {
  title = 'f_project';
}

import { HttpClient, HttpClientModule } from '@angular/common/http';
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ApplicationConfigService } from '../config/application-config.service';

@Component({
  selector: 'app-main',
  standalone: true,
  imports: [],
  templateUrl: './main.component.html',
  styleUrl: './main.component.scss'
})
export class MainComponent implements OnInit{


  public ConnectionName: string = '';



  constructor(private route: ActivatedRoute, private http: HttpClient, private AppConfig: ApplicationConfigService, private cdr: ChangeDetectorRef) {
    this.ConnectionName = AppConfig.connectionName;
  }

  ngOnInit(): void {
    console.log("ConnectionName: " + this.ConnectionName);
  }
}


Invalid Cyrillic filename in chrome.downloads.download in Linux

I get Error: Invalid filename when I try to download any file with Cyrillic name in my Google Chrome Extension by chrome.downloads.download. It works fine in Windows, but it does not work in Fedora Linux 39 Workstation. If I change my OS locale to Belarusian — I get the same error.

Do you have any suggestions how to fix it?

It is a simple code in background script:

chrome.downloads.download({
    url : e.data.link,
    filename : name,
});

How can i stop triggering component that is added to DataTable when i used .destroy() function?

I have added custom component in datatable.

Here is custom component:
enter image description here

Here is js code:

function customizeSeeteleDatatable()
        {
            //Removed default search box
            $('#seeteledatatable_filter').remove();
            $(".row").find(".col-md-6").removeClass("col-md-6");
            const search_component = '<div class="customize-tan-search" style="display:flex; width:100%; margin-bottom:10px;"><select class="form-control search_tan1"><option value="">Select Attribute</option></select><input type="text" placeholder="Search data" class="form-control search_tan1_value">'
                                    + '<select class="form-control search_tan2"><option value="">Select Attribute</option></select><input type="text" placeholder="Search data" class="form-control search_tan2_value">'
                                    + '<select class="form-control search_tan3"><option value="">Select Attribute</option></select><input type="text" placeholder="Search data" class="form-control search_tan3_value">'
                                    + '<button class="btn btn--dark tansearch" style="margin-left:10px; line-height:0;">Search</button><button class="btn btn--dark cleartansearch" disabled style="line-height: 0">Clear</button></div>'
            $('#seeteledatatable_length').append(search_component);
            $('#seeteledatatable_length').css({'display': 'flex'});
            $('select[name="seeteledatatable_length"]').css('width', '60px');
            $('#seeteledatatable_length *').css({ 'font-size': '12px', 'height': '25px' });
            $('.tansearch, .cleartansearch').css({ 'padding': '12px' });
            $('.search_tan1, .search_tan2, .search_tan3').css({'padding': '0', 'margin-left':'5px', 'margin-right':'2px'})
    
            const export_button = '<div class="col-md-4" style="text-align: center; align-self:center"><button class="btn btn--dark tanexport" disabled>Export Data</button></div>'
            $('#seeteledatatable_wrapper').children().eq(2).children().eq(0).removeClass('col-md-5').addClass('col-md-3');
            $('#seeteledatatable_wrapper').children().eq(2).children().eq(1).removeClass('col-md-7').addClass('col-md-5');
            $('#seeteledatatable_wrapper').children().eq(2).children().eq(0).after(export_button);
            getFromIndexedDbSession("ctc_tan_data").then((data) => {
                if (data) {
                    const tanDataHeader = Object.keys(data[1][0]['tan_data'][0]);
                    for (let i = 0; i < tanDataHeader.length; i++)
                        $('.search_tan1, .search_tan2, .search_tan3').append('<option value="' + tanDataHeader[i] + '">' + tanDataHeader[i] + '</option>');
                    if(tan_data_search)
                    {
                        var data = cloneObject(datatable_data['ctc_tan_data_page_search'])
                        var payload = data[0]
                        $('.search_tan1').val(payload.attribute1);
                        $('.search_tan1_value').val(payload.attribute1_value);
                        $('.search_tan2').val(payload.attribute2);
                        $('.search_tan2_value').val(payload.attribute2_value);
                        $('.search_tan3').val(payload.attribute3);
                        $('.search_tan3_value').val(payload.attribute3_value);
                        $('.cleartansearch').prop('disabled', false);
                    }
                    $('.loaderimage').hide();
                }
                else
                {
                    $('.loaderimage').hide();
                }
              });
    
    }
         
    function seeteledata_render(data) {
                var tanDataHead = ''
                var tanRowData = ''
                $('#seeteledatatable').DataTable().destroy();
                $('#deploymentiddetail').DataTable().destroy();
                if (!data || !data[0]['tan_data'].length) {
                        $('#tandataheader').empty();
                        var tanDataHead = "<table><tr><td>No Data</td></tr></table>";
                        var cleanedTag = purifyDOM(tanDataHead);
                        $('#tandataheader').html(cleanedTag);
                        $('#tanrowdata').empty();
                        var tanRowData = "<table><tr><td>No Data</td></tr></table>";
                        cleanedTag = purifyDOM(tanRowData);
                        $('#tanrowdata').html(cleanedTag);
                        $('#seeteledatatable').DataTable({ "searching": false });
                        customizeSeeteleDatatable();
                    return;
                }
                const tanDataHeader = Object.keys(data[0]['tan_data'][0]);
                for (var head = 0; head < tanDataHeader.length; head++) {
                    tanDataHead += '<th style="width: 10%">' + tanDataHeader[head] + '</th>'
                }
                $('#tandataheader').empty()
                tanDataHead = "<table><tr>" + tanDataHead + "</tr></table>"
                var cleaned_tag = purifyDOM(tanDataHead)
                $('#tandataheader').html(cleaned_tag)
                $.each(data[0]['tan_data'], function (index, element) {
                    var rowElements = ''
                    var rowStart = '<tr>'
                    var rowElements = "<td>" + "Data" + "</td>";
                    var rowEnd = '</tr>'
                    tanRowData += rowStart + rowElements + rowEnd
                });
                $('#tanrowdata').empty()
                tanRowData = "<table>" + tanRowData + "</table>"
                var cleaned_tag = purifyDOM(tanRowData)
                $('#tanrowdata').html(cleaned_tag)
                $('#seeteledatatable').DataTable({
                    "lengthMenu": [10, 20, 50, 100],
                    "pageLength": 10,
                    "initComplete": function (settings, json) {
                        $("#seeteledatatable").wrap("<div style='overflow:auto; width:100%;position:relative;'></div>");

                },
                "oLanguage": {
                    "sInfo": "Showing _START_ to _END_ entries",
                    "sLengthMenu": "Show _MENU_"
                },
            });
            customizeSeeteleDatatable();
    
        }

$(document).on('click', '.pagination a', async function(event) {
     data = [];    
     seeteledata_render(data);
});

Here is problem:

I have to destroy table and reinitiate table on every page number click because i am using backend pagination that calls an API on every page number click. And data rendered in custom component is static and comes from Indexeddb. Due to more data that should render in custom component, its taking more time when i click on new page number.

How can i preserve custom component when i use $('#seeteledatatable').DataTable().destroy(); so that its dont re-render every time i click on new page number ?

how can i solve this problem??.

Javascript getattribute from each element in array

i have this code and i want to get a new array with the href attribute of each element in the array; maybe there is a different way to do it

let countries = document.querySelectorAll('.el');
let countriesList = Array.prototype.slice.call(countries);
let arra = countriesList.map(link);
function link() {
   for(let i = 0; i < countriesList.length; i++) {
      countriesList[i].getAttribute('href');
   }  
}
console.log(arra)
<div>
  <a class='el' href='italy.php'>Italy</a>
  <a class='el' href='france.php'>France</a>
  <a class='el' href='japan.php'>Japan</a>
  <a class='el' href='china.php'>China</a>
</div>

MudTooltip doesn’t always disappear when cursor moves away

I am using MudTooltip in a Blazor web app (.NET 8, MudBlazor 6.18.0, Chrome).

When I hover over the menu icon, the tooltip appears.

Right-click the same menu icon and open it in a new tab.

Go back to the original tab and the tooltip is still there, even when not hovering over it.
Sometimes, I got the same bug with left-click.

Is this a bug of MudBlazor/MudTooltip? Any way to fix it permanently/temporarily?

enter image description here