Simple Shuffle. js поиск не работает с Bootstrap 4 картами - PullRequest
1 голос
/ 19 апреля 2020

Итак, в последние дни я пытался заставить Shuffle.js работать с моими картами в Bootstrap 4, чтобы получить хороший эффект перетасовки при поиске / фильтрации этих карт.

Вот структура моего HTML и моего JS. Вы также можете найти здесь ссылку JSFiddle. net.

class Card {
  constructor(ref) {
    this.hmi_ref = ref;

    // Bootstap : container type
    this.BS = {}
    this.BS.container = document.createElement('div');
    this.BS.card = document.createElement('div');
    this.BS.image = document.createElement('img');
    this.BS.info = document.createElement('div');
    this.BS.title = document.createElement('h4');
    this.BS.link = document.createElement('a');

    this.BS.card.appendChild(this.BS.link);
    this.BS.link.appendChild(this.BS.image);
    this.BS.card.appendChild(this.BS.title);
    this.BS.container.appendChild(this.BS.card);

    this.BS.container.className = 'col-4 mb-3';
    this.BS.card.className = 'card h-100';
    this.BS.image.className = 'card-img-top';
    this.BS.title.className = 'card-title text-center align-middle';
  }

  add(name, image, page_link) {
    this.BS.image.src = image;
    this.BS.title.textContent = name;
    this.BS.link.href = page_link;
    let newNode = this.BS.container.cloneNode(true);
    this.hmi_ref.appendChild(newNode);
  }
}

let myCard = new Card( document.getElementById('card-space') );
[
    {title: 'Vacanza studio Londra', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Roma', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Bangkok', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Catania', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanze studio"},
    {title: 'Vacanza studio Siracusa', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Ragusa', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Trapani', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
].map(e => myCard.add(e.title, e.img, e.link, e.category));

class Shuffler {
    constructor(element) {
        this.shuffle = new window.Shuffle(element, {
            itemSelector: '.card',
            sizer: element.querySelector('.sizer'),
        }); 
        document.getElementById('searchBox').addEventListener('keyup', this._handleSearchKeyup.bind(this));
    }

    /**
     * Filter the shuffle instance by items with a title that matches the search input.
     * @param {Event} evt Event object.
     */
    _handleSearchKeyup(evt) {
        const searchText = evt.target.value.toLowerCase();
        this.shuffle.filter(element => {
            console.log('filtering...');
            const titleText = element.querySelector('.card-title').textContent.toLowerCase().trim();
            return titleText.indexOf(searchText) !== -1;
        });
    }
}

window.onload = () => {
    window.demo = new Shuffler(document.querySelector('#card-space'));
}  
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

<div class="container pt-3">
  <div class="row">
    <div class="col">
      <!-- Main column -->
      <div class="row pt-4">
        <div class="col-9">
          <div id="card-space" class="row h-100">
            <div class="col-1@sm sizer"></div>
          </div>
        </div>
        <div class="col-3">
          <div class="row">
            <form class="form-inline" action="javascript:void(0);">
              <div class="input-group">
                <div class="input-group-prepend">
                  <div class="input-group-text"><i class="fa fa-search" aria-hidden="true"></i></div>
                </div>
                <input id="searchBox" class="form-control" type="search" placeholder="Cerca" aria-label="Cerca">
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<script src="https://unpkg.com/shufflejs@5"></script>
<!-- jQuery first, then Popper.js and then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

Кроме того, точка, в которой я думаю, что она определенно ломается, заключается в следующем

this.shuffle.filter(element => {
    const titleText = element.querySelector('.card-title').textContent.toLowerCase().trim();
    return titleText.indexOf(searchText) !== -1;
});

, поскольку я не могу отладить внутри Это.

У кого-нибудь есть идеи по поводу решения этой проблемы? Я обнаружил, что библиотека Shuffle. js довольно сложна, так как гладко это чувство, которое я испытываю, когда вижу конечный (желаемый!) Эффект.

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Взгляните на это демо . Что я сделал, так это полностью удалил всю структуру сетки и пошел на Bootstrap card-deck. Причина этого в том, как эта библиотека ищет массив элементов для фильтрации.

_getItems() {
    return Array.from(this.element.children)
        .filter(el => matches(el, this.options.itemSelector))
        .map(el => new ShuffleItem(el));
}

Это в основном означает, что он принимает прямые дочерние элементы и соответствует вашему itemSelector. В вашей структуре HTML он принимает все столбцы и не может найти классы itemSelector в ваших столбцах.

Другим важным шагом было использование data-groups и / или data-title. Сейчас я установил его только для заголовка (name), но я считаю, что ваша цель - добавить отдельные группы. Вы можете заполнить их из уже созданного селектора категорий (только с одной опцией).

this.BS.card.setAttribute('data-title', name);
this.BS.card.setAttribute('data-groups', name);

Это решение включает фильтр, включает высоту, и только слева теперь реагирует .card-deck , поскольку колода карт великолепна (я повторяю здесь).

Организация нескольких делений в CSS / JS?
l oop каждые 3 ряд с использованием bootstrap карты
Как добавить расстояние между рядами колоды карт в bootstrap

отзывчивая колода карт CSS демо

0 голосов
/ 19 апреля 2020

Вы можете фильтровать Array, а не Object. Я делаю console.log, чтобы вы могли видеть это.

class Card {
  constructor(ref) {
    this.hmi_ref = ref;

    // Bootstap : container type
    this.BS = {}
    this.BS.container = document.createElement('div');
    this.BS.card      = document.createElement('div');
    this.BS.image     = document.createElement('img');
    this.BS.info      = document.createElement('div');
    this.BS.title     = document.createElement('h4');
    this.BS.link      = document.createElement('a');

    this.BS.card.appendChild(this.BS.link);
    this.BS.link.appendChild(this.BS.image);
    this.BS.card.appendChild(this.BS.title);
    this.BS.container.appendChild(this.BS.card);

    this.BS.container.className = 'col-4 mb-3';
    this.BS.card.className      = 'card h-100';
    this.BS.image.className     = 'card-img-top';
    this.BS.title.className     = 'card-title text-center align-middle';
  }

  add ( name, image, page_link){
    this.BS.image.src = image;
    this.BS.title.textContent = name;
    this.BS.link.href = page_link;
    let newNode = this.BS.container.cloneNode(true);
    this.hmi_ref.appendChild(newNode);
  }
}
      
let myCard = new Card( document.getElementById('card-space') );
[
    {title: 'Vacanza studio Londra', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Roma', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Bangkok', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Catania', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanze studio"},
    {title: 'Vacanza studio Siracusa', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Ragusa', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
    {title: 'Vacanza studio Trapani', img: 'https://source.unsplash.com/random/1920x1080', link: 'https://source.unsplash.com/random/1920x1080', category: "Vacanza studio"},
].map(e => myCard.add(e.title, e.img, e.link, e.category));

class Shuffler {
    constructor(element) {
        this.shuffle = new window.Shuffle(element, {
            itemSelector: '.card',
            sizer: element.querySelector('.sizer'),
        }); 
        document.getElementById('searchBox').addEventListener('keyup', this._handleSearchKeyup.bind(this));
    }

    /**
     * Filter the shuffle instance by items with a title that matches the search input.
     * @param {Event} evt Event object.
     */
    _handleSearchKeyup(evt) {
        const searchText = evt.target.value.toLowerCase();
        Object.values(this.shuffle.element.children).filter(element => {
            const titleText = element.textContent.toLowerCase().trim();
            console.log(element.textContent.toLowerCase().trim(), titleText.indexOf(searchText));
            return titleText.indexOf(searchText) !== -1;
        });
    }
}

window.onload = () => {
    window.demo = new Shuffler(document.querySelector('#card-space'));
}   
</script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>

<body>
  <div class="container pt-3">
    <div class="row">
      <div class="col">
        <!-- Main column -->
        <div class="row pt-4">
          <div class="col-9">
            <div id="card-space" class="row">
              <!-- <div class="col-1@sm sizer"></div> -->
            </div>
          </div>
          <div class="col-3">
            <div class="row">
              <form class="form-inline" action="javascript:void(0);">
                <div class="input-group">
                  <div class="input-group-prepend">
                    <div class="input-group-text"><i class="fa fa-search" aria-hidden="true"></i></div>
                  </div>
                  <input id="searchBox" class="form-control" type="search" placeholder="Cerca" aria-label="Cerca">
                </div>
              </form>
            </div>
            <div class="row">
              <select class="custom-select my-3" id="eventCategories">
                <option selected>Scegli una categoria</option>
              </select>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/Shuffle/5.2.3/shuffle.min.js"></script>
  <!-- jQuery first, then Popper.js and then Bootstrap JS -->
  <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</body>

</html>
...