From 0e2d0e80564fcea932d520810e35b228fd96733d Mon Sep 17 00:00:00 2001 From: Adam Stein Date: Thu, 17 Aug 2017 15:27:42 -0400 Subject: [PATCH] Added 'addImage' and 'deleteImage' options to use images instead of text for the buttons. Added unit tests to verify images were added. Updated usage doc to list new options. --- docs/usage.rst | 8 ++++++++ src/jquery.formset.js | 26 +++++++++++++++++++++----- tests/basic.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index d87bd4c..3402810 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -302,6 +302,14 @@ complete list of available options is shown below:: This means you can also pass in DOM elements, or a function (in newer versions of jQuery) as your selector. + ``addImage`` + Use the specified image instead of text for the add button. This should + be a URL that will be automatically wrapped in an tag. + + ``deleteImage`` + Use the specified image instead of text for the delete button. This should + be a URL that will be automatically wrapped in an tag. + .. note:: The ``addCssClass`` and ``deleteCssClass`` options must be unique. Internally, the plugin uses the class names to target the add and delete links. Any other elements with the same class applied to them will also diff --git a/src/jquery.formset.js b/src/jquery.formset.js index d910758..7701ee7 100644 --- a/src/jquery.formset.js +++ b/src/jquery.formset.js @@ -55,22 +55,30 @@ insertDeleteLink = function(row) { var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.'), addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.'); + + if (options.deleteImage) { + deleteElement = ''; + } else { + deleteElement = options.deleteText; + } + if (row.is('TR')) { // If the forms are laid out in table rows, insert // the remove button into the last table cell: - row.children(':last').append('' + options.deleteText + ''); + row.children(':last').append('' + deleteElement + ''); } else if (row.is('UL') || row.is('OL')) { // If they're laid out as an ordered/unordered list, // insert an
  • after the last list item: - row.append('
  • ' + options.deleteText +'
  • '); + row.append('
  • ' + deleteElement +'
  • '); } else { // Otherwise, just insert the remove button as the // last child element of the form's container: - row.append('' + options.deleteText +''); + row.append('' + deleteElement +''); } // Check if we're under the minimum number of forms - not to display delete link at rendering if (!showDeleteLinks()){ row.find('a.' + delCssSelector).hide(); + } else { } row.find('a.' + delCssSelector).click(function() { @@ -172,19 +180,25 @@ } // FIXME: Perhaps using $.data would be a better idea? options.formTemplate = template; + + if (options.addImage) { + addElement = ''; + } else { + addElement = options.addText; + } if ($$.is('TR')) { // If forms are laid out as table rows, insert the // "add" button in a new table row: var numCols = $$.eq(0).children().length, // This is a bit of an assumption :| - buttonRow = $('' + options.addText + '') + buttonRow = $('' + addElement + '') .addClass(options.formCssClass + '-add'); $$.parent().append(buttonRow); if (hideAddButton) buttonRow.hide(); addButton = buttonRow.find('a'); } else { // Otherwise, insert it immediately after the last form: - $$.filter(':last').after('' + options.addText + ''); + $$.filter(':last').after('' + addElement + ''); addButton = $$.filter(':last').next(); if (hideAddButton) addButton.hide(); } @@ -218,7 +232,9 @@ $.fn.formset.defaults = { prefix: 'form', // The form prefix for your django formset formTemplate: null, // The jQuery selection cloned to generate new form instances + addImage: null, // Image for the add link (overrides text) addText: 'add another', // Text for the add link + deleteImage: null, // Image for the delete link (overrides text) deleteText: 'remove', // Text for the delete link addCssClass: 'add-row', // CSS class applied to the add link deleteCssClass: 'delete-row', // CSS class applied to the delete link diff --git a/tests/basic.js b/tests/basic.js index a66be7e..b89b6fc 100755 --- a/tests/basic.js +++ b/tests/basic.js @@ -13,6 +13,8 @@ assert.equal($.fn.formset.defaults.keepFieldValues, '', 'keepFieldValues: '); assert.equal($.fn.formset.defaults.added, null, 'added callback: null'); assert.equal($.fn.formset.defaults.removed, null, 'removed callback: null'); + assert.equal($.fn.formset.defaults.addImage, null, 'addImage: null'); + assert.equal($.fn.formset.defaults.deleteImage, null, 'deleteImage: null'); }); module('Basic Formset Tests', { @@ -26,7 +28,9 @@ test('Test Formset Creation', function (assert) { assert.equal($('#stacked-form div').size(), 1, 'Default form is present.'); assert.equal($('#stacked-form .delete-row').size(), 1, 'Delete button created.'); + assert.equal($('#stacked-form .delete-row').text(), 'remove', 'Delete text created.'); assert.equal($('#stacked-form .add-row').size(), 1, 'Add button created.'); + assert.equal($('#stacked-form .add-row').text(), 'add another', 'Add text created.'); assert.ok($('#stacked-form div:first').hasClass('dynamic-form'), 'FormCssClass added to forms.'); }); @@ -205,4 +209,30 @@ assert.equal($totalForms.val(), $minForms.val(), 'Form count is now equal to min allowed.'); assert.ok($del.first().is(':hidden'), 'Delete button is hidden again.'); }); + + module('Basic Formset Tests', { + setup: function () { + $('#stacked-form div').formset({ + 'addImage': 'add.png', + 'deleteImage': 'delete.png' + }); + } + }); + + test('Test Formset Creation with Images', function (assert) { + assert.equal($('#stacked-form div').size(), 1, 'Default form is present.'); + assert.equal($('#stacked-form .delete-row').size(), 1, 'Delete button created.'); + assert.equal( + $('#stacked-form .delete-row').html(), + "", + 'Delete image created.' + ); + assert.equal($('#stacked-form .add-row').size(), 1, 'Add button created.'); + assert.equal( + $('#stacked-form .add-row').html(), + "", + 'Add image created.' + ); + assert.ok($('#stacked-form div:first').hasClass('dynamic-form'), 'FormCssClass added to forms.'); + }); }(jQuery));