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

    0xD34F
    @0xD34F Куратор тега React
    {this.state.ad.map(n => (
      <div key={n.id}>
        <h2>{n.title}</h2>
        <div>{n.images.map(src => <img src={src} />)}</div>
      </div>
    ))}
    Ответ написан
    1 комментарий
  • Как сгруппировать элементы массива по значению одного из свойств?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вот метод группировки (не только массивов, но и любых итерируемых объектов):

    function group(data, key, val = n => n) {
      const getKey = key instanceof Function ? key : n => n[key];
      const getVal = val instanceof Function ? val : n => n[val];
      const result = {};
    
      for (const n of data) {
        const k = getKey(n);
        (result[k] = result[k] || []).push(getVal(n));
      }
    
      return result;
    }

    Как использовать в вашем случае:

    group(arr, 'room')
    // или
    group(arr, n => n.room)

    Но можно и так:

    group(Array(5).keys(), n => n % 2 ? 'нечётные' : 'чётные')

    Или так:

    group('a8-C!39', n => (
      n.toLowerCase() !== n.toUpperCase() ? 'буква' :
      !Number.isNaN(+n)                   ? 'цифра' :
                                            'другое'
    ))

    Или вот ещё вариант:

    <input name="xxx" value="69">
    <input name="xxx" value="187">
    <input name="xxx" value="666">
    <input name="yyy" value="-1">

    group(document.querySelectorAll('input'), 'name', n => +n.value)
    Ответ написан
    4 комментария
  • Как отрендерить разметку из строки?

    0xD34F
    @0xD34F Куратор тега React
    Ответ написан
    Комментировать
  • Как вытащить нужную часть из ссылки?

    0xD34F
    @0xD34F
    preg_match('~(?<=\/)\w+(?=\?|$)~', $str, $match);
    $result = $match[0];
    Ответ написан
    2 комментария
  • Как найти блок в котором находится другой блок с определенным классом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $(this).closest('tr').prevAll('tr:has(.name-pnd)').first()

    https://jsfiddle.net/8odvzagr/
    Ответ написан
    Комментировать
  • Как вставить элемент несколько раз во все элементы с заданным классом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Куда, что и сколько раз надо добавить:

    const containers = document.querySelectorAll('.counts');
    const tag = 'div';
    const className = 'count';
    const count = 3;

    Добавляем:

    const html = [...Array(count)]
      .map((_, i) => `<${tag} class="${className}">${i + 1}</${tag}>`)
      .join('');
    
    for (const n of containers) {
      n.insertAdjacentHTML('beforeend', html);
    }

    или

    for (let i = 0; i < containers.length; i++) {
      for (let j = 0; j < count;) {
        const el = document.createElement(tag);
        el.classList.add(className);
        el.innerText = ++j;
        containers[i].appendChild(el);
      }
    }

    или

    const fragment = document.createDocumentFragment();
    fragment.append(...Array.from({ length: count }, (_, i) => (
      Object.assign(document.createElement(tag), {
        textContent: -~i,
        className,
      })
    )));
    
    containers.forEach(n => n.append(fragment.cloneNode(true)));
    Ответ написан
  • Как динамически создавать элементы во Vue.js?

    0xD34F
    @0xD34F Куратор тега Vue.js
    is:

    <component
      v-for="n in flyingButtons"
      :is="n.tag"
      :class="n.class"
    >
      {{ n.title }}
    </component>
    Ответ написан
    Комментировать
  • Как в jquery выбрать первые элементы коллекции?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Получить отдельно, объединить: $('div').eq(0).add($('span').eq(0)).

    Можно функцию сделать, которая будет принимать несколько селекторов:

    const getFirst = (...selectors) => selectors.reduce((acc, n) => acc.add($(n)[0]), $());
    
    const $first = getFirst('div', 'span');
    Ответ написан
    Комментировать
  • Как сделать пагинацию через Vuex?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Хранилище

    Какие свойства должны быть в стейте - номер текущей страницы; количество элементов на странице; общее количество элементов; данные текущей страницы; флаг, сигнализирующий о том, что в данный момент осуществляется загрузка данных (первые четыре у вас уже есть, последнее почему-то находится в компоненте - надо переместить):

    state: {
      page: 0,
      perPage: 5,
      total: 0,
      posts: [],
      loading: false,
    },

    Понадобится геттер, вычисляющий количество страниц:

    getters: {
      numPages: state => Math.ceil(state.total / state.perPage),
    },

    Что и как будет обновляться в стейте:

    mutations: {
      updateLoading: (state, loading) => state.loading = loading,
      updatePosts: (state, { posts, total, page }) => Object.assign(state, { posts, total, page }),
    },

    Загрузка данных - до запроса устанавливаете loading в true, после переключаете обратно в false; запрос, сохранение результатов - тут, думаю, всё понятно:

    actions: {
      async fetchPosts({ state, commit }, page) {
        commit('updateLoading', true);
    
        const start = (page - 1) * state.perPage;
        const end = page * state.perPage;
        const url = `https://jsonplaceholder.typicode.com/posts?_start=${start}&_end=${end}`;
    
        try {
          const response = await fetch(url);
          const posts = await response.json();
          const total = response.headers.get('x-total-count');
          commit('updatePosts', { posts, total, page });
        } catch (e) {
          console.error(e);
        }
    
        commit('updateLoading', false);
      },
    },

    Компонент пагинации

    Получает два параметра - номер текущей страницы и количество страниц:

    props: [ 'page', 'numPages' ],

    Имеет методы для перехода к конкретной странице (отправляет номер новой страницы в родительский компонент - тому виднее, что с ним делать) и к странице относительно текущей:

    methods: {
      goTo(page) {
        this.$emit('paginate', page);
      },
      next(step) {
        this.goTo(this.page + step);
      },
    },

    Чтобы не давать пользователю переходить к несуществующим страницам, сделаем вычисляемые свойства, указывающие, является ли текущая страница первой/последней,...

    computed: {
      isFirst() {
        return this.page <= 1;
      },
      isLast() {
        return this.page >= this.numPages;
      },
    },

    ...и используем эти свойства для блокировки кнопок перехода на предыдущую/следующую/первую/последнюю страницы:

    <button @click="goTo(1)" :disabled="isFirst">&lt;&lt;</button>
    <button @click="next(-1)" :disabled="isFirst">&lt;</button>
    {{ page }} / {{ numPages }}
    <button @click="next(+1)" :disabled="isLast">&gt;</button>
    <button @click="goTo(numPages)" :disabled="isLast">&gt;&gt;</button>

    Ну и добавим поддержку директивы v-model:

    model: {
      prop: 'page',
      event: 'paginate',
    },


    Как всем этим пользоваться

    В компоненте, из которого планируется осуществление пагинации, делаем вычисляемое свойство, значением которого является номер текущей страницы из хранилища, а при установке нового значения будет вызываться действие, загружающее данные:

    computed: {
      page: {
        get() {
          return this.$store.state.page;
        },
        set(page) {
          this.$store.dispatch('fetchPosts', page);
        },
      },

    Привязываем через v-model это свойство к экземпляру компонента пагинации (ну и количество страниц не забываем ему передать):

    <компонент-пагинации
      v-model="page"
      :num-pages="$store.getters.numPages"
    />

    Не забываем указать, какую страницу хотим видеть по умолчанию:

    created() {
      this.page = 1;
    },

    Отображение данных:

    <div v-if="$store.state.loading">данные загружаются, ждите</div>
    <компонент-для-отображения-данных v-else :данные="$store.state.posts" />


    https://jsfiddle.net/08hno57q/
    Ответ написан
    Комментировать
  • Как в javascript получить всех соседей элемента?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Из элемента стучимся в его родительский элемент, из родителя получаем коллекцию вложенных элементов, отбрасываем исходный элемент:

    const siblings = Array.prototype.filter.call(
      this.parentNode.children,
      n => n !== this
    );

    Это если делать по-простому. Но есть и дурацкий вариант - можно пробежаться по ссылкам на предыдущие и следующие элементы:

    const siblings = [];
    for (let el = this; (el = el.previousElementSibling); siblings.unshift(el)) ;
    for (let el = this; (el = el.nextElementSibling); siblings.push(el)) ;
    Ответ написан
    1 комментарий
  • Как получить отдельно стоящую букву?

    0xD34F
    @0xD34F Куратор тега Регулярные выражения
    2 комментария
  • Как выровнять SVG анимацию по центру?

    0xD34F
    @0xD34F
    <circle cx="50%" cy="50%"
    Ответ написан
    Комментировать
  • Как передать данные с кнопки, по которому вызван magnific popup?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $('.openFormPopup').click(e => $('#btn-clicked').val(e.target.dataset.title));
    Ответ написан
    3 комментария
  • Как правильно написать цепочку promise для элементов в forEach?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const asyncForEach = (data, callback) =>
      Array.prototype.reduce.call(
        data,
        (promise, n, i, a) => promise.then(() => callback(n, i, a)),
        Promise.resolve()
      ).then(() => {});
    
    // или
    
    async function asyncForEach(data, callback) {
      for (const [ i, n ] of data.entries()) {
        await callback(n, i, data);
      }
    }

    asyncForEach(
      document.querySelectorAll('li'),
      li => new Promise(r => setTimeout(() => r(console.log(li.textContent)), 1000))
    );
    Ответ написан
    Комментировать
  • Vue.js Калькулятор цен. Как справиться с radio кнопками?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Указывать в v-model радиокнопок следует не разные свойства, а одно и то же - в качестве значения оно будет принимать value выбранной кнопки.
    Ответ написан
    3 комментария
  • Как увеличить число внутри строки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Здесь только регуляркой или как?

    Конечно, использовать регулярные выражения не обязательно:

    function incrementNumberInString(str) {
      for (let i = 0, iNum = -1; i < str.length; i++) {
        if ('0123456789'.includes(str[i])) {
          if (iNum === -1 && str[i - 1] === '[') {
            iNum = i;           
          }
        } else if (iNum !== -1 && str[i] === ']') {
          return str.slice(0, iNum) + (Number(str.slice(iNum, i)) + 1) + str.slice(i);
        } else {
          iNum = -1;
        }
      }
    
      return str;
    }

    Но с ними будет гораздо проще:

    str.replace(/(?<=\[)\d+(?=\])/, m => ++m)
    // или
    str.replace(/\[\d+\]/, m => '[' + (m.slice(1, -1) - -1) + ']')
    // или
    str.replace(/\[(\d+)\]/, (m, g1) => `[${-~g1}]`)
    Ответ написан
    Комментировать
  • Каким образом лучше использовать React & SVG?

    0xD34F
    @0xD34F Куратор тега React
    как лучше реализовать функционал, чтобы иконка была одна, а в нужных компонентах мы докидывали цвет?

    сделать соответствующий параметр
    Ответ написан
    2 комментария
  • Почему json выводится таким образом?

    0xD34F
    @0xD34F Куратор тега Vue.js
    выводит побуквенно

    Тот факт, что вы ожидали иного, ясно говорит следующее: вы не знаете, что такое json. Не понимаете, что это строка. Что сам json и объекты, получаемые при его парсинге - не одно и то же.

    Строки v-for так и перебирает - "побуквенно". То есть, значениями user являются строки единичной длины. Ну а свойств id, name, price и т.д. у строк нет, отсюда пустота там, где вы выводите свойства элементов users.
    Ответ написан
    Комментировать
  • Почему не удаляется item?

    0xD34F
    @0xD34F Куратор тега React
    почему не удаляется item, а добавляется?

    ДобавляЕтся - это как? Я бы поверил в "добавляЮтся" - если в deleteItem передать несуществующий id, тогда индекс элемента будет равен -1, и новый массив окажется копией исходного без последнего элемента (slice(0, -1)) плюс полная копия (slice(0)).

    Кстати, а что в deleteItem передаётся? Непонятно, как этот метод используется - код компонента TodoList вы почему-то не показали (как и код компонента, представляющего отдельный todo, если таковой у вас имеется).

    А вообще, удаление делается не так, есть же filter:

    deleteItem = id => {
      this.setState(({ todoData }) => ({
        todoData: todoData.filter(n => n.id !== id),
      }));
    }
    Ответ написан
    5 комментариев