• Как добавить v-bind:style к первому элементу, созданному в цикле v-for?

    @alexalexes
    У блока c v-for нужно объявить индекс:
    v-for="(item, index) in items"
    тогда:
    v-bind:style="index == 0 ? {стили для первого элемента} : {}"
    Ответ написан
    3 комментария
  • Как сгенерировать нечётное рандомное число?

    @alexalexes
    Нечетное число n можно выразить через параметр t:
    n = 2* t - 1
    Будем рандомизировать параметр t и переводить его в n, но нужны минимальное значение и максимальное.
    min = 2 * t - 1, отсюда:
    t_min = (min + 1) / 2
    max = 2 * t - 1, отсюда:
    t_max = (max + 1) / 2
    Деление, скорее всего целочисленное.
    Получается:
    var n_random = 2 * randomEvenInt((min + 1) / 2,  (max + 1) / 2) - 1;
    Ответ написан
    Комментировать
  • Как очистить корзину после заказа?

    @alexalexes
    Посмотрите функцию showCart. При каких условиях она рисует пустую корзину, такое состояние поставьте в cart.
    function delGoods()
    {
        cart = {}; // ... я поставил пустой объект, к примеру.
        saveCart();
        showCart();
    }
    Ответ написан
    Комментировать
  • Как в js div тянуть другому div?

    @alexalexes
    Копать в математику 7 класса или в алгебру 1 курса универа, раздел "линейные функции".
    Дано:
    1. координата курсора мыши в момент захвата блока: (x1, y1);
    2. координата курсора мыши после протягивания: (x2, y2);
    3. координата центра красного блока: (x3, y3);
    4. координата центра синего блока: (x4, y4);
    Проблема 1 - как определить, можно двигать блок или нет?
    Ответ 1.
    Замечаем, что точки (x1, y1) и (x2, y2) - образуют линию L1 - это прямая траектория движения мыши.
    А точки (x3, y3) и (x4, y4) - образуют линию L2 - это прямая траектория, по которой должен двигаться один из квадратов.
    L1 имеет коэф. линейной функции k1, который вычисляется как k1 = ((y2 - y1) - b1) / (x2 - x1);
    L2 имеет коэф. линейной функции k2, который вычисляется как k2 = ((y4 - y3) - b2) / (x4 - x3);
    Но на самом деле, нас интересуют не эти коэф-ты, а дифференциалы, поэтому b1, b2 - постоянные коэф. можно откинуть:
    d1 = (y2 - y1) / (x2 - x1);
    d2 = (y4 - y3) / (x4 - x3).
    Когда можно двигать блок?
    Когда d1 ~ d2 c некоторой погрешностью r, то есть:
    |d1 - d2| <= r1
    Коэф. ошибки r1 будет больше, чем меньше (y2 - y1), (y4 - y3), (x2 - x1), (x4 - x3).
    Коэф.-ты d1, d2 имеют невычисляемые случаи, когда x2 = x1, или когда x4 = x3, но строгости равенства трудно добиться, поэтому проверяем на коэф. ошибки малой величины r2.
    (x2 - x1) <= r2 или (x4 - x3) <= r2.
    Сначала проверяется возможность вычисляемости d1 и d2.
    если они вычисляемые и критерий |d1 - d2| <= r1 выполняется, то блок двигать можно.
    Если один из диф-лов не вычисляем, а другой - вычисляем, то блок двигать нельзя.
    Если оба диф-лов невычисляемы, то если у (y2 - y1) и (y4 - y3) знак результата одинаков, то блок двигать можно.
    Это только конец первого этапа, дальше вам пригодятся d1, d2 коэф.-ты, а также нужно вычислить интервал соприкосновения блоков, но эта уже другая история.
    Ответ написан
    Комментировать
  • Как отследить появление элемента на экране и получить его id?

    @alexalexes
    Самым ленивым способом эту функцию можно переписать так:
    var block_show = []; // начальный массив, можно не инициировать null-ами
     
    function scrollTracking(){
      var wt = $(window).scrollTop();
      var wh = $(window).height();
      var elems = $();  // тут пишем селектор для выбора коллекции элементов, позиции которых нужно отследить
      var elem_count = elems.length;
     // перебираем элементы, и выводим что появилось на экране, что нет.  
      var et = null, eh = null;
    for (var i = 0; i < elem_count; i++)
      {
     et = elems[i].offset().top;  // тут уже получаем параметр от i-ого элемента
       eh = elems[i].outerHeight(); // тут уже получаем параметр от i-ого элемента
     
      if (wt + wh >= et && wt + wh - eh * 2 <= et + (wh - eh)){
        if (block_show[i] === undefined || block_show[i] === null || block_show[i] === false) { // анализ block_show тоже от i-ого элемента
          console.log('Блок ' + i + ' в области видимости');
        }
        block_show[i] = true;  // установка block_show тоже от i-ого элемента
      } else {
        if (block_show[i] === undefined || block_show[i] === null || block_show[i] === true) { // анализ block_show тоже от i-ого элемента
          console.log('Блок ' + i + ' скрыт');
        }
        block_show[i] = false; // установка block_show тоже от i-ого элемента
      }
      } // конец цикла обхода отслеживаемых элементов
    }

    Обратите внимание, что в if-ах проявилось сравнение с undefined, это позволяет не создавать первоначальный массив, наполненный null-ами, но можно наполнить по числу отслеживаемых элементов. И все сравнение идут по === это позволяет учитывать типы переменных при сравнении, оно более строгое.
    Ответ написан
  • Как написать SQL запрос для данного случая?

    @alexalexes
    Сначала обновите записи в таблице checkanaliz:
    update  checkanaliz set id_napravlenie = 1 where id_napravlenie = 2

    Потом удалите из таблицы napravlenie записи:
    delete from napravlenie where id = 2
    Это же элементарные действия, которые вам доступны в SQL.
    Ответ написан
  • Валидация формы, как сохранить загруженные файлы?

    @alexalexes
    Делать отдельный файловый менеджер для загрузки не подходит - можно загрузить лишние файлы, появляются трудности в редактировании/обновлении записей. AJAX валидация формы решит проблему частично - если один из файлов не пройдет, то придется загружать все файлы заново.

    У вас как раз накопился технический долг в виде реализации полноценного файлового менеджера.
    Который должен сразу после выбора пользователем файлов отправлять каждый файл по ajax на сервер. Сервер в это время складывает файлы во временный каталог пользователя, отдавая в качестве ajax-ответа его временное хэш-имя. Во время отправки формы вы уже не отправляете содержимое input[type=file], а отправляете список хэш-имен удачно загруженных файлов, а на стороне сервера если все поля валидны и файлы валидны (их можно допроверить), то просто копируете файлы из временного каталога в постоянный (или в базу, или в облако, или другой каталог облака, смотря где основное хранилище). Если какая-та проверка неудачная, то вы легко можете вернуть обратно клиенту его заполненные поля, и список загруженных файлов, указав, в каком файле какая ошибка. На стороне клиента можно восстановить как поля, так и список файлов в менеджере.
    Если не хотите в полной мере решать технический долг, то можно поступить более простым путем.
    После выбора файлов пользователем, вычитываете их содержимое объектом FileReader и складываете в кодировке base64 в скрытые поля input[type=hidden] (при окончании зачищаете input[type=file], чтобы форма была нагружена только бинарными данными из скрытых полей), это позволит вам отправлять список файлов вместе с отправкой формы и восстанавливать input[type=hidden] поля при возникновении ошибки, при возврате данных формы обратно клиенту для корректировки.
    Такой подход увеличит время отправки и получения формы, не освободит от того, что вам нужно прорисовывать состояние списка файлов на форме, освободит только от использования ajax.
    Ответ написан
    Комментировать
  • Почему возвращается ошибка Fatal error: Function name must be a string in?

    @alexalexes
    Либо у вас сервер PHP ниже версии 5.3.0 (не позволяет использовать магический метод __invoke).
    Либо попробуйте $this добавить в замыкание (где use).
    return $current($context, function ($context) use ($this, $next) {
                return $this($context, $next);
    Ответ написан
  • Ошибка при направлении на другую страницу?

    @alexalexes
    Если хотите работать с заголовками, то размещать голый html с включениями php кода нельзя, будет засоряться лог предупреждениями.
    При исполнении php файла в начале он должен молчать как рыба, если логика работы предусматривает выбор - работать сначала с заголовками, а потом выводить контент, или просто выводить контент (через print, echo и т.д.).
    То есть, заголовки должны срабатывать первыми, любое echo между выполнением header() будет нарушать порядок.
    Ответ написан
    Комментировать
  • Как вывести не id элемента, а слово, которое к нему привязано?

    @alexalexes
    После этой строчки:
    $countryN->execute([':id' => $countries_id]);
    ... вам нужно применить один из методов:
    $rows = $countryN->fetchAll();
    var_dump($rows);

    или
    $row = $countryN->fetch();
    var_dump($row);

    Почитать тут и тут.
    Вкратце, работа с базой идет по таким этапам:
    1) Подключение к БД (хост, логин пароль и тд)
    1.1) Обработка ошибок подключения
    2) Передача параметров кодировки, форматов даты/время, локали и тд
    3) Подготовка запроса (prepare функция)
    3.1) Обработка синтаксических ошибок текста запроса.
    4) Подготовка входных и выходных параметров запроса (bind функция)
    4.1) Обработка ошибок параметров (результат возврата значения bind функции).
    5) Выполнение (execute функция).
    5.1) Обработка ошибок выполнения (обычно, смотрят состояние возврата значения execute функции).
    6) Выборка результата (фетчинг, используем fetch-функции).
    *) https://www.php.net/manual/ru/pdo.errorinfo.php получение состояния ошибки на любом этапе.
    Ответ написан
    Комментировать
  • В чем может быть ошибка Select2?

    @alexalexes
    К переменной data применяют метод работы с массивом slice(), но в этот момент data не является массивом (он же object в понимании JS).
    Такие ошибки возникают, когда перед обработкой массива забывают прописать исключительные состояния, когда объект data может быть сформирован не в виде пустого массива, а, например, может содержать в себе сведения об ошибке, переданные из слоя абстракции, который в обычной ситуации генерирует data как массив.
    Ответ написан
    Комментировать
  • Как сделать рандом с процентами?

    @alexalexes
    Возьмите интервал генерации случайных чисел (от 0 до 99) и раскидайте сгенерированные числа по эквивалентным интервалам (0...69, 70...89, 90...99) - если число попало в опред. интервал, значит ширина интервала будет вероятностью попадания в него этого числа.
    $rnd_number = rand(0, 99);
    switch(true)
    {
      case $rnd_number < 70: 
       echo "One";
        break;
     case $rnd_number >= 70 && $rnd_number < 90:
        echo "Two";
        break;
     case $rnd_number  >= 90:
        echo "Three";
        break;
    }

    Чтобы в этом убедиться, повторите эксперимент, например, 1000 раз:
    $counter = array('One'=> 0, 'Two' => 0, 'Three' => 0);
    for($i = 0; $i < 1000; $i++)
    {
      $rnd_number = rand(0, 99);
      switch(true)
      {
        case $rnd_number < 70: 
         $counter["One"]++;
          break;
       case $rnd_number >= 70 && $rnd_number < 90:
          $counter["Two"]++;
          break;
       case $rnd_number  >= 90:
          $counter["Three"]++;
          break;
      }
    }
    var_dump($counter);

    Если хотите эксплуатировать именно функцию array_rand(), то ей нужно предоставить такой массив:
    $block_array = array('One','One','One','One','One','One','One','Two','Two','Three');
    $counter = array('One'=> 0, 'Two' => 0, 'Three' => 0);
    for($i = 0; $i < 1000; $i++)
    {
     $gen_value = array_rand($block_array);
     $counter[$gen_value]++;  
    }
    var_dump($counter);

    Вес каждого элемента увеличивается путем его тиражирования пропорционально вероятности его выпадания.
    Решение не будет отличаться от классики.
    Ответ написан
    Комментировать
  • Как составить SQL запрос?

    @alexalexes
    Зачем вам таблица t1?
    У продукта могут быть несколько родителей?
    Если нет, то t1 избыточна, вам будет достаточно в каждой записи продукта указывать, кто у нее parent.
    Если нужно найти самый дешевый продукт в пределах одного родителя, то делается это так:
    select *
    from (select parent, product,
                        rank() over (partition by parent order by price) price_rnk
               from t2
             )  a
    where price_rnk = 1

    Клауза over partition поддерживается mySQL не ниже 8 версии. Самым распространенным версиям (5 или 6, не помню), нужно делать велосипед из пользовательских переменных @.
    Ответ написан
    1 комментарий
  • Не приходит товар на почту после оплаты?

    @alexalexes
    Подключите в отдельном php файле модуль include "includes/setmailer.php";
    и попробуйте себе что-нибудь отправить, отдельно от бизнес-логики оплаты.
    PS: Возможно, придется исправить конфиг этого модуля по части smtp протокола.
    PPS: У хостинга, от куда вы отправляете письмо, могут быть особенности с работой smtp - уточняйте.
    Ответ написан
    4 комментария
  • Как получить вложенные изображения при отправке формы?

    @alexalexes
    Ваша форма должна как-то сообщить серверу, что пользователь удалил файлы.
    Например, в скрытых input полях (у которых type="hidden") держать перечень метаданных (id или имя файла) удаленных файлов, которые были загружены на сервер ранее. При отправке формы, сравнивать список удаленных файлов и имеющихся файлов.
    Если форма не отправляется целиком в привычном понимании, то при помощи аякс-запросов при клике на удалить сообщать серверу, что именно удалили.
    Ответ написан
  • Почему js переменная выводится как объект?

    @alexalexes
    Переменная itemImg у вас как объект DOMElement.
    Его нельзя просто так вставить в строковое представление HTML.
    Чтобы получить itemImg как HTML строку, нужно проделать такой кульбит с использованием контейнера:
    var wrap = document.createElement('div'); //побочный контейнер для извлечения innerHTML
    wrap.appendChild(itemImg.cloneNode(true)); // клонируем внутрь контейнера интересуемый элемент
    var itemImgAsHTML = wrap.innerHTML; // извлекаем содержимое контейнера как HTML строку, то что вам и нужно.

    Потом это примените тут:
    var itemResult = "<div class='order-item'><div class='order-item__data-left'><div class='order-item__data-left__img'>"+itemImgAsHTML+"</div><div class='order-item__data-left__item-data'>${itemName}${itemVendorCode}</div></div><div class='order-item__data-right'><div class='order-item__data-right__delete-item'><button class='delete-item'>Удалить</button></div><div class='order-item__data-right__item-price'><h3>Цена: ${itemPrice}р</h3></div></div>";// Записываю нужную мне конструкцию для вставки в корзину

    PS: Можно предельно сократить преобразование:
    var itemResult = "<div class='order-item'><div class='order-item__data-left'><div class='order-item__data-left__img'>"+document.createElement('div').appendChild(itemImg.cloneNode(true)).innerHTML+"</div><div class='order-item__data-left__item-data'>${itemName}${itemVendorCode}</div></div><div class='order-item__data-right'><div class='order-item__data-right__delete-item'><button class='delete-item'>Удалить</button></div><div class='order-item__data-right__item-price'><h3>Цена: ${itemPrice}р</h3></div></div>";// Записываю нужную мне конструкцию для вставки в корзину
    Ответ написан
  • Почему в PHP zlib не работает во врапперах?

    @alexalexes
    Попробуйте одинарные кавычки вместо двойных.
    'php://filter/read=convert.base64-decode|zlib.inflate/resource='.$sourceFile

    PS:
    Нашел вот такой комментарий на Хакере.
    https://xakep.ru/2012/11/22/php-filter-wrapper-attacks/
    При всех выгодах данный метод уничтожения стопперов не может быть универсальным. В 2009 году было замечено, что функция base64_decode некорректно обрабатывает строки, содержащие в середине знаки равенства [#47174]. Этот баг был довольно оперативно исправлен для функции base64_decode, но для фильтра convert.base64-decode никаких исправлений сделано не было. Поэтому, если при «выдавливании» на каком-то шаге получаются данные, содержащие знак равенства, дальнейшее применение фильтра convert.base64-decode уничтожит преобразуемую строку.

    $s = 'php://filter/read=convert.base64-decode/resource=data:,dGVzdA==CRAP'; 
    var_dump(file_get_contents($s)); // print: string(0) ""

    Ответ написан
  • Как занести сразу несколько значении в таблицу?

    @alexalexes
    Самый топорный способ подготовки файла с данными.
    1. Открываете файл в Notepad++.
    2. Ctrl+H (Замена).
    3. Режим поиска ставите "Регулярные выражения".
    4. Найти:
    ^
    5. Заменить (название таблицы подставляете свое):
    insert into table\(name\) values \('
    6. Нажать "Заменить все".
    7. Найти:
    \r
    8. Заменить:
    '\);
    9. Нажать "Заменить все".
    В итоге получаете 500 строк инсертов. Выполняете их одной транзакцией любым доступным способом.
    Ответ написан
    Комментировать
  • Как восстановить загрузчик виндовс?

    @alexalexes
    Если настольный компьютер, то скорее всего вход в биос будет по клавише DEL.
    Если ноутбук, то сочетание клавиш, принятое у этого производителя в качестве входа в биос (может быть DEL или F2, или Esc или любая другая нестандартная комбинация клавиш).
    Если у вас компьютер куплен не ранее пару лет назад, то вам предстоит повоевать с загрузчиком UEFI, чтобы адекватно начал грузиться носитель, с которого будете устанавливать ОС.
    Ответ написан
    Комментировать
  • Как найти значение которое генерируется в js?

    @alexalexes
    Если значение переменной v44 будет иметь предсказуемую позицию на странице (или в куках, или в глобальном объекте JS - window) после выполнения всех операций ее подготовки и загрузки, то вполне возможно получить нужный результат, если воспользоваться средой Selenium. Она позволяет создать окружение для получения страницы аналогично полноценному браузеру и позволяет манипулировать компонентами окружения в том числе для извлечения данных.
    Ответ написан