Products manager with TABLE
by seefeld
HTML
<script src="http://documentcloud.github.com/underscore/underscore.js"></script>
<p>(Navigate with the arrow keys ↑ ↓ and edit the product's name)</p>
<table>
<theah>
<td> </td>
<th>Id</th>
<th>Product</th>
<td> </td>
</theah>
<tbody id=products></tbody>
</table>
<p style="margin-top:8px;">
<button id=deleteSelected type=button>Delete selected</button>
<button id=selectAll type=button>Select all</button>
<button id=toggle type=button>Toggle</button>
</p>
CSS
.action
, input[type=checkbox] {
cursor:pointer;
}
.action.delete {
background:rgba(255,0,0,0.3);
}
tr {
background:#F5F5F5;
}
tr:nth-child(even) {
background:#E1E1E1;
}
tr:hover {
background:#B2DBFC;
}
.productDescription {
background:transparent;
padding-left:4px;
}
input[type=text] {
border:none;
}
JavaScript
// Populate products
var $products = $('tbody#products');
for (var i = 1; i <= 5; i++) {
$products.append('<tr data-product-id=' + i + ' class=product>'
+ '<td><input type=checkbox /></td>'
+ '<td>' + i + '</td>'
+ '<td><input class=productDescription type=text value="Product ' + i + '" /></td>'
+ '<td><button class="action delete" type=button title=Delete>X</button></td>'
+ '</tr>');
}
// Select text on enter and trigger arrow keys navigation
$(':input.productDescription').bind('focus', function() {
$(this).select();
}).bind('keydown', function(e) {
if (e.which === 40) {
var $next = $(this).data('next');
if ($next != null) {
$next.select();
}
} else if (e.which === 38) {
var $prev = $(this).data('prev');
if ($prev != null) {
$prev.select();
}
}
});
function chainNavigation() {
var $productDescriptions = $(':input.productDescription');
$productDescriptions.each(function(i) {
$(this).data('next', $productDescriptions[i + 1]);
$(this).data('prev', $productDescriptions[i - 1]);
});
}
function deleteProduct(e) {
var toDelete = [];
e.each(function() {
var $row = $(this).closest('tr');
toDelete.push($row.data('productId'));
$row.css('background', 'rgba(255,0,0,0.3)').fadeOut(function() {
$(this).remove();
chainNavigation();
});
});
console.info('To delete: ' + JSON.stringify(toDelete));
}
chainNavigation();
// Inline delete buttons
$('button.action.delete').bind('click', function() {
deleteProduct($(this).attr('disabled', true));
});
// Footer action buttons
$('button#selectAll').bind('click', function() {
$(':input[type=checkbox]').attr('checked', true);
});
$('button#toggle').bind('click', function() {
$(':input[type=checkbox]').each(function() {
...