diff --git a/grunt.js b/grunt.js
index f8a2f7e..17f0026 100644
--- a/grunt.js
+++ b/grunt.js
@@ -187,6 +187,24 @@ containers = lib+'containers/';
}
}
},
+ 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)
//zip will be created manually
/*
diff --git a/package.json b/package.json
index b67b3b8..208fffd 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "x-editable",
+ "name": "X-editable",
"title": "X-editable",
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery",
"version": "1.0.0",
@@ -19,10 +19,6 @@
{
"type": "MIT",
"url": "https://github.com/vitalets/x-editable/blob/master/LICENSE-MIT"
- },
- {
- "type": "GPL",
- "url": "https://github.com/vitalets/x-editable/blob/master/LICENSE-GPL"
}
],
"dependencies": {
@@ -30,8 +26,7 @@
},
"devDependencies": {
"grunt": "~0.3.11",
- "grunt-contrib": "0.1.1",
- "moment": "1.7.0"
+ "grunt-contrib": "0.1.1"
},
"keywords": []
}
\ No newline at end of file
diff --git a/src/containers/editable-container.js b/src/containers/editable-container.js
index ba4b51a..405877b 100644
--- a/src/containers/editable-container.js
+++ b/src/containers/editable-container.js
@@ -1,26 +1,15 @@
/**
-* Editable Container
-* Container can be popover, inline form or whatever
-* Container must provide following:
-* 1. methods:
-* show(),
-* hide(),
-* tip() - returns jquery object of container element
-* option()
-*
-* 2. events:
-* - save
-* - cancel
-*
-* 3. settings: trigger, value, placement
-*/
+Container for editableform. It can be popup (bootstrap-popover, jqueryui-tooltip, poshytip..) or inline.
+Applied as jQuery method to any element. Element is used only for positioning!
+
+@class editableContainer
+**/
(function ($) {
-
- //Constructor
+
var EditableContainer = function (element, options) {
this.init(element, options);
};
-
+
//methods
EditableContainer.prototype = {
containerName: null, //tbd in child class
@@ -28,18 +17,19 @@
init: function(element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.editableContainer.defaults, $.fn.editableform.utils.getConfigData(this.$element), options);
+ this.options.trigger = 'manual';
this.initContainer();
-
+
//bind 'destroyed' listener to destroy container when element is removed from dom
this.$element.on('destroyed', $.proxy(function(){
this.destroy();
}, this));
},
-
+
initContainer: function(){
- this.call(this.options);
+ this.call(this.options);
},
-
+
initForm: function() {
this.$form = $('
')
.editableform(this.options)
@@ -52,92 +42,152 @@
return this.$form;
},
+ /**
+ Returns jquery object of container
+ @method tip()
+ **/
tip: function() {
- return this.container().$tip;
+ return this.container().$tip;
},
-
- //return instance of container
+
container: function() {
- return this.$element.data(this.containerName);
+ return this.$element.data(this.containerName);
},
-
- //call container's method
+
call: function() {
- this.$element[this.containerName].apply(this.$element, arguments);
+ this.$element[this.containerName].apply(this.$element, arguments);
},
-
+
+ /**
+ Shows container with form
+ @method show()
+ **/
show: function () {
this.call('show');
this.tip().addClass('editable-container');
-
+
this.initForm();
this.tip().find(this.innerCss).empty().append(this.$form);
this.$form.editableform('render');
- },
-
- hide: function() {
- this.call('hide');
- },
-
- setPosition: function() {
- //tbd in child class
- },
-
- cancel: function() {
- if(this.options.autohide) {
- this.hide();
- }
- this.$element.triggerHandler('cancel');
- },
-
- save: function(e, params) {
- if(this.options.autohide) {
- this.hide();
- }
- this.$element.triggerHandler('save', params);
- },
-
- option: function(key, value) {
- this.options[key] = value;
- this.call('option', key, value);
- },
-
- destroy: function() {
- this.call('destroy');
- }
+ },
+
+ /**
+ Hides container with form
+ @method hide()
+ **/
+ hide: function() {
+ this.call('hide');
+ },
+
+ /**
+ Updates the position of container when content changed.
+ @method setPosition()
+ **/
+ setPosition: function() {
+ //tbd in child class
+ },
+
+ cancel: function() {
+ if(this.options.autohide) {
+ this.hide();
+ }
+ /**
+ Fired when form was cancelled by user
+
+ @event cancel
+ @param {Object} event event object
+ **/
+ this.$element.triggerHandler('cancel');
+ },
+
+ save: function(e, params) {
+ if(this.options.autohide) {
+ this.hide();
+ }
+ /**
+ Fired when new value was submitted
+
+ @event save
+ @param {Object} event event object
+ @param {Object} params additional params
+ @param {mixed} params.newValue submitted value
+ @param {Object} params.response ajax response
+ **/
+ this.$element.triggerHandler('save', params);
+ },
+
+ /**
+ Sets new option
+ @method option(key, value)
+ @param {string} key
+ @param {mixed} value
+ **/
+ option: function(key, value) {
+ this.options[key] = value;
+ this.call('option', key, value);
+ },
+
+ /**
+ Destroys the container instance
+ @method destroy()
+ **/
+ destroy: function() {
+ this.call('destroy');
+ }
+
};
-
+
//jQuery plugin definition
$.fn.editableContainer = function (option) {
var args = arguments;
return this.each(function () {
var $this = $(this),
- dataKey = 'editableContainer',
- data = $this.data(dataKey),
- options = typeof option === 'object' && option;
+ dataKey = 'editableContainer',
+ data = $this.data(dataKey),
+ options = typeof option === 'object' && option;
if (!data) {
$this.data(dataKey, (data = new EditableContainer(this, options)));
}
-
+
if (typeof option === 'string') { //call method
data[option].apply(data, Array.prototype.slice.call(args, 1));
}
});
};
-
+
//store constructor
$.fn.editableContainer.Constructor = EditableContainer;
-
+
//defaults - must be redefined!
$.fn.editableContainer.defaults = {
- trigger: 'manual',
- value: null,
- placement: 'top',
- autohide: true
+ /**
+ Initial value of form input
+
+ @property value
+ @type mixed
+ @default null
+ **/
+ value: null,
+ /**
+ Placement of container relative to element. Can be top|right|bottom|left. Not used for inline container.
+
+ @property placement
+ @type string
+ @default 'top'
+ **/
+ placement: 'top',
+ /**
+ Wether to hide container on save/cancel.
+
+ @property autohide
+ @type boolean
+ @default true
+ **/
+ autohide: true
};
-
+
/*
* workaround to have 'destroyed' event to destroy popover when element is destroyed
* see http://stackoverflow.com/questions/2200494/jquery-trigger-event-when-an-element-is-removed-from-the-dom
@@ -149,5 +199,5 @@
}
}
};
-
+
}(window.jQuery));
\ No newline at end of file
diff --git a/src/containers/editable-popover.js b/src/containers/editable-popover.js
index 6bf22fc..db071ad 100644
--- a/src/containers/editable-popover.js
+++ b/src/containers/editable-popover.js
@@ -6,6 +6,11 @@
(function ($) {
//extend methods
+ /**
+ Container based on Bootstrap Popover
+
+ @class editableContainer (popover)
+ **/
$.extend($.fn.editableContainer.Constructor.prototype, {
containerName: 'popover',
innerCss: '.popover-content p',
diff --git a/src/containers/editable-tooltip.js b/src/containers/editable-tooltip.js
index d2d65dc..7596367 100644
--- a/src/containers/editable-tooltip.js
+++ b/src/containers/editable-tooltip.js
@@ -6,6 +6,11 @@
(function ($) {
//extend methods
+ /**
+ Container based on jQuery UI Tooltip
+
+ @class editableContainer (tooltip)
+ **/
$.extend($.fn.editableContainer.Constructor.prototype, {
containerName: 'tooltip',
innerCss: '.ui-tooltip-content',
diff --git a/src/editable-form/editable-form-bootstrap.js b/src/editable-form/editable-form-bootstrap.js
index 11cea04..8fe22a2 100644
--- a/src/editable-form/editable-form-bootstrap.js
+++ b/src/editable-form/editable-form-bootstrap.js
@@ -1,6 +1,10 @@
/**
-* Editable-form Bootstrap engine
-*/
+Editableform based on Twitter Bootstrap
+
+@class editableform (bootstrap)
+@module editableform
+@uses editableform
+**/
(function ($) {
//form template
diff --git a/src/editable-form/editable-form-jqueryui.js b/src/editable-form/editable-form-jqueryui.js
index 8e76b96..1d2585d 100644
--- a/src/editable-form/editable-form-jqueryui.js
+++ b/src/editable-form/editable-form-jqueryui.js
@@ -1,6 +1,10 @@
/**
-* Editable-form jQuery UI engine
-*/
+Editableform based on jQuery UI
+
+@class editableform (jqueryui)
+@module editableform
+@uses editableform
+**/
(function ($) {
$.extend($.fn.editableform.Constructor.prototype, {
diff --git a/src/editable-form/editable-form.js b/src/editable-form/editable-form.js
index fe00806..e9f0bfe 100644
--- a/src/editable-form/editable-form.js
+++ b/src/editable-form/editable-form.js
@@ -1,21 +1,12 @@
/**
-* Editable-form plugin
-* Form with single input element, two buttons and automatic loader, shown on init/submit
-* Plugin applied to DIV tag and show form inside
-* Input must be one of following types:
-* - text
-* - textarea
-* - select
-* - date
-* -
-*
-* EVENTS:
-* - render
-* - resize
-* - save
-*/
-(function ($) {
+Form with single input element, two buttons and two states: normal/loading.
+Applied as jQuery method to DIV tag (not to form tag!)
+Editableform is linked with one of input types, e.g. 'text' or 'select'.
+@class editableform
+**/
+(function ($) {
+
var EditableForm = function (element, options) {
this.options = $.extend({}, $.fn.editableform.defaults, options);
this.$container = $(element); //div, containing form
@@ -42,6 +33,11 @@
initTemplate: function() {
this.$form = $($.fn.editableform.template);
},
+ /**
+ Renders editableform
+
+ @method render
+ **/
render: function() {
this.$loading = $(this.options.loading);
this.$container.empty().append(this.$loading);
@@ -49,6 +45,11 @@
this.initTemplate();
+ /**
+ Fired when rendering starts
+ @event rendering
+ @param {Object} event event object
+ **/
this.$container.triggerHandler('rendering');
//render input
@@ -72,6 +73,11 @@
}, this));
},
cancel: function() {
+ /**
+ Fired when form was cancelled by user
+ @event cancel
+ @param {Object} event event object
+ **/
this.$container.triggerHandler('cancel');
},
showLoading: function() {
@@ -96,7 +102,12 @@
showForm: function() {
this.$loading.hide();
this.$form.show();
- this.input.activate();
+ this.input.activate();
+ /**
+ Fired when form is shown
+ @event show
+ @param {Object} event event object
+ **/
this.$container.triggerHandler('show');
},
@@ -145,6 +156,19 @@
.done($.proxy(function(response) {
this.error(false);
this.value = newValue;
+ /**
+ Fired when form is submitted
+ @event save
+ @param {Object} event event object
+ @param {Object} params additional params
+ @param {mixed} params.newValue submitted value
+ @param {Object} params.response ajax response
+
+ @example
+ $('#form-div').on('save'), function(e, params){
+ if(params.newValue === 'username') {...}
+ });
+ **/
this.$container.triggerHandler('save', {newValue: newValue, response: response});
}, this))
.fail($.proxy(function(xhr) {
@@ -194,7 +218,22 @@
}
};
- //jquery plugin definition
+ /*
+ Initialize editableform. Applied to jQuery object.
+
+ @method $().editableform(options)
+ @params {Object} options
+ @example
+ var $form = $('<div>').editableform({
+ type: 'text',
+ name: 'username',
+ url: 'post.php',
+ value: 'vitaliy'
+ });
+
+ //to display form you should call 'render' method
+ $form.editableform('render');
+ */
$.fn.editableform = function (option) {
var args = arguments;
return this.each(function () {
@@ -217,14 +256,86 @@
//defaults
$.fn.editableform.defaults = {
/* see also defaults for input */
+
+ /**
+ Type of input. Can be text|textarea|select|date
+
+ @property type
+ @type String
+ @default 'text'
+ **/
type: 'text',
+ /**
+ Url for submit
+
+ @property url
+ @type String|Object|Array
+ @default null
+ **/
url:null,
+ /**
+ Additional params for submit
+
+ @property params
+ @type Object
+ @default null
+ **/
params:null,
+ /**
+ Name of field. Will be submitted on server. Can be taken from id attribute.
+
+ @property name
+ @type String
+ @default null
+ **/
name: null,
+ /**
+ Primary key of editable object (e.g. record id in database). Use Object for composite keys.
+
+ @property pk
+ @type String|Object|Function
+ @default null
+ **/
pk: null,
- value: null, //initial value
- send: 'auto', //always|auto|never
+ /**
+ Initial value. If not defined - will be taken from element's content.
+ For select type should be defined (as it is ID of shown text).
+
+ @property value
+ @type String|Object
+ @default null
+ **/
+ value: null,
+ /**
+ Strategy for sending data on server. Can be auto|always|never.
+ When 'auto' data will be sent on server only if pk defined, otherwise new value will be stored in element.
+
+ @property send
+ @type String
+ @default 'auto'
+ **/
+ send: 'auto',
+ /**
+ Template for loading element
+
+ @property loading
+ @type String
+ @default
+ **/
loading: '',
+ /**
+ Function for client-side validation. If returns string - means validation not passed and string showed as error.
+
+ @property validate
+ @type Function
+ @default null
+ @example
+ validate: function(value) {
+ if($.trim(value) == '') {
+ return 'This field is required';
+ }
+ }
+ **/
validate: null
};
diff --git a/src/element/editable-element.js b/src/element/editable-element.js
index 038c69a..905d28a 100644
--- a/src/element/editable-element.js
+++ b/src/element/editable-element.js
@@ -1,11 +1,9 @@
/**
-* Editable-element
-* Initialize HTML element that can be editable by click.
-* 1. methods
-*
-* 2. events
-* - render
-*/
+Makes editable any HTML element on page.
+Applied as jquery method.
+
+@class editable
+**/
(function ($) {
var Editable = function (element, options) {
@@ -27,7 +25,7 @@
//editableContainer must be defined
if(!$.fn.editableContainer) {
- $.error('You must define $.fn.editableContainer via including corresponding file (e.g. editablePopover)');
+ $.error('You must define $.fn.editableContainer via including corresponding file (e.g. editable-popover.js)');
return;
}
@@ -89,11 +87,28 @@
} else {
this.enable();
}
+ /**
+ Fired each time when element's text is rendered. Occurs on initialization and on each update of value.
+ Can be used for customizing display of value.
+
+ @event render
+ @param {Object} event event object
+ @param {Object} editable editable instance
+ @example
+ $('#action').on('render', function(e, editable) {
+ var colors = {0: "gray", 1: "green", 2: "blue", 3: "red"};
+ $(this).css("color", colors[editable.value]);
+ });
+ **/
this.$element.triggerHandler('render', this);
this.isInit = false;
}, this));
},
+ /**
+ Enables editable
+ @method enable()
+ **/
enable: function() {
this.options.disabled = false;
this.$element.removeClass('editable-disabled');
@@ -106,6 +121,10 @@
}
},
+ /**
+ Disables editable
+ @method disable()
+ **/
disable: function() {
this.options.disabled = true;
this.hide();
@@ -117,6 +136,10 @@
}
},
+ /**
+ Toggles enabled / disabled state of editable element
+ @method toggleDisabled()
+ **/
toggleDisabled: function() {
if(this.options.disabled) {
this.enable();
@@ -125,6 +148,13 @@
}
},
+ /**
+ Sets new option
+
+ @method option(key, value)
+ @param {string} key
+ @param {mixed} value
+ **/
option: function(key, value) {
if(key === 'disabled') {
if(value) {
@@ -143,7 +173,7 @@
}
},
- /**
+ /*
* set emptytext if element is empty (reverse: remove emptytext if needed)
*/
handleEmpty: function () {
@@ -175,8 +205,9 @@
},
/**
- * show container with form
- */
+ Shows container with form
+ @method show()
+ **/
show: function () {
if(this.options.disabled) {
return;
@@ -206,8 +237,9 @@
},
/**
- * hide container with form
- */
+ Hides container with form
+ @method hide()
+ **/
hide: function () {
if(this.container && this.container.tip().is(':visible')) {
this.container.hide();
@@ -220,8 +252,9 @@
},
/**
- * show/hide form container
- */
+ Toggles container visibility (show / hide)
+ @method toggle()
+ **/
toggle: function () {
if(this.container && this.container.tip().is(':visible')) {
this.hide();
@@ -230,7 +263,7 @@
}
},
- /**
+ /*
* called when form was submitted
*/
save: function(e, params) {
@@ -261,6 +294,12 @@
}
},
+ /**
+ Sets new value of editable
+ @method setValue(v, convertStr)
+ @param {mixed} v new value
+ @param {boolean} convertStr wether to convert value from string to internal format
+ **/
setValue: function(v, convertStr) {
if(convertStr) {
this.value = this.input.str2value(v);
@@ -281,10 +320,35 @@
/* EDITABLE PLUGIN DEFINITION
* ======================= */
+ /**
+ jQuery method to initialize editable element.
+
+ @method $().editable(options)
+ @params {Object} options
+ @example
+ $('#username').editable({
+ type: 'text',
+ url: 'post.php',
+ pk: 1
+ });
+ **/
$.fn.editable = function (option) {
- //special methods returning non-jquery object
+ //special API methods returning non-jquery object
var result = {}, args = arguments, datakey = 'editable';
switch (option) {
+ /**
+ Runs client-side validation for all editables in jquery array
+
+ @method validate()
+ @returns {Object} validation errors map
+ @example
+ $('#username, #fullname').editable('validate');
+ // possible result:
+ {
+ username: "username is requied",
+ fullname: "fullname should be minimum 3 letters length"
+ }
+ **/
case 'validate':
this.each(function () {
var $this = $(this), data = $this.data(datakey), error;
@@ -294,6 +358,18 @@
});
return result;
+ /**
+ Returns current values of editable elements. If value is null or undefined it will not be returned
+ @method getValue()
+ @returns {Object} object of element names and values
+ @example
+ $('#username, #fullname').editable('validate');
+ // possible result:
+ {
+ username: "superuser",
+ fullname: "John"
+ }
+ **/
case 'getValue':
this.each(function () {
var $this = $(this), data = $this.data(datakey);
@@ -303,6 +379,18 @@
});
return result;
+ /**
+ This method collects values from several editable elements and submit them all to server.
+ It is designed mainly for creating new records.
+
+ @method submit(options)
+ @param {object} options
+ @param {object} options.url url to submit data
+ @param {object} options.data additional data to submit
+ @param {function} options.error error handler (called on both client-side and server-side validation errors)
+ @param {function} options.success success handler
+ @returns {Object} jQuery object
+ **/
case 'submit': //collects value, validate and submit to server for creating new record
var config = arguments[1] || {},
$elems = this,
@@ -360,14 +448,71 @@
$.fn.editable.defaults = {
- type:'text',
+ /**
+ Type of input. Can be text|textarea|select|date
+
+ @property type
+ @type String
+ @default 'text'
+ **/
+ type: 'text',
+ /**
+ Sets disabled state of editable
+
+ @property disabled
+ @type boolean
+ @default false
+ **/
disabled: false,
+ /**
+ How to toggle editable. Can be click|manual.
+
+ @property toggle
+ @type string
+ @default 'click'
+ **/
toggle: 'click',
- trigger: 'manual',
+ /**
+ Text shown when element is empty.
+
+ @property emptytext
+ @type string
+ @default 'Empty'
+ **/
emptytext: 'Empty',
+ /**
+ Allows to automatically set element's text based on it's value. Usefull for select and date.
+ For example, if element's list is {1: 'a', 2: 'b'} value set to 1, it's text will be automatically set to a.
+ Can be auto|always|never. auto means text will be set only if element is empty.
+ always|never means always(never) try to set element's text.
+
+ @property autotext
+ @type string
+ @default 'auto'
+ **/
autotext: 'auto',
+ /**
+ Wether to return focus on element after form is closed.
+ This allows fully keyboard input.
+
+ @property enablefocus
+ @type boolean
+ @default false
+ **/
enablefocus: false,
- success: function(response, newValue) {} //value successfully sent on server and response status = 200
+ /**
+ Success callback. Called when value successfully sent on server and response status = 200.
+ Can be used to process json response. If this function returns string - means error occured and string is shown as error message.
+
+ @property success
+ @type function
+ @default null
+ @example
+ success: function(response, newValue) {
+ if(!response.success) return response.msg;
+ }
+ **/
+ success: function(response, newValue) {}
};
}(window.jQuery));
\ No newline at end of file