Задать вопрос
  • Где найти такой слайдер?

    ashfedor
    @ashfedor Автор вопроса
    Набросал свой скрипт, конечно нужно дорабатывать, но как основа пойдет
    стили и разметку думаю не сложно понять
    <div class="home-cases__slider home-cases__stack" style="height: 675px;">
      <div class="home-cases__slide ">
        <div class="home-cases__slider-item ">
          карточка
        </div>
      </div>
      <div class="home-cases__slide ">
    
        <div class="home-cases__slider-item ">
          карточка
        </div>
      </div>
      <div class="home-cases__slide ">
    
        <div class="home-cases__slider-item ">
          карточка
        </div>
      </div>
    </div>
    <script>
        (function () {
          function initStack(root) {
            const stack  = root.querySelector('.home-cases__stack');
            if (!stack) return;
            const slides = Array.from(stack.querySelectorAll('.home-cases__slide'));
            if (!slides.length) return;
    
            const scope  = root.closest('.home-cases') || document;
            const prevBt = scope.querySelector('.home-cases__slider-prev');
            const nextBt = scope.querySelector('.home-cases__slider-next');
            const surface = root.querySelector('.home-cases__viewport') || stack;
    
            let i = 0;
    
            function a11y() {
              slides.forEach((sl) => {
                const hidden = !sl.classList.contains('is-active') &&
                  !sl.classList.contains('is-prev-1') &&
                  !sl.classList.contains('is-prev-2');
                sl.setAttribute('aria-hidden', hidden ? 'true' : 'false');
                sl.querySelectorAll('a,button,input,select,textarea,[tabindex]')
                  .forEach(el => el.tabIndex = hidden ? -1 : 0);
              });
            }
    
            function setHeight() {
              stack.style.height = slides[i].offsetHeight + 'px';
            }
    
            function render() {
              const n  = slides.length;
              const n1 = (i + 1) % n;
              const n2 = (i + 2) % n;
    
              slides.forEach((sl, idx) => {
                sl.classList.remove('is-active','is-prev-1','is-prev-2','is-hidden');
                if (idx === i)       sl.classList.add('is-active');
                else if (idx === n1) sl.classList.add('is-prev-1');
                else if (n > 2 && idx === n2) sl.classList.add('is-prev-2');
                else sl.classList.add('is-hidden');
              });
    
              setHeight();
              a11y();
    
              // якщо використовуємо ResizeObserver — перевішуємо на новий активний
              ro && (ro.disconnect(), ro.observe(slides[i]));
            }
    
            // висота по зміні контенту — без «стрибків»
            const ro = new ResizeObserver(setHeight);
            ro.observe(slides[i]);
    
            // кнопки
            nextBt && nextBt.addEventListener('click', () => { i = (i + 1) % slides.length; render(); });
            prevBt && prevBt.addEventListener('click', () => { i = (i - 1 + slides.length) % slides.length; render(); });
    
            // === свайп / drag ===
            (function attachSwipe() {
              const HAS_POINTER = 'PointerEvent' in window;
              const THRESHOLD = 40;     // пікселів для спрацьовування
              const TOLERANCE = 10;     // мертва зона
              let startX = 0, startY = 0;
              let isDown = false, isDragging = false, isScrolling = false;
              let swiped = false;
    
              // не починати drag із клікабельних елементів
              function isInteractive(el) {
                return !!el.closest('a,button,input,select,textarea,label,[data-no-drag]');
              }
    
              function getPoint(e){
                if (e.touches && e.touches[0]) return { x: e.touches[0].clientX, y: e.touches[0].clientY };
                return { x: e.clientX, y: e.clientY };
              }
    
              function down(e){
                if (isInteractive(e.target)) return; // даємо клікнути
                const p = getPoint(e);
                startX = p.x; startY = p.y;
                isDown = true; isDragging = false; isScrolling = false;
                surface.classList.add('is-grabbing');
                // pointer capture (де є)
                if (e.pointerId != null && surface.setPointerCapture) {
                  try { surface.setPointerCapture(e.pointerId); } catch(_) {}
                }
              }
    
              function move(e){
                if (!isDown) return;
                const p = getPoint(e);
                const dx = p.x - startX;
                const dy = p.y - startY;
    
                if (!isDragging) {
                  if (Math.abs(dx) < TOLERANCE && Math.abs(dy) < TOLERANCE) return;
    
                  if (Math.abs(dy) > Math.abs(dx)) { // вертикальний жест => скрол
                    isScrolling = true;
                    up(e);
                    return;
                  }
                  isDragging = true;
                }
    
                if (isDragging) {
                  // блокуємо нативний горизонтальний скрол під час свайпу
                  if (e.cancelable) e.preventDefault();
                }
              }
    
              function up(e){
                if (!isDown) return;
                surface.classList.remove('is-grabbing');
    
                if (!isScrolling && isDragging) {
                  const p = getPoint(e);
                  const dx = p.x - startX;
                  if (Math.abs(dx) > THRESHOLD) {
                    if (dx < 0) i = (i + 1) % slides.length;           // ліворуч => наступний
                    else        i = (i - 1 + slides.length) % slides.length; // праворуч => попередній
                    render();
                    swiped = true;
                  }
                }
    
                isDown = isDragging = isScrolling = false;
              }
    
              // блокуємо кліки після свайпу
              root.addEventListener('click', function(e){
                if (swiped) { e.preventDefault(); e.stopPropagation(); swiped = false; }
              }, true);
    
              // Події з урахуванням підтримки PointerEvent
              if (HAS_POINTER) {
                surface.addEventListener('pointerdown', down);
                surface.addEventListener('pointermove', move, { passive: false });
                surface.addEventListener('pointerup', up);
                surface.addEventListener('pointercancel', up);
                surface.addEventListener('pointerleave', up);
              } else {
                // fallback для старого iOS Safari
                surface.addEventListener('touchstart', down, { passive: true });
                surface.addEventListener('touchmove', move, { passive: false });
                surface.addEventListener('touchend', up);
                surface.addEventListener('mousedown', down);
                window.addEventListener('mousemove', move);
                window.addEventListener('mouseup', up);
              }
            })();
    
            window.addEventListener('resize', setHeight, { passive: true });
            render();
          }
    
          document.querySelectorAll('.home-cases').forEach(initStack);
        })();
      </script>
    Ответ написан
    Комментировать
  • Как вывести посты, свой тип записи нужной категории WordPress?

    ashfedor
    @ashfedor Автор вопроса
    Накопал решение
    может кому понадобится
    $posts = array(
                                'post_type' => 'offer',
                                'tax_query' => array(
                                  array(
                                    'taxonomy' => 'offer_cat',
                                    'field' => 'term_id',
                                    'terms' => [$term->term_id]
                                  ),
                                )
                                );
    Ответ написан
    Комментировать
  • Ошибка при переходе на php8 WordPress, Как исправить?

    ashfedor
    @ashfedor Автор вопроса
    Напишу на всякий случай может кому-то пригодится.
    Все оказалось проще чем обычно!)
    На этом сервере в 8 версии не поддерживается краткое <?
    нужно писать полностью <?php
    Ответ написан
    2 комментария
  • Как запустить модальное окно с Спасибо?

    ashfedor
    @ashfedor Автор вопроса
    Все намного проще чем казалось! может кому то понадобится
    вот хук
    function wpcf7_modal_mailsent_js() {
      wp_enqueue_script( 'sweetalert', 'https://unpkg.com/sweetalert/dist/sweetalert.min.js' );
    }
    
    /**
     * Выводит на экран модальное окно при успешной отправки формы.
     *
     * @return void
     */
    function wpcf7_modal_mailsent_js_inline() {
      ?>
      <script>
        // Срабатывает при успешной отправке формы.
        document.addEventListener('wpcf7mailsent', function (response) {
          MicroModal.close('modal-1')
          // Запускает модальное окно.
          MicroModal.show('modal-2');
        }, false);
      </script>
    
      <style>
          .wpcf7-mail-sent-ok {
              display: none !important;
          }
      </style>
      <?php
    }
    Ответ написан
    Комментировать
  • Как заставить laravel-filemanager грузить изображения?

    ashfedor
    @ashfedor Автор вопроса
    Вобщем все решилось намного проще!
    Зашел скачал версию PHP
    VS16 x64 Thread Safe была VS16 x64 Non Thread Safe
    и все заработало!
    Ответ написан
    Комментировать
  • Как добавить мультиязычность в файл настройки темы theme.yaml WinterCms (OctoberCms)?

    ashfedor
    @ashfedor Автор вопроса
    Нашел ответ, может кому то пригодится
    https://octoclub.ru/d/41-rainlab-translate-%D0%BF%...
    Ответ написан
    Комментировать
  • Как решить проблему с запуском Nuxt?

    ashfedor
    @ashfedor Автор вопроса
    вот что нарыл, может кому то понадобится. Проблема наблюдается в последних версиях Nuxt 2,15,7 и в новой они планируют исправить, сейчас рекомендуют в конфиг прописать
    build: {
    babel: {
    plugins: [
    ["@babel/plugin-proposal-class-properties", { "loose": true }],
    ["@babel/plugin-proposal-private-methods", { "loose": true }],
    ["@babel/plugin-proposal-private-property-in-object", { "loose": true }]
    ],
    }
    }
    Ответ написан
    1 комментарий
  • Как обновить mounted hook vue?

    ashfedor
    @ashfedor Автор вопроса
    Может кому-то пригодится убрал соединение из mounted
    и добавил
    watch:{
          desk_id:function () {
            axios
              .get('/api/v1/desks/' + this.desk_id)
              .then(response => {
                this.name = response.data.data.name
                console.log('изеняем' + this.desk_id)
              })
              .catch(error =>{
                console.log(error)
                this.errored = true
              })
              .finally(()=>{
                this.loading = false
              })
          }
        },
    Ответ написан
    Комментировать
  • Почему данные из API перестают отображаться после перезагрузки страницы?

    Пропиши в mounted() запуск екшена SET_DATA
    вообще конечно нужен и код самого компонента
    Ответ написан
  • Как на blade правильно выводить html код из базы, вставляя его во внутрь верстки?

    я вот так делаю и нунужные теги p отсекает и то что нужно оставляет
    {!! strip_tags( $post->text)!!}
    Ответ написан
    Комментировать
  • Почему поле ENUM в таблице выдает null хотя там 1?

    ashfedor
    @ashfedor Автор вопроса
    Вопрос снимается, я просто в методе не передал поле favorite
    Добавил и все заработало. Короче тупонул)))
    Ответ написан
    Комментировать
  • Как включить счетчик в цикле в Twig на Octobercms?

    ashfedor
    @ashfedor Автор вопроса
    Все очень просто.
    решение вот такое
    {% set count = count+1 %}
    просто переменную нужно объявлять заново
    Ответ написан
    Комментировать
  • В Woocomerce есть у пользователя поле телефон. а как его вывести для регистрации не подскажете?

    ashfedor
    @ashfedor Автор вопроса
    Нашел на просторах решение. Внедрил вроде хорошо работает!
    ## --- FOR CHECKOUT --- ##

    // Checkout billing phone validation (Checking length)
    add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
    function my_custom_checkout_field_process() {
    if ( $_POST['billing_phone'] && strlen($_POST['billing_phone']) < 10 )
    wc_add_notice( __('Please type a correct phone number…', 'woocommerce'), 'error' );
    }

    ## --- FOR CUSTOM REGISTRATION FORM --- ##

    // Add custom fields to registration form.
    add_action('woocommerce_register_form_start', 'text_domain_woo_reg_form_fields');
    function text_domain_woo_reg_form_fields() {
    ?>


    <?php _e('First name', 'woocommerce'); ?>*



    <?php _e('Last name', 'woocommerce'); ?>*




    <?php _e( 'Phone', 'woocommerce' ); ?>


    *



    <?php
    }

    // Checking & validation of custom fields in registration form.
    add_action('woocommerce_register_post', 'text_domain_woo_validate_reg_form_fields', 10, 3);
    function text_domain_woo_validate_reg_form_fields( $username, $email, $validation_errors ) {
    if (isset($_POST['billing_first_name']) && empty($_POST['billing_first_name'])) {
    $validation_errors->add('billing_first_name_error', __('İsim alanı zorunludur! / Name field is required!', 'woocommerce'));
    }
    if (isset($_POST['billing_last_name']) && empty($_POST['billing_last_name'])) {
    $validation_errors->add('billing_last_name_error', __('Soyisim alanı zorunludur! / Surname field is required!', 'woocommerce'));
    }
    if (isset($_POST['billing_phone']) && empty($_POST['billing_phone'])) {
    $validation_errors->add('billing_phone_error', __('Telefon alanı zorunludur! / Phone field is required!', 'woocommerce'));
    }

    // ==> CHECKING PHONE LENGTH (10 character minimal) <==
    if (isset($_POST['billing_phone']) && strlen($_POST['billing_phone']) < 10 ) {
    $validation_errors->add('billing_phone_error', __('Please type a correct phone number…', 'woocommerce'));
    }
    return $validation_errors;
    }

    // Add custom fields to registration form.
    add_action( 'woocommerce_created_customer', 'custom_save_extra_register_fields' ); // <==== Missing
    function custom_save_extra_register_fields($customer_id) {
    //First name field
    if (isset($_POST['billing_first_name'])) {
    update_user_meta($customer_id, 'first_name', sanitize_text_field($_POST['billing_first_name']));
    update_user_meta($customer_id, 'billing_first_name', sanitize_text_field($_POST['billing_first_name']));
    }
    //Last name field
    if (isset($_POST['billing_last_name'])) {
    update_user_meta($customer_id, 'last_name', sanitize_text_field($_POST['billing_last_name']));
    update_user_meta($customer_id, 'billing_last_name', sanitize_text_field($_POST['billing_last_name']));
    }
    //Phone field
    if (isset($_POST['billing_phone'])) {
    update_user_meta($customer_id, 'phone', sanitize_text_field($_POST['billing_phone']));
    update_user_meta($customer_id, 'billing_phone', sanitize_text_field($_POST['billing_phone']));
    }
    }
    Ответ написан
    Комментировать