How to set amount of an item dynamically in javascript

I am trying to integrate a payment gateway on my website. Here is my code

products.php

<div class='row footer'>
 <div class='col-5 col-lg-5'>
    <button class='btn btn-action kkiapay-button' 
      amount-price='" . $row['price'] . "' 
      onclick='openKkiapayWidget()'>" . $row['action'] . "
    </button>
 </div>
 <div class='col-7 col-lg-7 price'>
    <span>XOF " . number_format($row['price']) . "</span>
 </div>
</div>

main.js

openKkiapayWidget({
    amount:"50000",
    position:"center",
    callback:"",
    theme:"red",
    key:"< my-api-key >"
});

Now, the problem is that there are many products with different prices; but here I can only put a static amount (50000) which applies to all products when the action button is clicked. Is there any way I can dynamically get the price of products and set it in my function in case of a product that has a different price?

I tried this but it doesn’t work

var price = $(this).amount("price");
openKkiapayWidget({
    amount:""+price+"",
    position:"center",
    callback:"",
    theme:"red",
    key:"<my-api-key>"
});

JavaScripting in Mirth – Ignore DG1 segments Until Condition Is Met

DG1|1||Z3800^Single liveborn infant, delivered vaginally^I10|||A|||||||||||||||||||||
DG1|2||Z23^Encounter for immunization^I10|||S||||||||||||||||||||E|
DG1|3||A3800^Single liveborn infant, delivered vaginally^I10|||P||||||||||||||||||||E|
DG1|4||B3800^Single liveborn infant, delivered vaginally^I10|||S||||||||||||||||||||E|

The above message sample is formatted in a way that I only want to start reading the values of DG1 when DG1.6 = P. And then read in the DG1 segments after when DG1.6 is P. In the above example, I want to ignore DG1|1, DG1|2 and then only store the values of DG1|3 and DG1|4. I tried using localeCompare but soon realized that doesn’t look like what I can easily use. I also tried assigning A, P, and S numerical values to compare which I think will work (essentially adding |1|+1 when A = 1, |2|+2 when S = 2, etc. But I feel like I’m complicating it.

DG1 is a dynamic set in HL7 so it can be of any length.

Here’s my current code set that will ignore DG1 segment when DG1.6 is “A”.

var dxXML = '';
var dg1Count = msg['DG1'].length();

for (var i = 0; i < dg1Count; i++) {
    var dx;
    var poa;

    if (msg['DG1'][i] != undefined) {
        if (msg['DG1'][i]['DG1.6']['DG1.6.1'].toString() == 'A' || msg['DG1'][i]['DG1.6']['DG1.6.1'].toString() == 'ADMITTING') {
            //format: <Dx Code="${dx0}" POA="${poa0}" Pos="1"/>
            dx = '';
            poa = '';
            if (dxXML != '') {
                dxXML = dxXML + 'n<Dx Code="' + dx + '" POA="' + poa + '" Pos="' + i + '"/>';
            } else {
                dxXML = '<Dx Code="' + dx + '" POA="' + poa + '" Pos="' + i + '"/>';
            }
        }
        //normal dx. the first non-blank dx will be imported as PDX. This means the i can be any integer.
        else {
            dx = msg['DG1'][i]['DG1.3']['DG1.3.1'].toString();
            poa = msg['DG1'][i]['DG1.26']['DG1.26.1'].toString();
            
            if (dx == '') continue;
            if (poa == 'E' || poa == '') {
                poa = '1'; 
            }       
    
            if (dxXML != '') {              
                dxXML = dxXML + 'n<Dx Code="' + dx + '" POA="' + poa + '" Pos="' + i + '"/>';
            } else {                    
                dxXML = '<Dx Code="' + dx + '" POA="' + poa + '" Pos="' + i + '"/>';
            }
        }
    }
    else {
        //do nothing to not add the blank ones.
    }
}
$c('DX_DOM', dxXML);

Any guidance on how to accomplish this will be appreciated.

Vue-gapi keep google user logged in even when app is closed and then re-launched

I am currently working on my apps backup options. One option is to store a backup file to the users google drive. I am using VUE-GAPI wrapper. Right now I can successfully log the user in and connect to google drive to get a list of backup files.

What I am having a problem with is keeping the user logged in when the app is closed and then re-launched so that it automatically re connects to the users google drive.

I would like to know how that can be achieved with the google API.

I can get the users google Id and access token from when they login. I was thinking of saving that to the backend database and then on launch of my app process the information to re establish the authenticated link to the users drive. But I am unsure where to use this information for re authentication or if it is even possible to use that information.

this is what I have for my login

login() {
      window.gapi.auth2.getAuthInstance().signIn({
        scope: "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.metadata"
      }).then(() => {
          console.log('successfully authenticated');
          this.authenticated = true;
          this.userData = this.$gapi.getUserData();
          this.$gapi.refreshToken
          console.log(this.userData);
        })
        .catch((err) => {
          console.error("Login call failed: %s", err.message);
        });
    },

Any insight on this issue would be helpful or even an alternate solution to get this done would be great.

How get the href of each class and store it inside a list (javascript)?

There is a list I have with 7 entries. On the picture below you can see the area which I marked purple: 6 entries. You see the area which I marked blue, all the 7 entries got the same <a class “FPmhX notranslate MBL3Z”.
My question is how can I get the href of each entry and store them all in a list/array? In this example, the href of first entry is /foo.96/.

If my question is not clear please tell me and I will try to describe it differently! 🙂

enter image description here

jQuery click function not working on individual h4 items

I am trying to add a click event function to each name element in my function below for the autocomplete. When you click on the movie title, it should send that title through the getMovie and getQuotes function. However, the current code takes the last name in the autocomplete list and sends that title through, instead of the user click. I am not sure when the best solution is to the problem.

var sendTitle = function() {
  var title = $("input[name='movie-search-title']").val();
  getMovie(title)
  getQuotes(title)
}
$("input[name='movie-search-title']").keydown(function(e) {
  if (e.keyCode == 13) {
    e.preventDefault();
    sendTitle();
  }
})
// movie autocomplete 
var $input = document.getElementById('searchBox');
var baseUrl = "http://sg.media-imdb.com/suggests/";
var $result = document.getElementById('result');
$input.addEventListener('keyup', function() {
  //clearing blank spaces from input
  var cleanInput = $input.value.replace(/s/g, "");
  //clearing result div if the input box in empty
  if (cleanInput.length === 0) {
    $result.innerHTML = "";
  }
  if (cleanInput.length > 0) {
    var queryUrl = baseUrl + cleanInput[0].toLowerCase() + "/" +
      cleanInput.toLowerCase() +
      ".json";
    $.ajax({
      url: queryUrl,
      dataType: 'jsonp',
      cache: true,
      jsonp: false,
      jsonpCallback: "imdb$" + cleanInput.toLowerCase()
    }).done(function(result) {
      //clearing result div if there is a valid response
      if (result.d.length > 0) {
        $result.innerHTML = "";
      }
      for (var i = 0; i < result.d.length; i++) {
        var category = result.d[i].id.slice(0, 2);
        if (category === "tt" || category === "nm") {
          //row for risplaying one result
          var resultRow = document.createElement('p');
          resultRow.setAttribute('class', 'resultRow')
          //creating and setting description
          var description = document.createElement('div');
          description.setAttribute('class', 'description');
          var name = document.createElement('h4');
          var snippet = document.createElement('h5');
          if (category === "tt" && result.d[i].y) {
            name.innerHTML = result.d[i].l + " (" + result.d[i].y + ")";
          } else {
            name.innerHTML = result.d[i].l;
          }
          snippet.innerHTML = result.d[i].s;
          var nameText = name.innerHTML
          $(description).append(name);
          $(resultRow).append(description);
          $("#result").append(resultRow);
        }
        // problem here! 
        $(name).click(function(e) {
          e.preventDefault();
          var title = nameText.slice(0, nameText.lastIndexOf(" "))
          console.log(title)
          getMovie(title)
        });
      }
    });
  }
});

// movie search 
var getMovie = function(title) {
  $("#main").removeClass("hidden");
  $("#search-form").trigger("reset");
  //format the OMDB api url 
  var apiUrl = `http://www.omdbapi.com/?t=${title}&plot=full&apikey=836f8b0`
  //make a request to the url 
  fetch(apiUrl)
    .then(function(response) {
      // request was successful 
      if (response.ok) {
        response.json().then(function(movieData) {
          console.log(movieData)
          showMovie(movieData)
        });
      } else {
        alert("Error: title not found!");
      }
    })
    .catch(function(error) {
      alert("Unable to connect to cine score app");
    });
};
var getMovieId = function(currMovieTitle) {
  const settings = {
    "async": true,
    "crossDomain": true,
    "url": `https://imdb8.p.rapidapi.com/title/find?q=${currMovieTitle}`,
    "method": "GET",
    "headers": {
      "x-rapidapi-host": "imdb8.p.rapidapi.com",
      "x-rapidapi-key": "229d984177msh18d191b1335378fp137dcejsn7c92ab2acfaf"
    }
  };

  $.ajax(settings).done(function(response) {
    console.log(response);
    var specialId = response.results[0].id
    var specialId = specialId.replace("/title/", "")
    var specialId = specialId.replace("/", "")
    console.log(specialId)
    getSoundTrack(specialId)
  });
}
var getSoundTrack = function(specialId) {
  const settings = {
    "async": true,
    "crossDomain": true,
    "url": `https://imdb8.p.rapidapi.com/title/get-sound-tracks?tconst=${specialId}`,
    "method": "GET",
    "headers": {
      "x-rapidapi-host": "imdb8.p.rapidapi.com",
      "x-rapidapi-key": "229d984177msh18d191b1335378fp137dcejsn7c92ab2acfaf"
    }
  };

  $.ajax(settings).done(function(soundTrackData) {
    console.log(soundTrackData);
  });
}
var getQuotes = function(title) {
  $("#quote-items").html("");
  $("#movie-quotes-heading").removeClass("hidden");
  var title = title.replaceAll(" ", "_")
  const settings = {
    "async": true,
    "crossDomain": true,
    "url": `https://movie-and-tv-shows-quotes.p.rapidapi.com/quotes/from/${title}`,
    "method": "GET",
    "headers": {
      "x-rapidapi-host": "movie-and-tv-shows-quotes.p.rapidapi.com",
      "x-rapidapi-key": "229d984177msh18d191b1335378fp137dcejsn7c92ab2acfaf"
    }
  };

  $.ajax(settings).done(function(quoteData) {
      console.log(quoteData);
      showQuotes(quoteData)
    })
    .fail(function(xhr, status, error) {
      //Ajax request failed.
      var errorMessage = xhr.status + ': ' + xhr.statusText
      console.log(`Error - ${errorMessage}`);
      $("#movie-quotes-heading").addClass("hidden");
    });
}
var showMovie = function(movieData) {
  $("#movie-title").text(movieData.Title)
  let currMovieTitle = movieData.Title
  getMovieId(currMovieTitle);
  $("#year-rating").text(`${movieData.Year}, ${movieData.Rated}`)
  $("#genre").text(`${movieData.Genre}`)
  $("#synopsis").text(movieData.Plot)
  $("#poster").attr("src", movieData.Poster);
  $("#cast-list").text(`Main Cast: ${movieData.Actors}`)
  $("#director").text(`Director: ${movieData.Director}`)
  $("#writer").text(`Writer(s): ${movieData.Writer}`)
  $("#imdb-rate").text(`${movieData.Ratings[0].Source} - ${movieData.Ratings[0].Value}`)
  $("#tomatoes-rate").text(`${movieData.Ratings[1].Source} - ${movieData.Ratings[1].Value}`)
  $("#metacritic-rate").text(`${movieData.Ratings[2].Source} - ${movieData.Ratings[2].Value}`)
  var tomatoesRate = (movieData.Ratings[1].Value).replace("%", "")
  parseInt(tomatoesRate)
  if (tomatoesRate <= 60) {
    $("#tomatoes-rate").attr("src", "https://www.clipartmax.com/png/full/351-3516739_cherry-tomato-clipart-tomatoe-rotten-tomatoes-icon-png.png")
  } else if (tomatoesRate >= 60) {
    $("#tomatoes-rate").attr("src", "https://www.clipartmax.com/png/full/50-503981_rotten-tomatoes-fresh-logo.png")
  }
}
var showQuotes = function(quoteData) {
  $("#movie-quotes-heading").text("Movie Quotes")
  quoteData.forEach(quoteItem => {
    var carouselItem = document.createElement("div")
    $(carouselItem).html(`<h4 class='quote'>"${quoteItem.quote}"<br><br><span class='quote-character'>-${quoteItem.character}</span></h4><br>`)
    $(carouselItem).appendTo("#quote-items");
  });
}
body {
  font: 400 15px Lato, sans-serif;
  line-height: 1.8;
  color: #818181;
}

.hidden {
  display: none;
}

h2 {
  font-size: 24px;
  text-transform: uppercase;
  color: #303030;
  font-weight: 600;
  margin-bottom: 30px;
}

h4 {
  font-size: 19px;
  line-height: 1.375em;
  color: #303030;
  font-weight: 400;
  margin-bottom: 30px;
}

.jumbotron {
  background-color: #40376E;
  color: #fff;
  padding: 100px 25px;
  font-family: Montserrat, sans-serif;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

form {
  width: 100%;
  display: flex;
  gap: 20px;
  flex-direction: row;
}

#results {
  display: flex;
  flex-direction: column;
  justify-content: left;
  width: 20%;
  text-align: left;
  color: antiquewhite;
}

.container-fluid {
  padding: 60px 50px;
}

.bg-grey {
  background-color: #f6f6f6;
}

.logo-small {
  color: #40376E;
  font-size: 50px;
}

.logo {
  color: #40376E;
  font-size: 200px;
}

.thumbnail {
  padding: 0 0 15px 0;
  border: none;
  border-radius: 0;
}

.thumbnail img {
  width: 100%;
  height: 100%;
  margin-bottom: 10px;
}

#tomatoes-rate {
  width: 80%;
  height: 80%;
}

.carousel-control.right,
.carousel-control.left {
  background-image: none;
  color: #40376E;
}

.carousel-indicators li {
  border-color: #40376E;
}

.carousel-indicators li.active {
  background-color: #40376E;
}

.item h4 {
  font-size: 19px;
  line-height: 1.375em;
  font-weight: 400;
  font-style: italic;
  margin: 70px 0;
}

.item span {
  font-style: normal;
}

.panel {
  border: 1px solid #40376E;
  border-radius: 0 !important;
  transition: box-shadow 0.5s;
}

.panel:hover {
  box-shadow: 5px 0px 40px rgba(0, 0, 0, .2);
}

.panel-footer .btn:hover {
  border: 1px solid #40376E;
  background-color: #fff !important;
  color: #40376E;
}

.panel-heading {
  color: #fff !important;
  background-color: #40376E !important;
  padding: 25px;
  border-bottom: 1px solid transparent;
  border-top-left-radius: 0px;
  border-top-right-radius: 0px;
  border-bottom-left-radius: 0px;
  border-bottom-right-radius: 0px;
}

.panel-footer {
  background-color: white !important;
}

.panel-footer h3 {
  font-size: 32px;
}

.panel-footer h4 {
  color: #aaa;
  font-size: 14px;
}

.panel-footer .btn {
  margin: 15px 0;
  background-color: #40376E;
  color: #fff;
}

.navbar {
  margin-bottom: 0;
  background-color: #40376E;
  z-index: 9999;
  border: 0;
  font-size: 12px !important;
  line-height: 1.42857143 !important;
  letter-spacing: 4px;
  border-radius: 0;
  font-family: Montserrat, sans-serif;
}

.navbar li a,
.navbar .navbar-brand {
  color: #fff !important;
}

.navbar-nav li a:hover,
.navbar-nav li.active a {
  color: #40376E !important;
  background-color: #fff !important;
}

.navbar-default .navbar-toggle {
  border-color: transparent;
  color: #fff !important;
}

footer .glyphicon {
  font-size: 20px;
  margin-bottom: 20px;
  color: #40376E;
}

.slideanim {
  visibility: hidden;
}

.slide {
  animation-name: slide;
  -webkit-animation-name: slide;
  animation-duration: 1s;
  -webkit-animation-duration: 1s;
  visibility: visible;
}

@keyframes slide {
  0% {
    opacity: 0;
    transform: translateY(70%);
  }
  100% {
    opacity: 1;
    transform: translateY(0%);
  }
}

@-webkit-keyframes slide {
  0% {
    opacity: 0;
    -webkit-transform: translateY(70%);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0%);
  }
}

@media screen and (max-width: 768px) {
  .col-sm-4 {
    text-align: center;
    margin: 25px 0;
  }
  .btn-lg {
    width: 100%;
    margin-bottom: 35px;
  }
}

@media screen and (max-width: 480px) {
  .logo {
    font-size: 150px;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Cine Score</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="assets/css/style.css" </head>

  <body id="mainPage" data-spy="scroll" data-target=".navbar" data-offset="60">

    <!-- Navigation Menu -->
    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>                        
      </button>
          <a class="navbar-brand" href="#myPage">Cine Score</a>
        </div>
        <div class="collapse navbar-collapse" id="myNavbar">
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#past-searches">Past Searches</a></li>
            <li><a href="#favorite-soundtracks">Favorite Soundtracks</a></li>
          </ul>
        </div>
      </div>
    </nav>

    <!-- Movie Search Jumbotron -->
    <div id="movie-search" class="jumbotron text-center">
      <h1>Search for a movie!</h1>
      <form id="search-form">
        <input id="searchBox" name="movie-search-title" type="text" class="form-control" size="50" placeholder="movie title" />
        <button id="searchBtn" type='button' class="btn btn-danger" onclick="sendTitle()">Search</button>
      </form>
      <div id="result"></div>
    </div>


    <main id="main" class=hidden>
      <!-- Container (main movie info) -->
      <div id="movie-info" class="container-fluid">
        <div class="row">
          <div class="col-sm-8">
            <h2 id="movie-title"></h2><br>
            <h4 id="year-rating"></h4>
            <h4 id="genre"></h4><br>
            <p id="synopsis"></p>
            <br><button id="get-soundtrack" class="btn btn-default btn-lg">Get the soundtrack</button>
          </div>
          <div class="col-sm-4">
            <span id="movie-poster">
        <img id="poster" src="" />
      </span>
          </div>
        </div>
      </div>

      <!-- Container (cast) -->
      <div id="cast" class="container-fluid bg-grey">
        <div class="row">
          <div id="cast-icon" class="col-sm-4">
            <span>
        <img  src="https://cdn-icons-png.flaticon.com/512/3873/3873990.png" />
      </span>
          </div>
          <div class="col-sm-8">
            <h2>Cast</h2><br>
            <h4 id="cast-list"></h4><br>
            <p id="director">
            </p>
            <p id="writer">
            </p>
          </div>
        </div>
      </div>

      <!-- Container (Score Section) -->
      <div id="score" class="container-fluid">
        <div class="row">
          <div class="col-sm-4">
            <span id="rating-img">
        <img id="tomatoes-rate" src=""/>
      </span>
          </div>
          <div class="col-sm-8 text-center">
            <h2>SCORE</h2><br>
            <h4 id="imdb-rate"></h4><br>
            <h4 id="tomatoes-rate"></h4><br>
            <h4 id="metacritic-rate"></h4><br>
          </div>
        </div>
      </div>

      <!-- Container (Sountrack Section) -->
      <div id="soundtrack" class="container-fluid text-center bg-grey">
        <h2>Sountrack</h2><br>
        <h4 id="movie-title-soundtrack">Movie Soundtrack</h4>
        <div class="container-fluid text-center">
          <p>Soundtrack Image</p>
          <p>List of songs</p>
          <button id="save-to-favorites" class="btn btn-default btn-lg">Save to favorites!</button>
        </div>
      </div>

      <!-- Container (Movie Quotes Section)-->
      <div id="movie-quotes" class="container-fluid text-center">
        <h2 id="movie-quotes-heading"></h2>
        <div id="quote-items" class="carousel slide text-center" data-ride="carousel"></div>
      </div>

      <!-- Footer -->
      <footer class="container-fluid text-center">
        <a href="#mainPage" title="To Top">
          <span class="glyphicon glyphicon-chevron-up"> Top </span>
        </a>
      </footer>
    </main>
  </body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <script src="assets/js/script.js"></script>

</html>

Convert JQuery Slide Functions To CSS Transitions

I wish to convert my FAQ section that utilizes Jquery to smoothly slide each question up and down into pure Javascript and CSS transitions.

The reason is for optimization and making a page as lightweight as possible. My goal is to remove jquery from my website altogether because it’s unnecessary.

I have uploaded my FAQ section into an HTML page and hosted it on a URL. This way, you can try it for yourself and see it in action. Please check here.

You can click on each title, and it will slide up and down. To have an exact replica of what I currently have is proving to be difficult. I have tried CSS transitions but it seems to require changing the height. Right now, I use display: block or display: none because the height is unknown. translateY(100%) to calculate the height at runtime didn’t seem to work either.

I will insert my current Jquery code here:

<style>

    #sectionFAQWrapper {

        padding-bottom: 30px;

    }
    #sectionFAQWrapper ul {

        padding: 5px 0px 12px 0px;
        margin: 0px;

    }
    #sectionFAQWrapper ul li {

        list-style-type: none;
        font-size: 20px;

    }
    #sectionFAQTopBanner {

        text-align: center;
        padding: 40px 0px;
        background: linear-gradient(90deg, rgb(74 79 177) 0%, rgb(31 32 82) 100%);
        color: #fff;
        margin-bottom: 30px;

    }
    #sectionFAQTopBanner h2 {

        font-weight: 600;
        letter-spacing: -1px;
        font-size: 46px;
        margin: 0;
        font-family: 'Oswald';

    }
    .questionItemWrapper {

        max-width: 1000px;
        margin: 0 auto;

    }
    #sectionFAQWrapper h3 {

        font-size: 30px;

    }
    #sectionFAQWrapper p {

        font-size: 20px;
        padding-bottom: 10px;
        font-weight: 400;
        margin: 0;

    }
    .questionItemBoldBlue {

        color: #4549a5;
        font-weight: 600;

    }
    .questionItemBoldTopBorderBlue {

        border-top: none;

    }
    .questionItemHeader {

        position: relative;
        background-color: rgba(0,0,0,.03);
        padding: 15px;
        margin: 0px 10px;

    }
    .questionItemHeader div {

        display: inline-block;
        font-family: 'Oswald';

    }
    .questionItemToggle {

        position: absolute;
        top: 17px;
        left: 14px;
        content: url(https://cdn.shopify.com/s/files/1/0022/5103/0563/files/doubleDownArrowBlack.png?v=1621284261);
        height: 34px;
        width: 34px;

    }
    .questionItemRotate180 {

        transform: rotate(180deg);
        content: url(https://cdn.shopify.com/s/files/1/0022/5103/0563/files/doubleDownArrowBlue.png?v=1621284261);

    }
    .questionItemQuestion {

        font-size: 28px;
        padding-left: 40px;

    }
    .questionItemContent {

        padding: 20px 20px 10px 20px;
        margin: 0;
        display: none;
        font-family: 'Open Sans';

    }

</style>


<div id="sectionFAQWrapper">

    <div id="sectionFAQInner">

        <div id="sectionFAQTopBanner">

            <h2>FREQUENTLY ASKED QUESTIONS</h2>

        </div>

        <div class="questionItemWrapper questionItemBoldTopBorderBlue">
            
            <div class="questionItemHeader">
                <div class="questionItemToggle questionItemBoldBlue questionItemRotate180"></div>
                <div class="questionItemQuestion questionItemBoldBlue">Title #1</div>
            </div>

            <div class="questionItemContent" style="display: block;">

                <p><b>Content Paragraph #1</p>

                <p><b>Content Paragraph #2</p>

            </div>

        </div>

        <div class="questionItemWrapper questionItemBoldTopBorderBlue">
            
            <div class="questionItemHeader">
                <div class="questionItemToggle"></div>
                <div class="questionItemQuestion">Title #2</div>
            </div>

            <div class="questionItemContent" style="display: none;">

                <p><b>Content Paragraph #1</p>

                <p><b>Content Paragraph #2</p>

            </div>

        </div>

</div>


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


<script>
    
    // When DOM has loaded
    $(document).ready(function() {

        // FAQ section
        $(".questionItemWrapper").click(function() {

          $(this).find('.questionItemContent').toggle( "slow", function() {});

          $(this).find('.questionItemQuestion').toggleClass("questionItemBoldBlue");
          $(this).find('.questionItemToggle').toggleClass("questionItemBoldBlue");
          $(this).find('.questionItemToggle').toggleClass("questionItemRotate180");
          $(this).toggleClass("questionItemBoldTopBorderBlue");

        });

    // End of document.ready()
    });

</script>

How can I reveal an element behind a flatlist and have it interactable in React Native?

I am trying to render an element that is positioned absolutely behind a flatlist and it will be revealed once the user scrolls to the bottom. The issue I am facing is that the element needs to be interactable, and the flatlist root element takes all pointerevents instead of the background element.

const FlatlistOverElement: FC = () => (
  <View style={{ flex: 1, width: '100%' }}>
    <FlatList
      data={data}
      style={{ flexGrow: 1 }}
      ListFooterComponent={() => (
        <View style={{ height: BACKGROUND_ELEMENT_HEIGHT, opacity: 0 }} />
      )}
      renderItem={RenderItem}
    />
    <AbsolutelyPositionedElementBehindFlatList />
  </View>
)

I have tried to remove pointerevents from the flatlist, then the flatlist is not scrollable.

I have tried to set the height of the flatlist smaller, and let the content overflow. This allows the user to interact with the element, but for that part of the screen, the user can not scroll the flatlist.

What other approach can I utilise in order to solve this issue ?

Prerender.io is not rendering homepage schema scripts but will render them everywhere else

I have an SPA that uses prerender.io to send static pages back to the browser primarily so that my schema scripts will be visible to the bots. If I use the structured data testing tool I can plainly see that everywhere except the homepage will render the schema scripts that exist in the body of the page. The homepage happens to have a website schema script in the head of the document that DOES render and is observed by the structured data testing tool, but the News and Events schemas won’t render. Elsewhere on the News and Events landing pages the schema scripts show up just fine in the structured data testing tool.

I checked the origin-request lamba that vets what URLs get rendered by prerender and the homepage is not included in the regex:

RegExp('/(catalog?|ill/*|wiki/*|docdel/*|ovgtsl2018/*|hackathon/*|rigorandrelevance/*|specialist/*|onesearch/*|instruction/potofgold/*|cds/*|directory/*|documents/*|eresources/*|guide-on-the-side/*|medieval/*|libcat/*|utilities/*|search?)')

Here is the full JS for the origin-request:


// Source: https://bravetheheat.medium.com/prerendering-and-aws-cloudfront-7a6635e9f2dc
module.exports.handler = async (event, context, callback) => {
  const request = event.Records[0].cf.request

  // Here are some paths we never want to hit prerender, even if they have the correct headers.
  const badPaths = new RegExp('/(catalog?|ill/*|wiki/*|docdel/*|ovgtsl2018/*|hackathon/*|rigorandrelevance/*|specialist/*|onesearch/*|instruction/potofgold/*|cds/*|directory/*|documents/*|eresources/*|guide-on-the-side/*|medieval/*|libcat/*|utilities/*|search?)')

  if (request.headers['x-prerender-token'] && request.headers['x-prerender-host'] && !badPaths.test(request.uri)) {
    request.origin = {
      custom: {
        domainName: 'service.prerender.io',
        port: 443,
        protocol: 'https',
        readTimeout: 20,
        keepaliveTimeout: 5,
        customHeaders: {},
        sslProtocols: ['TLSv1', 'TLSv1.1'],
        path: '/https%3A%2F%2F' + request.headers['x-prerender-host'][0].value,
      },
    }
  } else {
    // Not using prerender. Redirect to index.html since this is an SPA
    // ...Unless it's one of these file extensions, in which case the request should continue unaltered
    const validExtensions = [
      '.html',
      '.js',
      '.json',
      '.css',
      '.jpg',
      '.jpeg',
      '.png',
      '.ico',
      '.map',
      '.txt',
      '.kml',
      '.svg',
      '.webmanifest',
      '.webp',
      '.xml',
      '.zip',
      '.woff',
      '.woff2',
      '.ttf',
      '.otf',
    ]
    const parsedPath = path.parse(request.uri)
    if (parsedPath.ext === '' || !validExtensions.includes(parsedPath.ext)) {
      request.uri = '/index.html'
    }
  }
  callback(null, request)
}

Could anything here prevent the homepage from getting sent to prerender? Any suggestions on where to look or what to do to get the index.html file to be sent to prerender and back to the browser as a statically rendered file?

I have a feeling this has something to do with the fact this is an SPA and index.html is the only ACTUAL file in the file system. I know there is some magic that happens when the request for any other file (i.e. https://www.blahblah.com/catalog/shirt), which doesn’t exist, is requested and a 404 will result, which is then routed and handled and sent back as the URL path. Could the fact that index.html does not create this 404 be related to why the it’s not being sent to prerender?

How to sort the date form to latest to the oldest in array of objects react js

im trying to sort the date from this array of objects from the latest to the oldest. Im trying this code, copying the array to a new const then using it with sort, but I have the same result, no sorted date. My code is below:

const array=[...user?.editedBy]
console.log(array,"array")

const sortedDates = array?.sort((dateA, dateB) => dateB.date -dateA.date )
console.log(sortedDates,'sortedArray')

The first pic its the console log from array and the second from sortedDates,
So the same result, can someone please help me figure it out what Im missing???
*Thank you in advance *

enter image description here
enter image description here

How to prevent user from adding duplicate values in a array in Javascript

I have been looking all over for a correct answer on this but can’t seem to get one that works. I am trying to take input for an array that allows a max of 6 entries and does not allow duplicates. My code that I was playing around with only alerts me when I already have duplicates in the array. What would be the correct way to prevent a duplicate value from ever being added then displaying an error stating so?

I need to carry it over to list on the HTML doc but for right now I’m working on not allowing it to add duplicates so I’ve been using the Console tool

Any help would be much appreciated

Javascript:

"use strict"

//DO NOT MODIFY THE CODE BELOW
//wait for everything to load before executing this here code
$(document).ready(()=> {
    // create a new constant to hold a date reference for the current moment
    const dt = new Date();
    //Get the current year from the date reference, and put it
    //in the yield field in the footer.
    $('#year').text(dt.getFullYear());
});
//ADD YOUR CODE BELOW
let franzList = [];

function addTo() {
    franzList.push(document.getElementById("listItemInput").value);
    console.log(franzList);
}

function clearList() {
    franzList.length = 0; 
}


function hasDuplicates(array) {
    let valuesSoFar = Object.create(null);
    for (let i = 0; i < array.length; ++i) {
        let value = array[i];
        if (value in valuesSoFar) {
            return true;
        }
        valuesSoFar[value] = true;
    }
    return false;
}

$(document).ready(()=> {
    $("#addItemToList").click( () => {
        let error = false;
    
        const listItemInput         = $("#listItemInput").val().trim();

        $("#listItemInput").val(listItemInput);

        if(listItemInput == "") {
            console.error("input field blank");
            alert("Error! Franz Liszt's list item cannot be empty. This is unacceptable. 
Franz Lizst demands you correct his list!");
            error = true;
        } else if (franzList.length > 5) {
            console.error("6 items in the list only!");
            alert("Error! Franz Listz's list can only hold 6 items!");
            error = true;
        } else if (hasDuplicates(franzList) === true) {
            alert("Error! No duplicates allowed!")
            error = true;
        }
        $("#listItemInput").val(listItemInput);

        /*
        if(checkDuplicate(franzList) == true) {
            console.log("No Duplicates");
        } else {
            console.log("DUPLICATE NOT ALLOWED!");
            alert("NO DUPLICATES ALLOWED");
            error = true;
        }
        */

        if(!error) {
            addTo();
            $("#listItemInput").val("")
         //if error message is displayed form will not submit    
        } else {
            alert("Nothing added due to error");
        }

    })

    $("#clearList").click( () => {
        clearList();
    })

});

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <title></title>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="style.css"/>
  <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=Montserrat&family=Yellowtail&display=swap" rel="stylesheet">
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
  <script src="script.js"></script>
</head>
<body>
  <main>
    <h1>Franz Liszt's List</h1>
    <h2>Listing Things Since 1811!</h2>
    <p>Franz Liszt was more than a Hungarian composer, virtuoso pianist, conductor, music teacher, arranger, and organist of the Romantic era.</p>
    <p>He was more than a writer, philanthropist, and Fraciscan tertiary.</p>
    <p>No, Franz Liszt loved lists. </p>
    <p>Let us pay homage to Franz Lizst's list love by adding some items to our list below.</p>
      <div class="container">
        <div class="left">
        <!-- <label for="listItemInput">Input an item below:</label><br/>-->
          <h3>Input an item below:</h3>
          <input id="listItemInput" type="text" placeholder="Input item here"></input><br/>
          <button id="addItemToList">Add Item to Franz Liszt's List</button> <br/>
          <button id="clearList">Clear Franz Liszt's List</button> 
      <br/>
        </div>
      <div class="right">
        <h3>Franz Liszt's List Items:</h3>
        <ul id="listItemsHolder"></ul>
      </div>
  </div>
  <footer>
    &copy;<span id="year"></span> - Franz Kafka. All rights reserved?
  </footer>
  </main>
</body>
</html>

Automatic scroll bar

Good afternoon,

I’m creating a chat initially in PHP in which in the div called “Message” I load the conversation that was generated.

Through JavaScript/Ajax, I access the PHP file and bring up the conversation that was recorded, putting the data from this file in the Message div. For obvious reasons, after a message number X, a scroll is generated in this div. Using CSS, I set up an “overflor:auto” that generates the vertical scroll.

Initially, I couldn’t get the scroll bar to go down, showing the last message sent. Using the code below, I managed to do this…

$(document).ready(function()
{
    setInterval(function(){
        readMessage();
        var textArea = document.getElementById('Message');
        textArea.scrollTop = textArea.scrollHeight;
    },1000);
});

However, if I want to read a previous message, above and outside the field of view, when manually moving up the scroll (by clicking on the scrollbar and up OR on the mouse, scrolling up), the code above makes the scroll come down, not allowing me to read what I want from the conversation.

How can I solve this problem?

Thank you very much in advance!

How do I animate two letters swapping?

I am trying to make a website where hovering over a misspelling consisting of transposition of two letters corrects it, like so:

var swap = document.querySelector('.swap');

swap.addEventListener('mouseover', swapIn);
swap.addEventListener('mouseout', swapOut);

function swapIn(e) {
  e.target.parentNode.firstChild.classList.toggle('shifted-right');
  e.target.parentNode.lastChild.classList.toggle('shifted-left');
}

function swapOut(e) {
  e.target.parentNode.firstChild.classList.toggle('shifted-right');
  e.target.parentNode.lastChild.classList.toggle('shifted-left');
}
body {
  font-size: 24px;
}

.swap {
  display: inline;
}

span {
    -webkit-transition: all 0.3s linear;
    -moz-transition: all 0.3s linear;
    -o-transition: all 0.3s linear;
    transition: all 0.3s linear;
}

.shifted-right {
  margin-left: 20px;
  color: blue;
}

.shifted-left {
  margin-left: -25px;
  color: red;
}
E<div class="swap" id="swap"><span class="left-swap" id="ls">q</span><span class="right-swap" id="rs">c</span></div>uis me vivit fortunatior?

However, as you can see, the letters don’t swap well, and besides, I don’t want to calculate the precise margins for each different letter width.

What’s a better approach to doing this?

TS7053: Element implicitly has an ‘any’ type

Sry for my stupid question, but i can`t search answer for my promlem.
TS7053: Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type ‘{ width: number; height: number; title: string; }’

let menu:{width:number; height:number; title:string} = {
width: 200,
height: 300,
title: 'My menu',
 }
function multiplyNumeric(menu:{width:number; height: number; title: string}):void {

for (let k in menu){
    if (typeof menu[k] === "number"){
        menu[k] = Number(menu[k]) * 2;
    }
}
}
multiplyNumeric(menu);