Задать вопрос
  • Как сделать range slider который будет изменяться по клику на кнопку?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const interval = [ 0, 150 ];
    
    const $slider = $('#storlekslider').slider({
      range: 'max',
      min: interval[0],
      max: interval[1],
      step: 1,
      slide: (e, ui) => update(ui.value),
    });
    
    const $input = $('#storlek_testet').on('input', e => update(e.target.value));
    
    $('button').click(e => update(+$input.val() + 50 * ($(e.target).text() === '+' ? 1 : -1)));
    
    
    function update(val) {
      val = Math.max(interval[0], Math.min(interval[1], val));
      $input.val(val);
      $slider.slider('value', val).find('.ui-slider-handle').text(val);
    }
    Ответ написан
    Комментировать
  • Каким способом можно сделать автосоздание переменных для v-model?

    0xD34F
    @0xD34F Куратор тега Vue.js
    mounted() {
      this.$el.querySelectorAll('input').forEach(n => n.dispatchEvent(new Event('input')));
    },

    jsfiddle.net/whrgboxs
    Ответ написан
    Комментировать
  • Как сделать попеременное нажатие чекбоксов?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Внутри:

    inheritAttrs: false,
    model: {
      prop: 'checked',
    },
    props: [ 'value', 'checked' ],
    computed: {
      innerChecked: {
        get() {
          return this.checked;
        },
        set(val) {
          this.$emit('input', val);
        },
      },
    },

    <label>
      <input
        type="checkbox"
        v-model="innerChecked"
        v-bind="$attrs"
        :value="value"
      >
      <slot></slot>
    </label>

    Снаружи:

    data: () => ({
      items: [
        { label:  'hello, world!!', value:  69 },
        { label:  'fuck the world', value: 187 },
        { label: 'fuck everything', value: 666 },
      ],
      checked: [ 187 ],
    }),
    watch: {
      checked(val) {
        if (val.length > 1) {
          this.checked = val.slice(-1);
        }
      },
    },

    <v-checkbox
      v-for="n in items"
      v-model="checked"
      :value="n.value"
      name="items[]"
    >
      {{ n.label }}
    </v-checkbox>

    https://jsfiddle.net/769wdoq5/

    Один вопрос - на хрена? Можно заменить чекбоксы радиокнопками, и добавить ещё одну, которая будет обозначать отсутствие выбора.
    Ответ написан
    Комментировать
  • Как перебрать объекты с вложенностью?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Чтобы дальше два раза одно и то же не писать, небольшой декоратор:

    const processNonEmptyObjectOnly = (f, defaultResult) =>
      data => (
        data = data instanceof Object ? Object.entries(data) : [],
        data.length ? f(data) : defaultResult
      );

    Собираем разметку:

    const createTreeHTML = processNonEmptyObjectOnly(data => `
      <ul>${data.map(n => `
        <li>
          ${n[0]}
          ${createTreeHTML(n[1])}
        </li>`).join('')}
      </ul>`
    , '');
    
    
    document.body.insertAdjacentHTML('beforeend', createTreeHTML(data));

    Или, создаём элементы напрямую:

    const createTreeElement = processNonEmptyObjectOnly(data =>
      data.reduce((ul, n) => (
        ul.append(document.createElement('li')),
        ul.lastChild.append(n[0], createTreeElement(n[1])),
        ul
      ), document.createElement('ul'))
    , '');
    
    
    document.body.append(createTreeElement(data));
    Ответ написан
    Комментировать
  • Комбинированная пагинация во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    https://jsfiddle.net/vp4qawfg/

    Или можно взять что-нибудь готовое, на awesome-vue есть подборка компонентов пагинации, среди которых можно найти такие, которые реализуют требуемую функциональность.
    Ответ написан
    Комментировать
  • Как получить максимальное и минимальное значение и передать в параметры input'а?

    0xD34F
    @0xD34F Куратор тега Vue.js
    computed: {
      range() {
        const prices = this.filterData.map(n => n.price);
        return {
          min: Math.min(...prices),
          max: Math.max(...prices),
        };
      },
    
      // или
    
      range() {
        return this.filterData.reduce(({ min, max }, { price: n }) => ({
          min: min < n ? min : n,
          max: max > n ? max : n,
        }), { min: Infinity, max: -Infinity });
      },
    
      // или
    
      range() {
        const prices = this.filterData.map(n => n.price).sort((a, b) => a - b);
        return {
          min: prices[0] ?? Infinity,
          max: prices[prices.length - 1] ?? -Infinity,
        };
      },
    },

    <input type="range" v-bind="range">
    Ответ написан
    Комментировать
  • Функция jQuery.fn.load() is deprecated?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Что-то не понимаете - первым делом следует заглянуть в документацию:

    Note: This API has been removed in jQuery 3.0; please use .on( "load", handler ) instead of .load( handler ) and .trigger( "load" ) instead of .load()
    Ответ написан
    Комментировать
  • Как получить первые и последние слова всех строк текста?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.split('\n').filter(Boolean).map(n => n.split(' ')).map(n => [ n[0], n[n.length - 1] ])

    или

    Array.from(str.matchAll(/(^\S+).*?(\S+$)/gm), n => n.slice(1))
    Ответ написан
    Комментировать
  • Как отфильтровать объекты из массива по id?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Группируем данные:

    const grouped = Object.entries(arr.reduce((acc, n) => (
      (acc[n.id] ??= []).push(n.name),
      acc
    ), {}));

    Затем собираем html:

    document.body.insertAdjacentHTML('beforeend', grouped
      .map(([ k, v ]) => `
        <ul id="list-${k}">${v.map(n => `
          <li>${n}</li>`).join('')}
        </ul>`)
      .join('')
    );

    Или напрямую создаём элементы:

    document.body.append(...grouped.map(([ id, names ]) => {
      const ul = document.createElement('ul');
      ul.id = `list-${id}`;
    
      ul.append(...names.map(n => {
        const li = document.createElement('li');
        li.textContent = n;
        return li;
      }));
    
      return ul;
    }));
    Ответ написан
    Комментировать
  • Как скрыть часть телефонного номера звездочками?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.replace(/\d{3}-\d{2}/, '***-**')
    // или
    str.slice(0, 9) + '***-**' + str.slice(15)
    // или
    str.replace(/\d(?=\d*-)/g, '*')
    // или
    str.replace(/\d+(?=-)/g, m => '*'.repeat(m.length))
    // или
    str.replace(/(?<=\) ).{6}/, '***-**')
    // или
    str.match(/^.{9}|.{3}$/g).join('***-**')
    Ответ написан
    1 комментарий
  • Почему не работает сортировка массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Вы не понимаете,...

    • ...как работают условные операторы:

      if (sortArray[i]) {

      Что если там 0? Тогда этот элемент обработан не будет - не попадёт в результирующий массив. О чём, кстати, и говорится в сообщении об ошибке, в возвращаемом вами отсортированном массиве элементов меньше, чем в исходном:

      expected [ Array(14980) ] to deeply equal [ Array(15000) ]

    • ...когда условные операторы следует применять - первый не нужен, элемент с индексом i всегда существует, так что засовывать в firstArray его следует без проверок.
    • ...как, имея индекс, проверить наличие соответствующего элемента в массиве.

    Исправленный вариант вашего кода.

    function pendulum(arr) {
      arr.sort((a, b) => a - b);
    
      const head = [];
      const tail = [];
    
      for (let i = 0; i < arr.length; i += 2) {
        head.push(arr[i]);
    
        if (i + 1 < arr.length) { // или if (arr.hasOwnProperty(i + 1)) {
          tail.push(arr[i + 1]);
        }
      }
    
      return [ ...head.reverse(), ...tail ];
    }


    А вообще, не надо тут никаких if'ов.
    const pendulum = arr => arr
      .sort((a, b) => a - b)
      .reduce((acc, n, i) => (acc[i & 1].push(n), acc), [ [], [] ])
      .flatMap((n, i) => i ? n : n.reverse());
    Ответ написан
    Комментировать
  • Как правильно удалять строки из таблицы?

    0xD34F
    @0xD34F Куратор тега JavaScript
    href="javascript:deleteRow(this);"

    Замените на onclick="deleteRow(this)".

    Или, просто уберите, и сделайте делегированный обработчик клика:

    document.querySelector('table').addEventListener('click', e => {
      const btn = e.target.closest('.btn');
      if (btn) {
        btn.closest('tr').remove();
      }
    });

    нашел другой вариант

    $('body').on('click', 'btn btn-warning', function() {
            $(this).parents('tr').remove();
        });


    НО проблема в том, что при нажатии удаляется полностью все строки, которые...

    Это не "вариант", а неработоспособный мусор - где точки перед именами классов?

    Что до удаления строк - этого не происходит. А вот страница перезагружается. Потому что href у ссылки пустой и не отменяете действие по умолчанию при клике. Надо так:

    $('body').on('click', '.btn.btn-warning', function(e) {
      e.preventDefault();
      $(this).closest('tr').remove();
    });

    Или, вместо пустой строки записывайте # ссылкам в href.
    Ответ написан
    Комментировать
  • Как добавить генератор символа в строке, через каждые N символов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const getStr = length => Array
      .from({ length }, n => (
        n = Array(length).fill('.'),
        n[Math.random() * length | 0] = 'Q',
        n.join('')
      ))
      .join('\n');
    Ответ написан
    Комментировать
  • Почему не выводит правильно информацию о погоде?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что передаёте в sendRequesr вместо строки с городом соответствующий ей элемент <a>.
    Ответ написан
    3 комментария
  • Как установить значение в select multiple используя jquery?

    0xD34F
    @0xD34F Куратор тега JavaScript
    {"value":"[\"2b2df5f4-256d-402e-b074-c460ee394a2e

    Двойные кавычки перед [ видите? - value (days тоже) это строка, а не массив. Так что не хватает JSON.parse.
    Ответ написан
    1 комментарий
  • Как создать двухмерный массив данные из нескольких input JS?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Сколько tbody у таблицы? Одна штука:

    document.querySelector('tbody').addEventListener('input', function() {
      const data = Array.from(
        this.children,
        tr => Array.from(tr.querySelectorAll('input'), input => input.value)
      );
    
      console.log(data);
    });

    Несколько:

    document.querySelector('table').addEventListener('input', e => {
      const { map, flatMap } = Array.prototype;
      const data = flatMap.call(
        e.currentTarget.tBodies,
        tbody => map.call(
          tbody.rows,
          tr => map.call(tr.cells, td => td.lastElementChild.value)
        )
      );
    
      console.log(data);
    });
    
    // или
    
    document.querySelector('table').addEventListener('input', function() {
      const numHeadRows = this.querySelectorAll('thead tr').length;
      const data = [];
    
      for (const input of this.querySelectorAll('tbody input')) {
        const td = input.parentNode;
        const iCol = td.cellIndex;
        const iRow = td.parentNode.rowIndex - numHeadRows;
        (data[iRow] ??= [])[iCol] = input.value;
      }
    
      console.log(data);
    });
    Ответ написан
    4 комментария
  • Как реализовать сортировку таблицы по нажатию на заголовок столбца?

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

    Сделайте вычисляемое свойство, которое будет представлять отсортированный массив. Текущий столбец - ключ, по которому из элементов массива извлекаются значения для сравнения; результат сравнения умножается на +/- 1, в зависимости от текущего направления сортировки.

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

    https://jsfiddle.net/qny6cvsr/1/
    Ответ написан
    Комментировать
  • Как не обрабатывать клик, если нажатие кнопки мыши произошло над другим элементом?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Добавить в компонент модального окна свойство, которое будет указывать, начат ли процесс закрытия окна. Выставляется в true только по mousedown на корневом элементе, в остальных случаях сбрасывается. При событии mouseup на корневом элементе проверяется значение, если true - можно закрывать.

    data: () => ({
      closing: false,
    }),

    <template>
      <div
        @mousedown="closing = $event.target === $el"
        @mouseup.self="closing && close()"
      >
        ...

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

    0xD34F
    @0xD34F Куратор тега JavaScript
    document.querySelectorAll('.top > .nick').forEach(function(n) {
      const text = n.textContent;
      !this.has(text) && this.add(text) || n.remove();
    }, new Set);

    или

    [...document.querySelector('.top').children].reduce((acc, n) => {
      const text = n.innerText;
      acc.includes(text) ? n.parentNode.removeChild(n) : acc.push(text);
      return acc;
    }, []);

    или

    Object
      .values(Array
        .from(document.querySelectorAll('.top > .nick'))
        .reduce((acc, n) => ((acc[n.innerText] ??= []).push(n), acc), {}))
      .forEach(n => n.forEach((m, i) => i && (m.outerHTML = '')));

    или

    const el = document.querySelector('.top');
    el.innerHTML = [...new Set(el.innerHTML.match(/<span.*?\/span>/g) ?? [])].join(' ');

    или

    const el = document.querySelector('.top');
    el.innerHTML = Array
      .from(el.getElementsByClassName('nick'), n => n.innerText)
      .filter((n, i, a) => i === a.indexOf(n))
      .reduce((acc, n) => acc + (acc && ' ') + `<span class="nick">${n}</span>`, '');
    Ответ написан
    Комментировать
  • Как из массива объектов получить массив уникальных ключей?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Коротко:

    const keys = [...new Set(arr.flatMap(Object.keys))];

    Длинно:

    const keys = Array.from(arr.reduce((acc, n) => {
       for (const k in n) if (n.hasOwnProperty(k)) {
         acc.add(k);
       }
    
       return acc;
     }, new Set));
    Ответ написан
    Комментировать