• Как решить проблему с рассинхронизацией данных при вызове функции?

    cyber-jet
    @cyber-jet
    Ни какого рассинхрона не происходит, просто данные передаются в одну сторону, самое простое, в TheAdminPagination.vue повесить вотчер на totalPages, если меняется, сбрасывать на 1. В данном коде передавать prop currentPage из родителя не имеет ни какого смысла.
    Ответ написан
    1 комментарий
  • Как правильно организовать файловую архитектуру проекта laravel + vue 3?

    Adamos
    @Adamos
    https://inertiajs.ru/
    Файловая архитектура?
    Свои классы бэкенда - в свою папку, чтобы не путать с ларовскими.
    Чтобы они работали - добавляешь в composer.json в раздел
    "autoload": { "psr-4": { "App\\": "app/", "YourNamespace\\": "yourFolder/"}}

    Фронт - Vue в resources/js, Blade в resources/views.
    Остальное - штатные ларовские папки.
    Ответ написан
    1 комментарий
  • Как решить проблему исчезновения данных товаров при перезагрузке страницы во Vue.js приложении?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Во-первых: не используй onMounted внутри стора. onMounted - это хук компонента, а не стора. Оно работает только благодаря стечению обстоятельств.
    Во вторых: products должны быть ref. Сейчас они не реактивны(никак не реагируют на изменения). При этом ты присваииваешь массиву value. То что это хоть как-то работало - очередное чудо.
    В-третьих: ты должен учитывать, что какое-то время данные будут грузиться и показывать лоадер пока их нет.

    В общем если загрузка должна начинаться в лбом случае при первой инициализации store'a(обычно загрузку привязывают к маршрутам или компонентам), то выглядеть оно будет как-то так:
    export const useAllMainFiltersStore = defineStore('allMainFilters', () => {
      const products = ref([]);
    
      try {
        async function getStoreData() {
          sidebarResizeStore.updateSidebarVisibility()
          const data = await productsData();
          products.value = data;
        }
        getStoreData()
      } catch (error) {
        console.error('Error:', error);
      }
      
      return {
        products,
      }
    })


    В компоненте:
    const route = useRoute();
    // продукт делаем вычисляемым, чтоб не городить вотчеров
    const product = computed(() => getProductById(route.params.id));
    
    function getProductById(id) {
      console.log('products component: ', mainFiltersStore.products) //при первой загрузке всё ок, при перезагрузке страницы всё ломается и пустой массив в придачу
      return products.find(product => product.id == id);
    }
    
    watch(product, current => {
      // проверяем что продукт есть
      if (current) fetchComments(current.id);
    }, { immediate: true })
    Ответ написан
    3 комментария
  • Как правильно реализовать передачу данных между не связанными друг с другом компонентами в vue3?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Если ты не используешь SSR, то тебе достаточно просто reactive/ref объекта, чтоб получить эрзац-стор, тупо:
    // где-нибудь 
    export const basket = reactive([]); // или ref([]) по вкусу. 
    // везде где надо
    import { basket } from './...'

    Реактивность будет прекрасно работать.

    Почему кто-то использует специальные store если можно делать так? Потому что сторы учитывают работу в режиме SSR, а также позволяют удобную отладку в случае множества запутанных связей.
    Вам я бы тоже рекомендовал использовать таки store - только pinia, а не vuex. Не вижу причин его не использовать.

    По поводу EventBus: с одной стороны новичку её использовать категорически не рекомендуется, т.к. работа со store куда удобнее, очевиднее и надёжнее. Однако и совсем отрицать её использование тоже не следует, шина отлично подходит для случаев когда мы имеем дело именно с событиями, а не изменением состояния. Т.е. послать какой-нить notification или лог - самое оно, использовать для изменения basket, как в вашем случае - нет.
    Ответ написан
    1 комментарий
  • Как правильно реализовать передачу данных между не связанными друг с другом компонентами в vue3?

    vndrussia
    @vndrussia
    Вроде разработчик,а вроде и нет
    Если я правильно понял,то кроме использования Vuex (store) или localStorage,один из способов - это использование глобальной шины событий (Event Bus). В данном случае, можно использовать шину событий для передачи данных между компонентами без необходимости прямой связи через props/emit или store.
    https://v3.vuex.vuejs.org/ru/
    https://webformyself.com/event-bus-dlya-obmena-svo...
    Ответ написан
    4 комментария
  • Как решить проблему с переходом между страницами при использовании кнопок сохранения в форме с AJAX?

    @Arhangelx
    Я думаю тут проблема на стороне сервера в возвращаемым url, если вы храните ссылку которую посещает пользователь в сессие поскольку неизвестно откуда берется эта ссылка для возврата назад у меня два варианта предположения
    1) ссылка берется при открытии страниц и тогда нужно не запоминать ссылку на страницу формы (если не желаете туда возвращать пользователя) или лучше отправлять пользователя на фиксированный URL
    2) вероятней всего ссылка берется из referrer и тогда нужно не запоминать ссылку когда происходит отправка формы

    но как по мне если способов попасть на форму не так много то лучше самому определить фиксированную ссылку куда пользователь должен быть возвращен
    Ответ написан
    1 комментарий
  • Как решить проблему с сохранением выбранного языка при смене языка на мобильных устройствах?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Вопрос в том что ты там закрываешь и открывешь, что у тебя в {{Route('ChangeLanguage', N)}}?
    Если там что-то вида /en и /tr то у тебя будет открываться собственно та версия, которая сохранена в закладках\истории, а не так которая была выбрана.

    Почему? Потому что твой код не предусматривает автоматическую смену адреса при загрузке, только при выборе.
    Если ты ожидал, что
    selectLang.selectedIndex = localStorage.getItem(storageKey);
    вызовет change автоматически - это не так, программная смена не вызывает событий.

    Теперь о самом коде:
    1. Нахрена там fetch? Ты зачем-то грузишь страницу в воздух, после чего переключаешь на неё.
    2. Весь код в принципе хрень. Перенаправление на нужный язык должно происходить на сервере. Если нужен выбор на клиенте с запоминанием - используй куки и читай эти куки на сервере.
    Ответ написан
    6 комментариев
  • Как удалить все объекты из массива по заданному свойству и правильно пересчитать значения данных свойств?

    szQocks
    @szQocks
    Ты не отфильтровываешь price , ты получаешь ссылку на отфильрованный массив, а сам price массив не изменяется.

    Решение:

    const deleteBaggagePrice = price = price.filter( //проверка price на наличие свойства baggageID
           (prop) => !prop.hasOwnProperty("baggageID") //если есь удалить объект
         );
    Ответ написан
    4 комментария
  • Как правильно заполнить пустые свойства объекта данными, полученными из формы по одинаковому id?

    @chelnokov_a
    Метод map() не меняет исходный массив а возвращает модифицированный (пример на скрине)

    63e929abe0b0f210918857.png

    Такж е, если тебе надо поменять данные в 1 обьекте из массива, то лучше сначала получить его через метод find()
    const currentObj = currentPassengers.find(item => item.PassengersId === passengerIdEdit)
    currentObj.Name = dataName;
    currentObj.Surname: dataSurname;


    Как-то так. Это не обязательно, но более понятно что происходит.
    Ответ написан
    3 комментария
  • Почему отрабатывает if после отработки else?

    XanXanXan
    @XanXanXan
    childArr.map(item => { // перебираю все карточки в корзине
    .map() обычно используется не для простого перебора, а чтобы вернуть перебранный массив.

    в первом селекте 1 авто а во втором 2
    В этому случае «перебираются» 2 элемента через этот .map().

    При обработке первого элемента отработает случай else, так как на тот момент amountSum будет равно 0 (в storage ничего нет) + dataCars.carAmount = 1. Всего 1, что меньше limitCar.
    При обработке второго элемента уже будет amountSum = 1 (записалось при обработке 1-го элемента) + dataCars.carAmount = 2. Всего три что больше limitCar и поэтому будет предупреждение (случай из if).

    но после повторного добавления авто в корзину возвращаются удаленные карточки
    let getCars = JSON.parse(localStorage.getItem(LSKeyCars) || "[]");
    Это записывается один раз. А после очистки корзины не переписывается, если не перезагружать страницу. Поэтому карточки берутся из этой переменной, а не из обновлённых данных storage.

    spoiler

    const CARS_LIMIT = 2;
    
    const optionsBlock = document.querySelector('.parent');
    const cart = document.querySelector('.info');
    
    const addOptionButton = document.querySelector('.add');
    const addToCartButton = document.querySelector('.btn');
    const clearCartButton = document.querySelector('.delete-all');
    
    addOptionButton.addEventListener('click', addOption);
    addToCartButton.addEventListener('click', addItemToCart);
    clearCartButton.addEventListener('click', clearCart);
    
    optionsBlock.addEventListener('click', ({ target }) => {
        if (target.closest('.remove')) {
            target.parentNode.remove();
        }
    });
    
    function addOption() {
        optionsBlock.insertAdjacentHTML('beforeend',
            `<div class="child">
                  <span class="remove">✖</span>
                      <input type="text" class="model" placeholder="Введите модель авто">
                  <select class="amount">
                      <option value="" disabled selected>Количество</option>
                      <option value="1">1</option>
                      <option value="2">2</option>
                      <option value="3">3</option>
                  </select>
              </div>`)
    }
    
    function clearCart() {
        localStorage.removeItem('cars');
        renderCart();
    }
    
    function addItemToCart() {
        const currentCarsState = getStorageState() ?? [];
        const carInfoOptions = [...document.querySelectorAll('.child')];
    
        const carsAmount = currentCarsState.reduce((acc, { carAmount }) => acc + carAmount, 0);
    
        const { carsData, selectedAmount } = carInfoOptions.reduce((acc, carInfo) => {
            const carAmount = +carInfo.querySelector('.amount').value;
            const carModel = carInfo.querySelector('.model').value;
    
            const currentCarData = {
                id: Math.floor(Math.random() * 100), //плохой вариант, т.к. случайные числа могут повторяться
                carModel,
                carAmount,
            };
    
            acc.carsData.push(currentCarData);
            acc.selectedAmount += carAmount;
    
            return acc;
    
        }, { carsData: [], selectedAmount: 0 })
    
        if (carsAmount + selectedAmount > CARS_LIMIT) {
            alert('Количество автомобилей превышает количество взрослых');
            return;
        }
    
        localStorage.setItem('cars', JSON.stringify([...currentCarsState, ...carsData]));
        renderCart();
    }
    
    function getStorageState() {
        return JSON.parse(localStorage.getItem('cars'));
    }
    
    function renderCart() {
        const cartData = getStorageState();
        cart.innerHTML = !cartData ? '' : cartData.map(car => `<div class="item" id="${car.id}">
        <div class="title">ЛИЧНЫЙ ТРАНСПОРТ</div>
        <div>Модель авто: ${car.carModel}</div>
        <div>Количество авто: ${car.carAmount}</div>
      </div>`).join('');
    }

    Ответ написан
    1 комментарий
  • Как присвоить объекту input.value по id?

    Seasle
    @Seasle Куратор тега JavaScript
    У Вас проверка реализована некорректно: получили ID и его с собой сравнили.
    <div class="parent__block">
      <form class="child__block" data-id="1">
        <div class="">name: </div><input type="text" class="name" name="name">
        <div class="">surname: </div><input type="text" class="surname" name="surname">
        <button type="submit">click</button>
      </form>
    </div>
    <div class="parent__block">
      <form class="child__block" data-id="2">
        <div class="">name: </div><input type="text" class="name" name="name">
        <div class="">surname: </div><input type="text" class="surname" name="surname">
        <button type="submit">click</button>
      </form>
    </div>

    const persons = [
      { id: 1, check: 1 },
      { id: 2, check: 0 }
    ];
    
    const onFormSubmit = (form) => {
      form.addEventListener('submit', (event) => {
        event.preventDefault();
    
        const id = parseInt(form.dataset.id);
        if (!Number.isNaN(id)) {
          const formData = new FormData(form);
          const person = persons.find((person => person.id === id));
    
          person.name = formData.get('name');
          person.surname = formData.get('surname');
          
          console.log(persons);
        }
      });
    };
    
    document
      .querySelectorAll('form[data-id]')
      .forEach((form) => onFormSubmit(form));
    Ответ написан
    1 комментарий
  • Как создать родительский массив объектов с определенными свойствами на основе другого массива объектов?

    The_Sketch
    @The_Sketch
    Веб разработчик x)
    // Исходный массив объектов
    const sourceArray = [
    {name: 'John', age: 25},
    {name: 'Jane', age: 30},
    {name: 'Bob', age: 20}
    ];

    // Создание родительского массива объектов с определенными свойствами
    const parentArray = sourceArray.map(item => ({ name: item.name, ageGroup: item.age > 25 ? 'adult' : 'young' }));

    во это проверь
    Ответ написан
    1 комментарий
  • Почему localStorage.getItem(key) отрабатывает только после второго клика?

    ae_ph
    @ae_ph
    I'm a owl )
    Я исправил данный кода, теперь это должно работать для вас.
    Вот пример на CodePen
    Тот-же код, что и на codepen...

    HTML
    <div class="container">
      <div class="cart">
        <input class="input amount-one" type="text" value="0" />
        <input class="input amount-two" type="text" value="0" />
        <input class="input amount-three" type="text" value="0" />
        <button class="btn">click</button>
      </div>
      <div class="cart">
        <input class="input amount-one" type="text" value="0" />
        <input class="input amount-two" type="text" value="0" />
        <input class="input amount-three" type="text" value="0" />
        <button class="btn">click</button>
      </div>
      <div class="box">
        <input id="clear" type="button" value="clear all" />
        <div class="info"></div>
      </div>
    </div>


    CSS
    body {
      display: flex;
      justify-content: center;
      background-color: #1d1e22;
    }
    .container {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
    }
    .cart {
      display: flex;
      flex-direction: column;
      margin: 20px;
    }
    .input {
      padding-left: 20px;
      height: 20px;
      margin-bottom: 5px;
      font-size: 20px;
      border-radius: 10px;
    }
    .btn {
      height: 30px;
      font-size: 20px;
      border-radius: 10px;
    }
    .box {
      display: flex;
      flex-direction: column;
      align-items: center;
      margin: 20px;
    }
    #clear {
      width: 100px;
      height: 40px;
      margin-bottom: 10px;
      font-size: 20px;
      border-radius: 10px;
    }
    .info {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 200px;
      height: 30px;
      border: 2px solid #bbb;
      background-color: #fff;
    }


    JavaScript
    let currentTariff = JSON.parse(localStorage.getItem('cabins') || '[]');
    const passengersMax = 3; // Максимальное количество пассажиров
    let accommodationSum = currentTariff.reduce((acc, curr) => acc + curr.accommodation, 0);
    const btn = document.querySelectorAll('.btn');
    const info = document.querySelector('.info');
    
    // Вывести текущие тарифные данные в информационный блок
    const render = (tariff = currentTariff) => {
      [...tariff].forEach(el => {
        info.insertAdjacentHTML('beforeend', `<div>${el.accommodation}</div>`);
      });
    };
    render();
    
    btn.forEach(button => {
      button.addEventListener('click', function (e) {
        const cart = e.target.closest('.cart');
        const countOne = cart.querySelector('.amount-one').value;
        const countTwo = cart.querySelector('.amount-two').value;
        const countThree = cart.querySelector('.amount-three').value;
        const accommodationPass = parseInt(countOne) + parseInt(countTwo) + parseInt(countThree);
    
        if (accommodationSum + accommodationPass > passengersMax) {
          alert('В этом заказе вы превысили максимальное количество человек');
          return;
        }
    
        const obj = {
          countOne: countOne,
          countTwo: countTwo,
          countThree: countThree,
          accommodation: parseInt(accommodationPass),
        };
    
        // Обновляем текущий тариф и отображаем новые данные
        currentTariff.push(obj);
        updateState();
    
        const sum = currentTariff.reduce((acc, curr) => acc + curr.accommodation, 0);
        info.innerHTML = `<div>Общая сумма: ${sum}</div>`;
    
        accommodationSum = sum; // Устанавливаем сумму размещения на текущую сумму
      });
    
      function updateState() {
        localStorage.setItem('cabins', JSON.stringify(currentTariff));
      }
      // Очищаем входы и информационный блок при нажатии кнопки "clear all"
    function clearData() {
        currentTariff.length = 0;
        localStorage.removeItem('cabins');
        info.innerHTML = '';
        const inputs = document.querySelectorAll('input[type="text"]');
        inputs.forEach(input => {
          input.value = 0;
        });
        accommodationSum = 0;  // Сбрасываем сумму размещения до 0
    }
    
      const clearBtn = document.querySelector('input#clear');
      clearBtn.addEventListener('click', clearData);
    });
    Ответ написан
  • Как создать массив объектов с определенными свойствами на основе другого массива объектов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    // значения withSeat вместо раскладывания в отдельные переменные собираете в объект
    const withSeat = {
      adult: 1,
      teenager: 1,
      babe: 0,
    };
    
    
    const passengers = cabins.flatMap(n => Object
      .entries(n)
      .flatMap(([ k, v ]) => Array.from(
        { length: v },
        () => ({ withSeat: withSeat[k] })
      ))
    );
    Ответ написан
    6 комментариев
  • Как запретить отрисовку функций рендера html по результату запроса fetch по условию?

    Классический способ борьбы с вложенностью - вынос кода в функции:
    const renderResult = (result) => {
        if (result.result === 0) {
            alert("Not found");
        } else {
            currentItem.push(info);
            render([info]);
            update();
        }
    };
    if (item < 0) {
        alert("not render")
    } else {
        fetch(url, options)
            .then((response) => response.json())
            .then(renderResult)
    }
    Ответ написан
    1 комментарий
  • Как запретить отрисовку функций рендера html по результату запроса fetch по условию?

    XanXanXan
    @XanXanXan
    Если пугает вложенность, можно добавить ретёрнов. А фетч завернуть в асинк-авейт.

    if (item < 0) return;
    
    const response = await fetch(url, options);
    const result = await response.json();
    
    if (result.result === 0) return;
    
    currentItem.push(info);
    render([info]);
    update();
    Ответ написан
    1 комментарий
  • Как правильно выводить данные из дата атрибутов родителей в дочерние элементы в определенном порядке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.addEventListener('click', updateCounter);
    document.addEventListener('input', updateCounter);
    
    document.querySelectorAll('.tariff__counter').forEach(n => {
      const max = n.dataset.seats;
      n.querySelectorAll('.tariff__counter-max').forEach(m => m.innerText = max);
      n.querySelectorAll('.amount').forEach(m => m.max = max);
      n.querySelectorAll('button').forEach(m => m.dataset.change = m.innerText === '+' ? 1 : -1);
    });
    
    function updateCounter({ target: t }) {
      const input = t.closest('.tariff__counter-block')?.querySelector('.amount');
      if (input) {
        const { min, max, value } = input;
        input.value = Math.max(min, Math.min(max, (value | 0) + (t.dataset.change | 0)));
      }
    }
    Ответ написан
    1 комментарий
  • Как правильно провалидировать поля формы?

    @historydev Куратор тега JavaScript
    Острая аллергия на анимешников
    1 комментарий
  • Как с помощью js получить данные из переменной php?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попросите изменить шаблон примерно так:
    <span class="animals" data-allowed="{{$cabin->HasAnimals}}">
      {{$cabin->HasAnimals?Translate::GetTranslation('Animals Allowed'):Translate::GetTranslation('Animals Not Allowed')}}
    </span>

    Так сможете найти этот span и взять из него
    const span = document.querySelector('span.animals');
    const isAnimalsAllowed = !!span.dataset.allowed;


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

    В целом, хорошо бы от бэка получить чистые данные, безо всяких оформлений в разметку и переводов.
    И заниматься отрисовкой целиком на фронте.
    Ответ написан
    3 комментария
  • Как реализовать правильное поведение удаления всех данных из localStorage?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Стоит что-то выбрать как «единственный источник правды». Например, тот же localStorage.
    Тогда все функции будут сначала брать из LS массив машин (или пустой массив).

    jsFiddle
    Ответ написан
    3 комментария