$(document).ready(function() { // add/remove/sort items in a has_many relationship $('.has-many-selector').hasManySelector(); }); (function($){ $.fn.hasManySelector = function(options) { var populateSelect = function(context) { context.select.find('optgroup, option').remove(); for (var i = 0; i < context.data.collection.length; i++) { var obj = context.data.collection[i]; if (typeof(obj.name) != 'undefined') { // grouped items var optgroup = $('').attr('label', obj.name); var size = 0; for (var j = 0; j < obj.items.length; j++) { var innerObj = obj.items[j]; if ($.inArray(innerObj[1], context.data.taken_ids) == -1) { optgroup.append(new Option(innerObj[0], innerObj[1], true, true)); size++; } } if (size > 0) context.select.append(optgroup); } else { if ($.inArray(obj[1], context.data.taken_ids) == -1) { var option = new Option("", obj[1], true, true); $(option).text(obj[0]); context.select.append(option); } } } if (context.select.find('option').size() == 0) context.list.find('li.template').hide(); else context.list.find('li.template').show(); } var addId = function(context, id) { context.data.taken_ids.push(id); populateSelect(context); if (context.data.taken_ids.length > 0) { context.empty.hide(); context.list.next('input[type=hidden]').remove(); } if (context.data.taken_ids.length == context.data.collection.length) context.sep.hide(); } var removeId = function(context, id) { context.data.taken_ids = jQuery.grep(context.data.taken_ids, function(value) { return value != id; }); populateSelect(context); if (context.data.taken_ids.length == 0) { context.empty.show(); context.list.after(''); } context.sep.show(); } var registerElementEvents = function(context, data, domElement) { // remove domElement.find('a.remove').click(function(e) { domElement.remove(); removeId(context, data.id); context.list.sortable('refresh'); e.preventDefault(); e.stopPropagation(); }); } var registerElementTemplateEvents = function(context, domElement) { // bind the "Add field" button domElement.find('button').click(function(e) { var newElement = { id: context.select.val(), label: context.select.find('option:selected').text() }; addId(context, newElement.id); addElement(context, newElement, { refreshPosition: true }); context.list.sortable('refresh'); e.preventDefault(); e.stopPropagation(); }); } /* ___ Add an element into the list ___ */ var addElement = function(context, data, options) { options = $.extend({ 'is_template': false, 'refreshPosition': false }, options); data = $.extend({ behaviour_flag: function() { return options.is_template ? 'template' : 'added' }, base_name: function() { return options.is_template ? '' : context.baseInputName }, if_template: function() { return options.is_template } }, data); var html = Mustache.to_html(context.template, data); var domElement = null; if (options.is_template) { domElement = context.list.append('