UNPKG

repeatable-fields

Version:

Repeatable Fields is a jQuery plugin which let's you create a set of fields that can be made to repeat.

200 lines (158 loc) 5.73 kB
/* * jQuery Repeatable Fields v1.5.0 * http://www.rhyzz.com/repeatable-fields.html * * Copyright (c) 2014-2018 Rhyzz * License MIT */ (function($) { "use strict"; $.fn.repeatable_fields = function(custom_settings) { var self = this; self.after_add = function(container, new_row) { var row_count = $(container).attr('data-rf-row-count'); row_count++; $('*', new_row).each(function() { $.each(this.attributes, function() { this.value = this.value.replace(self.settings.row_count_placeholder, row_count - 1); }); }); $(container).attr('data-rf-row-count', row_count); }; self.default_settings = { wrapper: '.wrapper', container: '.container', row: '.row', add: '.add', remove: '.remove', move: '.move', move_up: '.move-up', move_down: '.move-down', move_steps: '.move-steps', template: '.template', is_sortable: true, before_add: null, after_add: self.after_add, before_remove: null, after_remove: null, sortable_options: null, row_count_placeholder: '{{row-count-placeholder}}', }; self.settings = $.extend({}, self.default_settings, custom_settings); self.initialize = function(parent) { $(self.settings.wrapper, parent).each(function() { var wrapper = this; var container = $(wrapper).children(self.settings.container); // Disable all form elements inside the row template $(container).children(self.settings.template).hide().find(':input').each(function() { $(this).prop('disabled', true); }); var row_count = $(container).children(self.settings.row).filter(function() { return !$(this).hasClass(self.settings.template.replace('.', '')); }).length; $(container).attr('data-rf-row-count', row_count); $(wrapper).on('click', self.settings.add, function(event) { event.stopImmediatePropagation(); var row_template = $($(container).children(self.settings.template).clone().removeClass(self.settings.template.replace('.', ''))[0].outerHTML); // Enable all form elements inside the row template $(row_template).find(':input').each(function() { $(this).prop('disabled', false); }); if(typeof self.settings.before_add === 'function') { self.settings.before_add(container); } var new_row = $(row_template).show().appendTo(container); if(typeof self.settings.after_add === 'function') { self.settings.after_add(container, new_row, self.settings.after_add); } // The new row might have it's own repeatable field wrappers so initialize them too self.initialize(new_row); }); $(wrapper).on('click', self.settings.remove, function(event) { event.stopImmediatePropagation(); var row = $(this).parents(self.settings.row).first(); if(typeof self.settings.before_remove === 'function') { self.settings.before_remove(container, row); } row.remove(); if(typeof self.settings.after_remove === 'function') { self.settings.after_remove(container); } }); if(self.settings.is_sortable === true) { if(typeof $.ui !== 'undefined' && typeof $.ui.sortable !== 'undefined') { var sortable_options = self.settings.sortable_options !== null ? self.settings.sortable_options : {}; sortable_options.handle = self.settings.move; $(wrapper).find(self.settings.container).sortable(sortable_options); } $(wrapper).find(self.settings.container).on('click', function(event) { if(!$(event.target).is(self.settings.move_up) && !$(event.target).is(self.settings.move_down)) { return; } var steps = 1; if($(event.target).siblings(self.settings.move_steps).length === 1) { var custom_steps = parseInt($(event.target).siblings(self.settings.move_steps).val(), 10); if(isNaN(custom_steps) === false && (custom_steps > 0 || custom_steps === -1)) { steps = custom_steps; } } var current_row = $(event.target).closest(self.settings.row); var i = 0; if($(event.target).is(self.settings.move_up) === true) { var previous_row; for(i = 0; steps === -1 ? true : i < steps; i++) { if(previous_row === undefined) { if(current_row.prev().not(self.settings.template).length === 1) { previous_row = current_row.prev(); } else { break; } } else { if(previous_row.prev().not(self.settings.template).length === 1) { previous_row = previous_row.prev(); } else { break; } } } if(previous_row !== undefined) { previous_row.before(current_row); } } else if($(event.target).is(self.settings.move_down) === true) { var next_row; for(i = 0; steps === -1 ? true : i < steps; i++) { if(next_row === undefined) { if(current_row.next().length === 1) { next_row = current_row.next(); } else { break; } } else { if(next_row.next().length === 1) { next_row = next_row.next(); } else { break; } } } if(next_row !== undefined) { next_row.after(current_row); } } event.stopImmediatePropagation(); }); } }); }; // Initialize all repeatable field wrappers self.initialize(self); return self; }; })(jQuery);