问:
problems trying to create a Search Box/Filter with Vanillajavascript
In the Javascript exercise I am doing, besides creating a kind of bookstore out of a Json file, I have to include a search field, to filter by book title or writer's name.
To do that, I am following W3school tutorial about it, but I am struggling to translate it to my code. Because I am not sure over which elements to loop , etc...

I would much appreciate any help to guide me on the right direction.

This is the Html and JS I have written so far :

var data = {"books":[{"portada":"https://preview.ibb.co/bC5ELQ/alex_min.png","detalle":"https://preview.ibb.co/deD10Q/alex_min.png","titulo":"Dímelo en palabras","descripcion":"El polifacético escritor catalán n.","idioma":"es"},{"portada":"https://preview.ibb.co/dvM9AQ/eddie_min.png","detalle":"https://preview.ibb.co/hnT0H5/eddie_min.png","titulo":"Lo veo negro","descripcion":"una obra maestra de la ciencia ficción.","idioma":"es"},{"portada":"https://preview.ibb.co/nF3Un5/flecha_min.png","detalle":"https://preview.ibb.co/dUgbZk/flecha_min.png","titulo":"Mi algoritmo es más rápido","descripcion":"Un libro que te deja atado a su trama ","idioma":"es"}]}

var allBooks = data.books;

function getBooks () {

    var flipBox = document.getElementById("flipBox");

    for (i=0; i < allBooks.length; i++) {

        //create flip elements

        var flipContainer = document.createElement("div");
        flipContainer.setAttribute("class", "flipContainer")

        var flipper = document.createElement("div");
        flipper.setAttribute("class", "flipper");

        var front = document.createElement("div");
        front.setAttribute("class", "front");

        var back = document.createElement("div");
        back.setAttribute("class", "back");

        var coverImage = document.createElement("img");
        coverImage.setAttribute("src", allBooks[i].portada);
        coverImage.setAttribute("alt", allBooks[i].titulo);

        //add title

        var title = allBooks[i].titulo;
        var bookTitle = document.createElement("span");
        bookTitle.setAttribute("class", "bookTitle");
        bookTitle.innerHTML = title;
        var titleContainer = document.createElement("div");
        titleContainer.setAttribute("class", "titleContainer");

        //add title to div and then to back
        titleContainer.append(bookTitle);
        back.append(titleContainer);

        // add description

        var bookDescription = allBooks[i].descripcion;
        var text = document.createElement("div");
        text.setAttribute("class", "text");
        text.innerHTML = bookDescription;
        back.append(text);

        // add more-info button . First container for a-tag, then A-tag, then button
        var anchorContainer = document.createElement("div");
        anchorContainer.setAttribute("class", "anchorContainer")
        back.append(anchorContainer);

        var anchor = document.createElement("a");
        anchor.setAttribute("id", "anchor");
        anchor.setAttribute("href", allBooks[i].detalle);
        anchor.setAttribute("data-fancybox", "images");
        anchorContainer.append(anchor);

        var button = document.createElement("button");
        button.setAttribute("class", "button");
        button.innerHTML = "More Info";

        anchor.append(button);

        //Add elements

        front.appendChild(coverImage);
        flipper.append(front, back);
        flipContainer.append(flipper)

        flipBox.append(flipContainer);

    }
}
getBooks()

function searchBox() {
  // Declare variables
  var input, filter, ul, li, a, i, txtValue;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();

    console.log(filter);

  // Loop through all list items, and hide those who don't match the search query
  for (i = 0; i < allBooks[i].length; i++) {
    a = allBooks[i].getElementsByTagName("a")[0];
    txtValue = a.textContent || a.innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
}
searchBox()```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <link rel="stylesheet" href="bookshop_css.css">
<!-- I have deleted bootstrap and fancybox links and scripts, to make it shorter -->

  <title>Bookshop</title>
</head>

<body>

  <h1> here comes the books</h1>

  <div class="searchBar">
    <input type="text" id="myInput" onkeyup="searchBox()" value="" placeholder="Search for book title" title="Type in a name">
  </div>

  <div id="flipBox" class="container-fluid boxContainer grid">
  </div>
  <script src="bookshop_just_data.js"></script>
  <script src="bookshop_myscript.js"></script>
</body>
</html></code>```

答:
allBooks is an array of objects, hence allBooks[i] is an object, hence allBooks[i].length is undefined, since length is not an object's property or method :).

That said, there's no need to traverse allBooks (note there are many ways to achieve what you are trying). Here's my shot at it.

You just need to get the input text and test it against the title and author's name (which I couldn't find in your question, so this answer works only with the books' titles).

The books' titles are shown inside each span.bookTitle, so those are the first you should cache in a variable. Notice, caching them from the beginning will help with performance down the road when there are many books, preventing the need for querying the DOM on each keystroke BUT, remember to update that cache if you plan on adding books dynamically to the list.

Then you just need to traverse those spans and test their text contents, that's forEach. Then, every time you find a match, you show/hide the span's ancestor that matches .flipper.

Last but not least, I recommend not in-lining events in your html, try attaching them in JS, also don't use keyup for this, because it will process unnecessary keystrokes like Shift, Ctrl, etc., unless that's what you want..., if not go with input.

HIH

(()=>{let data = {"books": [{"portada": "https://preview.ibb.co/bC5ELQ/alex_min.png", "detalle": "https://preview.ibb.co/deD10Q/alex_min.png", "titulo": "Dímelo en palabras", "descripcion": "El polifacético escritor catalán n.", "idioma": "es"}, {"portada": "https://preview.ibb.co/dvM9AQ/eddie_min.png", "detalle": "https://preview.ibb.co/hnT0H5/eddie_min.png", "titulo": "Lo veo negro", "descripcion": "una obra maestra de la ciencia ficción.", "idioma": "es"}, {"portada": "https://preview.ibb.co/nF3Un5/flecha_min.png", "detalle": "https://preview.ibb.co/dUgbZk/flecha_min.png", "titulo": "Mi algoritmo es más rápido", "descripcion": "Un libro que te deja atado a su trama ", "idioma": "es"}]};
            let allBooks = data.books;
            function getBooks() {
                let flipBox = document.getElementById("flipBox");
                for (i = 0; i < allBooks.length; i++) {
                    let flipContainer = document.createElement("div");
                    flipContainer.setAttribute("class", "flipContainer")

                    let flipper = document.createElement("div");
                    flipper.setAttribute("class", "flipper");

                    let front = document.createElement("div");
                    front.setAttribute("class", "front");

                    let back = document.createElement("div");
                    back.setAttribute("class", "back");

                    let coverImage = document.createElement("img");
                    coverImage.setAttribute("src", allBooks[i].portada);
                    coverImage.setAttribute("alt", allBooks[i].titulo);

                    //add title

                    let title = allBooks[i].titulo;
                    let bookTitle = document.createElement("span");
                    bookTitle.setAttribute("class", "bookTitle");
                    bookTitle.innerHTML = title;
                    let titleContainer = document.createElement("div");
                    titleContainer.setAttribute("class", "titleContainer");

                    //add title to div and then to back
                    titleContainer.append(bookTitle);
                    back.append(titleContainer);

                    // add description

                    let bookDescription = allBooks[i].descripcion;
                    let text = document.createElement("div");
                    text.setAttribute("class", "text");
                    text.innerHTML = bookDescription;
                    back.append(text);

                    // add more-info button . First container for a-tag, then A-tag, then button
                    let anchorContainer = document.createElement("div");
                    anchorContainer.setAttribute("class", "anchorContainer");
                    back.append(anchorContainer);

                    let anchor = document.createElement("a");
                    anchor.setAttribute("id", "anchor");
                    anchor.setAttribute("href", allBooks[i].detalle);
                    anchor.setAttribute("data-fancybox", "images");
                    anchorContainer.append(anchor);

                    let button = document.createElement("button");
                    button.setAttribute("class", "button");
                    button.innerHTML = "More Info";

                    anchor.append(button);

                    //Add elements

                    front.appendChild(coverImage);
                    flipper.append(front, back);
                    flipContainer.append(flipper)

                    flipBox.append(flipContainer);

                }
            }
            getBooks();

            //cache the spans
            let elements = document.querySelectorAll('span.bookTitle');
            function searchBox() {
                let input = document.getElementById('myInput'),
                        filter = input.value.toLowerCase();
                applyInput(elements, filter);
            }

            function applyInput(elements, text) {
                Array.prototype.forEach.call(elements, function (element) {
                    let parentToAffect = element.closest('.flipper');
                    if (RegExp(text).test(element.textContent.toLowerCase())) {
                        parentToAffect.style.display = 'block';
                    } else
                        parentToAffect.style.display = 'none';
                });
            }

            document.getElementById('myInput').addEventListener('input', () => {
                searchBox();
            });
            //searchBox() <---- no need to execute this function on page load
            })();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <link rel="stylesheet" href="bookshop_css.css">
<!-- I have deleted bootstrap and fancybox links and scripts, to make it shorter -->

  <title>Bookshop</title>
</head>

<body>

  <h1> here come<!--s--> the books</h1>

  <div class="searchBar">
    <input type="text" id="myInput" value="" placeholder="Search for book title" title="Type in a name">
  </div>

  <div id="flipBox" class="container-fluid boxContainer grid">
  </div>
  <script src="bookshop_just_data.js"></script>
  <script src="bookshop_myscript.js"></script>
</body>
</html></code>```

(() => {
  let data = {
    "books": [{
      "portada": "https://preview.ibb.co/bC5ELQ/alex_min.png",
      "detalle": "https://preview.ibb.co/deD10Q/alex_min.png",
      "titulo": "Dímelo en palabras",
      "descripcion": "El polifacético escritor catalán nos muestra en su novela más romántica como, básicamente, nuestra relación es tan fácil como decirnos las cosas como son. Tal cual.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/dvM9AQ/eddie_min.png",
      "detalle": "https://preview.ibb.co/hnT0H5/eddie_min.png",
      "titulo": "Lo veo negro",
      "descripcion": "En ocasiones crees entender algo cuando te lo están explicando, pero en el momento de ponerte a programar surge siempre esta duda. ¿Lo ves?. Eduard Català se saca de la manga una obra maestra de la ciencia ficción.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/nF3Un5/flecha_min.png",
      "detalle": "https://preview.ibb.co/dUgbZk/flecha_min.png",
      "titulo": "Mi algoritmo es más rápido",
      "descripcion": "De nuevo Guerrero, de nuevo el flecha. Un libro que te deja atado a su trama desde que abres la cubierta. Te atrapa rápido, muy rápido, hyper rápido.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/hPod4k/joan_min.png",
      "detalle": "https://preview.ibb.co/f6J6qQ/joan_min.png",
      "titulo": "Amazing Design Art",
      "descripcion": "Delicado y cuidado en cada palabra, este segundo tomo de la Trilogía 'Amor Front-End' es de momento el más sofisticado del autor. Nos fascinó 'Romance CSS', nos encanta este, ¿Qué nos deparará 'Orgasmo JavaScript'?",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/iVRAuk/maruti_min.png",
      "detalle": "https://preview.ibb.co/fyBzn5/maruti_min.png",
      "titulo": "The Javascript Guru",
      "descripcion": "From India to Spain, this book explains us how your dreams like a developer can be real. Functions, Objects, Variables... All of JavaScript is here in this Amazing book.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/n82iEk/oruc_min.png",
      "detalle": "https://preview.ibb.co/h3GbZk/oruc_min.png",
      "titulo": "Azerbaijan Roulette",
      "descripcion": "Meanwhile you wait for the next Code challenge you can play some football with your mates... GOOOOOOOAAAAL!!",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/bHMWPk/roosy_min.png",
      "detalle": "https://preview.ibb.co/iwNGqQ/roosy_min.png",
      "titulo": "Java... what?",
      "descripcion": "For those of you that don't understand nothing about new technologies, Mr. Roosy arrives to give you some ray of light in your darkness. You'll never ask Java...what? again.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/n06LH5/vcarpio_min.png",
      "detalle": "https://preview.ibb.co/mJXuc5/vcarpio_min.png",
      "titulo": "Digital Nomad",
      "descripcion": "Entras a las 9 de la mañana, te repanchingas en tu silla, pones los pies en la mesa y empiezas a programar. La vida de un nómada digital puede ser maravillosa. Gran relato corto del Escritor y ex-programador de Facebook Victor Carpio.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/dPxsYv/Albert_min.png",
      "detalle": "https://preview.ibb.co/fwyY6F/Albert_min.png",
      "titulo": "El por qué de no usar Mustache",
      "descripcion": "El famoso escritor Albert Lara nos enseña el poder de JavaScript para crear plantillas y las razones por las que un sistema ideado justamente para este fin como es Mustache, no siempre es la mejor opción...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/e1z6tv/Bryn_min.png",
      "detalle": "https://preview.ibb.co/dVLfmF/Bryn_min.png",
      "titulo": "Shut up little bastards",
      "descripcion": "El silencio es necesario en estos tiempos para poder concentrarte. Bryn lucharÃ¡ contra viento y marea en esta cruda historia basada en hechos reales.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/fqbmtv/Eduardo_min.png",
      "detalle": "https://preview.ibb.co/mSBmRF/Eduardo_min.png",
      "titulo": "Sudo mucho",
      "descripcion": "Para qué aprender JavaScript si puedes estar subiendo copas sin parar. La historia de Eduardo nos llevará de estar hundido en la mierda hasta seguir hundido en la mierda.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/ctuvmF/Erica_min.png",
      "detalle": "https://preview.ibb.co/n5zHYv/Erica_min.png",
      "titulo": "No contéis conmigo",
      "descripcion": "Hay veces que no se puede soportar la presión. Este es uno de esos casos. Erica no lo consiguió pero hay gente que dice haberla visto en ciertas noches de verano...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/hBtc0a/Gerard_min.png",
      "detalle": "https://preview.ibb.co/nKxFLa/Gerard_min.png",
      "titulo": "Asincronía y su puta madre",
      "descripcion": "¿Qué entendemos por asincronía? ¿Por qué existe en este maldito mundo? ¿No es suficientemente sencillo el mundo síncrono?. De Haro nos trae una obra de ciencia ficción con más de un giro que no te esperas.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/esZT6F/Juan_min.png",
      "detalle": "https://preview.ibb.co/g1ZjDv/Juan_min.png",
      "titulo": "El java empieza ahorita",
      "descripcion": "HTML, CSS, JavaScript e incluso Jquery son juegos de niÃ±os para un hombre que se lo propone. Pero Java ya son palabras mayores. Un reto que hay que aceptar y asumir que serÃ¡ duro. La parte front quedó atrás, el Java empieza ahorita.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/jv3c0a/Lluis_min.png",
      "detalle": "https://preview.ibb.co/b0st6F/Lluis_min.png",
      "titulo": "document.write()",
      "descripcion": "No necesito más. No quiero funciones que no sé como funcionan. Document.write() hace lo que quiero y cuando quiero. Trágico relato de un hombre con una obsesión...",
      "idioma": "ca"
    }, {
      "portada": "https://preview.ibb.co/bBJXYv/Muhammad_min.png",
      "detalle": "https://preview.ibb.co/dJuHYv/Muhammad_min.png",
      "titulo": "Learning Syntax",
      "descripcion": "A man with the need to learn every word of every new programming language. An almost impossible goal that will make him struggle with life and with his interior.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/ja3XYv/Nuria_min.png",
      "detalle": "https://preview.ibb.co/m72RRF/Nuria_min.png",
      "titulo": "Design First",
      "descripcion": "Por mucho que JavaScript ayude a darle funcionalidad a la pÃ¡gina, lo primordial es el diseño. Sin un buen diseÃ±o, una pagina cae por su propio peso. Nuria nos explica la importancia de un gran impacto visual.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/hCVqLa/Vicent_min.png",
      "detalle": "https://preview.ibb.co/ci0rtv/Vicent_min.png",
      "titulo": "Code of Vincent",
      "descripcion": "El escritor fantástico Vicent Clapés nos trae una historia que narra como un simple programador consiguió convertirse en un autentico guerrero a base de código. Batallas contra dragones de Jquery y Magos de Javascript en una aventura de lo más freek.",
      "idioma": "ca"
    }, {
      "portada": "https://preview.ibb.co/iVRmtv/Victor_min.png",
      "detalle": "https://preview.ibb.co/gL0D6F/Victor_min.png",
      "titulo": "El maestro del parÃ¡metro",
      "descripcion": "Cuando te das cuenta que 10 funciones similares se pueden transformar en una sola simplemente pasándole un par de parámetros te das cuenta de todo su potencial. Es entonces cuando de transformas en un maestro del parámetro.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/dGcsYv/Auger_min.png",
      "detalle": "https://preview.ibb.co/dDGWtv/Auger_min.png",
      "titulo": "Local Storage",
      "descripcion": "Llamadas JSON, objetos Javascript, Table Sorter, iframe, pantallas de loading... Todo esto es tiempo perdido para el usuario. Necesitamos algo que nos ayude con eso. Aquí es donde entra el poder del Local Storage. Gotcha!!",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/h8s4fa/Edu_min.png",
      "detalle": "https://preview.ibb.co/js1aLa/Edu_min.png",
      "titulo": "Difícil. A veces lo fácil aburre.",
      "descripcion": "Cómo funciona un sort por dentro? ¿Por qué usar esta función y no inventar una que nos complique más la vida?. Estas y otras preguntas en un libro orientado a esas personas que piensan fuera de la caja.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/csHsYv/Francesc_min.png",
      "detalle": "https://preview.ibb.co/hJsRRF/Francesc_min.png",
      "titulo": "No lo entiendo",
      "descripcion": "El escritor, en su biografía más completa hasta la fecha, nos pone en su piel durante su iniciación a la programación antes de trabajar en Google. Era joven, con toda la vida por delante, pero no entendía nada...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/gjX4fa/Ignasi_min.png",
      "detalle": "https://preview.ibb.co/iotN0a/Ignasi_min.png",
      "titulo": "La la la. City of code",
      "descripcion": "Código, código y más código. Entre incontables líneas de código se cuela este programador con gran experiencia autor de otros Best Sellers como 'Tucutucu Master' o 'Métele chicha a mi salchicha'...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/cV1QmF/Raul_min.png",
      "detalle": "https://preview.ibb.co/jSRaLa/Raul_min.png",
      "titulo": "Function Man",
      "descripcion": "Típico cuatro ojos que está todo el día programando y haciendo mierdas como esta, en este libro cuenta como crear más funciones que variables... Un loco.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/kHC9Va/Gabriel_min.png",
      "detalle": "https://preview.ibb.co/m0APDv/Gabriel_min.png",
      "titulo": "Java Di Janeiro",
      "descripcion": "Con Java en la sangre y Php en las venas, desde Brasil llega este ex-músico para explicarnos todas las ventajas del, seguramente, mejor lenguaje del mundo.",
      "idioma": "es"
    }]
  };
  let allBooks = data.books;

  function getBooks() {
    let flipBox = document.getElementById("flipBox");
    let flipContainer = document.createElement("div");
      flipContainer.setAttribute("class", "flipContainer");
      flipBox.append(flipContainer);
    for (i = 0; i < allBooks.length; i++) {

      let flipper = document.createElement("div");
      flipper.setAttribute("class", "flipper");

      let front = document.createElement("div");
      front.setAttribute("class", "front");

      let back = document.createElement("div");
      back.setAttribute("class", "back");

      let coverImage = document.createElement("img");
      coverImage.setAttribute("src", allBooks[i].portada);
      coverImage.setAttribute("alt", allBooks[i].titulo);

      //add title

      let title = allBooks[i].titulo;
      let bookTitle = document.createElement("span");
      bookTitle.setAttribute("class", "bookTitle");
      bookTitle.innerHTML = title;
      let titleContainer = document.createElement("div");
      titleContainer.setAttribute("class", "titleContainer");

      //add title to div and then to back
      titleContainer.append(bookTitle);
      back.append(titleContainer);

      // add description

      let bookDescription = allBooks[i].descripcion;
      let text = document.createElement("div");
      text.setAttribute("class", "text");
      text.innerHTML = bookDescription;
      back.append(text);

      // add more-info button . First container for a-tag, then A-tag, then button
      let anchorContainer = document.createElement("div");
      anchorContainer.setAttribute("class", "anchorContainer");
      back.append(anchorContainer);

      let anchor = document.createElement("a");
      anchor.setAttribute("id", "anchor");
      anchor.setAttribute("href", allBooks[i].detalle);
      anchor.setAttribute("data-fancybox", "images");
      anchorContainer.append(anchor);

      let button = document.createElement("button");
      button.setAttribute("class", "button");
      button.innerHTML = "More Info";

      anchor.append(button);

      //Add elements

      front.appendChild(coverImage);
      flipper.append(front, back);
      //flipContainer.append(flipper)

      //flipBox.append(flipContainer);
      flipContainer.append(flipper);

    }
  }
  getBooks();

  //cache the spans
  let elements = document.querySelectorAll('span.bookTitle');

  function searchBox() {
    let input = document.getElementById('myInput'),
      filter = input.value.toLowerCase();
    applyInput(elements, filter);
  }

  function applyInput(elements, text) {
    Array.prototype.forEach.call(elements, function(element) {
      let parentToAffect = element.closest('.flipper');
      if (RegExp(text).test(element.textContent.toLowerCase())) {
        parentToAffect.style.display = 'block';
      } else
        parentToAffect.style.display = 'none';
    });
  }

  document.getElementById('myInput').addEventListener('input', () => {
    searchBox();
  });
  //searchBox() <---- no need to execute this function on page load
})();```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.navbar {
  display: flex;
}

.pageTitle {
  font-size: 60px;
  color: aqua;
  display: flex;
  display: flex;
  align-items: center;
  justify-content: center;
}

.quicksearch {
  width: 100%;
  /*    height: 30px;*/
  font-size: 16px;
}

body {
  background-image: url("/images/colorful-library.jpg") !important;
  background-size: auto;
  font-family: 'Roboto', Tahoma, Arial, sans-serif;
  line-height: 1.5;
  font-size: 13px;
  background-repeat: repeat;
  background-attachment: fixed;
}

.pageTitle {
  font-size: 50px;
  color: black;
  display: flex;
  display: flex;
  align-items: center;
  justify-content: center;
}

.boxContainer {
  width: 80%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding-bottom: 50px;
  padding-top: 50px;
}

img {
  width: 200px;
  /*width&Height must be same in .flipContainer, .front, .back*/
  height: 300px;
  border: 2px solid grey
}

.fancybox-image {
  width: 700px !important;
  height: 900px !important;
}

/* confir de CSS obtenida en https://davidwalsh.name/css-flip */

/* entire container, keeps perspective */

.flipContainer {
  perspective: 1000px;
}

/* flip the pane when hovered */

.flipContainer .flipper:hover,
.flipContainer .flipper.hover {
  transform: rotateY(180deg);
}

.flipContainer,
.front,
.back {
  width: 200px;
  height: 300px;
  margin-right: 5px
}

/* flip speed goes here */

.flipper {
  transition: 0.99s;
  transform-style: preserve-3d;
  position: relative;
}

/* hide back of pane during swap */

.front,
.back {
  backface-visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;
}

/* front pane, placed above back */

.front {
  z-index: 2;
  /* for firefox 31 */
  transform: rotateY(0deg);
}

/* back, initially hidden pane */

.back {
  transform: rotateY(180deg);
  margin-top: 5px;
  background-color: gainsboro;
  border: 2px solid grey;
  color: black;
  position: relative;
}

/* fin CSS code from davidwalsh.name */

/* Style for back elements : title, more info etc... */

.titleContainer {
  font-size: 40px !important;
  text-align: center;
  width: 100%;
  position: absolute;
  top: 5px;
}

.text {
  text-align: justify;
  padding: 10px;
  width: 100%;
  height: 200px;
  overflow-y: scroll;
  position: absolute;
  top: 100px;
  font-size: 20px !important;
}

.anchorContainer {
  width: 100%;
  position: absolute;
  top: 350px;
}

.button {
  /*   margin-top: 10px;*/
  font-size: 16px;
  width: 139.73px;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
  box-shadow: 2px 2px black;
  margin-top: 1px;
  background-color: orangered;
  color: white;
  margin-bottom: 2px;
}

button:hover {
  box-shadow: 1px 1px black;
  margin-top: 0px;
  background-color: #ff704d;
}

a:hover {
  text-decoration: none;
}

a {
  display: flex;
  justify-content: center;
}

.searchBar {
  position: fixed;
  display: inline-block;
  left: 50%;
  top: 8px;
  transform: translateX(-50%);
  width: 100%;
  max-width: 344px;
  height: 48px;
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  z-index: +1;
}

input {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 300px;
  height: 40px;
  left: 172px;
  margin: 4px 0;
  border: 0;
  border-radius: 0;
  outline: 0;
  box-sizing: border-box;
  font-size: 50px;
  font-weight: 300
}</code>```

 here come
    the books

    <input type="text" id="myInput" value="" placeholder="Search for book title" title="Type in a name">

```

Body:
In the Javascript exercise I am doing, besides creating a kind of bookstore out of a Json file, I have to include a search field, to filter by book title or writer's name.
To do that, I am following W3school tutorial about it, but I am struggling to translate it to my code. Because I am not sure over which elements to loop , etc...

I would much appreciate any help to guide me on the right direction.

This is the Html and JS I have written so far :

var data = {"books":[{"portada":"https://preview.ibb.co/bC5ELQ/alex_min.png","detalle":"https://preview.ibb.co/deD10Q/alex_min.png","titulo":"Dímelo en palabras","descripcion":"El polifacético escritor catalán n.","idioma":"es"},{"portada":"https://preview.ibb.co/dvM9AQ/eddie_min.png","detalle":"https://preview.ibb.co/hnT0H5/eddie_min.png","titulo":"Lo veo negro","descripcion":"una obra maestra de la ciencia ficción.","idioma":"es"},{"portada":"https://preview.ibb.co/nF3Un5/flecha_min.png","detalle":"https://preview.ibb.co/dUgbZk/flecha_min.png","titulo":"Mi algoritmo es más rápido","descripcion":"Un libro que te deja atado a su trama ","idioma":"es"}]}

var allBooks = data.books;

function getBooks () {

    var flipBox = document.getElementById("flipBox");

    for (i=0; i < allBooks.length; i++) {

        //create flip elements

        var flipContainer = document.createElement("div");
        flipContainer.setAttribute("class", "flipContainer")

        var flipper = document.createElement("div");
        flipper.setAttribute("class", "flipper");

        var front = document.createElement("div");
        front.setAttribute("class", "front");

        var back = document.createElement("div");
        back.setAttribute("class", "back");

        var coverImage = document.createElement("img");
        coverImage.setAttribute("src", allBooks[i].portada);
        coverImage.setAttribute("alt", allBooks[i].titulo);

        //add title

        var title = allBooks[i].titulo;
        var bookTitle = document.createElement("span");
        bookTitle.setAttribute("class", "bookTitle");
        bookTitle.innerHTML = title;
        var titleContainer = document.createElement("div");
        titleContainer.setAttribute("class", "titleContainer");

        //add title to div and then to back
        titleContainer.append(bookTitle);
        back.append(titleContainer);

        // add description

        var bookDescription = allBooks[i].descripcion;
        var text = document.createElement("div");
        text.setAttribute("class", "text");
        text.innerHTML = bookDescription;
        back.append(text);

        // add more-info button . First container for a-tag, then A-tag, then button
        var anchorContainer = document.createElement("div");
        anchorContainer.setAttribute("class", "anchorContainer")
        back.append(anchorContainer);

        var anchor = document.createElement("a");
        anchor.setAttribute("id", "anchor");
        anchor.setAttribute("href", allBooks[i].detalle);
        anchor.setAttribute("data-fancybox", "images");
        anchorContainer.append(anchor);

        var button = document.createElement("button");
        button.setAttribute("class", "button");
        button.innerHTML = "More Info";

        anchor.append(button);

        //Add elements

        front.appendChild(coverImage);
        flipper.append(front, back);
        flipContainer.append(flipper)

        flipBox.append(flipContainer);

    }
}
getBooks()

function searchBox() {
  // Declare variables
  var input, filter, ul, li, a, i, txtValue;
  input = document.getElementById('myInput');
  filter = input.value.toUpperCase();

    console.log(filter);

  // Loop through all list items, and hide those who don't match the search query
  for (i = 0; i < allBooks[i].length; i++) {
    a = allBooks[i].getElementsByTagName("a")[0];
    txtValue = a.textContent || a.innerText;
    if (txtValue.toUpperCase().indexOf(filter) > -1) {
      li[i].style.display = "";
    } else {
      li[i].style.display = "none";
    }
  }
}
searchBox()

<!DOCTYPE html>

  <meta charset="UTF-8">

  <link rel="stylesheet" href="bookshop_css.css">

  <title>Bookshop</title>

 here comes the books

    <input type="text" id="myInput" onkeyup="searchBox()" value="" placeholder="Search for book title" title="Type in a name">

Body:
allBooks is an array of objects, hence allBooks[i] is an object, hence allBooks[i].length is undefined, since length is not an object's property or method :).

That said, there's no need to traverse allBooks (note there are many ways to achieve what you are trying). Here's my shot at it.

You just need to get the input text and test it against the title and author's name (which I couldn't find in your question, so this answer works only with the books' titles).

The books' titles are shown inside each span.bookTitle, so those are the first you should cache in a variable. Notice, caching them from the beginning will help with performance down the road when there are many books, preventing the need for querying the DOM on each keystroke BUT, remember to update that cache if you plan on adding books dynamically to the list.

Then you just need to traverse those spans and test their text contents, that's forEach. Then, every time you find a match, you show/hide the span's ancestor that matches .flipper.

Last but not least, I recommend not in-lining events in your html, try attaching them in JS, also don't use keyup for this, because it will process unnecessary keystrokes like Shift, Ctrl, etc., unless that's what you want..., if not go with input.

HIH

(()=>{let data = {"books": [{"portada": "https://preview.ibb.co/bC5ELQ/alex_min.png", "detalle": "https://preview.ibb.co/deD10Q/alex_min.png", "titulo": "Dímelo en palabras", "descripcion": "El polifacético escritor catalán n.", "idioma": "es"}, {"portada": "https://preview.ibb.co/dvM9AQ/eddie_min.png", "detalle": "https://preview.ibb.co/hnT0H5/eddie_min.png", "titulo": "Lo veo negro", "descripcion": "una obra maestra de la ciencia ficción.", "idioma": "es"}, {"portada": "https://preview.ibb.co/nF3Un5/flecha_min.png", "detalle": "https://preview.ibb.co/dUgbZk/flecha_min.png", "titulo": "Mi algoritmo es más rápido", "descripcion": "Un libro que te deja atado a su trama ", "idioma": "es"}]};
            let allBooks = data.books;
            function getBooks() {
                let flipBox = document.getElementById("flipBox");
                for (i = 0; i < allBooks.length; i++) {
                    let flipContainer = document.createElement("div");
                    flipContainer.setAttribute("class", "flipContainer")

                    let flipper = document.createElement("div");
                    flipper.setAttribute("class", "flipper");

                    let front = document.createElement("div");
                    front.setAttribute("class", "front");

                    let back = document.createElement("div");
                    back.setAttribute("class", "back");

                    let coverImage = document.createElement("img");
                    coverImage.setAttribute("src", allBooks[i].portada);
                    coverImage.setAttribute("alt", allBooks[i].titulo);

                    //add title

                    let title = allBooks[i].titulo;
                    let bookTitle = document.createElement("span");
                    bookTitle.setAttribute("class", "bookTitle");
                    bookTitle.innerHTML = title;
                    let titleContainer = document.createElement("div");
                    titleContainer.setAttribute("class", "titleContainer");

                    //add title to div and then to back
                    titleContainer.append(bookTitle);
                    back.append(titleContainer);

                    // add description

                    let bookDescription = allBooks[i].descripcion;
                    let text = document.createElement("div");
                    text.setAttribute("class", "text");
                    text.innerHTML = bookDescription;
                    back.append(text);

                    // add more-info button . First container for a-tag, then A-tag, then button
                    let anchorContainer = document.createElement("div");
                    anchorContainer.setAttribute("class", "anchorContainer");
                    back.append(anchorContainer);

                    let anchor = document.createElement("a");
                    anchor.setAttribute("id", "anchor");
                    anchor.setAttribute("href", allBooks[i].detalle);
                    anchor.setAttribute("data-fancybox", "images");
                    anchorContainer.append(anchor);

                    let button = document.createElement("button");
                    button.setAttribute("class", "button");
                    button.innerHTML = "More Info";

                    anchor.append(button);

                    //Add elements

                    front.appendChild(coverImage);
                    flipper.append(front, back);
                    flipContainer.append(flipper)

                    flipBox.append(flipContainer);

                }
            }
            getBooks();

            //cache the spans
            let elements = document.querySelectorAll('span.bookTitle');
            function searchBox() {
                let input = document.getElementById('myInput'),
                        filter = input.value.toLowerCase();
                applyInput(elements, filter);
            }

            function applyInput(elements, text) {
                Array.prototype.forEach.call(elements, function (element) {
                    let parentToAffect = element.closest('.flipper');
                    if (RegExp(text).test(element.textContent.toLowerCase())) {
                        parentToAffect.style.display = 'block';
                    } else
                        parentToAffect.style.display = 'none';
                });
            }

            document.getElementById('myInput').addEventListener('input', () => {
                searchBox();
            });
            //searchBox() <---- no need to execute this function on page load
            })();

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <link rel="stylesheet" href="bookshop_css.css">
<!-- I have deleted bootstrap and fancybox links and scripts, to make it shorter -->

  <title>Bookshop</title>
</head>

<body>

  <h1> here come<!--s--> the books</h1>

  <div class="searchBar">
    <input type="text" id="myInput" value="" placeholder="Search for book title" title="Type in a name">
  </div>

  <div id="flipBox" class="container-fluid boxContainer grid">
  </div>
  <script src="bookshop_just_data.js"></script>
  <script src="bookshop_myscript.js"></script>
</body>
</html>

(() => {
  let data = {
    "books": [{
      "portada": "https://preview.ibb.co/bC5ELQ/alex_min.png",
      "detalle": "https://preview.ibb.co/deD10Q/alex_min.png",
      "titulo": "Dímelo en palabras",
      "descripcion": "El polifacético escritor catalán nos muestra en su novela más romántica como, básicamente, nuestra relación es tan fácil como decirnos las cosas como son. Tal cual.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/dvM9AQ/eddie_min.png",
      "detalle": "https://preview.ibb.co/hnT0H5/eddie_min.png",
      "titulo": "Lo veo negro",
      "descripcion": "En ocasiones crees entender algo cuando te lo están explicando, pero en el momento de ponerte a programar surge siempre esta duda. ¿Lo ves?. Eduard Català se saca de la manga una obra maestra de la ciencia ficción.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/nF3Un5/flecha_min.png",
      "detalle": "https://preview.ibb.co/dUgbZk/flecha_min.png",
      "titulo": "Mi algoritmo es más rápido",
      "descripcion": "De nuevo Guerrero, de nuevo el flecha. Un libro que te deja atado a su trama desde que abres la cubierta. Te atrapa rápido, muy rápido, hyper rápido.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/hPod4k/joan_min.png",
      "detalle": "https://preview.ibb.co/f6J6qQ/joan_min.png",
      "titulo": "Amazing Design Art",
      "descripcion": "Delicado y cuidado en cada palabra, este segundo tomo de la Trilogía 'Amor Front-End' es de momento el más sofisticado del autor. Nos fascinó 'Romance CSS', nos encanta este, ¿Qué nos deparará 'Orgasmo JavaScript'?",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/iVRAuk/maruti_min.png",
      "detalle": "https://preview.ibb.co/fyBzn5/maruti_min.png",
      "titulo": "The Javascript Guru",
      "descripcion": "From India to Spain, this book explains us how your dreams like a developer can be real. Functions, Objects, Variables... All of JavaScript is here in this Amazing book.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/n82iEk/oruc_min.png",
      "detalle": "https://preview.ibb.co/h3GbZk/oruc_min.png",
      "titulo": "Azerbaijan Roulette",
      "descripcion": "Meanwhile you wait for the next Code challenge you can play some football with your mates... GOOOOOOOAAAAL!!",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/bHMWPk/roosy_min.png",
      "detalle": "https://preview.ibb.co/iwNGqQ/roosy_min.png",
      "titulo": "Java... what?",
      "descripcion": "For those of you that don't understand nothing about new technologies, Mr. Roosy arrives to give you some ray of light in your darkness. You'll never ask Java...what? again.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/n06LH5/vcarpio_min.png",
      "detalle": "https://preview.ibb.co/mJXuc5/vcarpio_min.png",
      "titulo": "Digital Nomad",
      "descripcion": "Entras a las 9 de la mañana, te repanchingas en tu silla, pones los pies en la mesa y empiezas a programar. La vida de un nómada digital puede ser maravillosa. Gran relato corto del Escritor y ex-programador de Facebook Victor Carpio.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/dPxsYv/Albert_min.png",
      "detalle": "https://preview.ibb.co/fwyY6F/Albert_min.png",
      "titulo": "El por qué de no usar Mustache",
      "descripcion": "El famoso escritor Albert Lara nos enseña el poder de JavaScript para crear plantillas y las razones por las que un sistema ideado justamente para este fin como es Mustache, no siempre es la mejor opción...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/e1z6tv/Bryn_min.png",
      "detalle": "https://preview.ibb.co/dVLfmF/Bryn_min.png",
      "titulo": "Shut up little bastards",
      "descripcion": "El silencio es necesario en estos tiempos para poder concentrarte. Bryn lucharÃ¡ contra viento y marea en esta cruda historia basada en hechos reales.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/fqbmtv/Eduardo_min.png",
      "detalle": "https://preview.ibb.co/mSBmRF/Eduardo_min.png",
      "titulo": "Sudo mucho",
      "descripcion": "Para qué aprender JavaScript si puedes estar subiendo copas sin parar. La historia de Eduardo nos llevará de estar hundido en la mierda hasta seguir hundido en la mierda.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/ctuvmF/Erica_min.png",
      "detalle": "https://preview.ibb.co/n5zHYv/Erica_min.png",
      "titulo": "No contéis conmigo",
      "descripcion": "Hay veces que no se puede soportar la presión. Este es uno de esos casos. Erica no lo consiguió pero hay gente que dice haberla visto en ciertas noches de verano...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/hBtc0a/Gerard_min.png",
      "detalle": "https://preview.ibb.co/nKxFLa/Gerard_min.png",
      "titulo": "Asincronía y su puta madre",
      "descripcion": "¿Qué entendemos por asincronía? ¿Por qué existe en este maldito mundo? ¿No es suficientemente sencillo el mundo síncrono?. De Haro nos trae una obra de ciencia ficción con más de un giro que no te esperas.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/esZT6F/Juan_min.png",
      "detalle": "https://preview.ibb.co/g1ZjDv/Juan_min.png",
      "titulo": "El java empieza ahorita",
      "descripcion": "HTML, CSS, JavaScript e incluso Jquery son juegos de niÃ±os para un hombre que se lo propone. Pero Java ya son palabras mayores. Un reto que hay que aceptar y asumir que serÃ¡ duro. La parte front quedó atrás, el Java empieza ahorita.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/jv3c0a/Lluis_min.png",
      "detalle": "https://preview.ibb.co/b0st6F/Lluis_min.png",
      "titulo": "document.write()",
      "descripcion": "No necesito más. No quiero funciones que no sé como funcionan. Document.write() hace lo que quiero y cuando quiero. Trágico relato de un hombre con una obsesión...",
      "idioma": "ca"
    }, {
      "portada": "https://preview.ibb.co/bBJXYv/Muhammad_min.png",
      "detalle": "https://preview.ibb.co/dJuHYv/Muhammad_min.png",
      "titulo": "Learning Syntax",
      "descripcion": "A man with the need to learn every word of every new programming language. An almost impossible goal that will make him struggle with life and with his interior.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/ja3XYv/Nuria_min.png",
      "detalle": "https://preview.ibb.co/m72RRF/Nuria_min.png",
      "titulo": "Design First",
      "descripcion": "Por mucho que JavaScript ayude a darle funcionalidad a la pÃ¡gina, lo primordial es el diseño. Sin un buen diseÃ±o, una pagina cae por su propio peso. Nuria nos explica la importancia de un gran impacto visual.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/hCVqLa/Vicent_min.png",
      "detalle": "https://preview.ibb.co/ci0rtv/Vicent_min.png",
      "titulo": "Code of Vincent",
      "descripcion": "El escritor fantástico Vicent Clapés nos trae una historia que narra como un simple programador consiguió convertirse en un autentico guerrero a base de código. Batallas contra dragones de Jquery y Magos de Javascript en una aventura de lo más freek.",
      "idioma": "ca"
    }, {
      "portada": "https://preview.ibb.co/iVRmtv/Victor_min.png",
      "detalle": "https://preview.ibb.co/gL0D6F/Victor_min.png",
      "titulo": "El maestro del parÃ¡metro",
      "descripcion": "Cuando te das cuenta que 10 funciones similares se pueden transformar en una sola simplemente pasándole un par de parámetros te das cuenta de todo su potencial. Es entonces cuando de transformas en un maestro del parámetro.",
      "idioma": "en"
    }, {
      "portada": "https://preview.ibb.co/dGcsYv/Auger_min.png",
      "detalle": "https://preview.ibb.co/dDGWtv/Auger_min.png",
      "titulo": "Local Storage",
      "descripcion": "Llamadas JSON, objetos Javascript, Table Sorter, iframe, pantallas de loading... Todo esto es tiempo perdido para el usuario. Necesitamos algo que nos ayude con eso. Aquí es donde entra el poder del Local Storage. Gotcha!!",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/h8s4fa/Edu_min.png",
      "detalle": "https://preview.ibb.co/js1aLa/Edu_min.png",
      "titulo": "Difícil. A veces lo fácil aburre.",
      "descripcion": "Cómo funciona un sort por dentro? ¿Por qué usar esta función y no inventar una que nos complique más la vida?. Estas y otras preguntas en un libro orientado a esas personas que piensan fuera de la caja.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/csHsYv/Francesc_min.png",
      "detalle": "https://preview.ibb.co/hJsRRF/Francesc_min.png",
      "titulo": "No lo entiendo",
      "descripcion": "El escritor, en su biografía más completa hasta la fecha, nos pone en su piel durante su iniciación a la programación antes de trabajar en Google. Era joven, con toda la vida por delante, pero no entendía nada...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/gjX4fa/Ignasi_min.png",
      "detalle": "https://preview.ibb.co/iotN0a/Ignasi_min.png",
      "titulo": "La la la. City of code",
      "descripcion": "Código, código y más código. Entre incontables líneas de código se cuela este programador con gran experiencia autor de otros Best Sellers como 'Tucutucu Master' o 'Métele chicha a mi salchicha'...",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/cV1QmF/Raul_min.png",
      "detalle": "https://preview.ibb.co/jSRaLa/Raul_min.png",
      "titulo": "Function Man",
      "descripcion": "Típico cuatro ojos que está todo el día programando y haciendo mierdas como esta, en este libro cuenta como crear más funciones que variables... Un loco.",
      "idioma": "es"
    }, {
      "portada": "https://preview.ibb.co/kHC9Va/Gabriel_min.png",
      "detalle": "https://preview.ibb.co/m0APDv/Gabriel_min.png",
      "titulo": "Java Di Janeiro",
      "descripcion": "Con Java en la sangre y Php en las venas, desde Brasil llega este ex-músico para explicarnos todas las ventajas del, seguramente, mejor lenguaje del mundo.",
      "idioma": "es"
    }]
  };
  let allBooks = data.books;

  function getBooks() {
    let flipBox = document.getElementById("flipBox");
    let flipContainer = document.createElement("div");
      flipContainer.setAttribute("class", "flipContainer");
      flipBox.append(flipContainer);
    for (i = 0; i < allBooks.length; i++) {

      let flipper = document.createElement("div");
      flipper.setAttribute("class", "flipper");

      let front = document.createElement("div");
      front.setAttribute("class", "front");

      let back = document.createElement("div");
      back.setAttribute("class", "back");

      let coverImage = document.createElement("img");
      coverImage.setAttribute("src", allBooks[i].portada);
      coverImage.setAttribute("alt", allBooks[i].titulo);

      //add title

      let title = allBooks[i].titulo;
      let bookTitle = document.createElement("span");
      bookTitle.setAttribute("class", "bookTitle");
      bookTitle.innerHTML = title;
      let titleContainer = document.createElement("div");
      titleContainer.setAttribute("class", "titleContainer");

      //add title to div and then to back
      titleContainer.append(bookTitle);
      back.append(titleContainer);

      // add description

      let bookDescription = allBooks[i].descripcion;
      let text = document.createElement("div");
      text.setAttribute("class", "text");
      text.innerHTML = bookDescription;
      back.append(text);

      // add more-info button . First container for a-tag, then A-tag, then button
      let anchorContainer = document.createElement("div");
      anchorContainer.setAttribute("class", "anchorContainer");
      back.append(anchorContainer);

      let anchor = document.createElement("a");
      anchor.setAttribute("id", "anchor");
      anchor.setAttribute("href", allBooks[i].detalle);
      anchor.setAttribute("data-fancybox", "images");
      anchorContainer.append(anchor);

      let button = document.createElement("button");
      button.setAttribute("class", "button");
      button.innerHTML = "More Info";

      anchor.append(button);

      //Add elements

      front.appendChild(coverImage);
      flipper.append(front, back);
      //flipContainer.append(flipper)

      //flipBox.append(flipContainer);
      flipContainer.append(flipper);

    }
  }
  getBooks();

  //cache the spans
  let elements = document.querySelectorAll('span.bookTitle');

  function searchBox() {
    let input = document.getElementById('myInput'),
      filter = input.value.toLowerCase();
    applyInput(elements, filter);
  }

  function applyInput(elements, text) {
    Array.prototype.forEach.call(elements, function(element) {
      let parentToAffect = element.closest('.flipper');
      if (RegExp(text).test(element.textContent.toLowerCase())) {
        parentToAffect.style.display = 'block';
      } else
        parentToAffect.style.display = 'none';
    });
  }

  document.getElementById('myInput').addEventListener('input', () => {
    searchBox();
  });
  //searchBox() <---- no need to execute this function on page load
})();

.navbar {
  display: flex;
}

.pageTitle {
  font-size: 60px;
  color: aqua;
  display: flex;
  display: flex;
  align-items: center;
  justify-content: center;
}

.quicksearch {
  width: 100%;
  /*    height: 30px;*/
  font-size: 16px;
}

body {
  background-image: url("/images/colorful-library.jpg") !important;
  background-size: auto;
  font-family: 'Roboto', Tahoma, Arial, sans-serif;
  line-height: 1.5;
  font-size: 13px;
  background-repeat: repeat;
  background-attachment: fixed;
}

.pageTitle {
  font-size: 50px;
  color: black;
  display: flex;
  display: flex;
  align-items: center;
  justify-content: center;
}

.boxContainer {
  width: 80%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding-bottom: 50px;
  padding-top: 50px;
}

img {
  width: 200px;
  /*width&Height must be same in .flipContainer, .front, .back*/
  height: 300px;
  border: 2px solid grey
}

.fancybox-image {
  width: 700px !important;
  height: 900px !important;
}

/* confir de CSS obtenida en https://davidwalsh.name/css-flip */

/* entire container, keeps perspective */

.flipContainer {
  perspective: 1000px;
}

/* flip the pane when hovered */

.flipContainer .flipper:hover,
.flipContainer .flipper.hover {
  transform: rotateY(180deg);
}

.flipContainer,
.front,
.back {
  width: 200px;
  height: 300px;
  margin-right: 5px
}

/* flip speed goes here */

.flipper {
  transition: 0.99s;
  transform-style: preserve-3d;
  position: relative;
}

/* hide back of pane during swap */

.front,
.back {
  backface-visibility: hidden;
  position: absolute;
  top: 0;
  left: 0;
}

/* front pane, placed above back */

.front {
  z-index: 2;
  /* for firefox 31 */
  transform: rotateY(0deg);
}

/* back, initially hidden pane */

.back {
  transform: rotateY(180deg);
  margin-top: 5px;
  background-color: gainsboro;
  border: 2px solid grey;
  color: black;
  position: relative;
}

/* fin CSS code from davidwalsh.name */

/* Style for back elements : title, more info etc... */

.titleContainer {
  font-size: 40px !important;
  text-align: center;
  width: 100%;
  position: absolute;
  top: 5px;
}

.text {
  text-align: justify;
  padding: 10px;
  width: 100%;
  height: 200px;
  overflow-y: scroll;
  position: absolute;
  top: 100px;
  font-size: 20px !important;
}

.anchorContainer {
  width: 100%;
  position: absolute;
  top: 350px;
}

.button {
  /*   margin-top: 10px;*/
  font-size: 16px;
  width: 139.73px;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
  box-shadow: 2px 2px black;
  margin-top: 1px;
  background-color: orangered;
  color: white;
  margin-bottom: 2px;
}

button:hover {
  box-shadow: 1px 1px black;
  margin-top: 0px;
  background-color: #ff704d;
}

a:hover {
  text-decoration: none;
}

a {
  display: flex;
  justify-content: center;
}

.searchBar {
  position: fixed;
  display: inline-block;
  left: 50%;
  top: 8px;
  transform: translateX(-50%);
  width: 100%;
  max-width: 344px;
  height: 48px;
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  z-index: +1;
}

input {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 300px;
  height: 40px;
  left: 172px;
  margin: 4px 0;
  border: 0;
  border-radius: 0;
  outline: 0;
  box-sizing: border-box;
  font-size: 50px;
  font-weight: 300
}

<h1> here come
    <!--s-->the books</h1>

  <div class="searchBar">
    <input type="text" id="myInput" value="" placeholder="Search for book title" title="Type in a name">
  </div>

  <div id="flipBox" class="container-fluid boxContainer grid">
  </div>


来源: stackexchange

问:
JFrame actionlistener is activating before an identical/linked JPanel actionlistener
I'm new to programming and am trying my hand at swing.
I have a JFrame that serves as as the default menu, and I have a JPanel that appears in it to handle logins. After a successful login the JPanel is supposed to send the login information to JFrame so it knows who is currently logged in.

The problem is that the JButton, when clicked, is activating the send portion(whose code is the JFrame) before the JPanel has the chance to check the credentials. They are both using the same actionlistener so I don't know how to control the order.

```<code>public class GUIFrame extends JFrame {
    private DetailsPanel detailsPanel;
    private String curUsername;
    public GUIFrame(String title){
        super(title);
        detailsPanel = new DetailsPanel();
        setLayout(new BorderLayout());

        Container c = getContentPane();
        c.add(detailsPanel, BorderLayout.EAST);

        detailsPanel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!(detailsPanel.getCurUsername() == "")){
                    randomToBeImplementedFunctionThatWillLogIn();
                //TODO:
                // The check here happens BEFORE the detailsPanel processes everything
                // so the first time they create an account it won't log them in
                // and every subsequent time the PREVIOUS login creds will be used.
            }
        }
    });

public class DetailsPanel extends JPanel {

    private HashMap<String, String> logInMap = new HashMap<String, String>();

    private String curUsername = "";//the current logged in username
    public String getCurUsername(){
        return curUsername;
    }
    JTextField nameField;
    JTextField passField;
    public DetailsPanel(){
        nameField = new JTextField(0);
        passField = new JTextField(0);

    logIn.addActionListener( (e) -> {//login attempted
            if (logInMap.containsKey(nameField.getText())){
                if (passField.getText().equals(logInMap.get(nameField.getText()))){
                    //logged in
                    curUsername = nameField.getText();
                }
                else{
                    //wrong password, logged out
                    curUsername = "";

                }
            }
            else {
                logInMap.put(nameField.getText(), passField.getText());
                curUsername = nameField.getText();
                //create new account
            }

        } );

        GridBagConstraints gCons = new GridBagConstraints();
        gCons.gridy = 0;
        gCons.gridx = 0;
        add(nameField, gCons);
        gCons.gridy = 1;
        add(passField, gCons);
    }
    public void addActionListener(ActionListener al)
    {
        logIn.addActionListener(al);
    }
}
</code>```

on a successful login, DetailsPanel is supposed to send information to GUIFrame, and then GUIFrame logs in.

Instead, when actionlistener occurs, the GUIFrame attemps to login before DetailsPanel gets to check the credentials and send it to GUIFrame.

Is there a way to get the DetailsPanel.addActionListener() to come AFTER the logIn.addActionListener()?

答:
The order of events is generally not guaranteed.  Observationally, they tend to be trigged in FILO (first in, last out) order.

A better solution would be to decouple the process, so any interested parties are not reliant on the button action, but instead on the component telling them when the validation has occurred.

A "simple" solution is to use the existing API functionality

```<code>public class DetailsPanel extends JPanel {

    private HashMap<String, String> logInMap = new HashMap<String, String>();

    private String curUsername = "";//the current logged in username

    public String getCurUsername() {
        return curUsername;
    }
    JTextField nameField;
    JTextField passField;

    JButton logIn;

    public DetailsPanel() {
        nameField = new JTextField(0);
        passField = new JTextField(0);

        logIn.addActionListener((e) -> {//login attempted
            if (logInMap.containsKey(nameField.getText())) {
                if (passField.getText().equals(logInMap.get(nameField.getText()))) {
                    //logged in
                    curUsername = nameField.getText();
                    fireActionPerformed();
                } else {
                    //wrong password, logged out
                    curUsername = "";

                }
            } else {
                logInMap.put(nameField.getText(), passField.getText());
                curUsername = nameField.getText();
                //create new account
            }

        });

        GridBagConstraints gCons = new GridBagConstraints();
        gCons.gridy = 0;
        gCons.gridx = 0;
        add(nameField, gCons);
        gCons.gridy = 1;
        add(passField, gCons);
    }

    public void addActionListener(ActionListener al) {
        listenerList.add(ActionListener.class, al);
    }

    protected void fireActionPerformed() {
        ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
        if (listeners.length == 0) {
            return;
        }
        ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "validated");
        for (ActionListener listener : listeners) {
            listener.actionPerformed(evt);
        }
    }

}
</code>```

So, basically, or this does, is stores the "registered" ActionListeners in the available listenerList.  This is API provided by Swing available to all Swing components.

When the button is clicked and the identity verified, all registered parties are notified, via the fireActionPerformed method.

A more complete solution would probably involve your own event listener interface which could include validationSuccess and validationUnsuccessful and could pass back the user credentials as part of the event object

ContentLicense: CC BY-SA 4.0

Body:
I'm new to programming and am trying my hand at swing.
I have a JFrame that serves as as the default menu, and I have a JPanel that appears in it to handle logins. After a successful login the JPanel is supposed to send the login information to JFrame so it knows who is currently logged in.

The problem is that the JButton, when clicked, is activating the send portion(whose code is the JFrame) before the JPanel has the chance to check the credentials. They are both using the same actionlistener so I don't know how to control the order.

public class GUIFrame extends JFrame {
    private DetailsPanel detailsPanel;
    private String curUsername;
    public GUIFrame(String title){
        super(title);
        detailsPanel = new DetailsPanel();
        setLayout(new BorderLayout());

        Container c = getContentPane();
        c.add(detailsPanel, BorderLayout.EAST);

        detailsPanel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!(detailsPanel.getCurUsername() == "")){
                    randomToBeImplementedFunctionThatWillLogIn();
                //TODO:
                // The check here happens BEFORE the detailsPanel processes everything
                // so the first time they create an account it won't log them in
                // and every subsequent time the PREVIOUS login creds will be used.
            }
        }
    });

public class DetailsPanel extends JPanel {

    private HashMap<String, String> logInMap = new HashMap<String, String>();

    private String curUsername = "";//the current logged in username
    public String getCurUsername(){
        return curUsername;
    }
    JTextField nameField;
    JTextField passField;
    public DetailsPanel(){
        nameField = new JTextField(0);
        passField = new JTextField(0);

    logIn.addActionListener( (e) -> {//login attempted
            if (logInMap.containsKey(nameField.getText())){
                if (passField.getText().equals(logInMap.get(nameField.getText()))){
                    //logged in
                    curUsername = nameField.getText();
                }
                else{
                    //wrong password, logged out
                    curUsername = "";

                }
            }
            else {
                logInMap.put(nameField.getText(), passField.getText());
                curUsername = nameField.getText();
                //create new account
            }

        } );

        GridBagConstraints gCons = new GridBagConstraints();
        gCons.gridy = 0;
        gCons.gridx = 0;
        add(nameField, gCons);
        gCons.gridy = 1;
        add(passField, gCons);
    }
    public void addActionListener(ActionListener al)
    {
        logIn.addActionListener(al);
    }
}

on a successful login, DetailsPanel is supposed to send information to GUIFrame, and then GUIFrame logs in.

Instead, when actionlistener occurs, the GUIFrame attemps to login before DetailsPanel gets to check the credentials and send it to GUIFrame.

Is there a way to get the DetailsPanel.addActionListener() to come AFTER the logIn.addActionListener()?

Body:
The order of events is generally not guaranteed.  Observationally, they tend to be trigged in FILO (first in, last out) order.

A better solution would be to decouple the process, so any interested parties are not reliant on the button action, but instead on the component telling them when the validation has occurred.

A "simple" solution is to use the existing API functionality

public class DetailsPanel extends JPanel {

    private HashMap<String, String> logInMap = new HashMap<String, String>();

    private String curUsername = "";//the current logged in username

    public String getCurUsername() {
        return curUsername;
    }
    JTextField nameField;
    JTextField passField;

    JButton logIn;

    public DetailsPanel() {
        nameField = new JTextField(0);
        passField = new JTextField(0);

        logIn.addActionListener((e) -> {//login attempted
            if (logInMap.containsKey(nameField.getText())) {
                if (passField.getText().equals(logInMap.get(nameField.getText()))) {
                    //logged in
                    curUsername = nameField.getText();
                    fireActionPerformed();
                } else {
                    //wrong password, logged out
                    curUsername = "";

                }
            } else {
                logInMap.put(nameField.getText(), passField.getText());
                curUsername = nameField.getText();
                //create new account
            }

        });

        GridBagConstraints gCons = new GridBagConstraints();
        gCons.gridy = 0;
        gCons.gridx = 0;
        add(nameField, gCons);
        gCons.gridy = 1;
        add(passField, gCons);
    }

    public void addActionListener(ActionListener al) {
        listenerList.add(ActionListener.class, al);
    }

    protected void fireActionPerformed() {
        ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
        if (listeners.length == 0) {
            return;
        }
        ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "validated");
        for (ActionListener listener : listeners) {
            listener.actionPerformed(evt);
        }
    }

}

So, basically, or this does, is stores the "registered" ActionListeners in the available listenerList.  This is API provided by Swing available to all Swing components.

When the button is clicked and the identity verified, all registered parties are notified, via the fireActionPerformed method.

A more complete solution would probably involve your own event listener interface which could include validationSuccess and validationUnsuccessful and could pass back the user credentials as part of the event object


问:
I got this exception - The property or field 'ServerRelativeUrl' has not been initialized
I'm trying to upload a file generated at runtime in C# but I got below exception.

The property or field 'ServerRelativeUrl' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

I'm also using SharePoint CSOM and Microsoft.SharePoint.Client

```<code>using (var ctx = new ClientContext(siteUrl))
{
            try
            {
                ctx.Credentials = SPOCredentials;
                ctx.ExecuteQuery();
            }
            catch(ClientRequestException)
            {
                ctx.Credentials = SPCredentials;
                ctx.ExecuteQuery();
            }
            catch(NotSupportedException)
            {
                ctx.Credentials = SPCredentials;
                ctx.ExecuteQuery();
                Console.WriteLine("SharePoint On-Premise");
            }

            var library = ctx.Web.Lists.GetByTitle("testtest");

            var fileBytes = new byte[] { };
            fileBytes = ReadData();

            //Information about the file
            var fileInformation = new FileCreationInformation
            {
                //Server relative url of the document
                Url = library.RootFolder.ServerRelativeUrl + "/file.pdf",
                //Overwrite file if it's already exist
                Overwrite = true,
                //Content fo the file
                Content = fileBytes
            };
            //Upload the file to root folder of the Document library
            library.RootFolder.Files.Add(fileInformation);
            ctx.Load(library);
            ctx.ExecuteQuery();
}
</code>```

答:
The reason you get this message is because you haven't loaded the Rootfolder.  In order to use it, put the following in:</p>

```<code>var library = ctx.Web.Lists.GetByTitle("testtest");
ctx.Load(library.RootFolder);
ctx.ExecuteQuery();
</code>```

Body:
I'm trying to upload a file generated at runtime in C# but I got below exception.

The property or field 'ServerRelativeUrl' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

I'm also using SharePoint CSOM and Microsoft.SharePoint.Client

using (var ctx = new ClientContext(siteUrl))
{
            try
            {
                ctx.Credentials = SPOCredentials;
                ctx.ExecuteQuery();
            }
            catch(ClientRequestException)
            {
                ctx.Credentials = SPCredentials;
                ctx.ExecuteQuery();
            }
            catch(NotSupportedException)
            {
                ctx.Credentials = SPCredentials;
                ctx.ExecuteQuery();
                Console.WriteLine("SharePoint On-Premise");
            }

            var library = ctx.Web.Lists.GetByTitle("testtest");

            var fileBytes = new byte[] { };
            fileBytes = ReadData();

            //Information about the file
            var fileInformation = new FileCreationInformation
            {
                //Server relative url of the document
                Url = library.RootFolder.ServerRelativeUrl + "/file.pdf",
                //Overwrite file if it's already exist
                Overwrite = true,
                //Content fo the file
                Content = fileBytes
            };
            //Upload the file to root folder of the Document library
            library.RootFolder.Files.Add(fileInformation);
            ctx.Load(library);
            ctx.ExecuteQuery();
}

Body:
The reason you get this message is because you haven't loaded the Rootfolder.  In order to use it, put the following in:

var library = ctx.Web.Lists.GetByTitle("testtest");
ctx.Load(library.RootFolder);
ctx.ExecuteQuery();


问:
How to align 2 forms in the same line?
I'm trying to make the login view of a web page, this login view have two forms (one for register and another for login) and I want to align them and put them in the same line.

At first I've tried to use a table in order to achieve this, but this was unsuccessful, so I used some bootstrap form groups (rows and cols) but I was unsuccessful as well, in the end I managed to put them in the same line using the float attribute, but the result that I got it wasn't good enough.

            Inicio
            Nuevas Adiciones

                <button class="dropbtn">Categoría

                </button>

                    Punk
                    Rock
                    Emo

                <button class="dropbtn">Tipo de Material

                </button>

                    Vinilos
                    Discos Compactos
                    Casetes

                    Iniciar Sesión

    <form class="bord" style="float: left;">
        <legend>Crear Cuenta</legend>

            Example label
            <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">

            Another label
            <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">

    </form>

    <form class="bord" style="float: right;">
        <legend>Registrarse</legend>

            Example label
            <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">

            Another label
            <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">

    </form>

Contacto

Email: pedidos@vinilos.pe

Teléfono: 3291177

Vinilos.Pe © 2019 Derechos Reservados

```

<pre class="lang-css prettyprint-override"><code>
/* THIS IS MY CSS */

.bord {
    display: block;
    margin-top: 15px;
    padding-top: 0.35em;
    padding-bottom: 0.625em;
    padding-left: 0.75em;
    padding-right: 0.75em;
    border-style: solid;
    border-width: 2.5px;
    text-align: center;
  }
</code>```

I was trying to achieve the look of this mockup, but instead for some reason the footer comes up and it looks like this.

答:
This kind of layout you has two good options. You can use Display GRID or Display Flex. I will show an example with Flex. But i recomend the review of the all project, maybe it is better to use the GRID Display.

This is an example of structure, you do not need to follow it, but would recommend something in that style.

```<code><body class="container">
    <div class="content">
        <header class="content__header">
            ...
        </header>
        <div class="content__body">
            <div class="form-content">
                <form class="form form--register"></form>
            </div>
            <div class="form-content">
                <form class="form form--singup"></form>
            </div>
        </div>
        <footer class="content__footer">
            ...
        </footer>
    </div>
</body>
</code>```

For CSS something like this

```<code>.content {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.content__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    align-items: center;
}
</code>```

Title: How to align 2 forms in the same line?

Body:
I'm trying to make the login view of a web page, this login view have two forms (one for register and another for login) and I want to align them and put them in the same line.

At first I've tried to use a table in order to achieve this, but this was unsuccessful, so I used some bootstrap form groups (rows and cols) but I was unsuccessful as well, in the end I managed to put them in the same line using the float attribute, but the result that I got it wasn't good enough.

            Inicio
            Nuevas Adiciones

                <button class="dropbtn">Categoría

                </button>

                    Punk
                    Rock
                    Emo

                <button class="dropbtn">Tipo de Material

                </button>

                    Vinilos
                    Discos Compactos
                    Casetes

                    Iniciar Sesión

    <form class="bord" style="float: left;">
        <legend>Crear Cuenta</legend>

            Example label
            <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">

            Another label
            <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">

    </form>

    <form class="bord" style="float: right;">
        <legend>Registrarse</legend>

            Example label
            <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">

            Another label
            <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">

    </form>

Contacto

Email: pedidos@vinilos.pe

Teléfono: 3291177

Vinilos.Pe © 2019 Derechos Reservados

/* THIS IS MY CSS */

.bord {
    display: block;
    margin-top: 15px;
    padding-top: 0.35em;
    padding-bottom: 0.625em;
    padding-left: 0.75em;
    padding-right: 0.75em;
    border-style: solid;
    border-width: 2.5px;
    text-align: center;
  }

I was trying to achieve the look of this mockup, but instead for some reason the footer comes up and it looks like this.

Body:
This kind of layout you has two good options. You can use Display GRID or Display Flex. I will show an example with Flex. But i recomend the review of the all project, maybe it is better to use the GRID Display.

This is an example of structure, you do not need to follow it, but would recommend something in that style.

<body class="container">
    <div class="content">
        <header class="content__header">
            ...
        </header>
        <div class="content__body">
            <div class="form-content">
                <form class="form form--register"></form>
            </div>
            <div class="form-content">
                <form class="form form--singup"></form>
            </div>
        </div>
        <footer class="content__footer">
            ...
        </footer>
    </div>
</body>

For CSS something like this

.content {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.content__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    align-items: center;
}


问:
jList not displaying data from custom model?
I'm trying to populate a JList through subclassing the AbstractListModel.I have looked through numerous places to try and find what I was doing wrong, but never managed to resolve the problem.So this class handles my GUI...

```<code>//View
public class central extends javax.swing.JFrame {

public central() {
    initComponents();
    list.addMouseListener(new abstracts.mouseActions(list));

}

public void setListModel(ListModel l ){
    list.setModel(l);

}

// The rest are auto generated code for the interface, not relevant
</code>```

Then is my middle class...

```<code> public class MainCtrl {
//View reference
private views.central mainFrame = new views.central();
//Model reference
private abstracts.ListData model = new abstracts.ListData();
/*All this was testing purposes and it worked
  private DefaultListModel model = new DefaultListModel();
 */

private void showView(){
    mainFrame.setListModel(model);
    mainFrame.setVisible(true);
    models.contact p2 = new models.contact("Alex", "Christopher","alex@hotmail.com","22","Def");
    models.contact p1 = new models.contact("Joes", "Smith","joey@hotmail.com","33","Def");
    model.addContact(p2);
    model.addContact(p1);
    /* def version
      model.addElement(p2);

    */

}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        new MainCtrl().showView();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
</code>```

Then I have got the AbstractListModel implementation

```<code>public class ListData extends AbstractListModel {
//Store people info
private Vector<contact> people;

public ListData() {
    people = new Vector<contact>();
}

public void addContact(contact newPerson){
   people.add(newPerson);
   int per = people.indexOf(newPerson);
   fireIntervalAdded(this,0,getSize());
}

@Override
public contact getElementAt(int index){
    return  people.get(index);
}

@Override
public int getSize(){
    return people.size();
}

@Override
protected void fireIntervalAdded(Object src, int index, int index2){
 System.out.println(index2);
}

.....
</code>```

I tested DefautListModel and it displayed the values, but when I incorporate  a custom model it doesn't display ? Is there a extra step I'm missing ? Also mainCtrl is the main class...

Thanks could really use some help

答:
Instead of

fireIntervalAdded(this,0,getSize());

in your addContact() put

fireContentsChanged(this,0,getSize());

ContentLicense: CC BY-SA 3.0

Body:
I'm trying to populate a JList through subclassing the AbstractListModel.I have looked through numerous places to try and find what I was doing wrong, but never managed to resolve the problem.So this class handles my GUI...

//View
public class central extends javax.swing.JFrame {

public central() {
    initComponents();
    list.addMouseListener(new abstracts.mouseActions(list));

}

public void setListModel(ListModel l ){
    list.setModel(l);

}

// The rest are auto generated code for the interface, not relevant

Then is my middle class...

 public class MainCtrl {
//View reference
private views.central mainFrame = new views.central();
//Model reference
private abstracts.ListData model = new abstracts.ListData();
/*All this was testing purposes and it worked
  private DefaultListModel model = new DefaultListModel();
 */

private void showView(){
    mainFrame.setListModel(model);
    mainFrame.setVisible(true);
    models.contact p2 = new models.contact("Alex", "Christopher","alex@hotmail.com","22","Def");
    models.contact p1 = new models.contact("Joes", "Smith","joey@hotmail.com","33","Def");
    model.addContact(p2);
    model.addContact(p1);
    /* def version
      model.addElement(p2);

    */

}

public static void main(String[] args) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        new MainCtrl().showView();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

Then I have got the AbstractListModel implementation

public class ListData extends AbstractListModel {
//Store people info
private Vector<contact> people;

public ListData() {
    people = new Vector<contact>();
}

public void addContact(contact newPerson){
   people.add(newPerson);
   int per = people.indexOf(newPerson);
   fireIntervalAdded(this,0,getSize());
}

@Override
public contact getElementAt(int index){
    return  people.get(index);
}

@Override
public int getSize(){
    return people.size();
}

@Override
protected void fireIntervalAdded(Object src, int index, int index2){
 System.out.println(index2);
}

.....

I tested DefautListModel and it displayed the values, but when I incorporate  a custom model it doesn't display ? Is there a extra step I'm missing ? Also mainCtrl is the main class...

Thanks could really use some help


问:
Xamarin Create Binding project for StripeTerminal
I am attempting to create a binding project for the StripeTerminal CocoaPod (Stripe Terminal iOS). I setup the pod file. Then using the Xamarin docs, I installed Objective Sharpie, and used

sharpie pod bind

which created two files. StripeTerminal_ApiDefinitions.cs and StripeTerminal_StructsAndEnums.cs. Those files look good and have the methods I am expecting when I was using a XCode project.

I then pointed added a Native Reference to the StripeTerminal framework file, but it seems a link file was not created. The Xamarin help documentions mention that a iOS Native Library ends in .a, while this framework does not. I tried pointing the native reference to the folder of the framework, to the extensionless library, and even renamed the library project to .a. Each time when I attempt to build it gives me an error of "No API definition file specified".

答:
Your API definition file(s) should have a build action of ObjcBindingApiDefinition:

```<code><ItemGroup>
    <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
</ItemGroup>
</code>```

And your Enum|Structs file(s) should have a build action of ObjcBindingCoreSource:

```<code><ItemGroup>
    <ObjcBindingCoreSource Include="Structs.cs" />
</ItemGroup>
</code>```

Body:
Your API definition file(s) should have a build action of ObjcBindingApiDefinition:

<ItemGroup>
    <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
</ItemGroup>

And your Enum|Structs file(s) should have a build action of ObjcBindingCoreSource:

<ItemGroup>
    <ObjcBindingCoreSource Include="Structs.cs" />
</ItemGroup>


问:
How can I get the yesterday's data and show it to my form today?
The idea is that I have this 'Present' form that is a textbox one that the user can input the data.

Now, I want to show yesterday's data(readonly) for comparing the result yesterday vs the result today.

Ex:
Attendance: (yesterday- readonly textbox)

```<code>Andy Shrob
Paula Guinto
Mylene Miles
</code>```

Attendance (TODAY)

```<code>Paula Guinto
Mylene Miles
</code>```

How can I get yesterday and show it so I can see who's present yesterday and who's present today? I'm coding PHP and Javascript

I was thinking of this:

```<code>mysql_query("Select prestoday, presyesterday
FROM attendance
WHERE ???)
</code>```

All ideas are welcome. ;) Whether it be PHP code or Javascript or MYSQL Query

TABLE STRUCTURE:
mysql_select_db("csdcon", $con);

$sql="INSERT INTO attendance (prestoday, presyesterday, userdateinp, yesterdate)
                            VALUES
('$_POST[prestoday]','$_POST[presyesterday]','$_POST[userdateinp]','$_POST[yesterdate]')";

答:
TO get yesterday date

```<code> SELECT DATE_SUB(date_time,INTERVAL 1 DAY)
</code>```

To get yesterday results randomly

```<code>SELECT * from test_table where date_time = DATE_SUB(date_time,INTERVAL 1 DAY) order by rand()
</code>```

Body:
The idea is that I have this 'Present' form that is a textbox one that the user can input the data.

Now, I want to show yesterday's data(readonly) for comparing the result yesterday vs the result today.

Ex:
Attendance: (yesterday- readonly textbox)

Andy Shrob
Paula Guinto
Mylene Miles

Attendance (TODAY)

Paula Guinto
Mylene Miles

How can I get yesterday and show it so I can see who's present yesterday and who's present today? I'm coding PHP and Javascript

I was thinking of this:

mysql_query("Select prestoday, presyesterday
FROM attendance
WHERE ???)

All ideas are welcome. ;) Whether it be PHP code or Javascript or MYSQL Query

TABLE STRUCTURE:
mysql_select_db("csdcon", $con);

$sql="INSERT INTO attendance (prestoday, presyesterday, userdateinp, yesterdate)
                            VALUES
('$_POST[prestoday]','$_POST[presyesterday]','$_POST[userdateinp]','$_POST[yesterdate]')";

Body:
TO get yesterday date

 SELECT DATE_SUB(date_time,INTERVAL 1 DAY)

To get yesterday results randomly

SELECT * from test_table where date_time = DATE_SUB(date_time,INTERVAL 1 DAY) order by rand()


问:
How to write throws(in java) like code in golang
Is there any way in Golang for a func to "throws"(like in java) an error?

Through Which I can specify , my func may return error and caller needs to handle the error.

I am just trying to mimic "throws" like approach which we have in java.
May be this is very basic elementary type question , sorry for that , I am new in golang.

Note : I have tried panic, defer, recover , but problem is that if both the functions/methods is in same go file it is working properly , but if suppose both(caller and func) are different go file it is starting a different go routine , "defer" at caller level is not working properly.

I guess this approach is not also equivalent like "throws" , where function provider is not handling the error but caller did that , and take the recovery action. Function body provider just specify it may return some exception and caller have to handle the exception.

Thanks in advance...

答:
No, you cannot do that. Go does not support throwing exceptions.

As you have noticed, you can panic and recover, but it's not the same thing.


问:
How can I fix images being slow to load?
I'm using Images.asset() in my Flutter project and the images are stored in the same Solutions Folder and have been compressed.
However, when scrolling through, it takes time for the images to load and more time for the images to load again once you go back to the same pageview.

Here's a link to how it looks like

答: I think that this is a ListView.builder(), if am I correct, you can set a value, eg. 500, in the cacheExtent propriery, this will hold some data and will avoid destroy your previous content.


问:
ImageMagick - Alpha Mask on transparent background
I want to composite some pngs onto one png using Imagemagick.

One of the images (b_0_1.png) is a mask. I need to apply this using additive composition.

But there is a problems with the background in the result, which should be transparent, but has a black square.

Here is my command:

magick -size 256x256 canvas:transparent \
  img/a_0_0.png -geometry +111+64 -compose over -composite \
  img/b_0_1.png -geometry +94+48 -compose plus -composite \
  img/c_0_0.png -geometry +108+88 -compose over -composite \
  img/d_0_0.png -geometry +102+62 -compose over -composite \
png32:result.png
```

Result: https://picr.ws/i/6WT

The black region should be transparent.

Images: http://s000.tinyupload.com/index.php?file_id=91925640425537122879

答:
Using ImageMagick 7 you could use a command like this...

```<code>magick -background none \
   \( -page +111+64 a_0_0.png \) \
   \( -page +94+48 b_0_1.png -alpha copy -set compose plus \) \
   \( -page +108+88 c_0_0.png \) \
   \( -page +102+62 d_0_0.png \) \
   -page 256x256 -flatten png32:result.png
</code>```

That would set the paging geometry on each sub-image within their own parentheses.

Inside the parentheses with the mask image "b_0_1.png", the "-alpha copy" gets rid of the black, and the "-set compose" applies the compose method "plus" to that individual image.

Then the page size is set at 256x256, and all the parts are flattened and located according to their page geometry. Since the background setting is "none", the transparent canvas is created when the sub-images are flattened.

The compose method "over" is the default, so it's used on the images with no set compose method. The mask image is flattened using the compose method "plus".

I tested this with IM6 on bash and with IM7 on Windows. I changed my IM6 bash "convert" to "magick" for this IM7 example. It should work exactly the same with either version.

Body:
I want to composite some pngs onto one png using Imagemagick.

One of the images (b_0_1.png) is a mask. I need to apply this using additive composition.

But there is a problems with the background in the result, which should be transparent, but has a black square.

Here is my command:

magick -size 256x256 canvas:transparent \
  img/a_0_0.png -geometry +111+64 -compose over -composite \
  img/b_0_1.png -geometry +94+48 -compose plus -composite \
  img/c_0_0.png -geometry +108+88 -compose over -composite \
  img/d_0_0.png -geometry +102+62 -compose over -composite \
png32:result.png

Result: https://picr.ws/i/6WT

The black region should be transparent.

Images: http://s000.tinyupload.com/index.php?file_id=91925640425537122879

Body:
Using ImageMagick 7 you could use a command like this...

magick -background none \
   \( -page +111+64 a_0_0.png \) \
   \( -page +94+48 b_0_1.png -alpha copy -set compose plus \) \
   \( -page +108+88 c_0_0.png \) \
   \( -page +102+62 d_0_0.png \) \
   -page 256x256 -flatten png32:result.png

That would set the paging geometry on each sub-image within their own parentheses.

Inside the parentheses with the mask image "b_0_1.png", the "-alpha copy" gets rid of the black, and the "-set compose" applies the compose method "plus" to that individual image.

Then the page size is set at 256x256, and all the parts are flattened and located according to their page geometry. Since the background setting is "none", the transparent canvas is created when the sub-images are flattened.

The compose method "over" is the default, so it's used on the images with no set compose method. The mask image is flattened using the compose method "plus".

I tested this with IM6 on bash and with IM7 on Windows. I changed my IM6 bash "convert" to "magick" for this IM7 example. It should work exactly the same with either version.


问:
Trim a full string, not characters - Redshift
This is the same question as here, but the answers there were very specific to PHP (and I'm using Redshift SQL, not PHP).

I'm trying to remove specific suffixes from strings. I tried using RTRIM, but that will remove any of the listed characters, not just the full string. I only want the string changed if the exact suffix is there, and I only want it replaced once.

For example, RTRIM("name",' Inc') will convert "XYZ Company Corporation" into "XYZ Company Corporatio". (Removed final 'n' since that's part of 'Inc')

Next, I tried using a CASE statement to limit the incorrect replacements, but that still didn't fix the problem, since it will continue making replacements past the original suffix.

For example, when I run this:

CASE WHEN "name" LIKE '% Inc' THEN RTRIM("name",' Inc')

I get the following results:

"XYZ Association Inc" becomes "XYZ Associatio". (It trimmed Inc but also the final 'n')

I'm aware I can use the REPLACE function, but my understanding is that this will replace values from anywhere in the string, and I only want to replace when it exists at the end of the string.

How can I do this with Redshift? (I don't have the ability to use any other languages or tools here).

答:
You can use REGEXP_REPLACE to remove the trailing Inc by using a regex that anchors the Inc to the end of the string:

```<code>CASE WHEN "name" LIKE '% Inc' THEN REGEXP_REPLACE("name", ' Inc$', '')
</code>```

Body:
You can use REGEXP_REPLACE to remove the trailing Inc by using a regex that anchors the Inc to the end of the string:

CASE WHEN "name" LIKE '% Inc' THEN REGEXP_REPLACE("name", ' Inc$', '')


问:
global name is not defined error for static method
For the code below I wrote for Binary Search Tree, I get the error delete_node(curr,value)
NameError: global name 'delete_node' is not defined. I am wondering why this will be the case for static method which is called from the instance method delete(self,value) . Why does it not work as a static method? I am calling it from a instance method 'delete' so does it does not require access to instance members explicitly.</p>

```<code>class Node:
    def __init__(self,value=None):
        self.value = value
        self.left = None
        self.right = None

class BST:
    def __init__(self,value=None):
        self.root = Node(value)
    @staticmethod
    def delete_node(node,value):
       if node is None:
           return node
       if value > node.value:
           node.right = delete_node(node.right,value)
       elif value < node.value:
           node.left = delete_node(node.left,value)
       else:
           if node.left is None and node.right is None:
               node = None
               return None
           elif node.left is None:
               temp = node.right
               node = None
               return temp
           elif node.right is None:
               temp = node.left
               node = None
               return temp
           else:
            #min_value = get_min(node.right)
               node.value = get_min(node.right)
               node.right = delete_node(node.right,node.value)

       def delete(self,value):
           if self.root == None:
           return
           curr = self.root
           delete_node(curr,value)
def get_min(node):
    curr = node
    while curr.left:
        curr = curr.left
    return curr.value

if __name__ == '__main__':
    tree = BST(5)
    tree.delete(5)
</code>```

答:
The design of your class seems confusing.

In python, when we define a staticmethod that means the class name is just something like namespace, you can not access any member of the class in the staticmethod.

If you want static methods in C#, try classmethod.

I recommend the popular question for classmethod vs staticmethod.

In the specific question, change your code like this:

```<code>class BST:
    ...
    @staticmethod
    def delete_node(node,value):
    ...
               node.right = BST.delete_node(node.right,node.value)

    def delete(self,value):
        ...
        BST.delete_node(curr,value)
</code>```

Body:
For the code below I wrote for Binary Search Tree, I get the error delete_node(curr,value)
NameError: global name 'delete_node' is not defined. I am wondering why this will be the case for static method which is called from the instance method delete(self,value) . Why does it not work as a static method? I am calling it from a instance method 'delete' so does it does not require access to instance members explicitly.

class Node:
    def __init__(self,value=None):
        self.value = value
        self.left = None
        self.right = None

class BST:
    def __init__(self,value=None):
        self.root = Node(value)
    @staticmethod
    def delete_node(node,value):
       if node is None:
           return node
       if value > node.value:
           node.right = delete_node(node.right,value)
       elif value < node.value:
           node.left = delete_node(node.left,value)
       else:
           if node.left is None and node.right is None:
               node = None
               return None
           elif node.left is None:
               temp = node.right
               node = None
               return temp
           elif node.right is None:
               temp = node.left
               node = None
               return temp
           else:
            #min_value = get_min(node.right)
               node.value = get_min(node.right)
               node.right = delete_node(node.right,node.value)

       def delete(self,value):
           if self.root == None:
           return
           curr = self.root
           delete_node(curr,value)
def get_min(node):
    curr = node
    while curr.left:
        curr = curr.left
    return curr.value

if __name__ == '__main__':
    tree = BST(5)
    tree.delete(5)

Body:
The design of your class seems confusing.

In python, when we define a staticmethod that means the class name is just something like namespace, you can not access any member of the class in the staticmethod.

If you want static methods in C#, try classmethod.

I recommend the popular question for classmethod vs staticmethod.

In the specific question, change your code like this:

class BST:
    ...
    @staticmethod
    def delete_node(node,value):
    ...
               node.right = BST.delete_node(node.right,node.value)

    def delete(self,value):
        ...
        BST.delete_node(curr,value)