Skip links

Интернет-магазин на Hello Elementor

ВАЖНО!

Более подробный текст с описанием и ссылка на бекап появится после выхода последней части серии видео.

CSS код для горизонтального меню

Для добавления, переходим в виджете меню во вкладку Расширенные и открываем раздел Custom CSS

				
					@media (min-width: 768px) {
selector li {
    width: 100%;
}
}

@media (max-width: 768px) {
      .elementor-nav-menu__container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .elementor-nav-menu {
    display: flex !important;
    flex-wrap: nowrap !important;
  }

  .elementor-nav-menu__container::-webkit-scrollbar {
    display: none;
  }
    
}
				
			
JS код для обновления количества:

Для добавления, переходим в админ панели в раздел для добавления произвольного кода в Elementor или любого другого плагина, который вы используете для добавления JS кода.

				
					<script>
(function ($) {

  function renderStepper($btn, qty) {
    qty = parseInt(qty || 1, 10);

    const pid = $btn.data('product_id') || $btn.attr('data-product_id');
    if (!pid) return;

    const html = `
      <div class="eg-qty" data-product_id="${pid}">
        <button type="button" class="eg-qty__btn eg-qty__minus" aria-label="minus">−</button>
        <input type="number" class="eg-qty__input" min="0" step="1" value="${qty}">
        <button type="button" class="eg-qty__btn eg-qty__plus" aria-label="plus">+</button>
      </div>
    `;

    $btn.replaceWith(html);
  }

  function setStepperValue(productId, qty) {
    const $wrap = $(`.eg-qty[data-product_id="${productId}"]`);
    if ($wrap.length) {
      $wrap.find('.eg-qty__input').val(parseInt(qty || 0, 10));
      return true;
    }
    return false;
  }

  function fetchCartQtyMap() {
    const url = wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'eg_get_cart_qty');

    return $.getJSON(url)
      .then(function (res) {
        if (res && res.success && res.data && res.data.items) return res.data.items;
        return {};
      })
      .catch(function () {
        return {};
      });
  }

  function applyQtyToGrid(itemsMap) {
    $('.add_to_cart_button').each(function () {
      const $btn = $(this);
      const pid = parseInt($btn.data('product_id') || $btn.attr('data-product_id'), 10);
      if (!pid) return;

      const q = parseInt(itemsMap[pid] || 0, 10);
      if (q > 0) {
        renderStepper($btn, q);
      }
    });

    Object.keys(itemsMap || {}).forEach(function (pid) {
      setStepperValue(pid, itemsMap[pid]);
    });
  }

  function getQtyFromFragments(productId) {
    let found = null;
    const $mini = $('.widget_shopping_cart, .woocommerce-mini-cart');
    if (!$mini.length) return null;

    $mini.find('[data-product_id]').each(function () {
      const pid = parseInt($(this).data('product_id'), 10);
      if (pid === parseInt(productId, 10)) {
        const txt = $(this).closest('li, .woocommerce-mini-cart-item').text();
        const m = txt.match(/(\d+)\s*×/);
        if (m) found = parseInt(m[1], 10);
      }
    });

    return found;
  }

  function setCartQty(productId, qty) {
    qty = parseInt(qty, 10);
    if (isNaN(qty) || qty < 0) qty = 0;

    if (qty === 0) {
      const $remove = $(`.woocommerce-mini-cart a.remove[data-product_id="${productId}"],
                         .widget_shopping_cart a.remove[data-product_id="${productId}"]`).first();
      if ($remove.length) {
        $remove.trigger('click');
        return;
      }
    }

    return $.post(
      wc_add_to_cart_params.wc_ajax_url.toString().replace('%%endpoint%%', 'add_to_cart'),
      {
        product_id: productId,
        quantity: qty,
        eg_set_qty: 1
      }
    ).done(function () {
      $(document.body).trigger('added_to_cart');
    });
  }

  $(document.body).on('added_to_cart', function (e, fragments, cart_hash, $button) {
    if ($button && $button.length) {
      const pid = $button.data('product_id') || $button.attr('data-product_id');
      if (pid) {
        const current = getQtyFromFragments(pid) || 1;

        if (!setStepperValue(pid, current)) {
          renderStepper($button, current);
        }
      }
    }

    fetchCartQtyMap().then(function (itemsMap) {
      applyQtyToGrid(itemsMap);
    });
  });

  $(document).on('click', '.eg-qty__plus, .eg-qty__minus', function () {
    const $wrap = $(this).closest('.eg-qty');
    const pid = $wrap.data('product_id');
    const $inp = $wrap.find('.eg-qty__input');

    let val = parseInt($inp.val() || 0, 10);
    if ($(this).hasClass('eg-qty__plus')) val += 1;
    else val = Math.max(0, val - 1);

    $inp.val(val);
    setCartQty(pid, val);
  });

  $(document).on('change', '.eg-qty__input', function () {
    const $wrap = $(this).closest('.eg-qty');
    const pid = $wrap.data('product_id');
    const val = parseInt($(this).val() || 0, 10);
    setCartQty(pid, val);
  });

  $(function () {
    fetchCartQtyMap().then(function (itemsMap) {
      applyQtyToGrid(itemsMap);
    });

    setTimeout(function () {
      $('.add_to_cart_button').each(function () {
        const $btn = $(this);
        const pid = $btn.data('product_id') || $btn.attr('data-product_id');
        if (!pid) return;

        const q = getQtyFromFragments(pid);
        if (q && q > 0) {
          renderStepper($btn, q);
        }
      });
    }, 400);
  });

  const obsTarget = document.body;
  const observer = new MutationObserver(function (mutations) {
    let need = false;
    for (const m of mutations) {
      if (m.addedNodes && m.addedNodes.length) {
        if ($(m.addedNodes).find('.add_to_cart_button').length || $(m.addedNodes).is('.add_to_cart_button')) {
          need = true;
          break;
        }
      }
    }
    if (need) {
      fetchCartQtyMap().then(function (itemsMap) {
        applyQtyToGrid(itemsMap);
      });
    }
  });
  observer.observe(obsTarget, { childList: true, subtree: true });

})(jQuery);
</script>
				
			
PHP код для обновления количества:

Для добавления, переходим в админ панели в раздел Внешний вид – Редактор тем и выбираем файл functions.php, после чего в самый конец добавляем этот код.

				
					add_filter('woocommerce_add_to_cart_quantity', function($qty, $product_id){
    if (isset($_POST['eg_set_qty']) && $_POST['eg_set_qty'] == '1') {
        $pid = (int) $product_id;
        $new_qty = isset($_POST['quantity']) ? max(0, (int) $_POST['quantity']) : 1;

        foreach (WC()->cart->get_cart() as $cart_item_key => $item) {
            if ((int)$item['product_id'] === $pid) {
                WC()->cart->set_quantity($cart_item_key, $new_qty, true);
                return 0;
            }
        }
    }
    return $qty;
}, 10, 2);

add_action('wc_ajax_eg_get_cart_qty', 'eg_get_cart_qty');
add_action('wc_ajax_nopriv_eg_get_cart_qty', 'eg_get_cart_qty');

function eg_get_cart_qty() {
    if (!function_exists('WC') || !WC()->cart) {
        wp_send_json_success(['items' => []]);
    }

    $items = [];

    foreach (WC()->cart->get_cart() as $cart_item) {
        $pid = (int) $cart_item['product_id'];
        $qty = (int) $cart_item['quantity'];

        if ($pid > 0 && $qty > 0) {
            $items[$pid] = ($items[$pid] ?? 0) + $qty;
        }
    }

    wp_send_json_success(['items' => $items]);
}
				
			
CSS код для кнопок добавления в корзину

Для добавления, переходим в виджете кнопки добавления корзину во вкладку Расширенные и открываем раздел Custom CSS

				
					.eg-qty {
  display: flex;
  max-width: 150px;
}

.eg-qty__btn,
.eg-qty__input {

  box-sizing: border-box;
}

.e-loop-add-to-cart-form .eg-qty {
  margin-right: 0 !important;
  margin-left: auto;
}

.eg-qty__input {
  width: auto;
  text-align: center;
  border: none !important;
  outline: none !important;
  font-size: 18px;
  font-weight: 700;
  
}

.eg-qty__input::-webkit-outer-spin-button,
.eg-qty__input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.eg-qty__input[type="number"] {
  -moz-appearance: textfield;
}

.eg-qty__btn {
  border: 1px solid #ddd;
  background: #fff;
  cursor: pointer;
  line-height: 1;
  font-size: 18px;
  max-width: 50px !important;
}

				
			
Хотите узнать больше?
Подписывайтесь на мой Telegram-канал, в котором я делюсь эксклюзивным контентом, которого нет в блоге!
Эван
Онлайн
Свяжитесь со мной:

Связаться со мной проще всего в Telegram или WhatsApp – пишите прямо сейчас:

Мои каналы:
YouTube и Telegram-канал – место, где я делюсь опытом и фишками из практики.
Оставить заявку

Оставьте заявку и я свяжусь с вами в течении нескольких часов для более подробного обсуждения деталей.

Важно!

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

Закрыть
Explore
Листай