I created a quick "demonstration of proposal behavior" tool for my post on MSO: A proposal to put ALL answerers on a path to curating better content.
Because I have never asked for a review before and I am not a JavaScript or CSS SME, I'd like to see if I've used any antipatterns and how my code can be made more direct/maintainable/readable/professional.
The technique that I used to create repeatable table rows doesn't feel very slick.
I don't necessarily need the actual presentation to be improved (since it was just something I scratched up), but if anyone want to go down that rabbit hole, I won't stop you.
$(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>