Mi programa básicamente muestra libros y otra información al respecto. También debería poder eliminar dicho libro de la biblioteca y también la matriz en la que está almacenado. Aquí es donde radica mi problema, parece que no puedo eliminar ese libro exacto de la pantalla y la matriz. Intenté usar array.pop () y deleteRow (), pero solo eliminan desde la parte inferior. Gracias de antemano por la ayuda.

let myLibrary = [];

function book(name, author, pages, hasRead) {
    this.name = name;
    this.author = author;
    this.pages = pages;
    this.read = hasRead;
}

const Book1 = new book('Harry Potter', 'J. K. Rowling', 322, 'Yes');
const Book2 = new book('Great Expectations', 'Charles Dickens', 234, 'Yes');
const Book3 = new book('To Kill a Mockingbird', 'Harper Lee', 312, 'No')
const Book4 = new book('The Great Gatsby', 'F Scott Fitzgerald', 421, 'Yes');
const Book5 = new book('Ulysses', 'James Joyce', 267, 'Yes');
myLibrary.push(Book1, Book2, Book3, Book4, Book5);

function tableHeader() {
    var html = "<table id=myTable1>";
        html += "<tr>";
        html += "<th class=top1>" + 'BOOK NAME'+ "</th>";
        html += "<th class=top2>" + 'AUTHOR' + "</th>";
        html += "<th class=top3>" + 'PAGES' + "</th>";
        html += "<th class=top4>" + 'READ?' + "</th>";
        html += "</tr>";
    html += "</table>";
    document.getElementById("top").innerHTML = html
}
tableHeader();

function viewLibrary() {
    var html = "<table id=myTable>";
    for (i = 0; i < myLibrary.length; i++) {
        html += "<tr>";
        html += "<td>" + [i+1] + "</td>";
        html += "<td class=box1>" + myLibrary[i].name + "</td>";
        html += "<td class=box2>" + myLibrary[i].author + "</td>";
        html += "<td class=box3>" + myLibrary[i].pages + "</td>";
        html += "<td class=box4>" + myLibrary[i].read + "</td>";
        html += "<td class=del>" + 'X' + "</td>";
        html += "</tr>";
    }
    html += "</table>";
    document.getElementById("box").innerHTML = html;
}
viewLibrary();

function deleteBook() {
    var button = document.querySelectorAll('.del');
    var table = document.getElementById('myTable');
    var rowCount = table.rows.length;
    for (var i = 0; i < rowCount; i++) {
        button[i].addEventListener('click', function () {
            table.deleteRow(this);
            console.log(event);
            myLibrary.pop();
        })
    }
}
deleteBook();

function addModal() {
    var btn = document.getElementById("new-book");
    var modal = document.getElementById("myModal");
    var span = document.getElementsByClassName("close")[0];

    btn.onclick = function () {
        modal.style.display = "block";
    }
    span.onclick = function () {
        modal.style.display = "none";
    }
}
addModal();

function addBookToLibrary() {
    let name = document.getElementById('name').value;
    let author = document.getElementById('author').value;
    let pages = document.getElementById('pages').value;
    let read = document.getElementById('dropdown').value;
    var submit = document.getElementById("submit");
    var modal = document.getElementById("myModal");
    if (name === '' || author === '' || pages === '' || read === '') {
        alert("Fill out all values.")
        return false;
    } else {
        submit.onclick = function () {
            modal.style.display = "none";
        }
        const NewBook = new book(name, author, pages, read);
        myLibrary.push(NewBook);
        console.log(NewBook);
        viewLibrary();
        document.getElementById('name').value = '';
        document.getElementById('author').value = '';
        document.getElementById('pages').value = '';
        document.getElementById('dropdown').value = '';
        deleteBook();
    }
}

let x = document.querySelectorAll('button');
x.forEach(button => {
    button.addEventListener('click', () => {
        let selection = button.innerHTML;
        switch (selection) {
            case "Submit":
                addBookToLibrary();
                break;
        }
    })
})
body {
    background-color: #edc4b3;
}

/* The Modal (background) */
.modal {
    display: none;
    position: fixed;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgb(0, 0, 0);
    background-color: rgba(0, 0, 0, 0.4);
}

/* Modal Content/Box */
.modal-content {
    background-color: #eddcd2;
    margin: 15% auto;
    padding: 20px;
    border: 1px solid #888;
    width: 40%;
}

/* The Close Button */
.close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
}

.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}

table {
    margin-left: 14.5%;
    margin-top: 5%;
    width: 70%;
    background-color: #edddd4;
    border: 5px solid #8d99ae;
    border-collapse: collapse;
    margin-top: 2%;
}

#top {
    color: #9d6b53;
}

#box {
    margin-top: -1.5%;
}

.line {
    color: #774936;
}

td {
    padding-bottom: 10px;
    padding-top: 10px;
    padding-left: 10px;
}

h1 {
    text-align: center;
    text-transform: uppercase;
    font-family: 'Notable', sans-serif;
}

h2 {
    text-align: center;
    text-decoration: underline;
}

#new-book {
    margin-left: 79%;
    background-color: #888;
    cursor: pointer;
    margin-top: 2%;
    padding: 5px 5px;
    font-weight: bold;
}

/*tr:first-child { font-weight: bold }*/

#name, #author, #pages {
    width: 60%;
    border: 0;
    border-bottom: 1px solid black;
    font-size: 1rem;
    color: black;
    background-color: #eddcd2;
    font-family: 'Times New Roman', Times, serif;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 2px;
    padding-right: 2px;
}

td {
    font-family: 'Source Code Pro', monospace; 
}

#author {
    width: 58.5%;
}

#pages {
    width: 61.3%;
}

#dropdown {
    width: 28%;
    background-color: #edddd4;
    font-size: 17px;
    cursor: pointer;  
    box-sizing: border-box;
    margin: 0;
    border: 1px solid black;
    padding-top: 5px;
    padding-bottom: 5px;
}

#submit {
    background-color: black;
    border: none;
    color: white;
    padding: 16px 32px;
    text-decoration: none;
    margin: 4px 2px;
    cursor: pointer;
    width: 30%;    
    margin-left: 35%;
}

input:focus,
select:focus,
textarea:focus,
button:focus {
    outline: none;
}

.del {
    color: red;
    cursor: pointer;
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Library</title>
    <link rel="stylesheet" href="main.css">
</head>

<body>
    <button id='new-book'>Add Book</button>

    <section id="top"></section>
    <section id="box"></section>

    <div id="myModal" class="modal">
        <!-- Modal content -->
        <div class="modal-content">
            <span class="close">&times;</span>
            <h2>Add a new book</h2>

            <label for="name">Name of the Book:</label>
            <input type="text" id="name" name="fname" required><br><br>
            <label for="author">Name of the Author:</label>
            <input type="text" id="author" name="lname" required><br><br>
            <label for="pages">Number of Pages:</label>
            <input type="number" id="pages" name="pname" required><br><br>

            <p>Have you read this book?</p>
            <select id="dropdown" required>
                <option value="" disabled selected>Select your option</option>
                <option value="Yes">Yes</option>
                <option value="No">No</option>
            </select><br><br>

            <button id="submit">Submit</button>
        </div>
    </div>

    <script src="main.js"></script>
</body>

</html>
0
user3843256 23 jun. 2020 a las 16:43

4 respuestas

La mejor respuesta

Sugeriría un enfoque diferente. En lugar de crear sus nuevos elementos a través de la concatenación de cadenas y .innerHTML (que tiene implicaciones de rendimiento y seguridad), use la API DOM para crear sus nuevos elementos y luego simplemente adjunte un controlador de eventos a las celdas creadas dinámicamente que contienen el {{ X1}}.

Ver comentarios adicionales en línea a continuación:

let headers = ["name", "author", "pages", "read"];

// Get your DOM references just once, not every time
// your event handlers execute and make sure to always
// reference the DOM element, rather than a property
// of the DOM element. That way, if you ever decide 
// that you need a different property value, you won't
// have to scan the DOM for the element reference again.
let box = document.getElementById("box");
var btn = document.getElementById("new-book");
var modal = document.getElementById("myModal");
let closeModal = document.querySelector("span.close");
let name = document.getElementById('name');
let author = document.getElementById('author');
let pages = document.getElementById('pages');
let read = document.getElementById('dropdown');
var submit = document.getElementById("submit");
var modal = document.getElementById("myModal");

// DO NOT USE GETELEMENTSBYCLASSNAME and especially
// pass an idex to the first element within it:
// var span = document.getElementsByClassName("close")[0];
// Read this for details: https://stackoverflow.com/questions/54952088/how-to-modify-style-to-html-elements-styled-externally-with-css-using-js/54952474#54952474
// Instead, use .querySelector()
var span = document.querySelector(".close");

// Bind the "buttons" that show/hide the modal
// to a common function that does that.
btn.addEventListener('click', showHideModal);
closeModal.addEventListener('click', showHideModal);

function showHideModal(){
  // No need for if/then. Just toggle the use of
  // the .hidden CSS class
  modal.classList.toggle("hidden");
}

submit.addEventListener('click', addBookToLibrary);

function book(name, author, pages, hasRead) {
    this.name = name;
    this.author = author;
    this.pages = pages;
    this.read = hasRead;
}

// No need to create variables to store new book references,
// and then push them into the Array. Just put the new books 
// directly into the new  Array.
let myLibrary = [
  new book('Harry Potter', 'J. K. Rowling', 322, 'Yes'),
  new book('Great Expectations', 'Charles Dickens', 234, 'Yes'), 
  new book('To Kill a Mockingbird', 'Harper Lee', 312, 'No'),
  new book('The Great Gatsby', 'F Scott Fitzgerald', 421, 'Yes') ,
  new book('Ulysses', 'James Joyce', 267, 'Yes')
];

function makeLibrary() {
  // Get rid of the prior table (if exists)
  if(document.getElementById("myTable")){
    document.getElementById("myTable").remove();
  }
  
  // Instead of creating concatenated strings of HTML, which gets
  // messy and hard to maintain, create DOM objects and set their
  // propeties.
  let tbl = document.createElement("table");
  tbl.id = "myTable";
  
  for (i = 0; i < myLibrary.length; i++) {
    let row = document.createElement("tr");
    let numCell = document.createElement("td");
    numCell.textContent = i + 1;
    row.appendChild(numCell);
      
      // Loop over the headers array to build the row cells
      headers.forEach(function(header, index){
        let cell = document.createElement("td");
        cell.textContent = myLibrary[i][header];
        cell.classList.add("box" + (index + 1));
        row.appendChild(cell); // Add the cell to the row
      });
      
      let delCell = document.createElement("td");
      delCell.textContent = "X";
      delCell.classList.add("del");
      
      // Because the elements are now being created as elements
      // and not strings, you can set up even binding on them.
      delCell.addEventListener("click", function(){
        myLibrary.splice(i, 1);  // Remove book from library
        this.closest("tr").remove(); // Remove row
      });
      
      row.appendChild(delCell); // Add cell to row
      tbl.appendChild(row);     // Add row to table
      box.appendChild(tbl);     // Add table to section
    }
}

makeLibrary();

function addBookToLibrary() {
  if (name.value === '' || author.value === '' || pages.value === '' || read.value === '') {
    alert("Fill out all values.")
    return false;
  } else {
    myLibrary.push(new book(name.value, author.value, pages.value, read.value));
    makeLibrary();    
    
    name.value = '';
    author.value = '';
    pages.value = '';
    dropdown.value = '';
    showHideModal();
  }
}
body {
    background-color: #edc4b3;
}

/* Added classes */
h1.addBook { font-size: 1em; }
.hidden { display:none; }

/* The Modal (background) */
.modal {
    position: fixed;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgb(0, 0, 0);
    background-color: rgba(0, 0, 0, 0.4);
}

/* Modal Content/Box */
.modal-content {
    background-color: #eddcd2;
    margin: 15% auto;
    padding: 20px;
    border: 1px solid #888;
    width: 40%;
}

/* The Close Button */
.close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
}

.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}

table {
    margin-left: 14.5%;
    margin-top: 5%;
    width: 70%;
    background-color: #edddd4;
    border: 5px solid #8d99ae;
    border-collapse: collapse;
    margin-top: 2%;
}

#top {
    color: #9d6b53;
}

#box {
    margin-top: -1.5%;
}

.line {
    color: #774936;
}

td {
    padding-bottom: 10px;
    padding-top: 10px;
    padding-left: 10px;
}

h1 {
    text-align: center;
    text-transform: uppercase;
    font-family: 'Notable', sans-serif;
}

h2 {
    text-align: center;
    text-decoration: underline;
}

#new-book {
    margin-left: 79%;
    background-color: #888;
    cursor: pointer;
    margin-top: 2%;
    padding: 5px 5px;
    font-weight: bold;
}

/*tr:first-child { font-weight: bold }*/

#name, #author, #pages {
    width: 60%;
    border: 0;
    border-bottom: 1px solid black;
    font-size: 1rem;
    color: black;
    background-color: #eddcd2;
    font-family: 'Times New Roman', Times, serif;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 2px;
    padding-right: 2px;
}

td {
    font-family: 'Source Code Pro', monospace; 
}

#author {
    width: 58.5%;
}

#pages {
    width: 61.3%;
}

#dropdown {
    width: 28%;
    background-color: #edddd4;
    font-size: 17px;
    cursor: pointer;  
    box-sizing: border-box;
    margin: 0;
    border: 1px solid black;
    padding-top: 5px;
    padding-bottom: 5px;
}

#submit {
    background-color: black;
    border: none;
    color: white;
    padding: 16px 32px;
    text-decoration: none;
    margin: 4px 2px;
    cursor: pointer;
    width: 30%;    
    margin-left: 35%;
}

input:focus,
select:focus,
textarea:focus,
button:focus {
    outline: none;
}

.del {
    color: red;
    cursor: pointer;
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Library</title>
    <link rel="stylesheet" href="main.css">
</head>

<body>
    <button id='new-book'>Add Book</button>

    <section id="top">
       <!-- If you have static bits of HTML, don't create them
            dynamically in JavaScript, go ahead and hard-code them
            into the HTML.  This will reduce the amount of JavaScript
            and improve the speed of the page load. -->
       <table id="myTable1">
         <tr>
           <th class="top1">BOOK NAME</th>
           <th class=top2>AUTHOR</th>
           <th class=top3>PAGES</th>
           <th class=top4>READ?</th>
         </tr>
       </table>
    </section>
    <section id="box"></section>

    <div id="myModal" class="modal hidden">
        <!-- Modal content -->
        <div class="modal-content">
            <span class="close">&times;</span>
            <!-- You can't have an H2 if it's not a child of an H1. 
                 Don't choose a heading because of how it looks, pick
                 it because it represents the right heading level and
                 then style it with CSS. -->
            <h1 class="addBook">Add a new book</h1>

            <label for="name">Name of the Book:</label>
            <input type="text" id="name" name="fname" required><br><br>
            <label for="author">Name of the Author:</label>
            <input type="text" id="author" name="lname" required><br><br>
            <label for="pages">Number of Pages:</label>
            <input type="number" id="pages" name="pname" required><br><br>

            <p>Have you read this book?</p>
            <select id="dropdown" required>
                <option value="" disabled selected>Select your option</option>
                <option value="Yes">Yes</option>
                <option value="No">No</option>
            </select><br><br>

            <button id="submit">Submit</button>
        </div>
    </div>

    <script src="main.js"></script>
</body>
</html>
3
Scott Marcus 23 jun. 2020 a las 17:01

this en table.deleteRow(this) se refiere a un HTMLTableCellElement .

De acuerdo a este documento: https://www.w3schools.com/jsreF/met_table_deleterow.asp

Tendrás que pasar un índice en su lugar.

Editar:

¿Qué hay de agregar un atributo data-row a sus filas donde coloca el índice y luego obtener este índice usando element.dataset.row

P.EJ :

var html = "<table id=myTable1>";
        html += "<tr data-row=" + $yourIndex + ">";
        html += "<th class=top1>" + 'BOOK NAME'+ "</th>";
        html += "<th class=top2>" + 'AUTHOR' + "</th>";
        html += "<th class=top3>" + 'PAGES' + "</th>";
        html += "<th class=top4>" + 'READ?' + "</th>";
        html += "</tr>";
    html += "</table>";
0
r0ulito 23 jun. 2020 a las 14:14
function deleteBook() {
    var button = document.querySelectorAll('.del');
    var table = document.getElementById('myTable');
    var rowCount = table.rows.length;
    for (var i = 0; i < rowCount; i++) {
        button[i].addEventListener('click', function () {
            table.deleteRow(i);

            // I think pop will delete only the last element. 
            myLibrary.splice(i, 1);
        })
    }
}
0
user1592129 23 jun. 2020 a las 13:51

Use Splice para eliminar el elemento de la matriz. Utilice este enlace para su referencia .

Su forma de explicación es un poco vaga de entender.

0
Elango Sengottaiyan 23 jun. 2020 a las 16:20