• Как вывести результат из ответа JSON на HTML страницу?

    @iljaGolubev
    function createTable(i, data){
     const div = document.createElement("div");
     div.classList.add('data' + [i]);
     document.body.append(div); // тут!
     div.innerHTML =  i + "  <pre>"  + JSON.stringify(data,null,'  ' ) + "</pre>"; 
    }


    С таблицей будет сложнее пока вы получаете данные в разных реквестах - порядок XMLHttpRequest.DONE может не соответствовать i++;
    но для начала - вот (не проверял)
    const t= document.createElement('table')
    function addRow(table, index, json){
        const row=document.createElement('tr')
        const cell=document.createElement('td')
        cell.innerHTML= i + "  <pre>"  + JSON.stringify(json,null,'  ' ) + "</pre>"
        row.appendChild(cell)
        table.appendChild(row)
    }
    
    // ваши реквесты
    for(let i=0; i<count; i++) {
    ...
        addRow(1,data)
    ...
    }
    Ответ написан
  • Как поменять значение props-a?

    @iljaGolubev
    Изучите документацию и используйте v-model.

    Ещё можно provide/inject, composables, pinia... но начините с доки.
    Ответ написан
    Комментировать
  • Бесконечная загрузка страницы, как исправить?

    @iljaGolubev
    Патамушта.
    o=[1,2,3];
    console.log('o.len : ',o.length)
    // можно убрать && i<10
    for(let i=0;i<o.length && i<10; i++){
        o.splice(i+1,0,'added_'+i);
        console.log('NEW o.len : ',o.length)
    }
    Ответ написан
    Комментировать
  • Можно ли как либо защитить php-проект от "угона" другим наёмным программистом (фрилансером)?

    @iljaGolubev
    Если проект - монолит, то 100% клонируют при желании (опуская ответственность за это).

    Защита исходных кодов проекта php - отсутствие к ним доступа.
    Можно разделить монолит на фронт/бэк/сервис(ы) - всё отдельные проекты. Наёмный фрилансер получает доступ только к отдельной части. Всё самое важное (ноухау, бизнес-идею) - держать в сервисах, доступ к коду которых только у особо доверенных товарищей. CI/CD и интеграционные тесты обязательны.

    В целом, сложность проекта возрастает в разы... но если есть, что защищать, наверное, оно того стоит?
    Ответ написан
    1 комментарий
  • Как сохранить get параметр при переходе на другую страницу?

    @iljaGolubev
    через php дописать get параметр в адресной строке

    это невозможно - php не управляет браузером напрямую.
    ---
    Можно сделать редирект, но думаю для seo это тоже не хорошо.
    //псевдо
    if REFERRER has ?сity=mos
         return redirect REQUEST?сity=mos

    ---
    В php генерите страницы добавляя в ссылки нужные параметры
    т.е. на странице https://domen.ru/test/?сity=mos
    ссылка должна быть сразу https://domen.ru/test_2/?сity=mos

    ---
    Как вариант - через добавить ?сity=mos к нужным ссылкам на странице.
    Ответ написан
    Комментировать
  • Как в Carbon получить слово "День" склоняясь в зависимости от числа (дней,дня,дни)?

    @iljaGolubev
    В Carbon - через функции локализации.
    Внутри carbon использует symfony/translation, (pluralization)
    <?php
    $daysTranslator = 'ru_Days';
    $translator = \Carbon\Translator::get($daysTranslator);
    $translator->setTranslations([
        'day' => ':count день|:count дня|:count дней',
    ]);
    
    $date1 = Carbon::create(2018, 1, 1, 0, 0, 0);
    $date1before = Carbon::create(2018, 1, 2, 4, 0, 0);
    $date2before = Carbon::create(2018, 1, 3, 4, 0, 0);
    $date5before = Carbon::create(2018, 1, 6, 4, 0, 0);
    $localized=$date1->locale($daysTranslator);
    
    echo $localized->diffForHumans($date1before)."\n"; 
    echo $localized->diffForHumans($date2before)."\n"; 
    echo $localized->diffForHumans($date5before)."\n"; 
    
    // 1 день до
    // 2 дня до
    // 5 дней до


    Ещё сюда загляните - Склонение числительных
    Ответ написан
  • Как правильно создать layout страницы с изменяемым состоянием?

    @iljaGolubev
    Не работаю с react, но есть проекты на inertia+vue. Думаю, общий подход от этого не изменится.

    Вы уже используете inertia state (`props.auth.user.name`) - можно использовать и для popup. Props реактивные. Добавьте нужные значения (textPopup,isVisiblePopup,typePopup) в shared-data.
    Изменяете значение на странице с кнопкой - в шаблоне отобразится popup.
    function showPopup можно вынести в отдельный файл и импортировать на нужных страницах. showPopup изменяет prop.popup.textPopup и прочие.

    Плюс подхода - можно с сервера сразу передать нужные значения в попап из контроллера.
    Ответ написан
    2 комментария
  • Как найти точный url сайта на javascript?

    @iljaGolubev
    Вариантов нет.
    Они появятся когда изменение любого (нужного) из "множество разделов и фильтров" будет менять url страницы. Параметры запросы или якорь.
    Ответ написан
    Комментировать
  • Vue is not a constructor возникло при переходе на VUE 3?

    @iljaGolubev
    https://vuejs.org/guide/quick-start.html#using-vue...

    И посмотрите что у вас в box.js
    Ответ написан
    Комментировать
  • Как правильно в Laravel объединить дату и время если они находятся в разных полях?

    @iljaGolubev
    use Illuminate\Database\Eloquent\Casts\Attribute;
    
    class Order extends Model{
    
        protected $casts = ['date_time' => 'datetime:Y-m-d H:00'];
    
        function dateTime(): Attribute
        {
             return Attribute::make(
                get: fn () => $this->castAttribute(
                      'date_time',
                      ($this->date ?: '1970-01-01') . ' ' . ($this->time ?: '10:00:01')
                   )
                )
            );
        }
    
    }

    # php artisan tinker
    App\Models\Order::first()->date_time;
    # = Illuminate\Support\Carbon @0 {#7053
    #   date: 1970-01-01 00:00:00.0 UTC (+00:00),
    #  }


    https://laravel.com/docs/10.x/eloquent-mutators#de...
    Ответ написан
    Комментировать
  • Как переместится на n-ную запись в большом xml при помощи XMLReader?

    @iljaGolubev
    В php XMLReader нет возможности перейти на произвольную строку. При каждом запуске чтение начинается с начала файла. Значит нужно читать последовательно до того продукта на котором закончилась прошлая обработка.
    //Псевдокод. не проверял.
    
    $lastProductIndex=100000;
    // сначала нужно дочитать до <products>
    // потом перебирать <product>
    while($xmlReader->next("product") && --$lastProductIndex) {
        // skip
    }
    if($lastProductIndex==0){
        // тут последний обработанный прошлый раз
    }else{
        // продуктов стало меньше? 
    }
    Ответ написан
  • Как сделать сортировку сначала по непрочитанным сообщениям а потом по дате?

    @iljaGolubev
    https://laravel.com/docs/10.x/queries#orderbyraw
    для postgres раб
    ->orderByRaw('CASE isread WHEN 0 THEN 0 ELSE 1 END, last_message_time DESC')


    Не ваш случай, но в MySql
    можно ещё и так
    (не могу найти ссылку на доку)
    если нужно отобрать сначала конкретные id
    ORDER BY FIELD(id, 100, 100500, 300), last_message_time
    Ответ написан
  • Как сделать фиксированную ширину таблицы datatables с одинаковой шириной колонок?

    @iljaGolubev
    Если речь об этих datatables , то в общем-то с помощью css и атрибутов html.
    Например, если в body кроме table больше ничего нет, то так:
    <table id="example" width="70%" style=" white-space: pre-wrap;">
        <thead>
            <tr><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th></tr>
        </thead>
        <!-- ... -->

    $('#example').DataTable( {
        autoWidth: false,
        columnDefs: [
            { targets: '_all', "width": "1%" }
        ]
    } );

    Если используете бутстрап - у таблицы не должно быть 'nowrap' css класса.
    Используйте style="overflow-wrap: anywhere;" eсли в датасете есть слишком_длинные_значения_которые_точно_не_влезут в конечную ширину колонки .
    Ответ написан
  • Почему не удается получить актуальное значение переменной из Pinia в компоненте?

    @iljaGolubev
    и так же имеется pinia такого вида:

    где там pinia? - у вас просто composeable.
    каждый раз когда вы вызываете const {search} useSearchStore () выполняется const search = ref(''). т.е. это новый search.
    А в первых двух компонентах вы это не заметили

    потому что @searchData = "updateSearchQuery" - обновляете свой отдельный инстанс search.
    И вообще неработающий код показали... или неполностью (search.searchQuery - что такое?)


    // вот pinia
    export const useSearchStore = defineStore('search', () => {
      const search= ref('')
     function updateSearch(v) {
        search.value=v
      }
    
      return { search, updateSearch }
    })
    Ответ написан
    Комментировать
  • Как лучше подключать svg иконки во vue js?

    @iljaGolubev
    Если точно нужны inline svg, то vue-svg-loader - он делает автоматически ваш 1-й вариант.

    Ещё есть vite-svg-loader - подключается как плагин к vite и удобен тем, что можно из vite.config менять как импортировать файл (url или raw).

    Можно написать свой компонент в который передавать имя иконки. Только не делайте свой 2-й вариант - его недостаток в том, что все иконки всегда загружаются в браузер даже если никогда не будут показаны.

    через "v-if/v-else-if" рендерить ту, которая равна "close".

    Если у вас всего 2-3 иконки - можно и так, но в общем случае - старайтесь не использовать длинные "портянки" if/else. Почти всегда можно обойтись без такого кода. (conponent is или defineAsyncComponent)
    Ответ написан
    Комментировать
  • Как отдельно сделать логирование в Laravel для отдельного пакета?

    @iljaGolubev
    В пакете можно держать свои конфиги в таком же точно виде как в приложении ларавель.
    Непонятно, для чего вам понадобился канал логера пакета в приложении (снаружи пакета) . Имхо, только пакет его должен использовать. Но если очень хочется, можно так:
    // пакет config/logging.php
    return [
          'channels' => [
            'my-packet-name-log-channel' => [
                'driver' => 'single',
                'path' => env('MY_P_N_LOG_PATH', storage_path('logs/my-packet-name.log')),
                'level' => env('LOG_LEVEL', 'debug'),
                'replace_placeholders' => true,
                'permission' => 0664
                // ...
            ],
        ],
    
    ];


    // сервис провайдер пакета
    public function register(): void
        {
            if (!($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {
                $config = $this->app->make('config');
                $config->set('logging', array_merge_recursive(
                    require __DIR__ . '/../config/logging.php',
                    $config->get('logging', [])
                ));
            }
    
    }
    Ответ написан
    1 комментарий
  • Как делается такой эффект при скролле?

    @iljaGolubev
    если посмотреть в devtools network то видно кучу jpg и png.
    При прокрутке страницы нужно показывать нужное. Дальше пишите js управляющий логикой отображения.

    Можно через css background.
    Можно найти подходящую библиотеку (впрочем, сомневаюсь что именно такие существуют).
    Или использовать фреймворк: treejs, GSAP, konvajs. Последний, имхо, попроще будет для старта и ближе к решению на том сайте.
    Ответ написан
    Комментировать
  • Как разделить контент в блоке на две части?

    @iljaGolubev
    С трудом понял, что-же вам нужно, но, надеюсь, правильно:)
    Идея в том, чтобы рекурсивно перебирать все ноды спана, считать длину содержимого каждой ноды, и добавлять её в первую часть пока пока не превышен лимит количества. В начале итерации лимит - половина от всего текста спана.

    function aggregator (a, c, maxChars){
        if (a[0].textContent.length > maxChars) {
            a[1].appendChild(c)
        } else if (c.children?.length > 0) {
            const agg = spanParse(c, maxChars - a[0].textContent.length);
            a[0].appendChild(agg[0])
            if (agg[1]) {
                a[1].appendChild(agg[1])
            }
        } else {
            a[0].appendChild(c)
        }
        return a;
    }
    function spanParse(rootSpan, maxChars) {
        const aggregated = [document.createElement('span'), document.createElement('span')]
        return [...rootSpan.childNodes].reduce((a, c) => aggregator(a, c, maxChars), aggregated)
    }
    function split(elem) {
        const r = spanParse(elem, elem.textContent.length / 2)
        console.log(r[0].textContent.length, r[1].textContent.length)
    }
    
    split(document.getElementByTag('span'));


    С тем кодом который в вопросе работать будет если span с текстом есть на странице. Если с какой-то другой разметкой будут ошибки, то нужно докрутить логики в aggregator.
    Ответ написан
    Комментировать
  • Передать из родительского компонента в дочерний состояние?

    @iljaGolubev
    vue3 provide-inject а лучше через события
    vue2 state-management
    Ответ написан
    Комментировать
  • Как приостановить работу map до выполнения определённых условий пере return?

    @iljaGolubev
    Завернуть FileReader в Promise
    как-то так

    const readAsDataURL = (image) => {
      const fr= new FileReader();
      return new Promise((resolve, reject) => {
        fr.onerror = () => {  fr.abort();  reject(new Error( 'err msg' ));  };
    
        fr.onload = () => { resolve(fr.result); };
        fr.readAsDataURL(image)
      });
    };
    
    
    [...selectedImages].map( async (image, index) => {
       const data =  await readAsDataURL(image)
       return (<img src={data} alt="" key={`previewImage:${index}`} />
    })
    Ответ написан