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

Я создал инструмент для быстрой «демонстрации поведения предложения» для своего сообщения на MSO: Предложение направить ВСЕХ респондентов на путь улучшения содержания.

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

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

Мне не обязательно нужно улучшать саму презентацию (так как это было просто то, что я поцарапал), но если кто-то захочет спуститься в кроличью нору, я не стану вас останавливать.

$(document).on('click', '.add', function() {
  let mostRecentAnswer = $('#summary').prev(),
      id = !mostRecentAnswer.length ? 1 : 1 + mostRecentAnswer.data('id');
  $('#summary').before(
    '<tr data-id=' + id + '>'
      + '<td><input type="button" class="del" value="-"></td>'
      + '<td>'
        + '<label for="open' + id + '"><input type="radio" id="open' + id + '" name="status' + id + '" checked> Open</label>'
        + '<label for="closed' + id + '"><input type="radio" id="closed' + id + '" name="status' + id + '"> Closed</label>'
      + '</td>'
      + '<td class="newest5 hide"></td>'
      + '<td class="newest10 hide"></td>'
      + '<td class="newest20 hide"></td>'
    + '</tr>'
  );
  handleNewest();
});

$(document).on('click', '.del', function() {
  $(this).closest('tr').remove();
  handleNewest();
});

$(document).on('change', '[type="radio"]', function() {
  handleNewest();
});

function handleNewest() {
  let totalAnswers = $('#demo tr[data-id]').length;
  if (totalAnswers < 5) {
    $('#outcome').html('<b class="red">Please post carefully constructed and educational answers to questions which are at least 4 hours old -- it is presumed that this community has had ample to time to vet these new questions as clear, complete, unique and on-topic.</b>');
    return;
  }
  $('#outcome').html('More than 40% of your recent answers have been on open questions which the community has deemed to be a good fit for our repository of knowledge.');
  [5, 10, 20].forEach(function(group) {
    $('td[class^="newest' + group + '"]').addClass('hide').removeClass('groupStart groupEnd');
    if (totalAnswers >= group) {
      let lastCount = group - 1,
          sumOpen = 0,
          row = $('#summary').prev(),
          groupCell;
      for (let i = 0; i < group; ++i) {
        sumOpen += $('td label input[id^="open"]:checked', row).length;
        groupCell = $('td[class^="newest' + group + '"]', row);
        groupCell.removeClass('hide');
        if (!i) {
          groupCell.addClass('groupEnd');
        } else if (i === lastCount) {
          groupCell.addClass('groupStart');
        }
        row = row.prev();
      }
      let percent = Math.round(sumOpen / group * 100);
      $('#newest' + group + 'Total').html(percent).toggleClass('red', percent <= 40);
        $('td[class^="newest' + group + '"]:not(.hide)').toggleClass('redBG', percent <= 40);
        if (percent <= 40) {
          $('#outcome').html('<b  class="red">' + (100 - percent) + '% of your last ' + group + ' answers have been on closed pages. Please take more care to only post answers to clear, complete, unique, on-topic questions.</b>');
        }
      }
    });
  }
#demo {
  border-spacing: 0;
}

.newest5:not(.hide),
.newest10:not(.hide),
.newest20:not(.hide) {
  border-right: 1px solid black; min-width: 30px;
}

.groupStart {
  border-top-right-radius: 30px;
}

.groupEnd {
  border-bottom-right-radius: 30px;
}

#summaryLabel {
  text-align: right;
}

#[id$="Total"]:after {
  content: '%';
}

.red {
  color: red;
}

.newest5.redBG:not(.hide),
.newest10.redBG:not(.hide),
.newest20.redBG:not(.hide) {
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="demo">
  <tr id="summary">
    <td><input type="button" class="add" value="+"></td>
    <td id="summaryLabel">Open Percent:</td>
    <td id="newest5Total"></td>
    <td id="newest10Total"></td>
    <td id="newest20Total"></td>
  </tr>
</table>
<h2 id="outcome"></h2>

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *