Javascript - использование кнопок в сгенерированной таблице для демонстрации информации в боковом элементе

В настоящее время я пытаюсь выяснить, как расширить мою динамически сгенерированную таблицу с помощью кнопок. Указанные кнопки будут отображать (при нажатии) некоторые части информации из таблицы в элементе aside из HTML рассматриваемой страницы. Например, когда я нажимаю кнопку в первой строке, она показывает мне название продукта в этой строке в боковом блоке рядом с таблицей. Идея проста, исполнение не очень.

Создание бокового элемента не является сложной задачей, но создание динамических кнопок, которые могут отображать части динамической таблицы, для меня немного проблематично. Ниже приведен полный код, отвечающий за создание таблицы.

 window.onload = function(e) {
    createBook("book");
  }
var books = [{
    "author": "Eric T. Freeman",
    "title": "Head First JavaScript Programming: A Brain-Friendly Guide",
    "isbn": "978-1-4493-4398-9, 9781449343989",
    "publisher": "O'Reilly Media",
    "editions": [{
        "year": "2017",
        "covercolour": "gray"
      },
      {
        "year": "2014",
        "covercolour": "blue"
      }
    ]
  },
  {
    "author": "David Flanagan",
    "title": "JavaScript: The Definitive Guide",
    "isbn": "0596805527",
    "publisher": "O'Reilly Media",
    "editions": [{
        "year": "2016",
        "covercolour": "yellow"
      },
      {
        "year": "2011",
        "covercolour": "black"
      }
    ]
  }
];

function createBook(bookid) {
  var bookbox = document.getElementById(bookid);

  article = document.createElement("article");
  bookbox.appendChild(article);

  sectionInfo = createSection("List of Books");
  article.appendChild(sectionInfo);

  var infoTable = createTableBook(book);
  sectionInfo.appendChild(infoTable);

}

function createTableBook() {
  var table = document.createElement("table");
  table.classList.add("tableBasic");
  var tr = document.createElement("tr");
  var th1 = document.createElement("th");
  var th2 = document.createElement("th");
  var th3 = document.createElement("th");
  var th4 = document.createElement("th");
  var th5 = document.createElement("th");
  var th6 = document.createElement("th");
  th1.innerHTML = "Author";
  th2.innerHTML = "Title";
  th3.innerHTML = "ISBN";
  th4.innerHTML = "Publisher";
  th5.innerHTML = "Editions";
  th6.innerHTML = "Showcase";
  tr.appendChild(th1);
  tr.appendChild(th2);
  tr.appendChild(th3);
  tr.appendChild(th4);
  tr.appendChild(th5);
  tr.appendChild(th6);
  table.appendChild(tr);

  for (var index in books) {
    var tr = document.createElement("tr");
    var td1 = document.createElement("td");
    td1.innerHTML = books[index].author;
    tr.appendChild(td1);
    var td2 = document.createElement("td");
    td2.innerHTML = books[index].title;
    tr.appendChild(td2);
    var td3 = document.createElement("td");
    td3.innerHTML = books[index].isbn;
    tr.appendChild(td3);
    var td4 = document.createElement("td");
    td4.innerHTML = books[index].publisher;
    tr.appendChild(td4);
    var td5 = document.createElement("td");
 //   td5.appendChild(createEditionDetails(index));
    tr.appendChild(td5);
    var td6 = document.createElement("button");
    td6.innerHTML = "button";
    tr.appendChild(td6);
    table.appendChild(tr);
}
return table;
}

function buttonWork(asideID) {//function I want to use
    var aside = document.getElementById(asideID);

    var $row = $(this).closest("tr");
    var $text = $row.find(".name").text();
    aside.innerHTML += $text + '<br/>';
}
function createHeader(h, text) {
  header = document.createElement("header");
  h = document.createElement(h);
  h.innerHTML = text;
  header.appendChild(h);
  return header;
}

function createSection(title) {
  var section = document.createElement("section");
  section.appendChild(createHeader("h3", title));
  return section;
}
<section>
  <article>
    <aside>
      <br>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    </aside>
    <section id = "book">
    </section>
  </article>
</section>
<!--<script>
  window.onload = function(e) {
    createBook("book");
  }
</script>-->

После проб и ошибок мне удалось найти решение некоторых проблем, но я не могу найти способ надежного подключения кнопок к новой логике в функции buttonWork. Я мог бы использовать некоторые идеи для новичка в JS.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вы хотите отобразить информацию о щелчке, вы можете использовать либо кнопку/ввод, либо гиперссылку (в первом столбце), чтобы сделать строку/столбец доступной для щелчка.

Следующий фрагмент кода иллюстрирует, как сделать кнопку

var td1 = document.createElement('input');
td1.type = "button";
td1.className = "btn";
td1.value = books[index].author;
td1.onclick = (function() {write your function here});
td.appendChild(td1);

Используя существующий код, вы можете превратить столбец (в данном случае первый) в кнопку, изменив свой код, чтобы отразить, что innerHTML будет кнопкой (см. код, выделенный полужирным шрифтом), в отличие от добавления дополнительного столбца кнопок в Таблица.

Я бы рекомендовал добавить идентификаторы в столбцы. См. рабочий пример, чтобы проиллюстрировать, что я имею в виду (показывает, что кнопка добавляется в столбец «Автор»)

Самым важным будет то, что вы напишете в функции. Непонятно, что вы хотите здесь сделать, но если вы хотите написать в другой раздел, то получите этот раздел, вызвав его по его идентификатору, а затем напишите значения.

Надеюсь это поможет

 window.onload = function(e) {
    createBook("book");
  }
var books = [{
    "author": "Eric T. Freeman",
    "title": "Head First JavaScript Programming: A Brain-Friendly Guide",
    "isbn": "978-1-4493-4398-9, 9781449343989",
    "publisher": "O'Reilly Media",
    "editions": [{
        "year": "2017",
        "covercolour": "gray"
      },
      {
        "year": "2014",
        "covercolour": "blue"
      }
    ]
  },
  {
    "author": "David Flanagan",
    "title": "JavaScript: The Definitive Guide",
    "isbn": "0596805527",
    "publisher": "O'Reilly Media",
    "editions": [{
        "year": "2016",
        "covercolour": "yellow"
      },
      {
        "year": "2011",
        "covercolour": "black"
      }
    ]
  }
];

function createBook(bookid) {
  var bookbox = document.getElementById(bookid);

  article = document.createElement("article");
  bookbox.appendChild(article);

  sectionInfo = createSection("List of Books");
  article.appendChild(sectionInfo);

  var infoTable = createTableBook(book);
  sectionInfo.appendChild(infoTable);

}

function createTableBook() {
  var table = document.createElement("table");
  table.classList.add("tableBasic");
  var tr = document.createElement("tr");
  var th1 = document.createElement("th");
  var th2 = document.createElement("th");
  var th3 = document.createElement("th");
  var th4 = document.createElement("th");
  var th5 = document.createElement("th");
  var th6 = document.createElement("th");
  th1.innerHTML = "Author";
  th2.innerHTML = "Title";
  th3.innerHTML = "ISBN";
  th4.innerHTML = "Publisher";
  th5.innerHTML = "Editions";
  th6.innerHTML = "Showcase";
  tr.appendChild(th1);
  tr.appendChild(th2);
  tr.appendChild(th3);
  tr.appendChild(th4);
  tr.appendChild(th5);
  tr.appendChild(th6);
  table.appendChild(tr);

  for (var index in books) {
    var tr = document.createElement("tr");
    var td1 = document.createElement("td");
    **td1.innerHTML = '<input type = "button" value  = "' + books[index].author + '"' +'/>';**
    tr.appendChild(td1);
    var td2 = document.createElement("td");
    td2.innerHTML = books[index].title;
    tr.appendChild(td2);
    var td3 = document.createElement("td");
    td3.innerHTML = books[index].isbn;
    tr.appendChild(td3);
    var td4 = document.createElement("td");
    td4.innerHTML = books[index].publisher;
    tr.appendChild(td4);
    var td5 = document.createElement("td");
 //   td5.appendChild(createEditionDetails(index));
    tr.appendChild(td5);
    var td6 = document.createElement("td"); //a column reserved for buttons
//    td6.appendChild(createButtonShow(index)); //I suppose it's going to be a similar index requirement as in createEditionDetails function
    tr.appendChild(td6);
    table.appendChild(tr);
  }
  return table;
}

function createHeader(h, text) {
  header = document.createElement("header");
  h = document.createElement(h);
  h.innerHTML = text;
  header.appendChild(h);
  return header;
}

function createSection(title) {
  var section = document.createElement("section");
  section.appendChild(createHeader("h3", title));
  return section;
}
<section>
  <article>
    <aside>
      <br>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    </aside>
    <section id = "book">
    </section>
  </article>
</section>
<!--<script>
  window.onload = function(e) {
    createBook("book");
  }
</script>-->

Рекомендовать использовать id — не лучший подход. Это создает хрупкое решение, которое оказывается более сложным, чем нужно. Кроме того, ОП уже создает кнопки, поэтому непонятно, почему вы демонстрируете, как это сделать.

Scott Marcus 10.02.2019 21:24

@ScottMarcus OP явно должен знать, как добавить функциональность к кнопке. Я включил вызов функции при нажатии, что является центральным элементом ответа.

Rachel Gallen 10.02.2019 21:40

Ваш ответ звучит не так. Вы говорите о необходимости кнопки или гиперссылки, а затем продолжаете показывать код, который в основном уже есть в OP. Вы продолжаете говорить о преобразовании столбца в кнопку (что бы это ни значило). Кроме того, к кнопкам вообще не следует добавлять события кликов. Просто используйте делегирование событий.

Scott Marcus 10.02.2019 22:00
Ответ принят как подходящий

Во-первых, ваш код нужно исправить, потому что все содержимое таблицы должно помещаться в ячейку (th или td). В настоящее время ваши элементы button добавляются непосредственно к строкам. Но, после этой поправки, это проще, чем вы думаете.

  • Настройте всего один обработчик события click на столе и при каждом сгенерированная кнопка нажата, это событие всплывет в таблице и обрабатываться там. (делегация мероприятия)
  • Чтобы отличить одну часть информации от другой, каждая ячейка будет иметь связанный с ним класс.
  • В обработчике кликов мы найдем информацию, относящуюся к кнопку, которая была нажата с помощью методов .closest() и .querySelector(), и отобразить ее в стороне.

Кстати, не используйте .innerHTML, если вы не устанавливаете/не получаете какой-либо контент, содержащий HTML. При его использовании возникают проблемы с производительностью и безопасностью. Вместо этого используйте .textContent.

Наконец, код, который вы показываете, не использует изображения или внешние ресурсы, поэтому запуск всего этого по событию .load, хотя и работает, не лучший выбор. Вместо этого запустите ваш код, как только браузер завершит синтаксический анализ HTML в body. Самый простой способ сделать это — разместить свой код непосредственно перед закрывающим тегом body.

table {
 font-size:.8em;
 border:2px solid #363;
 font-family:Arial, Calibri, Helvetica;
}

th, td {
  border:1px solid #e0e0e0;
  padding:2px;
}
<body>
  <section>
    <article>
      <aside>
        <br>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </aside>
      <section id = "book">
      </section>
    </article>
  </section>

  <!-- Placing your script here ensures that it won't run until all the HTML
       above it has been parsed and the DOM is fully loaded. -->
  <script>
  
    // Object property/key names do not need to be in quotes unless they contain spaces
    var books = [{
        author: "Eric T. Freeman",
        title: "Head First JavaScript Programming: A Brain-Friendly Guide",
        isbn: "978-1-4493-4398-9, 9781449343989",
        publisher: "O'Reilly Media",
        editions: [{year: "2017", covercolour:"gray" },{year: "2014", covercolour:"blue"}]
      },
      {
        author: "David Flanagan",
        title: "JavaScript: The Definitive Guide",
        isbn: "0596805527",
        publisher: "O'Reilly Media",
        editions: [{year: "2016", covercolour:"yellow"},{year:"2011", covercolour:"black"}]
      }];

    function createBook(bookid) {
      var bookbox = document.getElementById(bookid);

      article = document.createElement("article");
      bookbox.appendChild(article);

      sectionInfo = createSection("List of Books");
      article.appendChild(sectionInfo);

      var infoTable = createTableBook(book);
      sectionInfo.appendChild(infoTable);
    }

    function createTableBook() {
      var table = document.createElement("table");
      table.classList.add("tableBasic");
      var tr = document.createElement("tr");
      var th1 = document.createElement("th");
      var th2 = document.createElement("th");
      var th3 = document.createElement("th");
      var th4 = document.createElement("th");
      var th5 = document.createElement("th");
      var th6 = document.createElement("th");
      th1.textContent = "Author";
      th2.textContent = "Title";
      th3.textContent = "ISBN";
      th4.textContent = "Publisher";
      th5.textContent = "Editions";
      th6.textContent = "Showcase";
      tr.appendChild(th1);
      tr.appendChild(th2);
      tr.appendChild(th3);
      tr.appendChild(th4);
      tr.appendChild(th5);
      tr.appendChild(th6);
      table.appendChild(tr);

      // Books is an array, for/in loops are for objects.
      // With Arrays, there are many different types of loops available, but .forEach()
      // is the simplest as it does away with indexers
      books.forEach(function(book){
        var tr = document.createElement("tr");
        var td1 = document.createElement("td");
        td1.textContent = book.author;
        td1.classList.add("author");   // <-- This will be used to locate the data you want to show
        tr.appendChild(td1);
    
        var td2 = document.createElement("td"); 
        td2.textContent = book.title;
        td2.classList.add("title");  // <-- This will be used to locate the data you want to show       
        tr.appendChild(td2);
    
        var td3 = document.createElement("td");
        td3.textContent = book.isbn;
        td3.classList.add("isbn");   // <-- This will be used to locate the data you want to show       
        tr.appendChild(td3);
    
        var td4 = document.createElement("td");
        td4.textContent = book.publisher;
        td4.classList.add("publisher");  // <-- Used to locate the data you want to show           
        tr.appendChild(td4);
    
        var td5 = document.createElement("td");
        // td5.appendChild(createEditionDetails(index));
        td5.classList.add("edition");   // <-- This will be used to locate the data you want to show   
        tr.appendChild(td5);
    
        // All table content must be contained inside of cells. You have to put your button in 
        // a cell and then that cell goes into the row.
        var td6 = document.createElement("td");
        var btn = document.createElement("button");
        btn.textContent = "Details";
        td6.appendChild(btn);
        tr.appendChild(td6);
    
        table.appendChild(tr);
      });
      return table;
    }

    function createHeader(h, text) {
      header = document.createElement("header");
      h = document.createElement(h);
      h.textContent = text;
      header.appendChild(h);
      return header;
    }

    function createSection(title) {
      var section = document.createElement("section");
      section.appendChild(createHeader("h3", title));
      return section;
    }
  
    createBook("book");
    
    // You'll need to reference the table and the aside more than once.
    // Just query for them one time and then keep referring to those variables:
    let tbl = document.querySelector("table");
    let side = document.querySelector("aside");

    // Any buttons within the table that get clicked will also cause a click event to 
    // trigger for the table itself. We'll handle the details there.
    tbl.addEventListener("click", function(evt){
      // Set the aside's text content by navigating to the clicked button's closest
      // (<tr>) and then query from there to find the cell with the desired class.
      // Here, we're showing the title in the aside, but you can substitute any of the other 
      // book data by just referring to the class that was assigned to the cell.
      side.textContent = evt.target.closest("tr").querySelector(".title").textContent;
    });
  </script>
</body>

Ты находка. Спасибо и за полезный комментарий. Это действительно было проще, чем я думал.

DrAhzek 10.02.2019 22:06

@DrAhzek Не за что. Я только что сделал еще одно обновление, поэтому еще раз взгляните на раздел цикла for.

Scott Marcus 10.02.2019 22:08

Кстати, мне интересно, как будет выглядеть список названий в этом примере? Например, давайте переключим детали для кнопки «Добавить», и это добавит этот конкретный заголовок (или что-то еще) в список, сгенерированный в файле aside. Было бы легко изменить раздел сценария загрузки для этой цели, например, с помощью addCollection? Или это более сложная работа, которая потребует некоторой гимнастики, чтобы заставить ее работать?

DrAhzek 10.02.2019 22:20

@DrAhzek Это было бы очень просто, вы бы просто создали новый элемент в aside и скопировали в него любые данные из текущей строки, которые хотите.

Scott Marcus 10.02.2019 22:32

Другие вопросы по теме