Задать вопрос
  • Как сделать при нажатие на кнопку в переключающем блоке было обязательное поле?

    0xD34F
    @0xD34F Куратор тега React
    В смысле - вам надо не давать пользователю переходить к следующему вопросу при отсутствие ответа?

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

    0xD34F
    @0xD34F Куратор тега JavaScript
    Можно удалять все возможные классы:

    const classes = $buttons.get().map(n => n.dataset.set);
    
    $buttons.click(function() {
      $('.current').removeClass('current');
      $(this).addClass('current');
    
      $blocks.removeClass(classes.join(' ')).addClass(this.dataset.set);
    });

    Или запоминать последний добавленный:

    let currentClass = null;
    
    $buttons.click(function() {
      $('.current').removeClass('current');
      $(this).addClass('current');
    
      const newClass = this.dataset.set;
      $blocks.removeClass(currentClass).addClass(newClass);
      currentClass = newClass;
    });
    Ответ написан
    2 комментария
  • Цикл создает лишнюю пустую строку?

    0xD34F
    @0xD34F
    if ($days_in_this_week < 8) {

    И как называется этот восьмой день? Я, честно говоря, не понял, зачем тут лишняя единица. В любом случае, проверять надо не верхнюю границу (всё равно выйти за неё не позволит условие продолжения цикла), а нижнюю - что в последней строке уже что-то есть, что она не пустая:

    if ($days_in_this_week > 1) {

    Но вообще, пустая строка в конце - это вовсе не косяк. Сколько строк всего может быть? - от четырёх (не високосный февраль, начинающийся в понедельник) до шести (месяц из 30 дней начинается в воскресенье, из 31 дня в воскресенье или субботу). Как-то не единообразно. Пусть всегда будет шесть строк, чтобы размер календаря не зависел от месяца. Так что отступаем от начала месяца назад до ближайшего понедельника, затем выводим 42 дня (шесть недель):

    function drawCalendar($year, $month) {
      $date = DateTime::createFromFormat('Y-m-d', "$year-$month-1");
      $day = DateInterval::createFromDateString('1 day');
      $weekdays = [ 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс' ];
    
      do {
        $date->sub($day);
      } while ($date->format('w') !== '1');
    
      $days = [];
      for ($i = 0; $i < 42; $i++, $date->add($day)) {
        $m = intval($date->format('m'));
        $days[] = $m === $month ? intval($date->format('d')) : '&nbsp;';
      }
    
      return "
    <table cellpadding=\"5\" cellspacing=\"5\" border=\"1\">
      <thead>
        <tr class=\"b-calendar__row\">".implode('', array_map(function($n) { return "
          <th class=\"b-calendar__head\">$n</th>"; }, $weekdays))."
        </tr>
      </thead>
      <tbody>".implode('', array_map(function($week) { return "
        <tr class=\"b-calendar__row\">".implode('', array_map(function($n, $i) { return "
          <td class=\"b-calendar__day ".($i > 4 ? 'b-calendar__weekend' : '')."\">
            $n
          </td>"; }, $week, array_keys($week)))."
        </tr>"; }, array_chunk($days, 7)))."
      </tbody>
    </table>";
    }
    
    
    echo drawCalendar(2018, 1);
    Ответ написан
    Комментировать
  • Как сделать поля привязанные к этому блоку?

    0xD34F
    @0xD34F Куратор тега React
    Ну, input'ы у вас уже есть, осталось только добавить обработчик onChange, в котором будет происходить обновление данных. И конечно, чтобы можно было управлять видимостью инпутов независимо, свойство, отвечающее за их отображение, должно быть не одно на все блоки, а у каждого своё:

    class App extends React.Component {
      state = {
        data: [
          '#088A85', '#0B2F3A', '#0B0B3B', '#2A0A29', '#B4045F',
          '#FA58F4', '#A9BCF5', '#58FA82', '#A9F5F2', '#CED8F6',
        ].map((n, i) => ({
          id: i + 1,
          color: n,
          title: `block #${i}`,
          opened: false,
        })),
      }
    
      updateItem(index, key, val) {
        const data = [...this.state.data];
        data[index][key] = val;
        this.setState({ data });
      }
    
      render() {
        return (
          <div>{this.state.data.map(({ id, color, title, opened }, i) => (
            <div key={id}>
              <div
                className="square"
                style={{ backgroundColor: color }}
                onClick={() => this.updateItem(i, 'opened', !opened)}
              >
                <p>{title}</p>
              </div>
              {opened &&
              <div>
                <input
                  value={color}
                  onChange={e => this.updateItem(i, 'color', e.target.value)}
                />
                <input
                  value={title}
                  onChange={e => this.updateItem(i, 'title', e.target.value)}
                />
              </div>}
            </div>))}
          </div>
        )
      }
    }

    .square {
      width: 100px;
      height: 100px;
    }
    Ответ написан
    Комментировать
  • Не работает добавление количества товара на сайте, в чем проблема?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Оба обработчика назначены одним и тем же элементам - .services_minus. То есть, при клике на плюс не происходит вообще ничего, а минус - количество будет уменьшаться, и сразу же увеличиваться обратно.

    Относительное расположение кнопок и элемента с количеством совсем не то, что вам кажется. Вместо того, чтобы хватать следующий элемент после кликнутой кнопки, надо от кнопки подняться до общего её и количества предка, внутри которого уже искать количество. Т.е., .next('.services_nomer') следует заменить на

    .closest('.services_button_block').find('.services_nomer')

    Нашли элемент с количеством, достали из него текст - это всё одно выражение, т.е. результатом является строка и самого элемента с количеством у вас на руках нет, устанавливать новый текст вы пытаетесь строке. Доставать текст из элемента с количеством надо там, где у вас parseInt. Или можно оформить как одно выражение и поиск элемента с количеством и его обновление, передав в метод text функцию, которая примет текущее содержимое элемента и должна будет вернуть новое:

    $('.services_minus').click(function() {
      $(this)
        .closest('.services_button_block')
        .find('.services_nomer')
        .text((i, text) => Math.max(0, text - 1));
    });
    
    $('.services_plus').click(function() {
      $(this)
        .closest('.services_button_block')
        .find('.services_nomer')
        .text((i, text) => +text + 1);
    });
    Ответ написан
    9 комментариев
  • Как вывести все элементы списка (в том числе вложенные)?

    0xD34F
    @0xD34F Куратор тега JavaScript
    почему после возвращения из рекурсивного вызова i=3 а не 2?

    Не выдумывайте, там 2.

    Ну а то, что функция работает не так, как вы ожидаете - это потому что переменная i является глобальной.
    Ответ написан
    Комментировать
  • Как округлить время Moment.js с точностью до 5 минут?

    0xD34F
    @0xD34F Куратор тега JavaScript
    const interval = 5 * 60 * 1000 // 5 минут, ага
    const x = moment(Math.ceil(moment() / interval) * interval).format('HH:mm:ss')
    Ответ написан
    1 комментарий
  • Зачем тут нужен apply()?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Почему я не могу сделать просто func(args) ?

    Потому что args - это массив аргументов, а вы должны передавать их по отдельности.

    Зачем нужно подставлять контекст?

    Не нужно. Можете делать так: func(...args).
    Ответ написан
    3 комментария
  • Как добавить условие, если input поле уже заполнено?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Можно затриггерить событие change после установки обработчика, вызвав соответствующий метод без параметров:

    $elems.change(function() {
      ...
    }).change();

    Или, если такой способ вам не подходит (например, ранее устанавливались другие обработчики change, и вы не хотите, чтобы они сработали), можно применить each, передав ему обработчик:

    function onChange() {
      ...
    }
    
    $elems.change(onChange).each(onChange);
    Ответ написан
    Комментировать
  • Как написать приложение перестановки набора карточек?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Ну типа вот, дальше допиливайте сами:

    class Game extends React.Component {
      state = {
        panesCurrent: [],
        panesDefault: [ 1, 1, 1, 0, -1, -1, -1 ],
        panesWin: [ -1, -1, -1, 0, 1, 1, 1 ],
      }
    
      componentDidMount() {
        this.reset();
      }
    
      componentDidUpdate() {
        if (this.state.panesCurrent.every((n, i) => n === this.state.panesWin[i])) {
          setTimeout(alert, 25, 'WIN');
        }
      }
    
      onClick(index) {
        const clicked = this.state.panesCurrent[index];
        if (clicked === 0) {
          return;
        }
    
        for (let i = 1; i <= 2; i++) {
          const t = index + clicked * i;
          if (this.state.panesCurrent[t] === 0) {
            const panes = [...this.state.panesCurrent];
            [ panes[index], panes[t] ] = [ panes[t], panes[index] ];
            this.setState({ panesCurrent: panes });
            break;
          }
        }
      }
    
      reset = () => {
        this.setState(({ panesDefault }) => ({
          panesCurrent: [...panesDefault],
        }));
      }
    
      render() {
        return (
          <div>
            <button onClick={this.reset}>reset</button>
            <div className="game">
              {this.state.panesCurrent.map((n, i) => (
                <div
                  className={'pane ' + [ 'left', '', 'right' ][n + 1]}
                  onClick={() => this.onClick(i)}
                ></div>
              ))}
            </div>
          </div>
        )
      }
    }

    .game {
      font-size: 5px;
    }
    
    .pane {
      display: inline-block;
      width: 10em;
      height: 10em;
      margin: 1em;
    }
    
    .pane.right::after,
    .pane.left::after {
      position: relative;
      display: inline-flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
      font-family: monospace;
      font-size: 4em;
    }
    .pane.right::after {
      content: "-->";
      color: red;
      border: 2px solid red;
    }
    .pane.left::after {
      content: "<--";
      color: lime;
      border: 2px solid lime;
    }
    Ответ написан
    2 комментария
  • Как передать индекс в компонент?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Индекс не нужен, передавайте сразу элемент массива:

    v-on:edit="editText($event, item)"

    Сам editText будет при этом выглядеть следующим образом:

    editText(operation, item) {
      item.text = operation.api.origElements.innerHTML;
    },
    Ответ написан
    2 комментария
  • Есть ли возможность перевернуть по оси-y значения google chart?

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

    vAxis: {
      direction: -1
    }
    Ответ написан
    Комментировать
  • Как заменить часть ссылки?

    0xD34F
    @0xD34F Куратор тега JavaScript
    text.replace(/http:/g, 'https:')
    Ответ написан
    Комментировать
  • Алгоритм получения координат элемента?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Можете подсказать что я делаю не так

    Да всё так. Не хватает только сравнения координат элементов .box и координат перемещаемой картинки. А именно - вторые должны быть больше left/top и меньше left+width/top+height первых. Четыре неравенства, ничего сложного.
    Ответ написан
    1 комментарий
  • Как исправить drag & drop?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Добавьте e.preventDefault() в метод mouseDown.
    Ответ написан
    2 комментария
  • Как удалить отфильтрованный элемента массива?

    0xD34F
    @0xD34F Куратор тега React
    Косяк в том, что передаёте в deleteItem индекс элемента отфильтрованного массива, а удаляете из исходного.

    Давайте вместо индексов будем использовать уникальные id (вместо строк в items придётся хранить объекты):

    deleteItem(id) {
      this.setState(({ items }) => ({
        items: items.filter(n => n.id !== id),
      }));
    }

    Полный код
    class App extends React.Component {
      state = {
        items: [...this.props.items.map((n, i) => ({
          id: i + 1,
          value: n,
        }))],
        newItem: '',
        search: '',
      }
    
      addItem = () => {
        this.setState(({ items, newItem }) => ({
          items: [ ...items, {
            id: 1 + Math.max(0, ...items.map(n => n.id)),
            value: newItem,
          } ],
          newItem: '',
        }));
      }
    
      deleteItem(id) {
        this.setState(({ items }) => ({
          items: items.filter(n => n.id !== id),
        }));
      }
    
      onChange = ({ target: { value, name } }) => {
        this.setState(() => ({
          [name]: value,
        }));
      }
    
      render() {
        const search = this.state.search.toLowerCase();
        const filteredItems = this.state.items.filter(n => n.value.toLowerCase().includes(search));
    
        return (
          <div>
            <div>
              <input
                value={this.state.newItem}
                onChange={this.onChange}
                name="newItem"
                placeholder="Add..."
              />
              <button onClick={this.addItem}>Добавить</button>
            </div>
            <div>
              <input
                value={this.state.search}
                onChange={this.onChange}
                name="search"
                placeholder="Search..."
              />
            </div>
            <ul>
              {filteredItems.map(n => (
                <li key={n.id}>
                  {n.value}
                  <button onClick={() => this.deleteItem(n.id)}>Удалить</button>
                </li>
              ))}
            </ul>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <App
        items={[
          'hello, world!!',
          'fuck the world',
          'fuck everything',
        ]}
      />,
      document.getElementById('app')
    );
    Ответ написан
    1 комментарий
  • Почему this.$props в скрипте компонента всегда undefined?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Неуместное использование стрелочных функций. В результате this внутри методов оказывается вовсе не экземпляром компонента. Соответственно, вы ни к каким свойствам компонента не имеете доступа.
    Ответ написан
    3 комментария