diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 8257188..6498081 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,5 +1,16 @@
X-editable changelog
=============================
+
+
+Version 1.1.1 Nov 30, 2012
+----------------------------
+[enh] 'showbuttons' option to hide buttons in form (vitalets)
+[enh] object can be passed in 'option' method to set several options at once (vitalets)
+[enh #20] toggle editable by 'dblclick' and 'mouseenter' (vitalets)
+[enh] added 'inputs-ext' directory with sample input 'address'. They will not be concatenated to main files (vitalets)
+[enh #13] 'onblur' option: to cancel, submit or ignore when user clicks outside the form (vitalets)
+[enh] 'ajaxOptions' parameter for advanced ajax configuration (vitalets)
+[enh] 'success' callback can return object to overwrite submitted value (vitalets)
Version 1.1.0 Nov 27, 2012
diff --git a/README.md b/README.md
index ca3354d..aa774c1 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ It is a new life of [bootstrap-editable plugin](http://github.com/vitalets/boots
See **http://vitalets.github.com/x-editable**
## Reporting issues
-When creating issues please provide jsFiddle example. You can just fork [this fiddle](http://jsfiddle.net/xBB5x/1/) as starting point.
+When creating issues please provide jsFiddle example. You can just fork [this fiddle](http://jsfiddle.net/xBB5x/5/) as starting point.
Your feedback is very appreciated!
## Contribution
@@ -60,7 +60,7 @@ Or use grunt's _qunit_ task grunt test
. For that you also need to [
You will get distributive in **lib/dist** and updated docs in **gh-pages/*.html**.
Do not edit **index.html** and **docs.html** directly! Instead look at [Handlebars](https://github.com/wycats/handlebars.js) templates in **generator/templates**.
-6.Commit changes on dev
branch and make pull request as usual.
+6.Commit changes on dev
/ gh-pages-dev
branch and make pull request as usual.
Thanks for your support!
diff --git a/grunt.js b/grunt.js
index 3b66d5b..4282da2 100644
--- a/grunt.js
+++ b/grunt.js
@@ -151,7 +151,8 @@ module.exports = function(grunt) {
'src/element/*.js',
'src/inputs/*.js',
'src/inputs/date/date.js',
- 'src/inputs/dateui/dateui.js'
+ 'src/inputs/dateui/dateui.js',
+ 'src/inputs-ext/**/*.js'
]
},
/*
@@ -192,29 +193,20 @@ module.exports = function(grunt) {
flatten: true
}
},
+ inputs_ext: {
+ files: {
+ '<%= dist %>/inputs-ext/': 'src/inputs-ext/**'
+ },
+ options: {
+ basePath: 'inputs-ext'
+ }
+ },
ui_datepicker: {
files: {
//copy jquery ui datepicker
'<%= dist %>/jquery-editable/jquery-ui-datepicker/' : 'src/inputs/dateui/jquery-ui-datepicker/**'
}
- }
- },
- yuidoc: {
- compile: {
- name: '<%= pkg.title || pkg.name %>',
- description: '<%= pkg.description %>',
- version: '<%= pkg.version %>',
- url: "<%= pkg.homepage %>",
- // logo: 'src/editable-form/img/loading.gif',
- options: {
- paths: "src/",
- ignorePaths: ['src/inputs/date/locales'],
- outdir: "../docs/",
-// theme: "simple",
- themedir: "../yuidoc-theme"
- //themedir: "../yuidoc-bootstrap-theme-master"
- }
- }
+ }
},
//compress does not work properly for MAC OS (see https://github.com/vitalets/bootstrap-editable/issues/19)
diff --git a/package.json b/package.json
index f7cf0e1..e0700a2 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "X-editable",
"title": "X-editable",
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery",
- "version": "1.1.0",
+ "version": "1.1.1",
"homepage": "http://github.com/vitalets/x-editable",
"author": {
"name": "Vitaliy Potapov",
diff --git a/src/containers/editable-container.css b/src/containers/editable-container.css
index 9098275..1a91e98 100644
--- a/src/containers/editable-container.css
+++ b/src/containers/editable-container.css
@@ -5,4 +5,9 @@
.editable-container.popover {
/* width: 300px;*/ /* debug */
width: auto; /* without this rule popover does not stretch */
+}
+
+.editable-container.editable-inline {
+ display: inline;
+ vertical-align: middle;
}
\ No newline at end of file
diff --git a/src/containers/editable-container.js b/src/containers/editable-container.js
index 8cc64c2..0029eba 100644
--- a/src/containers/editable-container.js
+++ b/src/containers/editable-container.js
@@ -27,7 +27,33 @@ Applied as jQuery method.
//bind 'destroyed' listener to destroy container when element is removed from dom
this.$element.on('destroyed', $.proxy(function(){
this.destroy();
- }, this));
+ }, this));
+
+ //attach document handlers (once)
+ if(!$(document).data('editable-handlers-attached')) {
+ //close all on escape
+ $(document).on('keyup.editable', function (e) {
+ if (e.which === 27) {
+ $('.editable-open').editableContainer('hide');
+ //todo: return focus on element
+ }
+ });
+
+ //close containers when click outside
+ $(document).on('click.editable', function(e) {
+ var $target = $(e.target);
+
+ //if click inside some editableContainer --> no nothing
+ if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
+ return;
+ } else {
+ //close all open containers (except one)
+ EditableContainer.prototype.closeOthers(e.target);
+ }
+ });
+
+ $(document).data('editable-handlers-attached', true);
+ }
},
//split options on containerOptions and formOptions
@@ -93,11 +119,22 @@ Applied as jQuery method.
/**
Shows container with form
@method show()
+ @param {boolean} closeAll Wether to close all other editable containers when showing this one. Default true.
**/
- show: function () {
+ show: function (closeAll) {
+ this.$element.addClass('editable-open');
+ if(closeAll !== false) {
+ //close all open containers (except this)
+ this.closeOthers(this.$element[0]);
+ }
+
+ this.innerShow();
+ },
+
+ /* internal show method. To be overwritten in child classes */
+ innerShow: function () {
this.call('show');
this.tip().addClass('editable-container');
-
this.initForm();
this.tip().find(this.innerCss).empty().append(this.$form);
this.$form.editableform('render');
@@ -108,10 +145,11 @@ Applied as jQuery method.
@method hide()
**/
hide: function() {
- if(!this.tip() || !this.tip().is(':visible')) {
+ if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) {
return;
}
- this.call('hide');
+ this.$element.removeClass('editable-open');
+ this.innerHide();
/**
Fired when container was hidden. It occurs on both save or cancel.
@@ -121,15 +159,21 @@ Applied as jQuery method.
this.$element.triggerHandler('hidden');
},
+ /* internal hide method. To be overwritten in child classes */
+ innerHide: function () {
+ this.call('hide');
+ },
+
/**
Toggles container visibility (show / hide)
@method toggle()
+ @param {boolean} closeAll Wether to close all other editable containers when showing this one. Default true.
**/
- toggle: function() {
+ toggle: function(closeAll) {
if(this.tip && this.tip().is(':visible')) {
this.hide();
} else {
- this.show();
+ this.show(closeAll);
}
},
@@ -210,6 +254,44 @@ Applied as jQuery method.
**/
destroy: function() {
this.call('destroy');
+ },
+
+ /*
+ Closes other containers except one related to passed element.
+ Other containers can be cancelled or submitted (depends on onblur option)
+ */
+ closeOthers: function(element) {
+ $('.editable-open').each(function(i, el){
+ //do nothing with passed element
+ if(el === element) {
+ return;
+ }
+
+ //otherwise cancel or submit all open containers
+ var $el = $(el),
+ ec = $el.data('editableContainer');
+
+ if(!ec) {
+ return;
+ }
+
+ if(ec.options.onblur === 'cancel') {
+ $el.data('editableContainer').hide();
+ } else if(ec.options.onblur === 'submit') {
+ $el.data('editableContainer').tip().find('form').submit();
+ }
+ });
+
+ },
+
+ /**
+ Activates input of visible container (e.g. set focus)
+ @method activate()
+ **/
+ activate: function() {
+ if(this.tip && this.tip().is(':visible') && this.$form) {
+ this.$form.data('editableform').input.activate();
+ }
}
};
@@ -248,7 +330,7 @@ Applied as jQuery method.
//store constructor
$.fn.editableContainer.Constructor = EditableContainer;
- //defaults - must be redefined!
+ //defaults
$.fn.editableContainer.defaults = {
/**
Initial value of form input
@@ -275,7 +357,16 @@ Applied as jQuery method.
@default true
@private
**/
- autohide: true
+ autohide: true,
+ /**
+ Action when user clicks outside the container. Can be cancel|submit|ignore
.
+ Setting ignore
allows to have several containers open.
+
+ @property onblur
+ @type string
+ @default 'cancel'
+ **/
+ onblur: 'cancel'
};
/*
@@ -290,4 +381,4 @@ Applied as jQuery method.
}
};
-}(window.jQuery));
\ No newline at end of file
+}(window.jQuery));
diff --git a/src/containers/editable-inline.js b/src/containers/editable-inline.js
index 92c5455..df585a6 100644
--- a/src/containers/editable-inline.js
+++ b/src/containers/editable-inline.js
@@ -26,7 +26,7 @@
return this.$form;
},
- show: function () {
+ innerShow: function () {
this.$element.hide();
if(this.$form) {
@@ -40,19 +40,13 @@
this.$form.editableform('render');
},
- hide: function () {
- if(!this.tip() || !this.tip().is(':visible')) {
- return;
- }
+ innerHide: function () {
this.$form.hide(this.options.anim, $.proxy(function() {
this.$element.show();
//return focus on element
if (this.options.enablefocus) {
this.$element.focus();
}
-
- //trigger event
- this.$element.triggerHandler('hidden');
}, this));
},
diff --git a/src/containers/editable-poshytip.js b/src/containers/editable-poshytip.js
index 5cbd427..3488ec9 100644
--- a/src/containers/editable-poshytip.js
+++ b/src/containers/editable-poshytip.js
@@ -28,11 +28,10 @@
this.call('update', $content);
},
- show: function () {
+ innerShow: function () {
this.$form.editableform('render');
- this.tip().addClass('editable-container');
-
this.call('show');
+ this.tip().addClass('editable-container');
this.$form.data('editableform').input.activate();
},
diff --git a/src/containers/editable-tooltip.js b/src/containers/editable-tooltip.js
index dcfa261..4fbc842 100644
--- a/src/containers/editable-tooltip.js
+++ b/src/containers/editable-tooltip.js
@@ -50,7 +50,7 @@
return this.container()._find(this.container().element);
},
- show: function() {
+ innerShow: function() {
this.call('open');
this.tip().addClass('editable-container');
@@ -62,12 +62,8 @@
this.$form.editableform('render');
},
- hide: function() {
- if(!this.tip() || !this.tip().is(':visible')) {
- return;
- }
+ innerHide: function() {
this.call('close');
- this.$element.triggerHandler('hidden');
},
setPosition: function() {
diff --git a/src/editable-form/editable-form-bootstrap.js b/src/editable-form/editable-form-bootstrap.js
index 50f72bb..3388544 100644
--- a/src/editable-form/editable-form-bootstrap.js
+++ b/src/editable-form/editable-form-bootstrap.js
@@ -5,11 +5,8 @@ Editableform based on Twitter Bootstrap
$.extend($.fn.editableform.Constructor.prototype, {
initTemplate: function() {
- this.$form = $($.fn.editableform.template);
- this.$form.find('.editable-error-block').addClass('help-block');
-
- //buttons
- this.$form.find('div.editable-buttons').append($.fn.editableform.buttons);
+ this.$form = $($.fn.editableform.template);
+ this.$form.find('.editable-error-block').addClass('help-block');
}
});
diff --git a/src/editable-form/editable-form-jqueryui.js b/src/editable-form/editable-form-jqueryui.js
index 804b6d2..9f0ea9e 100644
--- a/src/editable-form/editable-form-jqueryui.js
+++ b/src/editable-form/editable-form-jqueryui.js
@@ -4,10 +4,7 @@ Editableform based on jQuery UI
(function ($) {
$.extend($.fn.editableform.Constructor.prototype, {
- initTemplate: function() {
- this.$form = $($.fn.editableform.template);
-
- //buttons
+ initButtons: function() {
this.$form.find('.editable-buttons').append($.fn.editableform.buttons);
this.$form.find('.editable-submit').button({
icons: { primary: "ui-icon-check" },
@@ -17,7 +14,6 @@ Editableform based on jQuery UI
icons: { primary: "ui-icon-closethick" },
text: false
}).removeAttr('title');
-
}
});
diff --git a/src/editable-form/editable-form.css b/src/editable-form/editable-form.css
index 1ff18fe..874705a 100644
--- a/src/editable-form/editable-form.css
+++ b/src/editable-form/editable-form.css
@@ -38,7 +38,8 @@
.editableform-loading {
background: url('img/loading.gif') center center no-repeat;
height: 25px;
- width: auto;
+ width: auto;
+ min-width: 25px;
}
.editable-inline .editableform-loading {
diff --git a/src/editable-form/editable-form.js b/src/editable-form/editable-form.js
index b6f8018..a2db423 100644
--- a/src/editable-form/editable-form.js
+++ b/src/editable-form/editable-form.js
@@ -11,7 +11,7 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
var EditableForm = function (element, options) {
this.options = $.extend({}, $.fn.editableform.defaults, options);
- this.$element = $(element); //div (usually), containing form. not form tag!
+ this.$element = $(element); //div, containing form. Not form tag! Not editable-element.
this.initInput();
};
@@ -34,9 +34,9 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
},
initTemplate: function() {
this.$form = $($.fn.editableform.template);
-
- //buttons
- this.$form.find('div.editable-buttons').append($.fn.editableform.buttons);
+ },
+ initButtons: function() {
+ this.$form.find('.editable-buttons').append($.fn.editableform.buttons);
},
/**
Renders editableform
@@ -47,8 +47,14 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
this.$loading = $($.fn.editableform.loading);
this.$element.empty().append(this.$loading);
this.showLoading();
-
+
+ //init form template and buttons
this.initTemplate();
+ if(this.options.showbuttons) {
+ this.initButtons();
+ } else {
+ this.$form.find('.editable-buttons').remove();
+ }
/**
Fired when rendering starts
@@ -63,6 +69,11 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
//input
this.$form.find('div.editable-input').append(this.input.$input);
+ //automatically submit inputs when no buttons shown
+ if(!this.options.showbuttons) {
+ this.input.autosubmit();
+ }
+
//"clear" link
if(this.input.$clear) {
this.$form.find('div.editable-input').append($('
{success: true}
+ or {success: false, msg: "server error"}
you can check it inside this callback.
+ If it returns **string** - means error occured and string is shown as error message.
+ If it returns **object like** {newValue: <something>}
- it overwrites value, submitted by user.
+ Otherwise newValue simply rendered into element.
+
@property success
@type function
@default null
@@ -409,7 +432,36 @@ Editableform is linked with one of input types, e.g. 'text' or 'select'.
if(!response.success) return response.msg;
}
**/
- success: function(response, newValue) {}
+ success: function(response, newValue) {},
+ /**
+ Additional options for ajax request.
+ List of values: http://api.jquery.com/jQuery.ajax
+
+ @property ajaxOptions
+ @type object
+ @default null
+ **/
+ ajaxOptions: null,
+ /**
+ Wether to show buttons or not.
+ Form without buttons can be auto-submitted by input or by onblur = 'submit'.
+
+ @property showbuttons
+ @type boolean
+ @default true
+ **/
+ showbuttons: true
+
+ /*todo:
+ Submit strategy. Can be normal|never
+ submitmode='never'
usefull for turning into classic form several inputs and submitting them together manually.
+ Works pretty with showbuttons=false
+
+ @property submitmode
+ @type string
+ @default normal
+ */
+// submitmode: 'normal'
};
/*
diff --git a/src/element/editable-element.js b/src/element/editable-element.js
index f51afec..bd23548 100644
--- a/src/element/editable-element.js
+++ b/src/element/editable-element.js
@@ -47,34 +47,32 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.value = this.input.html2value($.trim(this.$element.html()));
isValueByText = true;
} else {
- this.value = this.input.str2value($.trim(this.options.value));
+ if(typeof this.options.value === 'string') {
+ this.options.value = $.trim(this.options.value);
+ }
+ this.value = this.input.str2value(this.options.value);
}
- //attach handler to close any container on escape
- $(document).off('keyup.editable').on('keyup.editable', function (e) {
- if (e.which === 27) {
- $('.editable-container').find('.editable-cancel').click();
- }
- });
-
- //attach handler to close container when click outside
- $(document).off('click.editable').on('click.editable', function(e) {
- var $target = $(e.target);
- //if click inside container --> do nothing
- if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
- return;
- }
- //close all other containers
- $('.editable-container').find('.editable-cancel').click();
- });
-
//add 'editable' class
this.$element.addClass('editable');
- //attach click handler. In disabled mode it just prevent default action (useful for links)
- if(this.options.toggle === 'click') {
+ //attach handler activating editable. In disabled mode it just prevent default action (useful for links)
+ if(this.options.toggle !== 'manual') {
this.$element.addClass('editable-click');
- this.$element.on('click.editable', $.proxy(this.click, this));
+ this.$element.on(this.options.toggle + '.editable', $.proxy(function(e){
+ e.preventDefault();
+ //stop propagation not required anymore because in document click handler it checks event target
+ //e.stopPropagation();
+
+ if(this.options.toggle === 'mouseenter') {
+ //for hover only show container
+ this.show();
+ } else {
+ //when toggle='click' we should not close all other containers as they will be closed automatically in document click listener
+ var closeAll = (this.options.toggle !== 'click');
+ this.toggle(closeAll);
+ }
+ }, this));
} else {
this.$element.attr('tabindex', -1); //do not stop focus on element when toggled manually
}
@@ -115,7 +113,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.options.disabled = false;
this.$element.removeClass('editable-disabled');
this.handleEmpty();
- if(this.options.toggle === 'click') {
+ if(this.options.toggle !== 'manual') {
if(this.$element.attr('tabindex') === '-1') {
this.$element.removeAttr('tabindex');
}
@@ -151,10 +149,24 @@ Makes editable any HTML element on the page. Applied as jQuery method.
Sets new option
@method option(key, value)
- @param {string} key
- @param {mixed} value
+ @param {string|object} key option name or object with several options
+ @param {mixed} value option new value
+ @example
+ $('.editable').editable('option', 'pk', 2);
**/
option: function(key, value) {
+ //set option(s) by object
+ if(key && typeof key === 'object') {
+ $.each(key, $.proxy(function(k, v){
+ this.option($.trim(k), v);
+ }, this));
+ return;
+ }
+
+ //set option by string
+ this.options[key] = value;
+
+ //disabled
if(key === 'disabled') {
if(value) {
this.disable();
@@ -163,12 +175,15 @@ Makes editable any HTML element on the page. Applied as jQuery method.
}
return;
}
-
- this.options[key] = value;
+
+ //value
+ if(key === 'value') {
+ this.setValue(value);
+ }
//transfer new option to container!
if(this.container) {
- this.container.option(key, value);
+ this.container.option(key, value);
}
},
@@ -193,21 +208,12 @@ Makes editable any HTML element on the page. Applied as jQuery method.
}
},
- click: function (e) {
- e.preventDefault();
- if(this.options.disabled) {
- return;
- }
- //stop propagation bacause document listen any click to hide all editableContainers
- e.stopPropagation();
- this.toggle();
- },
-
/**
Shows container with form
@method show()
+ @param {boolean} closeAll Wether to close all other editable containers when showing this one. Default true.
**/
- show: function () {
+ show: function (closeAll) {
if(this.options.disabled) {
return;
}
@@ -216,7 +222,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(!this.container) {
var containerOptions = $.extend({}, this.options, {
value: this.value,
- autohide: false //element itsef will show/hide container
+ autohide: false //element will take care to show/hide container
});
this.$element.editableContainer(containerOptions);
this.$element.on({
@@ -227,12 +233,9 @@ Makes editable any HTML element on the page. Applied as jQuery method.
} else if(this.container.tip().is(':visible')) {
return;
}
-
- //hide all other editable containers. Required to work correctly with toggle = manual
- $('.editable-container').find('.editable-cancel').click();
//show container
- this.container.show();
+ this.container.show(closeAll);
},
/**
@@ -247,18 +250,19 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//return focus on element
if (this.options.enablefocus && this.options.toggle === 'click') {
this.$element.focus();
- }
+ }
},
/**
Toggles container visibility (show / hide)
@method toggle()
+ @param {boolean} closeAll Wether to close all other editable containers when showing this one. Default true.
**/
- toggle: function() {
+ toggle: function(closeAll) {
if(this.container && this.container.tip().is(':visible')) {
this.hide();
} else {
- this.show();
+ this.show(closeAll);
}
},
@@ -324,7 +328,17 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.handleEmpty();
this.$element.triggerHandler('render', this);
}, this));
- }
+ },
+
+ /**
+ Activates input of visible container (e.g. set focus)
+ @method activate()
+ **/
+ activate: function() {
+ if(this.container) {
+ this.container.activate();
+ }
+ }
};
/* EDITABLE PLUGIN DEFINITION
@@ -459,7 +473,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
$.fn.editable.defaults = {
/**
- Type of input. Can be text|textarea|select|date
+ Type of input. Can be text|textarea|select|date|checklist
and more
@property type
@type string
@@ -475,9 +489,10 @@ Makes editable any HTML element on the page. Applied as jQuery method.
**/
disabled: false,
/**
- How to toggle editable. Can be click|manual
.
- When set to manual
you should manually call show/hide
methods of editable.
- Note: if you are calling show
on **click** event you need to apply e.stopPropagation()
because container has behavior to hide on any click outside.
+ How to toggle editable. Can be click|dblclick|mouseenter|manual
.
+ When set to manual
you should manually call show/hide
methods of editable.
+ **Note**: if you call show
or toggle
inside **click** handler of some DOM element,
+ you need to apply e.stopPropagation()
because containers are being closed on any click on document.
@example
$('#edit-button').click(function(e) {
@@ -490,6 +505,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
@default 'click'
**/
toggle: 'click',
+
/**
Text shown when element is empty.
@@ -519,7 +535,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
**/
enablefocus: false,
/**
- Initial value of input
+ Initial value of input. Taken from data-value
or element's text.
@property value
@type mixed
diff --git a/src/inputs-ext/address/address.css b/src/inputs-ext/address/address.css
new file mode 100644
index 0000000..f37a43b
--- /dev/null
+++ b/src/inputs-ext/address/address.css
@@ -0,0 +1,9 @@
+.editable-address {
+ display: block;
+ margin-bottom: 5px;
+}
+
+.editable-address span {
+ width: 70px;
+ display: inline-block;
+}
\ No newline at end of file
diff --git a/src/inputs-ext/address/address.js b/src/inputs-ext/address/address.js
new file mode 100644
index 0000000..ec144b8
--- /dev/null
+++ b/src/inputs-ext/address/address.js
@@ -0,0 +1,107 @@
+/**
+Address editable input.
+Internally value stored as {city: "Moscow", street: "Lenina", building: "15"}
+
+@class address
+@extends abstract
+@final
+@example
+awesome
+
+**/
+(function ($) {
+ var Address = function (options) {
+ this.init('address', options, Address.defaults);
+ };
+
+ $.fn.editableform.utils.inherit(Address, $.fn.editableform.types.abstract);
+
+ $.extend(Address.prototype, {
+ render: function() {
+ Address.superclass.render.call(this);
+
+ // this.$input.
+ },
+
+
+ value2html: function(value, element) {
+ var html = value.city + ', ' + value.street + ' st., bld. ' + value.building;
+ $(element).text(html);
+ },
+
+ html2value: function(html) {
+ /*
+ you may write parsing method to get value by element's html
+ e.g. "Moscow, st. Lenina, bld. 15" => {city: "Moscow", street: "Lenina", building: "15"}
+ but for complex structures I do not recommend do that.
+ Better always set value directly via javascript, e.g.
+ editable({
+ value: {
+ city: "Moscow",
+ street: "Lenina",
+ building: "15"
+ }
+ });
+ */
+ return null;
+ },
+
+ /*
+ method for converting data before sent on server.
+ As jQuery correctly sends objects via ajax, you can just return value
+ */
+ value2str: function(value) {
+ return value;
+ },
+
+ /*
+ this is mainly for parsing value defined in data-value attribute.
+ If you will always set value by javascript, no need to overwrite it
+ */
+ str2value: function(str) {
+ return str;
+ },
+
+ value2input: function(value) {
+ this.$input.find('input[name="city"]').val(value.city);
+ this.$input.find('input[name="street"]').val(value.street);
+ this.$input.find('input[name="building"]').val(value.building);
+ },
+
+ input2value: function() {
+ return {
+ city: this.$input.find('input[name="city"]').val(),
+ street: this.$input.find('input[name="street"]').val(),
+ building: this.$input.find('input[name="building"]').val()
+ };
+ },
+
+ activate: function() {
+ //set focus on city
+ this.$input.find('input[name="city"]').focus();
+ }
+ });
+
+ Address.defaults = $.extend({}, $.fn.editableform.types.abstract.defaults, {
+ tpl: ''+
+ ''+
+ '',
+
+ inputclass: 'editable-address'
+ });
+
+ $.fn.editableform.types.address = Address;
+
+}(window.jQuery));
\ No newline at end of file
diff --git a/src/inputs/abstract.js b/src/inputs/abstract.js
index a40d742..0da5ddb 100644
--- a/src/inputs/abstract.js
+++ b/src/inputs/abstract.js
@@ -46,7 +46,7 @@ To create your own input you should inherit from this class.
@param {DOMElement} element
**/
value2html: function(value, element) {
- var html = $('