Skip to content

Instantly share code, notes, and snippets.

@axelvnk
Created August 16, 2018 20:39
Show Gist options
  • Save axelvnk/c01c2bdd3596002b20f6f3a6b234de53 to your computer and use it in GitHub Desktop.
Save axelvnk/c01c2bdd3596002b20f6f3a6b234de53 to your computer and use it in GitHub Desktop.
Symfony collection form javascript library
/**
* Collection Form plugin
*
* @param element
* @constructor
*/
var CollectionForm = function (element) {
this.$element = $(element);
this.$list = this.$element.find('[data-form-collection="list"]:first');
this.count = this.$list.children().length;
this.lastChoice = null;
this.$element.on(
'click',
'[data-form-collection="add"]:first',
$.proxy(this.addItem, this)
);
this.$element.on(
'click',
'[data-form-collection="delete"]',
$.proxy(this.deleteItem, this)
);
this.$element.on(
'change',
'[data-form-collection="update"]',
$.proxy(this.updateItem, this)
);
$(document).on(
'change',
'[data-form-prototype="update"]',
$.proxy(this.updatePrototype, this)
);
};
CollectionForm.prototype = {
constructor : CollectionForm,
/**
* Add a item to the collection.
* @param event
*/
addItem: function (event) {
event.preventDefault();
var prototype = this.$element.data('prototype');
prototype = prototype.replace(
/__name__/g,
this.count
);
this.$list.append(prototype);
this.count = this.count + 1;
$(document).trigger('collection-form-add', [this.$list.children().last()]);
$('textarea').each(function(e){
var editor = CKEDITOR.instances[$(this).attr('id')];
if (editor) {
editor.destroy(true);
}
CKEDITOR.replace($(this).attr('id'));
});
},
/**
* Update item from the collection
*/
updateItem: function (event) {
event.preventDefault();
var $element = $(event.currentTarget),
url = $element.data('form-url'),
value = $element.val(),
$container = $element.closest('[data-form-collection="item"]'),
index = $container.data('form-collection-index'),
position = $container.data('form-collection-index');
if (url) {
$container.load(url, {'id' : value, 'position' : position});
} else {
var prototype = this.$element.find('[data-form-prototype="'+ value +'"]').val();
prototype = prototype.replace(
/__name__/g,
index
);
$container.replaceWith(prototype);
}
$(document).trigger('collection-form-update', [$(event.currentTarget)]);
},
/**
* Delete item from the collection
* @param event
*/
deleteItem: function (event) {
event.preventDefault();
$(event.currentTarget)
.closest('[data-form-collection="item"]')
.remove();
$(document).trigger('collection-form-delete', [$(event.currentTarget)]);
},
/**
* Update the prototype
* @param event
*/
updatePrototype: function (event) {
var $target = $(event.currentTarget);
var prototypeName = $target.val();
if (undefined !== $target.data('form-prototype-prefix')) {
prototypeName = $target.data('form-prototype-prefix') + prototypeName;
}
if (null !== this.lastChoice && this.lastChoice !== prototypeName) {
this.$list.html('');
}
this.lastChoice = prototypeName;
this.$element.data(
'prototype',
this.$element.find('[data-form-prototype="'+ prototypeName +'"]').val()
);
}
};
/*
* Plugin definition
*/
$.fn.CollectionForm = function (option) {
return this.each(function () {
var $this = $(this);
var data = $this.data('collectionForm');
var options = typeof option == 'object' && option;
if (!data) {
$this.data(
'collectionForm',
(data = new CollectionForm(this, options))
)
}
})
};
$.fn.CollectionForm.Constructor = CollectionForm;
/*
* Apply to standard CollectionForm elements
*/
$(document).on('collection-form-add', function(e, addedElement) {
$(addedElement).find('[data-form-type="collection"]').CollectionForm();
$(document).trigger('dom-node-inserted', [$(addedElement)]);
});
$(document).ready(function () {
$('[data-form-type="collection"]').CollectionForm();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment