Как использовать поиск/фильтр для HTML Div, сгенерированных из данных JSON с использованием JavaScript?

Я пытаюсь добавить фильтр для ссылок/div, сгенерированных из данных JSON.

У меня уже есть поисковый фильтр, работающий здесь без проблем, ЕСЛИ данные не генерируются в формате JSON. Но мне действительно нужно использовать JSON для более быстрой загрузки и обработки.

Проблема в том, что при этом он не фильтрует ссылки. Предполагается фильтровать div на основе текста внутри тегов <a></a>, включая некоторые скрытые тексты внутри тегов <span>..

В этом примере он может фильтровать только первый элемент в JSON, но не остальные.

// Links Filter
var input = document.getElementById("search-filter-cards");
input.addEventListener("input", searchFilterDivsMenu);

function searchFilterDivsMenu(e) {
  var filter = e.target.value.toUpperCase();
  var list = document.getElementById("links-list");
  var divs = list.getElementsByTagName("div");
  for (var i = 0; i < divs.length; i++) {
    var a = divs[i].getElementsByTagName("a")[0];
    if (a) {
      if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
        divs[i].style.display = "";
      } else {
        divs[i].style.display = "none";
      }
    }
  }
}

// JSON Data for each links
const maincards = {
  "linksList": [{
      'name': 'Java Bookmarks',
      'title': 'Java Bookmarks',
      'favicon': '../assets/links-favicons/java-bookmarks.png',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
    {
      'name': 'Chrono',
      'title': 'Chrono',
      'favicon': '../assets/links-favicons/chrono.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
    {
      'name': 'Kanban (May)',
      'title': 'EDEN Kanban',
      'favicon': '../assets/links-favicons/kanban.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out, Kanban board',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
  ]
};

const createMainCardLinks = ({
  name,
  title,
  favicon,
  url,
  tags,
  linkattributes
}) => `
    <div class = "card link-container">
      <img class = "link-img" src = "${favicon}"/>
      <a class = "link-title stretched-link" href = "${url}" ${linkattributes} title = "${title}">${name} <span class = "h-0">${tags}</span></a>
    </div>
  `;

const links = maincards.linksList.map(createMainCardLinks);
links.forEach(links => {
  document.getElementById("load-json-data").innerHTML += links;
});
.h-0 {
  display: none;
}
<body>
  <input id = "search-filter-cards" type = "text" autocomplete = "off" placeholder = "Type here to search">
  <div id = "links-list">
    <div class = "link-headers"><a class = "mb-0">Sample Links</a></div>
    <div id = "load-json-data"></div>
  </div>
</body>

Я новичок в 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) для оценки ваших знаний,...
2
0
56
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Мне потребовалась целая вечность, чтобы заметить, что у вас есть ВСЕ элементы div в списке ссылок вместо load-json-data.

Вот улучшенная версия. Это упрощено, и поскольку я переключаю только div в load-json-data, он работает.

// Links Filter
var input = document.getElementById("search-filter-cards");
input.addEventListener("input", searchFilterDivsMenu);

function searchFilterDivsMenu(e) {
  const filter = e.target.value.toUpperCase();
  const cards = document.querySelectorAll("#links-list .card");
  cards.forEach(card => {
    var a = card.querySelector("a");
    // console.info(filter, "|", a.textContent.toUpperCase(), "|", a.textContent.toUpperCase().indexOf(filter))
    card.hidden = !a || (filter && a.textContent.toUpperCase().indexOf(filter) === -1);
  })
}

// JSON Data for each links
const maincards = {
  "linksList": [{
      'name': 'Java Bookmarks',
      'title': 'Java Bookmarks',
      'favicon': '../assets/links-favicons/java-bookmarks.png',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
    {
      'name': 'Chrono',
      'title': 'Chrono',
      'favicon': '../assets/links-favicons/chrono.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
    {
      'name': 'Kanban (May)',
      'title': 'EDEN Kanban',
      'favicon': '../assets/links-favicons/kanban.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out, Kanban board',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
  ]
};

const createMainCardLinks = ({
  name,
  title,
  favicon,
  url,
  tags,
  linkattributes
}) => `
    <div class = "card link-container">
      <img class = "link-img" src = "${favicon}"/>
      <a class = "link-title stretched-link" href = "${url}" ${linkattributes} title = "${title}">${name} <span class = "h-0">${tags}</span></a>
    </div>
  `;

const links = maincards.linksList.map(createMainCardLinks);
document.getElementById("load-json-data").innerHTML = links.join("")
.h-0 {
  display: none;
}
<input id = "search-filter-cards" type = "text" autocomplete = "off" placeholder = "Type here to search">
<div id = "links-list">
  <div class = "link-headers"><a class = "mb-0">Sample Links</a></div>
  <div id = "load-json-data"></div>
  <div class = "card link-container">
    <img class = "link-img" src = "../assets/links-favicons/plus.ico" />
    <a class = "link-title stretched-link" href = "#" rel = "noopener noreferrer" target = "_blank" title = "Plus">Plus <span class = "h-0">Quick Links</span></a>
  </div>
  <div class = "card link-container">
    <img class = "link-img" src = "../assets/links-favicons/google.ico" />
    <a class = "link-title stretched-link" href = "#" rel = "noopener noreferrer" target = "_blank" title = "Google">Google <span class = "h-0">Quick Links</span></a>
  </div>
</div>

О верно! Это действительно отличное решение, и оно работает! Однако меня беспокоит то, что мне нужно добавить другой набор ссылок, поэтому еще один вариант <div id = "load-json-data"></div>, поэтому я действительно надеюсь отфильтровать <div id = "links-list">. Скажите, пожалуйста, возможно ли это? В любом случае, я посмотрю больше на это и посмотрю, смогу ли я его настроить. Благодарю вас!

ixcode 10.05.2022 21:03

Это первый раз, когда я касаюсь данных JSON, поэтому я действительно не уверен во многих вещах, поэтому большое спасибо за вашу помощь!

ixcode 10.05.2022 21:05

Это выглядит так: jsfiddle.net/вымзапфх В этой демонстрации я просто изменил HTML, чтобы добавить еще несколько примеров div под <div id = "load-json-data"></div>. При этом фильтр не будет работать для этих дополнительных элементов.

ixcode 10.05.2022 21:32

Спасибо и увидимся, я буду продолжать пытаться, пока не получу его, надеюсь.

ixcode 10.05.2022 22:21

Боже мой, теперь он работает, изменив селекторы, как вы сказали! Спасибо любезно!

ixcode 10.05.2022 22:42

Смотрите обновленный селектор и HTML

mplungjan 11.05.2022 07:20

Я использовал jquery для добавления, вы также можете использовать javascript.

const dataJSON = {
  "linksList": [{
      'name': 'Java Bookmarks',
      'title': 'Java Bookmarks',
      'favicon': '../assets/links-favicons/java-bookmarks.png',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
    {
      'name': 'Chrono',
      'title': 'Chrono',
      'favicon': '../assets/links-favicons/chrono.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
    {
      'name': 'Kanban (May)',
      'title': 'EDEN Kanban',
      'favicon': '../assets/links-favicons/kanban.ico',
      'url': '#',
      'tags': 'Login, Logout, Log-in, Log in, Log-out Log out, Kanban board',
      'linkattributes': 'rel = "noopener noreferrer" target = "_blank"'
    },
  ]
};

dataJSON.linksList.forEach((element) => {
$('#myDiv').append(`
<div><a href = "${element.url}"><img style = "margin-right:10px;" src = "${element.favicon}"/>${element.name}</a></div>
`);
})


function myFunction() {
    var input, filter, parentDiv, childDiv, a, i, txtValue;
    input = document.getElementById("myInput");
    filter = input.value.toUpperCase();
    parentDiv = document.getElementById("myDiv");
    childDiv = parentDiv.getElementsByTagName("div");
    for (i = 0; i < childDiv.length; i++) {
        a = childDiv[i].getElementsByTagName("a")[0];
        txtValue = a.textContent || a.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
            childDiv[i].style.display = "";
        } else {
            childDiv[i].style.display = "none";
        }
    }
}
* {
  box-sizing: border-box;
}

#myInput {
  background-position: 10px 12px;
  background-repeat: no-repeat;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#myDiv {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

#myDiv div a {
  border: 1px solid #ddd;
  margin-top: -1px; /* Prevent double borders */
  background-color: #f6f6f6;
  padding: 12px;
  text-decoration: none;
  font-size: 18px;
  color: black;
  display: block
}

#myDiv div a:hover:not(.header) {
  background-color: #eee;
}
<script src = "https://code.jquery.com/jquery-3.6.0.min.js" integrity = "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4 = " crossorigin = "anonymous"></script>

<h2>Links Search</h2>

<input type = "text" id = "myInput" onkeyup = "myFunction()" placeholder = "Search for names.." title = "Type in a name">

<div id = "myDiv">
  
</div>

Спасибо за ваш ответ, это тоже действительно хороший образец. Однако я пытался изменить ul и li's на divs, как в моем образце, но, похоже, это не сработало. Не могли бы вы показать мне, как это сделать, если вы используете div?

ixcode 10.05.2022 21:56

Я редактировал код с помощью div

Sumit Sharma 11.05.2022 05:06

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