Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit 1ec4fd212bc9bc2da0d32e60edda39bf7c15873b @vitalyrotari committed Mar 20, 2012
Showing with 264 additions and 0 deletions.
  1. BIN .DS_Store
  2. +127 −0 coffee/multifields.coffee
  3. BIN jquery/.DS_Store
  4. +137 −0 jquery/multifields.js
BIN .DS_Store
Binary file not shown.
@@ -0,0 +1,127 @@
+(($) ->
+ class MultiFields
+ constructor: (@container, options) ->
+ @rows = @container.children().addClass("multifields-row")
+ @rows.each () ->
+ $(@).append("<div class=\"multifields-row-buttons\" />");
+
+ @row = @rows.eq(0).clone()
+ @row.find("[disabled]").removeAttr("disabled").val("")
+
+ maxData = @container.data("maxFields")
+ titleData = @container.data("title")
+
+ @options =
+ max: if maxData then maxData else 5
+ title: if titleData then titleData else 5
+ buttons:
+ add: "<a href=\"#\">add</a>"
+ del: "<a href=\"#\">delete</a>"
+
+ if options
+ event.extend(@options, options)
+
+ @buttons =
+ add: $(@options.buttons.add).addClass("multifields-add-field")
+ del: $(@options.buttons.del).addClass("multifields-del-field")
+
+ @init()
+
+ init: () ->
+ @updateRows()
+ @updateButtons()
+
+ @container.on "click", "a.multifields-add-field", { MultiFields: @ }, (evt) ->
+ evt.preventDefault()
+ evt.data.MultiFields.add()
+
+ @container.on "click", "a.multifields-del-field", { MultiFields: @ }, (evt) ->
+ evt.preventDefault()
+ row = $(@).closest(".multifields-row")
+ index = evt.data.MultiFields.rows.index(row)
+ evt.data.MultiFields.remove(index)
+
+ return @
+
+ add: () ->
+ if @rows.length < @options.max
+ row = @row.clone()
+ num = @rows.length + 1
+
+ @container.append(row).trigger("MultiFields.add", row)
+ @update()
+
+ row.find("input:text").eq(0).focus()
+
+ return @
+
+ remove: (index) ->
+ if index > 0
+ @rows.eq(index).remove()
+ @container.trigger("MultiFields.remove", index)
+ @update()
+
+ return @
+
+ update: () ->
+ @updateRows()
+ @updateNames()
+ @updateButtons()
+ @container.trigger("MultiFields.update")
+
+ return @
+
+ updateButtons: () ->
+ max = @options.max
+ count = @rows.length
+
+ # Create new buttons for existing fields
+ @rows.find(".multifields-add-field, .multifields-del-field").remove().end().each (index, row) =>
+ row = $(row)
+ inputs = row.find(".multifields-row-buttons")
+
+ if inputs.length <= 0
+ inputs = row
+
+ if max != count and count is (index + 1)
+ inputs.append(@buttons.add.clone())
+
+ if index > 0
+ inputs.append(@buttons.del.clone())
+
+ return @
+
+ updateNames: () ->
+ @rows.each (number) ->
+ # Update ID attribute for labels
+ $(@).find("label[for]").each () ->
+ $(@).attr("for", (i, attr) ->
+ id = attr.replace(/\_[0-9]+\_{1,2}/, "_#{number}_")
+ return id
+ )
+
+ # Update ID and Name attributes for fields
+ $(@).find("[name]").each () ->
+ $(@).attr("name", (i, attr) ->
+ name = attr.replace(/\[[0-9]+\]{1,2}/, "[#{number}]")
+ return name
+ ).attr("id", (i, attr) ->
+ id = attr.replace(/\_[0-9]+\_{1,2}/, "_#{number}_")
+ return id
+ )
+
+ return @
+
+ updateRows: () ->
+ @rows = @container.children()
+ return @
+
+ $(document).ready () ->
+ $(".multifields").each () ->
+ elem = $(@)
+ obj = new MultiFields(elem)
+ elem.data("form.MultiFields", obj)
+
+
+ $.MultiFields = MultiFields
+).call this, jQuery
Binary file not shown.
@@ -0,0 +1,137 @@
+var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+(function($) {
+ var MultiFields;
+ MultiFields = (function() {
+ function MultiFields(container, options) {
+ var maxData, titleData;
+ this.container = container;
+ this.rows = this.container.children().addClass("multifields-row");
+ this.rows.each(function() {
+ return $(this).append("<div class=\"multifields-row-buttons\" />");
+ });
+ this.row = this.rows.eq(0).clone();
+ this.row.find("[disabled]").removeAttr("disabled").val("");
+ maxData = this.container.data("maxFields");
+ titleData = this.container.data("title");
+ this.options = {
+ max: maxData ? maxData : 5,
+ title: titleData ? titleData : 5,
+ buttons: {
+ add: "<a href=\"#\">add</a>",
+ del: "<a href=\"#\">delete</a>"
+ }
+ };
+ if (options) {
+ event.extend(this.options, options);
+ }
+ this.buttons = {
+ add: $(this.options.buttons.add).addClass("multifields-add-field"),
+ del: $(this.options.buttons.del).addClass("multifields-del-field")
+ };
+ this.init();
+ }
+ MultiFields.prototype.init = function() {
+ this.updateRows();
+ this.updateButtons();
+ this.container.on("click", "a.multifields-add-field", {
+ MultiFields: this
+ }, function(evt) {
+ evt.preventDefault();
+ return evt.data.MultiFields.add();
+ });
+ this.container.on("click", "a.multifields-del-field", {
+ MultiFields: this
+ }, function(evt) {
+ var index, row;
+ evt.preventDefault();
+ row = $(this).closest(".multifields-row");
+ index = evt.data.MultiFields.rows.index(row);
+ return evt.data.MultiFields.remove(index);
+ });
+ return this;
+ };
+ MultiFields.prototype.add = function() {
+ var num, row;
+ if (this.rows.length < this.options.max) {
+ row = this.row.clone();
+ num = this.rows.length + 1;
+ this.container.append(row).trigger("MultiFields.add", row);
+ this.update();
+ row.find("input:text").eq(0).focus();
+ }
+ return this;
+ };
+ MultiFields.prototype.remove = function(index) {
+ if (index > 0) {
+ this.rows.eq(index).remove();
+ this.container.trigger("MultiFields.remove", index);
+ this.update();
+ }
+ return this;
+ };
+ MultiFields.prototype.update = function() {
+ this.updateRows();
+ this.updateNames();
+ this.updateButtons();
+ this.container.trigger("MultiFields.update");
+ return this;
+ };
+ MultiFields.prototype.updateButtons = function() {
+ var count, max;
+ max = this.options.max;
+ count = this.rows.length;
+ this.rows.find(".multifields-add-field, .multifields-del-field").remove().end().each(__bind(function(index, row) {
+ var inputs;
+ row = $(row);
+ inputs = row.find(".multifields-row-buttons");
+ if (inputs.length <= 0) {
+ inputs = row;
+ }
+ if (max !== count && count === (index + 1)) {
+ inputs.append(this.buttons.add.clone());
+ }
+ if (index > 0) {
+ return inputs.append(this.buttons.del.clone());
+ }
+ }, this));
+ return this;
+ };
+ MultiFields.prototype.updateNames = function() {
+ this.rows.each(function(number) {
+ $(this).find("label[for]").each(function() {
+ return $(this).attr("for", function(i, attr) {
+ var id;
+ id = attr.replace(/\_[0-9]+\_{1,2}/, "_" + number + "_");
+ return id;
+ });
+ });
+ return $(this).find("[name]").each(function() {
+ return $(this).attr("name", function(i, attr) {
+ var name;
+ name = attr.replace(/\[[0-9]+\]{1,2}/, "[" + number + "]");
+ return name;
+ }).attr("id", function(i, attr) {
+ var id;
+ id = attr.replace(/\_[0-9]+\_{1,2}/, "_" + number + "_");
+ return id;
+ });
+ });
+ });
+ return this;
+ };
+ MultiFields.prototype.updateRows = function() {
+ this.rows = this.container.children();
+ return this;
+ };
+ return MultiFields;
+ })();
+ $(document).ready(function() {
+ return $(".multifields").each(function() {
+ var elem, obj;
+ elem = $(this);
+ obj = new MultiFields(elem);
+ return elem.data("form.MultiFields", obj);
+ });
+ });
+ return $.MultiFields = MultiFields;
+}).call(this, jQuery);

0 comments on commit 1ec4fd2

Please sign in to comment.