آموزش ساخت جستجوی زنده محصولات در ووکامرس بدون پلاگین

  • در این آموزش با استفاده از کد سفارشی، به فروشگاه خود شورتکد جستجوی زنده محصولات (Product Ajax Search) را اضافه میکنیم.

    مزایای استفاده از کد سفارشی برای ساخت جستجوی پیشرفته

    • استفاده از آن رایگان است.
    • قابل استفاده در گوتنبرگ، المنتور و سایر صفحه‌سازها.
    • بر خلاف پلاگین‌ها این کد سایت شما را کند نمیکند.
    • امکان جستجو بر اساس نام محصول، توضیحات محصول و SKU
    • امکان توسعه بیشتر و افزودن امکانات دلخواه.

    ساخت شورتکد جستجوی زنده محصولات در ووکامرس

    کد سفارشی زیر را به وب‌سایت خود اضافه کنید.

    برای قرار دادن کد سفارشی در سایت‌های وردپرسی از سه روش زیر می‌توانید استفاده کنید:

    • قرار دادن کد در فایل functions.php تم فرزند
    • استفاده از پلاگین‌های کمکی مانند code snippets
    • ساخت پلاگین اختصاصی خود

    بیشتر بخوانید: آموزش نحوه اضافه کردن کد سفارشی در وردپرس

    مشاهده کد
    /*
     *Product ajax search code by mrnargil
     *[woo_search num="4" sku="on" description="on" price="on" check_stock="off" cat="on" ]
     *https://mrnargil.ir/product-ajax-search-code/
     */
    add_shortcode("woo_search", "woo_search_func");
    function woo_search_func($atts)
    {
        $atts = shortcode_atts(
            [
                "image" => "on",
                "check_stock" => "", // on
                "sku" => "", // off
                "description" => "", // off
                "price" => "", // off
                "num" => "5",
                "cat" => "on", // on
            ],
            $atts,
            "woo_search"
        );
        static $woo_search_first_call = 1;
        $image = $atts["image"];
        $stock = $atts["check_stock"];
        $sku = $atts["sku"];
        $description = $atts["description"];
        $price = $atts["price"];
        $num = $atts["num"];
        $cat = $atts["cat"];
    
        $woo_search_form =
            '<div class="woo_search_bar woo_bar_el">
        <form class="woo_search woo_bar_el" id="woo_search' .
            $woo_search_first_call .
            '" action="/" method="get" autocomplete="off">
    		<span class="loading woo_bar_el" >
    		<svg width="25px" height="25px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none" class="hds-flight-icon--animation-loading woo_bar_el">
    <g fill="#676767" fill-rule="evenodd" clip-rule="evenodd">
    <path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z" opacity=".2"/>
    <path d="M7.25.75A.75.75 0 018 0a8 8 0 018 8 .75.75 0 01-1.5 0A6.5 6.5 0 008 1.5a.75.75 0 01-.75-.75z"/>
    </g>
    </svg>
    		</span>
            <input type="search" name="s" placeholder="جستجو" id="keyword" class="input_search woo_bar_el" onkeyup="searchFetch(this)"><button id="mybtn" class="search' .
            $woo_search_first_call .
            ' woo_bar_el">
            <svg width="20px" height="20px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M16.6725 16.6412L21 21M19 11C19 15.4183 15.4183 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg>
            </button>
            <input type="hidden" name="post_type" value="product">
            <input type="hidden" name="search_id" value="' .
            $woo_search_first_call .
            '">
            <input type="hidden" name="check_stock" value="' .
            $stock .
            '">
            <input type="hidden" name="sku" value="' .
            $sku .
            '">
            <input type="hidden" name="description" value="' .
            $description .
            '">
            <input type="hidden" name="price" value="' .
            $price .
            '">
            <input type="hidden" name="num" value="' .
            $num .
            '">
            <input type="hidden" name="cat" value="' .
            $cat .
            '">
        </form><div class="search_result woo_bar_el" id="datafetch" style="display: none;">
            <ul>
                <li>در حال جستجو..</li>
            </ul>
        </div></div>';
        $java =
            '<script>
    function searchFetch(e) {
    const searchForm = e.parentElement;
    searchForm.querySelector(".loading").style.visibility = "visible";
    
    var datafetch = e.parentElement.nextSibling
    if (e.value.trim().length > 0) { datafetch.style.display = "block"; } else { datafetch.style.display = "none"; }
    
    e.nextSibling.value = "Please wait..."
    var formdata' .
            $woo_search_first_call .
            ' = new FormData(searchForm);
    formdata' .
            $woo_search_first_call .
            '.append("image", "' .
            $image .
            '")
    formdata' .
            $woo_search_first_call .
            '.append("action", "woo_search")
    Ajaxwoo_search(formdata' .
            $woo_search_first_call .
            ',e)
    
    }
    async function Ajaxwoo_search(formdata,e) {
      const url = "' .
            admin_url("admin-ajax.php") .
            '?action=woo_search";
      const response = await fetch(url, {
          method: "POST",
          body: formdata,
      });
      const data = await response.text();
    if (data){	e.parentElement.nextSibling.innerHTML = data}else  {
    e.parentElement.nextSibling.innerHTML = `<ul><a href="#" style="display: block; padding-inline-start: 14px;"><li>محصولی پیدا نشد ...</li></a></ul>`
    }
    e.parentElement.querySelector(".loading").style.visibility = "hidden";
    }
    function goSearch(id){document.querySelector(id).click(); console.log(`clicked`) }
    
    document.addEventListener("click", function(e) { if (document.activeElement.classList.contains("woo_bar_el") == false ) { [...document.querySelectorAll("div.search_result")].forEach(e => e.style.display = "none") } else {if  (e.target?.value.trim().length > 0) { e.target.parentElement.nextSibling.style.display = "block"}} })
    
    </script>';
        $css = '<style>form.woo_search { display: flex; flex-wrap: nowrap; border: 1px solid #f0f0f0; border-radius: 10vh; padding: 3px 5px; background-color: white; box-shadow: 0px 6px 9px #00000017; }
    form.woo_search button#mybtn { display: grid; padding: 4px; cursor: pointer; background: none; align-items: center;border: none; }
    form.woo_search input#keyword {border: none;}
    div#datafetch {
        background: white;
        z-index: 10;
        position: absolute;
        max-height: 425px;
        overflow: auto;
        box-shadow: 0px 15px 15px #00000036;
        right: 0;
        left: 0;
        top: 50px;
    }
    div.woo_search_bar {
        width: 600px!important;
        max-width: 90%!important;
        position: relative;
    }
    
    div.search_result ul a li {
        display: flex;
        margin: 0px;
        padding: 0px 0px 0px 0px;
        color: #3f3f3f;
        font-weight: bold;
        flex-direction: column;
        justify-content: space-evenly;
    }
    div.search_result li {
        margin-inline-start: 20px;
        list-style: none;
    }
    div.search_result ul {
        padding: 18px 0px 0px 0px!important;
        list-style: none;
        margin: auto;
    }
    
    div.search_result ul a {
        display: grid;
        grid-template-columns: 70px 1fr max-content;
        margin-bottom: 10px;
        gap: 5px;
        padding: 0 9px;
    }
    div.search_result ul a h5 {
        font-size: 1em;
        padding: 0;
        margin: 0;
        font-weight: bold;
    }
    div.search_result ul a p.des {
        font-weight: normal;
        font-size: 0.9em;
        color: #676767;
        padding: 0;
        margin: 0;
        line-height: 1.3em;
    }
    div.search_result ul a h5.sku {
        font-weight: normal;
        font-size: 0.85em;
        color: #676767;
        padding: 0!important;
        margin: 0!important;
    }
    div.search_result ul a span.title_r_1 {
        display: flex;
        flex-direction: row;
        gap: 9px;
    }
    div.search_result ul a:hover {
        background-color: #f3f3f3;
    }
    .woo_search input#keyword {
        outline: none;
        width: 100%;
        background-color: white;
    }
    span.loading {
        display: grid;
        align-items: center;
    }
    @-webkit-keyframes rotating {
        from{
            -webkit-transform: rotate(0deg);
        }
        to{
            -webkit-transform: rotate(360deg);
        }
    }
    
    .hds-flight-icon--animation-loading {
        -webkit-animation: rotating 1s linear infinite;
    }
    span.loading {
        visibility: hidden;
    }
    span.price p {
        padding: 0;
        margin: 0;
    }
    span.price {
        display: flex;
        margin-inline-end: 5px;
        align-items: center;
        color: #535353;
    }
    span.price .sale-price {
        justify-content: flex-start;
    
    }
    span.price > span {
        display: flex;
        flex-direction: column-reverse;
    }
    div#datafetch a {
        text-decoration: none;
    }
    ul.cat_ul.woo_bar_el {
        display: flex;
        flex-wrap: wrap;
        gap: 0px;
    }
    a.cat_a.woo_bar_el {
        display: block;
        color: #5a5a5a;
        padding: 4px 15px;
        border-radius: 10vh;
        border: 1px solid #5a5a5a;
    }
    a.cat_a.woo_bar_el:hover {
        background-color: #5a5a5a;
        color: white;
    }
    
    p.search_title {
        margin: 10px 10px 0px 8px;
        line-height: normal;
        color: #676767;
        font-size: 0.9em;
        font-weight: normal;
        padding: 0;
    }
    hr.search_title {
        background-color: #cccccc;
        margin: 2px 8px 0px 8px;
    }
    .woo_bar_el bdi{
        font-size: 1rem;
    }
    </style>';
        if ($woo_search_first_call == 1) {
            $woo_search_first_call++;
            return "{$woo_search_form}{$java}{$css}";
        } elseif ($woo_search_first_call > 1) {
            $woo_search_first_call++;
            return "{$woo_search_form}";
        }
    }
    
    add_action("wp_ajax_woo_search", "woo_search");
    add_action("wp_ajax_nopriv_woo_search", "woo_search");
    function woo_search()
    {
        //sleep(1s);
        $search_id = esc_attr($_POST["search_id"]);
        $stock = esc_attr($_POST["check_stock"]);
        $sku = esc_attr($_POST["sku"]);
        $description = esc_attr($_POST["description"]);
        $price = esc_attr($_POST["price"]);
        $num = esc_attr($_POST["num"]);
        $cat = esc_attr($_POST["cat"]);
        $search_term = esc_attr($_POST["s"]);
    
        if ($sku == "off") {
            $sku = "style='display: none;'";
        }
        if ($description == "off") {
            $description = "style='display: none;'";
        }
    
        if ($cat == "on") {
            $categories = get_terms([
                "taxonomy" => "product_cat",
                "name__like" => $search_term,
                "orderby" => "name",
                "order" => "ASC",
            ]);
    
            if (!empty($categories) && !is_wp_error($categories)) {
                echo '<p class="search_title">دسته‌بندی محصولات</p> ';
                echo '<hr class="search_title">';
                echo '<ul class="cat_ul woo_bar_el">';
    
                foreach ($categories as $category) {
                    $category_link = get_term_link(
                        $category->term_id,
                        "product_cat"
                    );
                    $product_count = $category->count;
                    echo '<li class="cat_li woo_bar_el"><a class="cat_a woo_bar_el" href="' .
                        esc_url($category_link) .
                        '">' .
                        esc_html($category->name) .
                        " (" .
                        $product_count .
                        ")</a></li>";
                }
                echo "</ul>";
            }
        }
    
        $the_query = new WP_Query([
            "posts_per_page" => $num,
            "post_type" => "product",
            "s" => $search_term,
        ]);
    
        if (!$the_query->have_posts()) {
            $the_query = new WP_Query([
                "posts_per_page" => $num,
                "post_type" => "product",
                "meta_query" => [
                    [
                        "key" => "_sku",
                        "value" => $search_term,
                        "compare" => "LIKE",
                    ],
                ],
            ]);
        }
    
        $number_of_result = $the_query->found_posts;
        if ($number_of_result > 5) {
            $show_all =
                '<button class="show_all woo_bar_el" style="text-align: center; background: white; width: 100%; padding: 5px; color: #666464; cursor: pointer; font-size: 0.95em;border: none; "   onclick="goSearch(`button.search' .
                $search_id .
                '`)"  >مشاهده تمام محصولات.. (' .
                $number_of_result .
                ")</button>";
        } else {
            $show_all = "";
        }
    
        if ($the_query->have_posts()):
            if ($cat == "on") {
                echo '<p class="search_title"></p> ';
                echo '<hr class="search_title">';
            }
    
            echo '<ul class="woo_bar_el">';
            while ($the_query->have_posts()):
    
                $the_query->the_post();
                $product = wc_get_product();
                $current_price = $product->get_price_html();
                if ($current_price == "") {
                    $current_price = "ناموجود";
                    $sold_style =
                        "style='font-size: 0.75em; font-weight: bold; color: red; '";
                } else {
                    $sold_style = "";
                }
    
                if ( $stock == "on" && $product->is_in_stock() != 1 ) {
                    $stock_hide = "style='display: none;'";
                } else {
                    $stock_hide = "";
                }
                ?>
    
                <a href="<?php echo esc_url(
                    get_permalink()
                ); ?>" class="woo_bar_el" <?= $stock_hide ?> >
    <?php $image = wp_get_attachment_image_src(
        get_post_thumbnail_id(),
        "single-post-thumbnail"
    ); ?>
    <?php if (
        $image[0] &&
        trim(esc_attr($_POST["image"])) == "on"
    ) { ?>  <img src="<?php the_post_thumbnail_url(
          "thumbnail"
      ); ?>" style="height: 60px;padding: 0px 5px;"> <?php } else { ?>  <span></span> <?php } ?>
    <li><span class="title_r_1"><h5><?php the_title(); ?></h5 class="product_name"><h5 class="sku" <?= $sku ?> >(SKU:  <?php echo $product->get_sku(); ?>) </h5></span><p class="des" <?= $description ?> > <?php echo wp_trim_words(
         $product->get_short_description(),
         15,
         "..."
     ); ?> </p> </li>
    
    
    <?php if ($price != "off") { ?>
    	<span class="price" <?= $sold_style ?> > <span> <?= $current_price ?> </span></span>
     <?php } ?>
    </a>
            <?php
            endwhile;
            echo $show_all;
            echo "</ul>";
            wp_reset_postdata();
        endif;
        die();
    }
    

    اکنون می‌توانید با استفاده از شورتکد زیر سرچ محصولات را به صفحات خود اضافه کنید.

    [woo_search num="4" sku="on" description="off" price="on" check_stock="off" cat="on" ]

    تنظیمات نوار جستجوی محصولات

    برای سفارشی‌سازی این نوار جستجو هفت اتریبیوت در نظر گرفته‌ام که هر یک را با هم بررسی می‌کنیم.

    image:‌ نمایش تصویر محصولات (پیش‌فرض: on)
    در صورتی که نمیخواهید تصویر محصولات نمایش داده شوند آن را برابر off قرار دهید.

    [woo_search image="off"]

    description:‌ نمایش توضیحات کوتاه (پیش‌فرض: on)
    در صورتی که نمیخواهید توضیحات کوتاه محصولات نمایش داده شوند آن را برابر off قرار دهید.

    [woo_search description="off"]

    sku:‌ نمایش شناسه محصول (پیش‌فرض: on)
    در صورتی که نمیخواهید شناسه محصول نمایش داده شوند آن را برابر off قرار دهید.

    [woo_search sku="off"]

    price:‌ نمایش قیمت محصول (پیش‌فرض: on)
    در صورتی که نمیخواهید قیمت محصولات نمایش داده شوند آن را برابر off قرار دهید.

    [woo_search price="off"]

    cat:‌ جستجو در دسته‌بندی محصولات (پیش‌فرض: on)
    دسته‌بندی محصولات به همراه تعداد محصولات آن کتگوری در بالای نتایج نشان داده میشوند، در صورتی که نمیخواهید دسته‌بندی محصولات در نتایج نمایش داده شوند آن را برابر off قرار دهید.

    [woo_search cat="off"]

    check_stock:‌ حذف محصولات ناموجود از نتایج (پیش‌فرض: off)
    اگر میخواهید محصولات ناموجود در نتایج جستجو نمایش داده نشوند مقدار آن را برابر on قرار دهید.

    [woo_search check_stock="on"]

    num:‌ تعداد نتایج (پیش‌فرض: 5)
    با این اتریبیوت میتوانید تعداد محصولات نمایش داده شده را تغییر دهید.

    [woo_search num="10"]

    اکنون می‌توانید با ترکیب اتریبیوت‌های بالا نوار جستجوی مورد نظر خود را بسازید.

    توضیحاتی درمورد نحوه کار این کد (برای علاقه‌مندان به توسعه پلاگین وردپرس)

    در این کد با استفاده از جاوا اسکریپت و Ajax کلیدهای فشرده شده‌ی کاربر را به Endpoint که خودمان با استفاده از هوک wp_ajax_woo_search ساخته‌ایم ارسال میکنیم، و در آنجا با استفاده از کلاس WP_Query محصولات مرتبط را استخراج کرده و به فرانت اند ارسال میکنیم.
    بعنوان تمرین پیشنهاد میکنم یک آپشن به این سرچ‌بار اضافه کنید تا کاربر کتگوری مورد نظر خود را انتخاب کند و سرچ فقط در آن کتگوری انجام شود.

    مقالات مشابه

    آموزش ساخت جستجوی زنده محصولات در ووکامرس بدون پلاگین

    آموزش ساخت اسلایدر محصولات ووکامرس بدون پلاگین

    آموزش اتصال وردپرس به گوگل شیت برای ذخیره فرم‌ها

    آموزش آپدیت قیمت در وردپرس با استفاده گوگل شیت

    دیدگاه‌ها

    دیدگاهتان را بنویسید

    نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *