Fix problems with FormsetDataTable display

* display errors as tooltips, so that they don't stretch the table,
* make sure the "Add row" button is always displayed when the formset
  was created with extra>0
* don't delete extra empty rows from the end when the table when it is
  being redisplayed with errors
* make sure that only the "add row" button is clickable, not whole
  footer
* make sure the fields with errors are displayed as red

Change-Id: I7202965ba59f3565d350462c833d604782f7cc70
This commit is contained in:
Radomir Dopieralski 2013-10-10 09:14:45 +02:00
parent 177d972960
commit 35b4024770
5 changed files with 29 additions and 30 deletions

View File

@ -52,27 +52,35 @@ tuskar.formset_table = (function () {
module.replace_delete(table);
// if there are extra empty rows, add the button for new rows
if ($('#id_' + prefix + '-TOTAL_FORMS').val() >
$('#id_' + prefix + '-INITIAL_FORMS').val()) {
table.find('tfoot td').append(
'<a href="#" class="btn btn-small pull-right">' +
add_label +
'</a>'
).click(function () {
if (add_label) {
var button = $('<a href="#" class="btn btn-small pull-right">' +
add_label + '</a>');
table.find('tfoot td').append(button);
button.click(function () {
module.add_row(table, prefix, empty_row_html);
});
};
// if the formset is not empty, and is not being redisplayed,
// delete the empty extra row from the end
// if the formset is not empty and has no errors,
// delete the empty extra rows from the end
var initial_forms = +$('#id_' + prefix + '-INITIAL_FORMS').val();
var total_forms = +$('#id_' + prefix + '-TOTAL_FORMS').val();
if (table.find('tbody tr').length > 1 &&
$('#id_' + prefix + '-TOTAL_FORMS').val() >
$('#id_' + prefix + '-INITIAL_FORMS').val()) {
table.find('tbody tr:last').remove();
table.find('tbody td.error').length == 0 &&
total_forms > initial_forms) {
table.find('tbody tr').each(function (index) {
if (index >= initial_forms) {
$(this).remove();
};
});
module.reenumerate_rows(table, prefix);
$('#id_' + prefix + '-INITIAL_FORMS').val(
$('#id_' + prefix + '-TOTAL_FORMS').val());
};
// enable tooltips
table.find('td.error[title]').tooltip();
};
return module;

View File

@ -46,28 +46,15 @@ horizon.addInitFunction(function () {
var html = $('#qunit-fixture');
var table = html.find('table');
equal(table.find('tbody tr').length, 3);
equal(html.find('#id_flavors-TOTAL_FORMS').val(), 3);
equal(html.find('#id_flavors-INITIAL_FORMS').val(), 2);
tuskar.formset_table.init('flavors', '', 'Add row');
equal(table.find('tfoot tr a').html(), 'Add row');
equal(table.find('tbody tr').length, 2);
equal(html.find('#id_flavors-TOTAL_FORMS').val(), 2);
equal(html.find('#id_flavors-INITIAL_FORMS').val(), 2);
});
test("Init formset table -- no add", function() {
var html = $('#qunit-fixture');
var table = html.find('table');
table.find('tbody tr:last').remove();
html.find('#id_flavors-TOTAL_FORMS').val(2);
html.find('#id_flavors-INITIAL_FORMS').val(2);
equal(table.find('tbody tr').length, 2);
tuskar.formset_table.init('flavors', '', 'Add row');
tuskar.formset_table.init('flavors', '', '');
equal(table.find('tfoot tr a').length, 0);
equal(table.find('tbody tr').length, 2);
equal(html.find('#id_flavors-TOTAL_FORMS').val(), 2);
equal(html.find('#id_flavors-INITIAL_FORMS').val(), 2);
});
});

View File

@ -3,9 +3,6 @@
<td{{ cell.attr_string|safe }}>
{% if cell.field %}
{{ cell.field }}
{% for error in cell.field.errors %}
<span class="help-inline">{{ error }}</span>
{% endfor %}
{% else %}
{%if cell.wrap_list %}<ul>{% endif %}{{ cell.value }}{%if cell.wrap_list %}</ul>{% endif %}
{% endif %}

View File

@ -31,7 +31,11 @@
// prepare the js-enabled parts of the formset data table
var prefix = '{{ table.name|escapejs }}';
var empty_row_html = '{% filter escapejs %}{% include "formset_table/_row.html" with row=table.get_empty_row %}{% endfilter %}';
{% if table.formset_class.extra %}
var add_label = '{% filter escapejs %}{% trans "Add a row" %}{% endfilter %}';
{% else %}
var add_label = '';
{% endif %}
tuskar.formset_table.init(prefix, empty_row_html, add_label);
});

View File

@ -110,7 +110,10 @@ class FormsetCell(BaseCell):
self.field = None
else:
if self.field.errors:
self.attrs['class'] = self.attrs.get('class', '') + ' error'
self.attrs['class'] = (self.attrs.get('class', '') +
' error control-group')
self.attrs['title'] = ' '.join(
unicode(error) for error in self.field.errors)
class FormsetRow(BaseRow):