Задать вопрос
  • Как сериализовать вложенный объект?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Рекурсия есть:

    const serialize = (obj, path) => Object
      .entries(obj)
      .map(([ k, v ]) => {
        const p = path ? `${path}[${k}]` : k;
        return v instanceof Object ? serialize(v, p) : `${p}=${v}`;
      })
      .join('&');

    Рекурсии нет:

    function serialize(obj) {
      const result = [];
    
      for (const stack = [ [ obj, '' ] ]; stack.length;) {
        const [ n, path ] = stack.pop();
        if (n === Object(n)) {
          stack.push(...Object
            .keys(n)
            .map(k => [ n[k], path ? `${path}[${k}]` : k ])
            .reverse()
          );
        } else {
          result.push(`${path}=${n}`);
        }
      }
    
      return result.join('&');
    }
    Ответ написан
    Комментировать
  • Как проверить битую картинку?

    0xD34F
    @0xD34F Куратор тега JavaScript
    img.onload = () => images.appendChild(img);
    img.onerror = () => console.log('меня нет');
    Ответ написан
    Комментировать
  • Как воткнуть :data-vv-as и :data-vv-delay аттрибуты в vue-datepicker, чтобы они отрабатывали?

    0xD34F
    @0xD34F Куратор тега Vue.js
    не уверен, что применяются :data-vv-as и :data-vv-delay аттрибуты

    А эта ваша неуверенность - она основана хоть на чём-нибудь? Я вот знаю, что всё применяется.

    Может, дело в том, что в вашем примере вместо сообщения об ошибке, которое генерирует vee-validate, показывается какое-то другое? - потому вы и не видите подмены имени поля. А отсутствие задержки обусловлено тем, что единственный сценарий валидации, который вы проверяли - это отправка формы, а в соответствующем обработчике валидация осуществляется немедленно, в то время как задержка предназначена для пользовательского ввода:

    You can specify a delay to debounce the input event, a case scenario that you may want to wait for the user to stop typing then validate the field

    Сделал пример к сказанному выше:

    Сообщение об ошибке выводится то, которое генерирует vee-validate.
    Имитация пользовательского ввода - кнопка сброса, вместо прямой установки значения кидается событие input с пустой строкой; также обратите внимание, что при выборе даты выведенное сообщение об ошибке пропадает с указанной задержкой.
    Ответ написан
    Комментировать
  • Фильтр таблицы HTML по checkbox?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Ответ написан
    Комментировать
  • Как правильно добавлять и удалять обработчики событий в директиве (Vue)?

    0xD34F
    @0xD34F Куратор тега Vue.js
    сохранить доступ к el и binding

    Элемент будет доступен как this.

    Что до binding - можно использовать dataset для передачи значения. Например.

    UPD. Вынесено из комментариев:

    датасет дает нам возможность сохранять только примитивы

    Можно прицепить интересующий вас объект к элементу в качестве его свойства, типа так. Или использовать Map/WeakMap, где ключом будет элемент, например.

    А вообще, возможно, что вы неверно выбрали инструмент для решения своей проблемы, и тут вместо директивы следует использовать компонент.
    Ответ написан
    2 комментария
  • Как избежать switch при реализации компонента работающего с разными API/сущностями в VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    // где-то вне метода загрузки сканов
    const docApi = {
      oneDoc: oneDocApi,
      anotherDoc: anotherDocApi,
      ...
    };

    docApi[this.type].uploadScan();

    Можно даже в виде вычисляемого свойства оформить:

    computed: {
      docApi() {
        return docApi[this.type];
      },
    },

    this.docApi.uploadScan();
    Ответ написан
    Комментировать
  • Как в функциональном компоненте прописать условное отображение контента с помощью оператора "?"?

    0xD34F
    @0xD34F Куратор тега React
    Лишние фигурные скобки, должно быть так:

    const ItemCheckbox = ({
      position,
    }) => (
      position ? (
        <p>Hello</p>
      ) : (
        <p>Good</p>
      )
    );
    Ответ написан
    Комментировать
  • Как из родительского компонента сконфигурировать компонент ввода?

    0xD34F
    @0xD34F Куратор тега Vue.js
    у меня нет способа передать из родителя в инстанс компонента описание процедуры валидации

    Да неужели? А параметры на что?

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

    Ну так вы не тупо делайте emit, а при условии отсутствия ошибок.

    UPD. https://jsfiddle.net/369saL08/
    Ответ написан
    Комментировать
  • React - csv не видит мой массив?

    0xD34F
    @0xD34F Куратор тега React
    Добавьте key вашему CSVLink. Такой, чтобы зависел от содержимого rows.
    Ответ написан
  • Как отфильтровать определенные div с классами, совпадающие с дата-атрибутами ссылки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Во-первых, get-age - это не data-атрибут. Меняйте на data-age.

    Во-вторых, сделайте значения селекторами, т.е. вместо age_3_6 будет .age_3_6, вместо age_7_10 будет .age_7_10 и т.д., ну а у элемента "все" будет data-age="*".

    const itemSelector = '.ped_holder .ped';
    const buttonSelector = '.ages a';
    const activeButtonClass = 'active';
    const selectorAttr = 'age';

    const $buttons = $(buttonSelector).click(function() {
      const selector = $buttons
        .removeClass(activeButtonClass)
        .filter(this)
        .addClass(activeButtonClass)
        .data(selectorAttr);
    
      $(itemSelector).hide().filter(selector).show();
    });
    
    // или, к чёрту jquery
    
    const buttons = document.querySelectorAll(buttonSelector);
    const items = document.querySelectorAll(itemSelector);
    
    buttons.forEach(n => n.addEventListener('click', onClick));
    
    function onClick({ target: t }) {
      const selector = t.dataset[selectorAttr];
      buttons.forEach(n => n.classList.toggle(activeButtonClass, n === t));
      items.forEach(n => n.style.display = n.matches(selector) ? '' : 'none');
    }
    Ответ написан
    Комментировать
  • Возврат переменной из axios.get?

    0xD34F
    @0xD34F Куратор тега React
    getMyIP() {    
      return axios.get('https://httpbin.org/get').then(response => response.data.origin)
    }
      
    handleClick() {
      this.getMyIP().then(ip => console.log(`ip: ${ip}`))
    }
    Ответ написан
    Комментировать
  • Как сортировать даты только по дню и месяцу?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сортируем существующий массив:

    arr.sort((a, b) => {
      a = a.split('.', 2);
      b = b.split('.', 2);
      return (a[1] - b[1]) || (a[0] - b[0]);
    });

    Или, собираем отсортированный новый:

    const sortedArr = arr
      .map(n => n.split('.'))
      .sort((a, b) => (a[1] - b[1]) || (a[0] - b[0]))
      .map(n => n.join('.'));
    Ответ написан
    Комментировать
  • Почему событие onBlur в react-contenteditable срабатывает всегда, когда в метод передаётся аргумент?

    0xD34F
    @0xD34F Куратор тега React
    передаю метод без аргумента onBlur={this.handleChange}

    стоит мне изменить на onBlur={this.handleChange('title')}

    Т-а-а-а-к, ясно. Осознаёте ли вы, что в первом случае вы назначаете в качестве обработчика onBlur метод handleChange, а во втором - результат его выполнения? Вы вообще понимаете, что функция и вызов функции - не одно и то же?

    Хотите передавать параметр, делайте так: onBlur={() => this.handleChange('title')}. Или вместо передачи значения в качестве параметра добавляйте его элементу как атрибут, а в обработчике события считывайте:

    onBlur={this.handleChange} data-change-param="title"

    handleChange = (e) => {
      const changeParam = e.target.getAttribute('data-change-param');
      ...
    Ответ написан
    1 комментарий
  • Возможно ли решить задачу без циклов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Рекурсия:

    const sum = (val, index = 0) =>
      val instanceof Array
        ? val.length > index
          ? sum(val[index]) + sum(val, index + 1)
          : 0
        : val;
    Ответ написан
    Комментировать
  • Как проверить не пустой ли файл?

    0xD34F
    @0xD34F
    fs.stat(filename, function(err, stats) {
      if (stats.size) {
        console.log('not empty');
      } else {
        console.log('empty');
      }
    });
    Ответ написан
    Комментировать
  • Зачем в кастомный валидатор формы ещё раз передавать this?

    0xD34F
    @0xD34F
    Не надо ничего передавать. И вызывать валидатор при передаче в конструктор FormControl тоже не надо (вы что, действительно до сих пор не понимаете разницы между функцией и её вызовом?).

    Что вы забыли - так это вернуть из валидатора какой-нибудь результат. Например.
    Ответ написан
    Комментировать
  • Как правильно клонировать input[type=radio]?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Хотите, чтобы суффиксы у атрибутов name были правильные - оператор + вам в помощь, добавляйте сколько надо.

    Хотите, чтобы клонирование происходило не только по клику на кнопку, что существует изначально, но и по новым - клонируйте элементы вместе с обработчиками событий или делегируйте обработку клика контейнеру.

    // исправляем ваш код
    $('.add-attr').on('click', function() {
      const index = $('.radios').length + 1;
    
      const $lastRow = $(this).closest('.container').find('.item').last();
      const $newRow = $lastRow.clone(true).insertAfter($lastRow);
    
      $newRow.find('input[type="radio"]').prop('name', 'name-' + index);
    });
    
    // или переписываем его без использования jquery
    document.querySelector('.container').addEventListener('click', e => {
      if (e.target.classList.contains('add-attr')) {
        const row = e.currentTarget.firstElementChild.cloneNode(true);
        const name = `name-${e.currentTarget.children.length + 1}`;
        e.currentTarget.appendChild(row);
        row.querySelectorAll('[type="radio"]').forEach(n => n.name = name);
      }
    });
    Ответ написан
    6 комментариев
  • Как подсчитать количество блоков в блоке?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const count = document.querySelectorAll('.ablock [class*="bblock_"]').length;

    Если кроме .bblock_* других элементов внутри .ablock нет, то

    const count = document.querySelector('.ablock').children.length;
    Ответ написан
    Комментировать
  • Как клонировать селект с изменением id?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Очень странный способ клонировать select'ы - сохранить настройки плагина клонируемых элементов, деактивировать плагин на клонируемых элементах, клонировать элементы, инициализировать плагин у клонов и повторно у оригиналов, обновить настройки. Можно сделать попроще: в самом начале сделать клон элементов, и потом уже клонировать его; инициализацию плагина вынести в отдельную функцию, которая будет принимать набор элементов.

    Странный способ получать новые значения id - единица в качестве начального значения и постфиксный инкремент. В результате последовательность идентификаторов получается такая: 1, 2, 3,... Элементы с 1 и 2 уже есть. Начальным значением должно быть максимальное существующее значение плюс единица. Или просто максимум, но инкремент тогда префиксный.

    const $row = $('.b-items').clone();
    let ID = +$row.find('select').last().attr('id').split('-').pop();
    
    function selectize($el) {
      $el.selectize({
        allowEmptyOption: true,
        create: true,
      });
    }
    
    selectize($('select'));
    
    $('.btn-clone').on('click', function() {
      selectize($row
        .clone()
        .insertBefore(this)
        .find('select')
        .attr('id', () => `select-${++ID}`)
      );
    });
    Ответ написан
    3 комментария
  • Как получить аттрибут ссылки во vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Пробовал указать и a.href и a.getAttribute('href') и т.д.

    Лучше бы попробовали документацию почитать.

    @click.prevent="toPage"

    toPage(e) {
      console.log(e.target.href)
    }
    Ответ написан
    Комментировать