Skip to content

Commit 1d57afe

Browse files
committed
Added support for multiple CSS classes on add and remove links.
1 parent adb0905 commit 1d57afe

2 files changed

Lines changed: 65 additions & 31 deletions

File tree

src/jquery.formset.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
},
4545

4646
insertDeleteLink = function(row) {
47+
var delCssSelector = options.deleteCssClass.trim().replace(/\s+/g, '.'),
48+
addCssSelector = options.addCssClass.trim().replace(/\s+/g, '.');
4749
if (row.is('TR')) {
4850
// If the forms are laid out in table rows, insert
4951
// the remove button into the last table cell:
@@ -57,10 +59,10 @@
5759
// last child element of the form's container:
5860
row.append('<a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a>');
5961
}
60-
row.find('a.' + options.deleteCssClass).click(function() {
62+
row.find('a.' + delCssSelector).click(function() {
6163
var row = $(this).parents('.' + options.formCssClass),
6264
del = row.find('input:hidden[id $= "-DELETE"]'),
63-
buttonRow = row.siblings("a." + options.addCssClass + ', .' + options.formCssClass + '-add'),
65+
buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'),
6466
forms;
6567
if (del.length) {
6668
// We're dealing with an inline formset.
@@ -153,7 +155,7 @@
153155
// FIXME: Perhaps using $.data would be a better idea?
154156
options.formTemplate = template;
155157

156-
if ($$.attr('tagName') == 'TR') {
158+
if ($$.is('TR')) {
157159
// If forms are laid out as table rows, insert the
158160
// "add" button in a new table row:
159161
var numCols = $$.eq(0).children().length, // This is a bit of an assumption :|

tests/basic.js

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -107,43 +107,75 @@
107107
assert.ok(!$('#stacked-form .dynamic-form:last input:checkbox').attr('checked'), 'Cloned Checkbox element is unchecked.');
108108
});
109109

110-
var addCallback, delCallback;
110+
(function () {
111+
var addCallback, delCallback;
112+
113+
module('Basic Formset Tests', {
114+
setup: function () {
115+
addCallback = new Mock();
116+
addCallback.calls(3).required(1);
117+
delCallback = new Mock();
118+
delCallback.calls(1).required(1);
119+
120+
$('#stacked-form div').formset({
121+
keepFieldValues: 'input:text',
122+
added: addCallback,
123+
removed: delCallback
124+
});
125+
}
126+
});
127+
128+
test('Test Excluded Form Elements Are Ignored', function (assert) {
129+
assert.equal($('#stacked-form .dynamic-form').size(), 1, 'One default form present.');
130+
assert.equal($('#stacked-form .dynamic-form:first input:text').val(), 'me@example.com', 'Default INPUT element has value "me@example.com".');
131+
$('#stacked-form .add-row').trigger('click');
132+
assert.equal($('#stacked-form .dynamic-form').size(), 2, 'Cloned form added.');
133+
assert.equal($('#stacked-form .dynamic-form:last input:text').val(), 'me@example.com', 'Cloned INPUT element still has value "me@example.com".');
134+
});
135+
136+
test('Test "added" callback called once, for each form added', function (assert) {
137+
var i;
138+
for (i = 0; i < 3; i += 1) {
139+
$('#stacked-form .add-row').trigger('click');
140+
}
141+
assert.ok(addCallback.verify(), '"Added" callback called 3 times, with a single argument.');
142+
});
143+
144+
test('Test "removed" callback called once, for each form deleted', function (assert) {
145+
assert.equal($('#stacked-form .dynamic-form').size(), 1, 'One default form present.');
146+
assert.equal($('#stacked-form .dynamic-form:first .delete-row:visible').size(), 1, 'Default form has active delete button.');
147+
$('#stacked-form .dynamic-form:first .delete-row').trigger('click');
148+
assert.ok(delCallback.verify(), '"Removed" callback called once, with a single argument.');
149+
});
150+
}());
151+
111152

112153
module('Basic Formset Tests', {
113154
setup: function () {
114-
addCallback = new Mock();
115-
addCallback.calls(3).required(1);
116-
delCallback = new Mock();
117-
delCallback.calls(1).required(1);
118-
119155
$('#stacked-form div').formset({
120-
keepFieldValues: 'input:text',
121-
added: addCallback,
122-
removed: delCallback
156+
addCssClass: 'btn btn-add',
157+
deleteCssClass: 'btn btn-danger'
123158
});
124159
}
125160
});
126161

127-
test('Test Excluded Form Elements Are Ignored', function (assert) {
128-
assert.equal($('#stacked-form .dynamic-form').size(), 1, 'One default form present.');
129-
assert.equal($('#stacked-form .dynamic-form:first input:text').val(), 'me@example.com', 'Default INPUT element has value "me@example.com".');
130-
$('#stacked-form .add-row').trigger('click');
131-
assert.equal($('#stacked-form .dynamic-form').size(), 2, 'Cloned form added.');
132-
assert.equal($('#stacked-form .dynamic-form:last input:text').val(), 'me@example.com', 'Cloned INPUT element still has value "me@example.com".');
133-
});
134-
135-
test('Test "added" callback called once, for each form added', function (assert) {
136-
var i;
137-
for (i = 0; i < 3; i += 1) {
138-
$('#stacked-form .add-row').trigger('click');
139-
}
140-
assert.ok(addCallback.verify(), '"Added" callback called 3 times, with a single argument.');
162+
test('Test Form Addition With Multiple AddCssClasses', function (assert) {
163+
var $btn = $('#stacked-form .btn-add');
164+
assert.equal($('#id_form-TOTAL_FORMS').val(), '1', 'Default form is present.');
165+
assert.ok($btn.hasClass('btn'), 'Add button has class "btn" applied to it.');
166+
assert.ok($btn.hasClass('btn-add'), 'Add button has class "btn-add" applied to it.');
167+
$btn.trigger('click');
168+
assert.equal($('#id_form-TOTAL_FORMS').val(), '2', 'Updated "Total Forms" count.');
169+
assert.equal($('#stacked-form div').size(), 2, 'Added new form.');
141170
});
142171

143-
test('Test "removed" callback called once, for each form deleted', function (assert) {
144-
assert.equal($('#stacked-form .dynamic-form').size(), 1, 'One default form present.');
145-
assert.equal($('#stacked-form .dynamic-form:first .delete-row:visible').size(), 1, 'Default form has active delete button.');
146-
$('#stacked-form .dynamic-form:first .delete-row').trigger('click');
147-
assert.ok(delCallback.verify(), '"Removed" callback called once, with a single argument.');
172+
test('Test Form Removal With Multiple DeleteCssClasses', function (assert) {
173+
var $btn = $('#stacked-form .btn-danger');
174+
assert.equal($('#id_form-TOTAL_FORMS').val(), '1', 'Default form is present.');
175+
assert.ok($btn.hasClass('btn'), 'Remove button has class "btn" applied to it.');
176+
assert.ok($btn.hasClass('btn-danger'), 'Remove button has class "btn-danger" applied to it.');
177+
$btn.trigger('click');
178+
assert.equal($('#id_form-TOTAL_FORMS').val(), '0', 'Updated "Total Forms" count.');
179+
assert.equal($('#stacked-form div').size(), 0, 'Removed form.');
148180
});
149181
}(jQuery));

0 commit comments

Comments
 (0)