fbpx

Cách xây dựng trang Archive có lọc dạng Isotope

Dưới đây là Guideline của Nam trong việc xây dựng trang Archive có lọc dạng Isotope

Chúng ta sẽ đi theo Guideline có sẵn ở phần “Filtering”, hãy cùng tìm hiểu Demo dưới đây

Preview của hình ảnh bảng tuần haofn hóa học, trong đó thanh điều khiển phân loại chúng nằm ở phía trên
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.js"></script>
<!-- or -->
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
<h1>Isotope - filtering</h1>

<div class="button-group filters-button-group">
  <button class="button is-checked" data-filter="*">show all</button>
  <button class="button" data-filter=".metal">metal</button>
  <button class="button" data-filter=".transition">transition</button>
  <button class="button" data-filter=".alkali, .alkaline-earth">alkali and alkaline-earth</button>
  <button class="button" data-filter=":not(.transition)">not transition</button>
  <button class="button" data-filter=".metal:not(.transition)">metal but not transition</button>
</div>

<div class="grid">
  <div class="element-item transition metal " data-category="transition">
    <h3 class="name">Mercury</h3>
    <p class="symbol">Hg</p>
    <p class="number">80</p>
    <p class="weight">200.59</p>
  </div>
  <div class="element-item metalloid " data-category="metalloid">
    <h3 class="name">Tellurium</h3>
    <p class="symbol">Te</p>
    <p class="number">52</p>
    <p class="weight">127.6</p>
  </div>
  <div class="element-item post-transition metal " data-category="post-transition">
    <h3 class="name">Bismuth</h3>
    <p class="symbol">Bi</p>
    <p class="number">83</p>
    <p class="weight">208.980</p>
  </div>
  <div class="element-item post-transition metal " data-category="post-transition">
    <h3 class="name">Lead</h3>
    <p class="symbol">Pb</p>
    <p class="number">82</p>
    <p class="weight">207.2</p>
  </div>
  <div class="element-item transition metal " data-category="transition">
    <h3 class="name">Gold</h3>
    <p class="symbol">Au</p>
    <p class="number">79</p>
    <p class="weight">196.967</p>
  </div>
  <div class="element-item alkali metal " data-category="alkali">
    <h3 class="name">Potassium</h3>
    <p class="symbol">K</p>
    <p class="number">19</p>
    <p class="weight">39.0983</p>
  </div>
  <div class="element-item alkali metal " data-category="alkali">
    <h3 class="name">Sodium</h3>
    <p class="symbol">Na</p>
    <p class="number">11</p>
    <p class="weight">22.99</p>
  </div>
  <div class="element-item transition metal " data-category="transition">
    <h3 class="name">Cadmium</h3>
    <p class="symbol">Cd</p>
    <p class="number">48</p>
    <p class="weight">112.411</p>
  </div>
  <div class="element-item alkaline-earth metal " data-category="alkaline-earth">
    <h3 class="name">Calcium</h3>
    <p class="symbol">Ca</p>
    <p class="number">20</p>
    <p class="weight">40.078</p>
  </div>
  <div class="element-item transition metal " data-category="transition">
    <h3 class="name">Rhenium</h3>
    <p class="symbol">Re</p>
    <p class="number">75</p>
    <p class="weight">186.207</p>
  </div>
  <div class="element-item post-transition metal " data-category="post-transition">
    <h3 class="name">Thallium</h3>
    <p class="symbol">Tl</p>
    <p class="number">81</p>
    <p class="weight">204.383</p>
  </div>
  <div class="element-item metalloid " data-category="metalloid">
    <h3 class="name">Antimony</h3>
    <p class="symbol">Sb</p>
    <p class="number">51</p>
    <p class="weight">121.76</p>
  </div>
  <div class="element-item transition metal " data-category="transition">
    <h3 class="name">Cobalt</h3>
    <p class="symbol">Co</p>
    <p class="number">27</p>
    <p class="weight">58.933</p>
  </div>
  <div class="element-item lanthanoid metal inner-transition " data-category="lanthanoid">
    <h3 class="name">Ytterbium</h3>
    <p class="symbol">Yb</p>
    <p class="number">70</p>
    <p class="weight">173.054</p>
  </div>
  <div class="element-item noble-gas nonmetal " data-category="noble-gas">
    <h3 class="name">Argon</h3>
    <p class="symbol">Ar</p>
    <p class="number">18</p>
    <p class="weight">39.948</p>
  </div>
  <div class="element-item diatomic nonmetal " data-category="diatomic">
    <h3 class="name">Nitrogen</h3>
    <p class="symbol">N</p>
    <p class="number">7</p>
    <p class="weight">14.007</p>
  </div>
  <div class="element-item actinoid metal inner-transition " data-category="actinoid">
    <h3 class="name">Uranium</h3>
    <p class="symbol">U</p>
    <p class="number">92</p>
    <p class="weight">238.029</p>
  </div>
  <div class="element-item actinoid metal inner-transition " data-category="actinoid">
    <h3 class="name">Plutonium</h3>
    <p class="symbol">Pu</p>
    <p class="number">94</p>
    <p class="weight">(244)</p>
  </div>
</div>

Cùng phân tích 1 chút, đoạn đầu ta Import thư viện chính của Isotope

<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.js"></script>
<!-- or -->
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>

Tiếp đó, ta tiến hành xây dựng thanh điều khiển, mục đích của thanh này là khi bấm vào từng nút bấm thì nó sẽ tự lọc những dữ liệu của nút bấm đó và chỉ giữ lại những bản ghi dữ liệu “đạt điều kiện”

<div class="button-group filters-button-group">
  <button class="button is-checked" data-filter="*">show all</button>
  <button class="button" data-filter=".metal">metal</button>
  <button class="button" data-filter=".transition">transition</button>
  <button class="button" data-filter=".alkali, .alkaline-earth">alkali and alkaline-earth</button>
  <button class="button" data-filter=":not(.transition)">not transition</button>
  <button class="button" data-filter=".metal:not(.transition)">metal but not transition</button>
</div>

Tại đây ta thấy mỗi nút bấm đều có 1 attribute là data-filter, đây chính là phần dữ liệu điều kiện để lọc

  • data-filter=”*” chỉ tất cả dữ liệu
  • data-filter=”.metal” chỉ dữ liệu có chứa metal

Tiếp đó, bạn thực hiện xây dựng bảng dữ liệu, lưu ý rằng bảng dữ liệu cần nằm trong thẻ div với class=”grid”

<div class="grid">
...
<div class="element-item transition metal " data-category="transition">
    <h3 class="name">Mercury</h3>
    <p class="symbol">Hg</p>
    <p class="number">80</p>
    <p class="weight">200.59</p>
  </div>
...
</div>

Với mỗi thẻ dữ liệu sẽ có cách nhóm vào class, như bạn thấy thẻ div kia hiện có 3 thuộc tính

  • element-item
  • transition
  • metal

Trong đó element-item sẽ quyết định việc Isotope nhận diện thẻ dữ liệu (Sẽ làm rõ ở Script tiếp theo), transition & meta sẽ chỉ rõ thẻ này đang có những dữ liệu nào (sẽ hiển thị nếu bấm vào nút có data-filter tương ứng)

Tiếp đó chèn Script ở dưới để điều khiển file thư viện cũng như nhận dạng thành phần cần thực hiện lọc

<script>// external js: isotope.pkgd.js

// init Isotope
var iso = new Isotope( '.grid', {
  itemSelector: '.element-item',
  layoutMode: 'fitRows'
});


// bind filter button click
var filtersElem = document.querySelector('.filters-button-group');
filtersElem.addEventListener( 'click', function( event ) {
  // only work with buttons
  if ( !matchesSelector( event.target, 'button' ) ) {
    return;
  }
  var filterValue = event.target.getAttribute('data-filter');
  // use matching filter function
  iso.arrange({ filter: filterValue });
});

// change is-checked class on buttons
var buttonGroups = document.querySelectorAll('.button-group');
for ( var i=0, len = buttonGroups.length; i < len; i++ ) {
  var buttonGroup = buttonGroups[i];
  radioButtonGroup( buttonGroup );
}

function radioButtonGroup( buttonGroup ) {
  buttonGroup.addEventListener( 'click', function( event ) {
    // only work with buttons
    if ( !matchesSelector( event.target, 'button' ) ) {
      return;
    }
    buttonGroup.querySelector('.is-checked').classList.remove('is-checked');
    event.target.classList.add('is-checked');
  });
}
</script>

Trong đó thành phần // init Isotope var iso = new Isotope( ‘.grid’, { itemSelector: ‘.element-item’, layoutMode: ‘fitRows’ }); sẽ chỉ rõ thẻ dữ liệu muốn target cũng như thành phần “grid” bọc ở ngoài

Cách xây dựng trang Archive (List post type) dạng Isotope như trên

Không dài dòng nữa, hãy cùng xem full code nhé, như ở ví dụ là file archive-product.php

<?php
get_header();
if (have_posts()) :
    echo '<div class="root-blog section-margin  dsn-blog">';
    ?>

<div class="button-group filters-button-group narrow dsn-border-style d-flex" id="filters" style="margin-top:200px;margin-bottom:50px;">
                        <button class="button dsn-btn text-center dsn-border border-color-heading custom-button-category background-transparent image-zoom  is-checked" data-filter="*">All</button>

                        <?php
                            // Loop through categories - https://developer.wordpress.org/reference/functions/get_categories
                            $categories = get_categories( array(
                                'taxonomy' => 'phan_loai',
                                'orderby'  => 'name',
                                'order'    => 'ASC'
                            ) );
                            foreach( $categories as $category ) {
                                echo '<button class="button dsn-btn text-center dsn-border border-color-heading custom-button-category background-transparent image-zoom " data-filter=".'.$category->slug.'">';
                                echo $category->name;
                                echo '</button>';
                            }
                        ?>

                    </div>


<?php

    echo '<div class="grid dsn-grid-layout  dsn-grid  dsn-posts dsn-post-type-classic" style="    --dsn-width-item: 3;
    --dsn-col-item: 30px;
    --dsn-row-item: 50px;">';
    while (have_posts()) :
        the_post();
        get_template_part('template-parts/content/content-product');
       
    endwhile;

    echo '</div>';
    \DesignGrid\arctitOption::Pagination(array(
        'prev_text' => arctit_buttons_pagination(esc_html__('Prev', 'arctit'), 'dsn-prev'),
        'next_text' => arctit_buttons_pagination(esc_html__('Next', 'arctit')),
        'before_page_number' => '<span class="dsn-numbers dsn-heading-title title-tag"><span class="number">',
        'after_page_number' => '</span></span>'
    ), 'align-items-center');
    echo '</div>';
else:
    get_template_part('template-parts/content/content', 'none');
endif;

get_footer();

Tại functions.php ta cũng enqueue 1 số script như sau (Lưu ý là cái này áp dụng cho mấy anh em dùng child theme)

function arctit_child_enqueue_styles() {

    if (is_post_type_archive( 'product')) {
        wp_enqueue_script( 'isotope-script', 'https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js', array(), null, true );
        wp_enqueue_script( 'custom_isotope', get_stylesheet_directory_uri() . '/assets/js/custom_isotope.js', array(), '1.0.0', true );      
    };
}

add_action(  'wp_enqueue_scripts', 'arctit_child_enqueue_styles' );
Array

Nam là 1 Growth Hacker, Developer đam mê với sự nghiệp phát triển web