summaryrefslogtreecommitdiff
path: root/project/static/jquery/jquery-dynamic-form.js
diff options
context:
space:
mode:
Diffstat (limited to 'project/static/jquery/jquery-dynamic-form.js')
-rw-r--r--project/static/jquery/jquery-dynamic-form.js180
1 files changed, 180 insertions, 0 deletions
diff --git a/project/static/jquery/jquery-dynamic-form.js b/project/static/jquery/jquery-dynamic-form.js
new file mode 100644
index 0000000..a99fd46
--- /dev/null
+++ b/project/static/jquery/jquery-dynamic-form.js
@@ -0,0 +1,180 @@
+/**
+ * @author Stéphane Roucheray
+ * @extends jQuery
+ */
+
+jQuery.fn.dynamicForm = function (plusElmnt, minusElmnt, options){
+ var source = jQuery(this),
+ minus = jQuery(minusElmnt),
+ plus = jQuery(plusElmnt),
+ template = source.clone(true),
+ fieldId = 0,
+ formFields = "input, checkbox, select, textarea",
+ insertBefore = source.next(),
+ clones = [],
+ defaults = {
+ duration:1000
+ };
+
+ // Extend default options with those provided
+ options = $.extend(defaults, options);
+
+ isPlusDescendentOfTemplate = source.find("*").filter(function(){
+ return this == plus.get(0);
+ });
+
+ isPlusDescendentOfTemplate = isPlusDescendentOfTemplate.length > 0 ? true : false;
+
+ function normalizeElmnt(elmnt){
+ elmnt.find(formFields).each(function(){
+ var nameAttr = jQuery(this).attr("name"),
+ idAttr = jQuery(this).attr("id");
+
+ /* Normalize field name attributes */
+ if (!nameAttr) {
+ jQuery(this).attr("name", "field" + fieldId + "[]");
+ }
+
+ if (!/\[\]$/.exec(nameAttr)) {
+ jQuery(this).attr("name", nameAttr + "[]");
+ }
+
+ /* Normalize field id attributes */
+ if (idAttr) {
+ /* Normalize attached label */
+ jQuery("label[for='"+idAttr+"']").each(function(){
+ jQuery(this).attr("for", idAttr + fieldId);
+ });
+
+ jQuery(this).attr("id", idAttr + fieldId);
+ }
+ fieldId++;
+ });
+ };
+
+ /* Hide minus element */
+ minus.hide();
+
+ /* If plus element is within the template */
+ if (isPlusDescendentOfTemplate) {
+ function clickOnPlus(event){
+ var clone,
+ currentClone = clones[clones.length -1] || source;
+ event.preventDefault();
+
+ /* On first add, normalize source */
+ if (clones.length == 0) {
+ normalizeElmnt(source);
+ currentClone.find(minusElmnt).hide();
+ currentClone.find(plusElmnt).hide();
+ }else{
+ currentClone.find(plusElmnt).hide();
+ }
+
+ /* Clone template and normalize it */
+ clone = template.clone(true).insertAfter(clones[clones.length - 1] || source);
+ normalizeElmnt(clone);
+
+ /* Normalize template id attribute */
+ if (clone.attr("id")) {
+ clone.attr("id", clone.attr("id") + clones.length);
+ }
+
+
+ plus = clone.find(plusElmnt);
+ minus = clone.find(minusElmnt);
+
+ minus.get(0).removableClone = clone;
+ minus.click(clickOnMinus);
+ plus.click(clickOnPlus);
+
+ if (options.limit && (options.limit - 2) > clones.length) {
+ plus.show();
+ }else{
+ plus.hide();
+ }
+
+ clones.push(clone);
+ }
+
+ function clickOnMinus(event){
+ event.preventDefault();
+
+ if (this.removableClone.effect && options.removeColor) {
+ that = this;
+ this.removableClone.effect("highlight", {
+ color: options.removeColor
+ }, options.duration, function(){that.removableClone.remove();});
+ } else {
+
+ this.removableClone.remove();
+ }
+ clones.splice(clones.indexOf(this.removableClone),1);
+ if (clones.length == 0){
+ source.find(plusElmnt).show();
+ }else{
+ clones[clones.length -1].find(plusElmnt).show();
+ }
+ }
+
+ /* Handle click on plus */
+ plus.click(clickOnPlus);
+
+ /* Handle click on minus */
+ minus.click(function(event){
+
+ });
+
+ }else{
+ /* If plus element is out of the template */
+ /* Handle click on plus */
+ plus.click(function(event){
+ var clone;
+
+ event.preventDefault();
+
+ /* On first add, normalize source */
+ if (clones.length == 0) {
+ normalizeElmnt(source);
+ jQuery(minusElmnt).show();
+ }
+
+ /* Clone template and normalize it */
+ clone = template.clone(true).insertAfter(clones[clones.length - 1] || source);
+ if (clone.effect && options.createColor) {
+ clone.effect("highlight", {color:options.createColor}, options.duration);
+ }
+ normalizeElmnt(clone);
+
+ /* Normalize template id attribute */
+ if (clone.attr("id")) {
+ clone.attr("id", clone.attr("id") + clones.length);
+ }
+ if (options.limit && (options.limit - 3) < clones.length) {
+ plus.hide();
+ }
+ clones.push(clone);
+ });
+
+ /* Handle click on minus */
+ minus.click(function(event){
+ event.preventDefault();
+ var clone = clones.pop();
+ if (clones.length >= 0) {
+ if (clone.effect && options.removeColor) {
+ that = this;
+ clone.effect("highlight", {
+ color: options.removeColor, mode:"hide"
+ }, options.duration, function(){clone.remove();});
+ } else {
+ clone.remove();
+ }
+ }
+ if (clones.length == 0) {
+ jQuery(minusElmnt).hide();
+ }
+ plus.show();
+ });
+ }
+
+};