How do I make one if statement run after the other has run and the button is clicked again?

I’ve tried making if statements that activate other if statements but they just ran them both at the same time. I also tried else if statements but that didn’t seem to want to work… So how would I make an if statement that activates once the past if statement has been run and the button is pressed again. I hope that makes any sense in y’alls head. The help would be appreciated. 🙂

let One = true
let Two = false
let Three = false
function right() {
if(One === true){
if(Two === false){
document.getElementById("2").innerHTML = 1
 document.getElementById("1").innerHTML = ''
 Two = true
  One = false
  } else {
  if (Three === false) {
   document.getElementById("3").innerHTML = 1
   document.getElementById("2").innerHTML = ''
  Three = true
   Two = false
    }}}}

Why is the button created with createElement not showing?

let but1 = document.querySelector("#submit")
but1.addEventListener("click", displayTable);

function displayTable() {
  document.getElementById("setCriteria").classList.add("hide");
  let para = document.getElementById("table");

  const mathTYPE = document.querySelector('input[name="mathType"]:checked').value;
  const numberCHOICE = Number(document.querySelector('input[name="number"]:checked').value);
  let text = "";

  if (mathTYPE === "Addition") {
    for (let i = numberCHOICE; i < numberCHOICE + 1; i++) {
      for (let j = 0; j < 11; j++) {
        text += `${i} + ${j} = ${i+j}` + "<br>";
      }
    }
  } else if (mathTYPE === "Subtraction") {
    for (let i = numberCHOICE; i < numberCHOICE + 1; i++) {
      for (let j = 0; j < 11; j++) {
        text += `${i} - ${j} = ${i-j}` + "<br>";
      }
    }
  } else if (mathTYPE === "Multiplication") {
    for (let i = numberCHOICE; i < numberCHOICE + 1; i++) {
      for (let j = 0; j < 11; j++) {
        text += `${i} X ${j} = ${i*j}` + "<br>";
      }
    }
  } else {
    for (let i = numberCHOICE; i < numberCHOICE + 1; i++) {
      for (let j = 0; j < 11; j++) {
        text += `${i} / ${j} = ${i/j}` + "<br>";
      }
    }
  }
  para.innerHTML = text;
  createButton()


  function createButton() {
    let but2 = document.createElement("button");
    but2.textContent = "Go back to menu";
    document.body.appendChild(btn2);
    btn2.addEventListener('click', () => {
      document.getElementById("setCriteria").classList.remove("hide");
      para.classList.add("hide");
    })
  }
}
.hide {
  display: none;
  background-color: black;
}

body {
  background-color: pink;
  font-family: "Dancing Script", cursive;
  font-optical-sizing: auto;
  font-weight: 500;
  font-size: 1.5em;
  font-style: normal;
}

.intro {
  font-size: 1.8em;
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Dancing+Script:[email protected]&display=swap" rel="stylesheet">

<h1>Arithmetics</h1>
<section id="setCriteria">

  <p class="intro">Choose the type of indicator you want to practice:</p>

  <input type="radio" id="add" name="mathType" value="Addition">
  <label for="Addition">Addition</label><br>
  <input type="radio" id="sub" name="mathType" value="Subtraction">
  <label for="Subtraction">Subtraction</label><br>
  <input type="radio" id="mult" name="mathType" value="Multiplication">
  <label for="Multiplication">Multiplication</label><br>
  <input type="radio" id="div" name="mathType" value="Division">
  <label for="Division">Division</label><br>
  </form>
  <br>

  <p class="intro">Great! Now, let's decide what number you want to see the tables for:
  </p>

  <input type="radio" id="1" name="number" value="1">
  <label for="1">1</label><br>
  <input type="radio" id="2" name="number" value="2">
  <label for="2">2</label><br>
  <input type="radio" id="3" name="number" value="3">
  <label for="3">3</label><br>
  <input type="radio" id="4" name="number" value="4">
  <label for="4">4</label><br>
  <input type="radio" id="5" name="number" value="5">
  <label for="5">5</label><br>
  <input type="radio" id="6" name="number" value="6">
  <label for="6">6</label><br>
  <input type="radio" id="7" name="number" value="7">
  <label for="7">7</label><br>
  <input type="radio" id="8" name="number" value="8">
  <label for="8">8</label><br>
  <input type="radio" id="9" name="number" value="9">
  <label for="9">9</label><br>
  <input type="radio" id="10" name="number" value="10">
  <label for="10">10</label><br>
  </input>
  <br>
  <button type="submit" id="submit">Submit</button>
</section>
<p id="table"></p>

Hello, I want to build a simple website to see some basic math tables.

After the user selects a type of calculation and number, then click on submit button, they can see the result.

I would like to add a button at the bottom of the second page, that would have users go back to main page when they can select calculation type and number again.

However, that button does not show at the bottom of the second page.

How to share `response` between routes in Express for PayPal subscription?

I’m working on integrating PayPal subscriptions into my Node.js application using Express and encountered a problem sharing the subscription ID obtained from PayPal’s /create-subscription route with the /execute-subscription route.

The goal is to capture the subscriptionId from the response of the /create-subscription route:

const response = await axios.post("https://api-m.sandbox.paypal.com/v1/billing/subscriptions", subscriptionDetails, {
  headers: {
    Authorization: `Bearer ${access_token}`,
  },
});

And use it in the /execute-subscription route to activate the subscription:

const subscriptionId = response.data.id; 

However, I’m not sure how to properly pass subscriptionId between these two routes. Directly accessing response.data.id in the /execute-subscription route results in an undefined error, likely because response is not in scope.

Code Snippet

paypalRouter.post("/create-subscription", async (req,res) => {
  try {
    const subscriptionDetails = {
      plan_id: process.env.PAYPAL_SANDBOX_BUSSINESS_SUBSCRIPTION_PLAN_ID,
     
      application_context: {
        brand_name: "brand",
        return_url: "http://localhost:3001/paypal/execute-subscription",
        cancel_url: "http://localhost:3001/paypal/cancel-subscription",
      }
    };

    // Generar un token de acceso
    const params = new URLSearchParams();
    params.append("grant_type", "client_credentials");
    const authResponse = await axios.post(
      "https://api-m.sandbox.paypal.com/v1/oauth2/token",
      params,
      {
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        auth: {
          username: process.env.PAYPAL_CLIENT_ID,
          password: process.env.PAYPAL_SECRET,
        },
      }
    );

    const access_token = authResponse.data.access_token;

    const response = await axios.post(
      "https://api-m.sandbox.paypal.com/v1/billing/subscriptions",
      subscriptionDetails,
      {
        headers: {
          Authorization: `Bearer ${access_token}`,
        },
      }
    );

    console.log(response.data.id);
    console.error();
    return res.json({ subscriptionId: response.data.id, ...response.data });
  } catch (error) {
    console.log(error);
    return res.status(500).json("Something goes wrong");
  }
});



paypalRouter.get("/execute-subscription", async (req, res) => {
  const { token } = req.query; // El token de la suscripción que PayPal envía de vuelta

  try {
    // Paso 1: Obtener el Token de Acceso
    const params = new URLSearchParams();
    params.append("grant_type", "client_credentials");
    const authResponse = await axios.post("https://api-m.sandbox.paypal.com/v1/oauth2/token", params, {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
      auth: {
        username: process.env.PAYPAL_CLIENT_ID,
        password: process.env.PAYPAL_SECRET,
      },
    });

    const access_token = authResponse.data.access_token;

    const subscriptionId = response.data.id; 
    const executeResponse = 
    await axios.post(`https://api-m.sandbox.paypal.com/v1/billing/subscriptions/${subscriptionId}/activate`, {}, {
      headers: {
        Authorization: `Bearer ${access_token}`,
        'Content-Type': 'application/json'
      },
    });

    console.log("Subscription confirmed:", executeResponse.data);
    console.error();
        res.send("Subscription successful!");
  } catch (error) {
    console.error("Error executing subscription:", error.response ? error.response.data : error.message);
    res.status(500).send("An error occurred while executing the subscription.");
  }
});


Leaflet GeoSearch: Google Provider not working

I’m trying to incorporate search in my map using the Google Provider (I’m using this (Smeijer/Leaflet-GeoSearch) plugin with Leaflet), however I’m not able to make it work.
My code is very direct:

        const searchControl = new GeoSearch.GeoSearchControl({
            provider: new GeoSearch.GoogleProvider({
                apiKey: 'MY_GOOGLE_API_KEY'}),
            position: 'topright',
            style: 'bar',
            // provider: new GeoSearch.OpenStreetMapProvider(),
        });
        
        map.addControl(searchControl);

If I use the OSM provider (commented out in the code above), the search works fine (the results are kind of obsolete for my region, but it works) (Figure 1) . But if I use the Google Provider, nothing appears as a result of the search (Figure 2).

image

image

Some more details:

  • Both the Maps JS API and the Geocoding API are enabled on the Google Console (BTW, for the GridLayer I’m using GoogleMutant which uses the API key and it’s working flawless);
  • The API key is not under any restriction in the Google Console, since I’m only testing this integration for now;
  • The browser console outputs this:
    image
    I don’t think it is related to this problem, but I guess it doesn’t hurt to mention it.

How can I tell `yarn workspace` to refer to executables at the root of my Javascript monorepo?

I have a large Javascript (Typescript) monorepo with many subpackages:

root/
  package.json
  packages/
    packageA/
      package.json
    packageB/
      package.json
    ...
    packageZ/
      package.json

Libraries that I share across all subpackages are defined in root/package.json, two examples being vitest and typescript:

// root/package.json
...
"devDependencies": {
  "typescript": "^4.0.0",
  "vitest": "^1.0.0"
},
"dependencies": {
  "lodash": "^4.0.0"
}

So far, so good. The code in the subpackages (workspaces) has access to the libraries defined at the root; e.g., I can call lodash functions.

But say I then want to define a script in a subpackage:

// packageA/package.json
"scripts": {
  "test": "vitest $*",
  "build": "tsc --build"
}

If I try to run these scripts from a workspace, I get errors because yarn doesn’t know how to find the executable:

$ yarn workspace packageA test
command not found: vitest
$ yarn workspace packageA build
command not found: tsc

Ok, I can define the dependencies directly in packageA:

// packageA/package.json
"scripts": {
  "test": "vitest $*",
  "build": "tsc --build"
},
"devDependencies": {
  "typescript": "^4.0.0",
  "vitest": "^1.0.0"
}

Now yarn is fine with it:

$ yarn workspace packageA test
... stuff happens ...
$ yarn workspace packageA build
... stuff happens ...

… but I don’t want to define these dependencies once for every subpackage if I can help it. I’d rather define them once, at the root, both for simplicity and to ensure I’m always running exactly the same version in every package.

Is there a way to make this work? How can I refer to these executables at the root from a yarn workspace?

using useState inside a non react component – no error

I am not sure why this code works. Can someone explain?

File name : test.tsx

import { useState } from "react";

export const getComponents = () => {
  const hello = [].map(() => {
    const [state] = useState(0);
    return {
      b: "hello",
      d: <div>{state}</div>,
    };
  });
  return hello;
};

getComponents is not a React.isValidElement. Why am I able to use useState inside this function?

Codesandbox example : https://codesandbox.io/p/live/7f832aa1-c029-4083-98dd-c0068c502bc5

I would expect eslint to give me an error : ““react hooks must be called in a react function component or a custom react hook function”.”

amcharts maps PR polygon

Quiero eliminar las islas marcadas en la foto, pero son parte del poligono mayaguez, si quiero el que aparezca mayaguez pero solamente quiero eliminar esas islas que no me sirven I want remove this islands, but are part of the same polygon. the Id is “PR-MG”

Another example

I tried exclude the polygon, but i need the part in the map, so if exclude this polygon disappear all.

// Create polygon series var polygonSeries = chart.series.push( am5map.MapPolygonSeries.new(root, { geoJSON: am5geodata_puertoRicoLow, exclude: ["PR-VQ", "PR-CU", "PR-LZ", "PR-MG"] }) );

How can I call a method in a different component in vuejs?

The following code is not complete, but I wanted to create a method in pages/configurations.vue that called this.getTags() in setselectedMainMenu and this getTags() is in the sampleTypeModal.vue component. getSampleType is working, but how it is being called in the sampleTypes.vue component ends up being different, how can I call getTags correctly?

pages/configurations.vue

<template>
    <acc-layout-side-menu>
    
    <!-- Tabela Steps-->
    <sample-types
        v-if="selectedMainMenu == 4"
        ref="sampleType"
        class="full-height"
    ></sample-types>

    </acc-layout-side-menu>
</template>

<script>
import SampleTypes from '@/components/configurations/sampleTypes.vue';
export default {
    name: 'configurations',
    components: {
        
        SampleTypes
    },
    data() {
        return {
        //Menu Lateral
        selectedMainMenu: '1', 
        }
    },


    methods: {

        setselectedMainMenu(id){
            this.selectedMainMenu = id;
            localStorage.setItem('selectedMainMenu', id);
            switch(this.selectedMainMenu){
            case '1':
                break
            case '2':
                break
            case '3':
                this.getStepsList();
                break
            case '4':
                this.getSampleType();
                this.getTags();
                break
            default:
                return;
            }
        },

        getSampleType() {
            this.$nextTick(()=> {
                this.$refs.sampleType.getSampleType();
            })
        },        

    },
    mounted() {
        this.selectedMainMenu = '1';
    }
}
</script>

@/components/configurations/Modals/sampleTypeModal.vue

    <acc-data-table-v2
        :data="data2"
        :columns="columns2"
    >
    </acc-data-table-v2>

  <!-- Modal -->
  <sample-type-modal
    :visible.sync="isModalVisible"
    :modalTitle="modalTitle"
    :rowData="clickedRow"
    :rowData2="[]"
    :selectedSampleType="selectedSampleType"
    @refresh="getSampleType"
  />
</div>
 <script>
    import sampleTypeModal from '@/components/configurations/sampleType.vue';
      export default {
        name: "sampleTypes",
          components: {sampleTypeModal},
          props: {
          },
          data() {
            return {
                isModalVisible: false,
                modalTitle: null,
                selectedSampleType: null,
    
            // Tabela
            data2: [],

            isLoading: false,
            clickedRow: {},
            clickedRow2: [],
        }
    },

    methods: {


        async getSampleType(searchParams) {
            this.isLoading = true;
            try {
                const response = await this.$store.dispatch('getSampleTypeList', searchParams);
                this.data2 = response.data.data.data;
                this.lastPage = response.data.data.last_page;
                this.rowsPerPage = response.data.data.per_page || 20;
                this.currentPage = response.data.data.currentPage;
            } catch (error) {
                console.error('Error while fetching steps: ', error);
                this.$notify_error();
            } finally {
                this.isLoading = false;
            }
        },
    },
  };

@/components/configurations/Modals/sampleTypeModal.vue

<template>
    <acc-modal 
        :visible="visible"
        :title="modalTitle"
        @open="openModal"
        >
        <div class="custom-modal">
            <acc-form ref="form" :model="form" :rules="formRules">
            <div class="columns is-multiline">
                <div class="column is-6 py-0">
                    <acc-form-item :label="$t('app.table.name')" prop="description">
                        <acc-input v-model="form.description" autocomplete="off"></acc-input>
                    </acc-form-item>
                </div>
            </div>
            </acc-form>
        </div>
    </acc-modal>
</template>
<script>
export default{
     name: 'sampleTypeModal',


    data() {
        return {

            initialdata: null,
            isLoading: false,

            data2: [],
            tags: [],
            tagsdata: [
                { id: 1,  print_tag_id: '', number_prints: 1, is_deleted: false, is_edited: false, is_new: false},
            ],

        }
    },


    methods: {

        getTags() {
            this.$store.dispatch('getTagsList')
                .then(response => {
                if (response && response.data && response.data.data) {
                    this.tags = response.data.data;

                } else {
                    console.error('Invalid response structure: ', response);
                    this.$notify_error('Invalid response structure');
                }
                })
                .catch(error => {
                    console.error('Error while fetching sampleType: ', error);
                    this.$notify_error(error);
                })
        },
    }
}
</script>

scrape a JS-Rendered, JSON data using R

I’m trying to download some contents/data from a webpage with javascript rendered contents in R, After some searches I found a different solution but can’t get the exact required output,

here is one of the way so far I have tried

library(httr)
library(rjson)

link <- "https://rod.pulse.gop.pk/details_page.html?I=740287512"
response <- httr::POST(
  url = "https://rodb.pulse.gop.pk/registry_index_2/_search",
  httr::add_headers(
    .headers = c(
      "Authorization" = "'Basic ' + btoa('elastic:qZM2ov-qIa=UXr6+Gx8b')",  
      "Content-Type" = "application/json"
    )
  ), 
  body = link
)

data <- fromJSON(content(response, as="text"))

required data at a glance

data <- 
  structure(list(Id = 740287512L, UserId = 13887L, VendorId = 1L, 
                 UserWorkQueMasterId = 740237089L, RegisteredNumber = "310", 
                 JildNumber = "1489", PropertyNumber = "واقع رقبہ  موضع سوہان دیہاتی  اندر حدود  میونسپل کارپوریشن راولپنڈی تحصیل و ضلع راولپنڈی ", 
                 IsApproved = TRUE, IsJildCompleted = FALSE, BahiNumber = NA, 
                 RegistryDate = "1993-01-25", IsActive = TRUE, CreatedDate = "2023-10-23T20:09:19.310000", 
                 ModifiedDate = NA, CreatedBy = 13887L, ModifiedBy = NA, TehsilId = 112L, 
                 MauzaId = 0L, Address = "N/A", IsExported = NA, Area = "0-8-0-0", 
                 RegistryValue = 128000, RegistryExportImg = "cfe958064b6c79b71e03350b5394f32a", 
                 NonNullFCount = NA, NullFCount = NA, RegistryTypeId = 5L, 
                 MauzaName = NA, RegistryParties = list(structure(list(Id = 18595212:18595213, 
                                                                       Name = c("محمد یسین ", "چوہدری رحمت "
                                                                       ), SpouseName = c("شمس الدین ", "چوہدری الله دین "
                                                                       ), CNIC = c("21134087515", "0"), RegistryPartiesTypeId = 1:2, 
                                                                       CraetedDate = c("2023-10-23T20:09:19.310000", "2023-10-23T20:09:19.310000"
                                                                       ), ModifiedDate = c(NA, NA), CreatedBy = c(13887L, 13887L
                                                                       ), ModifiedBy = c(NA, NA), VendorId = c(1L, 1L), SequenceNumber = 1:2, 
                                                                       RegistryExportImg = c("b17f19516a4fc8742aa21ce8bf0340b4", 
                                                                                             "89c79a6b93dde25904088ce129b1a22a")), class = "data.frame", row.names = 1:2)), 
                 RegistryType = "بیع", Tehsil = "راولپنڈی"), row.names = 1L, class = "data.frame")

all the data is publicly available and any efficient solution would be acceptable

Blob image displaying from database

I’m literally going crazy. I can’t figure out where is the error in the code below whose purpose is to retrieve an image from a database and display it in a frame with id ‘img1’. I’ve tried every way but what I get is just a string that isn’t transformed into an image. Some advice?

<?php

//file foto.php

include './admin/conn.php';

if (!empty($_POST['photo'])) {

 $Id = $_POST['photo'];

  $query=$conny->query("SELECT * from picture where cf ='$Id'");
        while($row=$query->fetch_array()) {
        
    echo $row["image"];
         
        }
} else {
        echo $searchErr = "Errore nell'estrapolazione del dato IN/OUT";
    } 
    
?>
//file index.php

 $.ajax( {
                                method: 'POST',
                                url: 'foto.php',
                                async: false,
                                data:{
                                    photo: data14      
                                    },
                                
                                success: function (result) {
                                    if (result != null && result != "") {
                                    
                                     
                        alert(result);   //<<<<<< (i get a JFIF string)
                                
        
document.getElementById("img1").src= '<img src="data:image/jpeg;base64, base64_encode('+result+') width="150px" height="150px" />';    //<<<<< (i get an empty frame)
                                                    
                                }}
                            })

React state with JSX elements is setting the last ref in ref array to null

I have a piano key component. When a key is pressed a visual is created, which is set in a state “visual” so that the component rerenders with the new visual. This visual is a div which is also assigned a ref so that I can animate it easily. I have a counter ref to key into the “visual” state and “visual_ref” ref. After 3 seconds, I delete both the ref and the visual for the div as it is offscreen. Deleting the ref works fine, but deleting the visual deletes the corresponding visual, but also sets the last visual in the visual_ref to null. I do not know why

visual_ref.current 3 Visuals created. visual_ref.current[counter] is correctly deleted, however set_visuals deletion of its JSX element sets the last index of visual_ref.current to null. This is not because the last ref was assigned to it

PianoKey Component

 const audio = useRef(null)

  let visual_refs = useRef([])

  let curr_animation = useRef([null, true])

  let [visuals, set_visuals] = useState([])
  let glowline = useRef(null)

  let counter = useRef(0)

  useEffect(() => {
    console.log(visual_refs.current)
    if (visuals[counter.current] && curr_animation.current[1]) {
      curr_animation.current = [attribute_animation(visual_refs.current[counter.current], 'height', '0', '300000px', 1000000), false]
    }
    
  }, [visuals])


  useEffect(() => {
    if (pressed) {
      audio.current.play()

      set_visuals(prev_state => {
        curr_animation.current[1] = true

        return ({
          ...prev_state,
          [counter.current]: (
          <div key={`${counter.current}`} ref={ref => visual_refs.current[counter.current] = ref} 
          className={`visualizer-instance ${color === 'black' ? 'black-visualizer': ''}`}></div>
          )
      })}) 
      
      attribute_animation(glowline.current, 'opacity', '0', '1', 600, 'cubic-bezier(0,.99,.26,.99)')

    } else if (!pressed && pressed !== null && counter.current in visual_refs.current && curr_animation.current[0]) {

        curr_animation.current[0].pause()
        attribute_animation(visual_refs.current[counter.current], 'bottom', '0', '300000px', 1000000)
        attribute_animation(glowline.current, 'opacity', '1', '0', 3000, 'cubic-bezier(.19,.98,.24,1.01)')

        let curr_counter = counter.current
        setTimeout(() => {
          delete visual_refs.current[curr_counter]
          // BELOW DELETES EXTRA VISUAL REF
          set_visuals(prev_state => {
            const new_state = {...prev_state}

            delete new_state[curr_counter]
            return new_state
          })
        }, 3000, curr_counter)
          
        counter.current += 1
    }
  }, [pressed])

Unexpected results getting Firebase snapshot in p5.js javascript

My variables seem to be getting their values from the previous snapshot instead of the current one. No errors.
console logged variables right after snapshot and they don’t match with the PivId, but they do match the previous snapshot. The PivId is correct but the data is not. Very confused.

function getData() { //load data from Firebase data for selected pivot
  console.log("get data")
  const dbref = ref(db);
  get(child(dbref, "myPivots/" + PivId)) //select child node path for selected pivot 
    .then((snapshot) => {
      if (snapshot.exists()) {
        Active = snapshot.val().active;
        Bat = snapshot.val().bat;
        Head = snapshot.val().head;
        LastUpdate = snapshot.val().lastUpdate;
        PrevHead = snapshot.val().prevHead;
        StartDate = snapshot.val().startDate;
        console.log(snapshot.val());
      } else {
        alert("No data found");
      }
    })
    .catch((error) => {
      alert(error)
    })
   console.log("Head "+ Head);
   console.log("Bat "+ Bat);
}

console
https://drive.google.com/file/d/1NKaiH5j3LSRIQdJxVHiwlJqsnoznUcNL/view?
usp=sharing

firebase
https://drive.google.com/file/d/1dsvBtKJCtaU41ocru5xLqyZA1HXaLrd_/view?usp=sharing

Terminating turbolinks:click event listener once a user has navigated away from a form

I have been tasked with creating an unsaved changes alert in a form partial for a Ruby on Rails app (full MVC architecture). While not new to Rails, I am new to Views, turbolinks, and jquery and have been struggling here and there, so please bear with me.

Users should encounter the alert when they have made changes to the form that are unsaved/not submitted, and attempt to navigate elsewhere in the app, close their tab/browser window, refresh the browser, or use the browsers navigation arrows.

Currently, the code is working somewhat as intended. My main issue is that the turbolinks:click event listener continues to listen for click events after the alert has been dismissed and the user begins to navigate away from the form. If I dismiss the alert, click anywhere else in the app, the alert reappears. I then have to dismiss the alert every time I click somewhere. If I click ‘cancel’ on the alert, it appears as if the alert windows have stacked on top of one another (likely the amount of times I clicked around).

I am writing this as a script inside of the _form partial.

How can I terminate the turbolinks:click event listener once the user has dismissed the alert?

This is my first question on stackoverflow – please let me know if any protocol wasn’t followed. Thanks!

<script>
 
    function unsavedChangesAlert() {

      // initialize
      let formChanged = false;

      // add selectors, array for readability/maintainability
      const formSelectors = [

        '.custom-control-input', //handles section (GL, WC, etc.) toggles

        '.gl_fields select',
        '.gl_fields input[type="checkbox"]',
        '.wc_fields select',
        '.wc_fields input.commaClass',
        '.wc_fields input[type="checkbox"]',
        '.auto_fields select',
        '.auto_fields input[type="checkbox"]',
        '.umb_fields select',
        '.umb_fields input[type="checkbox"]',
        '.pl_fields select',
        '.pl_fields input[type="checkbox"]',
        '.im_fields input.commaClass',
        '.oh_fields input.commaClass',
        '.gk_fields input.commaClass',
        '.cg_fields input.commaClass',
        '.pollution_fields input.commaClass',
        '.pollution_fields input[type="checkbox"]',
        '.re_fields input.commaClass',
        '.re_fields input[type="checkbox"]',
        '.ava_fields input.commaClass',
        '.ava_fields input[type="checkbox"]',
        '.db_fields input.commaClass',
        '.db_fields input[type="checkbox"]',
      ];

      //take formSelectors array, join into single string
      const formInputs = document.querySelectorAll(formSelectors.join(', '));

      // event listeners for form inputs
      $(formInputs).on('change keydown input', function() {
        formChanged = true;
      });


      //to prevent alert on form submission; set flag to false
      let formSubmitted = false;

      // add event listener for beforeunload (browser refresh, browser close window/tab)
      $(window).on('beforeunload', function(event) {
        if (formChanged && !formSubmitted) {
          event.preventDefault();
          window.scrollTo(0, document.body.scrollHeight);

        };
      }); 

 $('#edit_ins_reqs_form').submit(function(){
        //set flag to true when form is submitted
        formSubmitted = true;
      });

 let confirmationShown = false;

  $(document).on('turbolinks:click', function(event) {
  console.log('one');
  const editForm = $('#edit_ins_reqs_form');

  // check if the clicked element or its ancestors contain the edit form
  if (!$(event.target).closest('#edit_ins_reqs_form').length) {

    console.log("two")
    const saveButton = $(event.target).closest('.submit');

    //check to exclude the save button
    if (!saveButton.length && !$(event.target).hasClass('submit')) {
      if (!confirmationShown && !confirm('turbolinks!!! You have unsaved changes. Are you sure you want to leave this page?')) {
        event.preventDefault();
        $(window).scrollTop($(document).height());
        confirmationShown = true;
      } else {
        //remove event listener once triggered
        $(document).off('turbolinks:click')
      }
    }
    console.log("three")
  }
});



  };

  //call it
  $(document).on('turbolinks:load', function() { 
    unsavedChangesAlert();
  });

</script>

Acrobat 2020 editing the Header or Footer in a PDF Document

I use Acrobat 2020 (pro) to edit a large document. When I insert a “Header” I can use the tool to edit “headers and footers” like in a Word Document.
https://www.adobe.com/au/acrobat/hub/how-to/how-to-use-headers-footers-in-pdfs.html
I have to do this because the document is puzzled of 100 different documents and is printed at the end.
The header contains a Page-Number and when I update the header, Acrobat will find the pagenumbers in all this textboxes and update the numbers (or text).
Now, I will find this pagenumbers in the document and a textbox nearby. Is there anybody who knows how to do this? Acrobat will find it, then eg VBA or Java Script will find it too.
But how?