diff --git a/jquery.jeditable.js b/jquery.jeditable.js
index 1d066d4..9df4cf3 100644
--- a/jquery.jeditable.js
+++ b/jquery.jeditable.js
@@ -15,52 +15,52 @@
*/
/**
- * Version 1.7.3
- *
- * ** means there is basic unit tests for this parameter.
- *
- * @name Jeditable
- * @type jQuery
- * @param String target (POST) URL or function to send edited content to **
- * @param Hash options additional options
- * @param String options[method] method to use to send edited content (POST or PUT) **
- * @param Function options[callback] Function to run after submitting edited content **
- * @param String options[name] POST parameter name of edited content
- * @param String options[id] POST parameter name of edited div id
- * @param Hash options[submitdata] Extra parameters to send when submitting edited content.
- * @param String options[type] text, textarea or select (or any 3rd party input type) **
- * @param Integer options[rows] number of rows if using textarea **
- * @param Integer options[cols] number of columns if using textarea **
- * @param Mixed options[height] 'auto', 'none' or height in pixels **
- * @param Mixed options[width] 'auto', 'none' or width in pixels **
- * @param String options[loadurl] URL to fetch input content before editing **
- * @param String options[loadtype] Request type for load url. Should be GET or POST.
- * @param String options[loadtext] Text to display while loading external content.
- * @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing.
- * @param Mixed options[data] Or content given as paramameter. String or function.**
- * @param String options[indicator] indicator html to show when saving
- * @param String options[tooltip] optional tooltip text via title attribute **
- * @param String options[event] jQuery event such as 'click' of 'dblclick' **
- * @param String options[submit] submit button value, empty means no button **
- * @param String options[cancel] cancel button value, empty means no button **
- * @param String options[cssclass] CSS class to apply to input form. 'inherit' to copy from parent. **
- * @param String options[style] Style to apply to input form 'inherit' to copy from parent. **
- * @param String options[select] true or false, when true text is highlighted ??
- * @param String options[placeholder] Placeholder text or html to insert when element is empty. **
- * @param String options[onblur] 'cancel', 'submit', 'ignore' or function ??
- *
- * @param Function options[onsubmit] function(settings, original) { ... } called before submit
- * @param Function options[onreset] function(settings, original) { ... } called before reset
- * @param Function options[onerror] function(settings, original, xhr) { ... } called on error
- *
- * @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com.
- *
- */
-
-(function($) {
-
- $.fn.editable = function(target, options) {
-
+ * Version 1.7.3
+ *
+ * ** means there is basic unit tests for this parameter.
+ *
+ * @name Jeditable
+ * @type jQuery
+ * @param String target (POST) URL or function to send edited content to **
+ * @param Hash options additional options
+ * @param String options[method] method to use to send edited content (POST or PUT) **
+ * @param Function options[callback] Function to run after submitting edited content **
+ * @param String options[name] POST parameter name of edited content
+ * @param String options[id] POST parameter name of edited div id
+ * @param Hash options[submitdata] Extra parameters to send when submitting edited content.
+ * @param String options[type] text, textarea or select (or any 3rd party input type) **
+ * @param Integer options[rows] number of rows if using textarea **
+ * @param Integer options[cols] number of columns if using textarea **
+ * @param Mixed options[height] 'auto', 'none' or height in pixels **
+ * @param Mixed options[width] 'auto', 'none' or width in pixels **
+ * @param String options[loadurl] URL to fetch input content before editing **
+ * @param String options[loadtype] Request type for load url. Should be GET or POST.
+ * @param String options[loadtext] Text to display while loading external content.
+ * @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing.
+ * @param Mixed options[data] Or content given as paramameter. String or function.**
+ * @param String options[indicator] indicator html to show when saving
+ * @param String options[tooltip] optional tooltip text via title attribute **
+ * @param String options[event] jQuery event such as 'click' of 'dblclick' **
+ * @param String options[submit] submit button value, empty means no button **
+ * @param String options[cancel] cancel button value, empty means no button **
+ * @param String options[cssclass] CSS class to apply to input form. 'inherit' to copy from parent. **
+ * @param String options[style] Style to apply to input form 'inherit' to copy from parent. **
+ * @param String options[select] true or false, when true text is highlighted ??
+ * @param String options[placeholder] Placeholder text or html to insert when element is empty. **
+ * @param String options[onblur] 'cancel', 'submit', 'ignore' or function ??
+ *
+ * @param Function options[onsubmit] function(settings, original) { ... } called before submit
+ * @param Function options[onreset] function(settings, original) { ... } called before reset
+ * @param Function options[onerror] function(settings, original, xhr) { ... } called on error
+ *
+ * @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com.
+ *
+ */
+
+(function ($) {
+
+ $.fn.editable = function (target, options) {
+
if ('disable' == target) {
$(this).data('disabled.editable', true);
return;
@@ -76,107 +76,113 @@
.removeData('event.editable');
return;
}
-
- var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options);
-
+
+ var settings = $.extend({}, $.fn.editable.defaults, {target: target}, options);
+
/* setup some functions */
- var plugin = $.editable.types[settings.type].plugin || function() { };
- var submit = $.editable.types[settings.type].submit || function() { };
- var buttons = $.editable.types[settings.type].buttons
- || $.editable.types['defaults'].buttons;
- var content = $.editable.types[settings.type].content
- || $.editable.types['defaults'].content;
- var element = $.editable.types[settings.type].element
- || $.editable.types['defaults'].element;
- var reset = $.editable.types[settings.type].reset
- || $.editable.types['defaults'].reset;
- var callback = settings.callback || function() { };
- var onedit = settings.onedit || function() { };
- var onsubmit = settings.onsubmit || function() { };
- var onreset = settings.onreset || function() { };
- var onerror = settings.onerror || reset;
-
+ var plugin = $.editable.types[settings.type].plugin || function () {
+ };
+ var submit = $.editable.types[settings.type].submit || function () {
+ };
+ var buttons = $.editable.types[settings.type].buttons
+ || $.editable.types['defaults'].buttons;
+ var content = $.editable.types[settings.type].content
+ || $.editable.types['defaults'].content;
+ var element = $.editable.types[settings.type].element
+ || $.editable.types['defaults'].element;
+ var reset = $.editable.types[settings.type].reset
+ || $.editable.types['defaults'].reset;
+ var callback = settings.callback || function () {
+ };
+ var onedit = settings.onedit || function () {
+ };
+ var onsubmit = settings.onsubmit || function () {
+ };
+ var onreset = settings.onreset || function () {
+ };
+ var onerror = settings.onerror || reset;
+
/* Show tooltip. */
if (settings.tooltip) {
$(this).attr('title', settings.tooltip);
}
-
- settings.autowidth = 'auto' == settings.width;
+
+ settings.autowidth = 'auto' == settings.width;
settings.autoheight = 'auto' == settings.height;
-
- return this.each(function() {
-
+
+ return this.each(function () {
+
/* Save this to self because this changes when scope changes. */
- var self = this;
-
+ var self = this;
+
/* Inlined block elements lose their width and height after first edit. */
/* Save them for later use as workaround. */
- var savedwidth = $(self).width();
+ var savedwidth = $(self).width();
var savedheight = $(self).height();
/* Save so it can be later used by $.editable('destroy') */
$(this).data('event.editable', settings.event);
-
+
/* If element is empty add something clickable (if requested) */
if (!$.trim($(this).html())) {
$(this).html(settings.placeholder);
}
-
- $(this).bind(settings.event, function(e) {
-
+
+ $(this).bind(settings.event, function (e) {
+
/* Abort if element is disabled. */
if (true === $(this).data('disabled.editable')) {
return;
}
-
+
/* Prevent throwing an exeption if edit field is clicked again. */
if (self.editing) {
return;
}
-
+
/* Abort if onedit hook returns false. */
if (false === onedit.apply(this, [settings, self])) {
- return;
+ return;
}
-
+
/* Prevent default action and bubbling. */
e.preventDefault();
e.stopPropagation();
-
+
/* Remove tooltip. */
if (settings.tooltip) {
$(self).removeAttr('title');
}
-
+
/* Figure out how wide and tall we are, saved width and height. */
/* Workaround for http://dev.jquery.com/ticket/2190 */
if (0 == $(self).width()) {
- settings.width = savedwidth;
+ settings.width = savedwidth;
settings.height = savedheight;
} else {
if (settings.width != 'none') {
- settings.width =
- settings.autowidth ? $(self).width() : settings.width;
+ settings.width =
+ settings.autowidth ? $(self).width() : settings.width;
}
if (settings.height != 'none') {
- settings.height =
+ settings.height =
settings.autoheight ? $(self).height() : settings.height;
}
}
-
+
/* Remove placeholder text, replace is here because of IE. */
- if ($(this).html().toLowerCase().replace(/(;|"|\/)/g, '') ==
+ if ($(this).html().toLowerCase().replace(/(;|"|\/)/g, '') ==
settings.placeholder.toLowerCase().replace(/(;|"|\/)/g, '')) {
- $(this).html('');
+ $(this).html('');
}
-
- self.editing = true;
- self.revert = $(self).html();
+
+ self.editing = true;
+ self.revert = $(self).html();
$(self).html('');
/* Create the form object. */
var form = $('
');
-
+
/* Apply css or style or both. */
if (settings.cssclass) {
if ('inherit' == settings.cssclass) {
@@ -190,7 +196,7 @@
if ('inherit' == settings.style) {
form.attr('style', $(self).attr('style'));
/* IE needs the second line or display wont be inherited. */
- form.css('display', $(self).css('display'));
+ form.css('display', $(self).css('display'));
} else {
form.attr('style', settings.style);
}
@@ -201,11 +207,11 @@
/* Set input content via POST, GET, given data or existing value. */
var input_content;
-
+
if (settings.loadurl) {
- var t = setTimeout(function() {
+ var t = setTimeout(function () {
input.disabled = true;
- content.apply(form, [settings.loadtext, settings, self]);
+ $(self).append('
' + settings.indicator + '
');
}, 100);
var loaddata = {};
@@ -216,180 +222,196 @@
$.extend(loaddata, settings.loaddata);
}
$.ajax({
- type : settings.loadtype,
- url : settings.loadurl,
- data : loaddata,
- async : false,
- success: function(result) {
- window.clearTimeout(t);
- input_content = result;
- input.disabled = false;
- }
+ type: settings.loadtype,
+ url: settings.loadurl,
+ data: loaddata,
+
+ success: function (result) {
+ window.clearTimeout(t);
+ $('.indicator', self).remove();
+
+ input_content = result;
+ input.disabled = false;
+ console.log(result);
+
+ content.apply(form, [input_content, settings, self]);
+ _post_init();
+ }
});
- } else if (settings.data) {
- input_content = settings.data;
- if ($.isFunction(settings.data)) {
- input_content = settings.data.apply(self, [self.revert, settings]);
- }
} else {
- input_content = self.revert;
- }
- content.apply(form, [input_content, settings, self]);
-
- input.attr('name', settings.name);
-
- /* Add buttons to the form. */
- buttons.apply(form, [settings, self]);
-
- /* Add created form to self. */
- $(self).append(form);
-
- /* Attach 3rd party plugin if requested. */
- plugin.apply(form, [settings, self]);
-
- /* Focus to first visible form element. */
- $(':input:visible:enabled:first', form).focus();
-
- /* Highlight input contents when requested. */
- if (settings.select) {
- input.select();
+ if (settings.data) {
+ input_content = settings.data;
+ if ($.isFunction(settings.data)) {
+ input_content = settings.data.apply(self, [self.revert, settings]);
+ }
+ } else {
+ input_content = self.revert;
+ }
+
+ content.apply(form, [input_content, settings, self]);
+ _post_init()
+
+
}
-
- /* discard changes if pressing esc */
- input.keydown(function(e) {
- if (e.keyCode == 27) {
- e.preventDefault();
- reset.apply(form, [settings, self]);
+
+ function _post_init() {
+
+ input.attr('name', settings.name);
+
+ /* Add buttons to the form. */
+ buttons.apply(form, [settings, self]);
+
+ /* Add created form to self. */
+ $(self).append(form);
+
+ /* Attach 3rd party plugin if requested. */
+ plugin.apply(form, [settings, self]);
+
+ /* Focus to first visible form element. */
+ $(':input:visible:enabled:first', form).focus();
+
+ /* Highlight input contents when requested. */
+ if (settings.select) {
+ input.select();
}
- });
-
- /* Discard, submit or nothing with changes when clicking outside. */
- /* Do nothing is usable when navigating with tab. */
- var t;
- if ('cancel' == settings.onblur) {
- input.blur(function(e) {
- /* Prevent canceling if submit was clicked. */
- t = setTimeout(function() {
+
+ /* discard changes if pressing esc */
+ input.keydown(function (e) {
+ if (e.keyCode == 27) {
+ e.preventDefault();
reset.apply(form, [settings, self]);
- }, 500);
- });
- } else if ('submit' == settings.onblur) {
- input.blur(function(e) {
- /* Prevent double submit if submit was clicked. */
- t = setTimeout(function() {
- form.submit();
- }, 200);
- });
- } else if ($.isFunction(settings.onblur)) {
- input.blur(function(e) {
- settings.onblur.apply(self, [input.val(), settings]);
- });
- } else {
- input.blur(function(e) {
- /* TODO: maybe something here */
+ }
});
- }
-
- form.submit(function(e) {
- if (t) {
- clearTimeout(t);
+ /* Discard, submit or nothing with changes when clicking outside. */
+ /* Do nothing is usable when navigating with tab. */
+ var t;
+ if ('cancel' == settings.onblur) {
+ input.blur(function (e) {
+ /* Prevent canceling if submit was clicked. */
+ t = setTimeout(function () {
+ reset.apply(form, [settings, self]);
+ }, 500);
+ });
+ } else if ('submit' == settings.onblur) {
+ input.blur(function (e) {
+ /* Prevent double submit if submit was clicked. */
+ t = setTimeout(function () {
+ form.submit();
+ }, 200);
+ });
+ } else if ($.isFunction(settings.onblur)) {
+ input.blur(function (e) {
+ settings.onblur.apply(self, [input.val(), settings]);
+ });
+ } else {
+ input.blur(function (e) {
+ /* TODO: maybe something here */
+ });
}
+ form.submit(function (e) {
+
+ if (t) {
+ clearTimeout(t);
+ }
- /* Do no submit. */
- e.preventDefault();
-
- /* Call before submit hook. */
- /* If it returns false abort submitting. */
- if (false !== onsubmit.apply(form, [settings, self])) {
- /* Custom inputs call before submit hook. */
+ /* Do no submit. */
+ e.preventDefault();
+
+ /* Call before submit hook. */
/* If it returns false abort submitting. */
- if (false !== submit.apply(form, [settings, self])) {
-
- /* Check if given target is function */
- if ($.isFunction(settings.target)) {
- var str = settings.target.apply(self, [input.val(), settings]);
- $(self).html(str);
- self.editing = false;
- callback.apply(self, [self.innerHTML, settings]);
- /* TODO: this is not dry */
- if (!$.trim($(self).html())) {
- $(self).html(settings.placeholder);
- }
- } else {
- /* Add edited content and id of edited element to POST. */
- var submitdata = {};
- submitdata[settings.name] = input.val();
- submitdata[settings.id] = self.id;
- /* Add extra data to be POST:ed. */
- if ($.isFunction(settings.submitdata)) {
- $.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
- } else {
- $.extend(submitdata, settings.submitdata);
- }
-
- /* Quick and dirty PUT support. */
- if ('PUT' == settings.method) {
- submitdata['_method'] = 'put';
- }
-
- /* Show the saving indicator. */
- $(self).html(settings.indicator);
-
- /* Defaults for ajaxoptions. */
- var ajaxoptions = {
- type : 'POST',
- data : submitdata,
- dataType: 'html',
- url : settings.target,
- success : function(result, status) {
- if (ajaxoptions.dataType == 'html') {
- $(self).html(result);
- }
- self.editing = false;
- callback.apply(self, [result, settings]);
- if (!$.trim($(self).html())) {
- $(self).html(settings.placeholder);
- }
- },
- error : function(xhr, status, error) {
- onerror.apply(form, [settings, self, xhr]);
- }
- };
-
- /* Override with what is given in settings.ajaxoptions. */
- $.extend(ajaxoptions, settings.ajaxoptions);
- $.ajax(ajaxoptions);
-
+ if (false !== onsubmit.apply(form, [settings, self])) {
+ /* Custom inputs call before submit hook. */
+ /* If it returns false abort submitting. */
+ if (false !== submit.apply(form, [settings, self])) {
+
+ /* Check if given target is function */
+ if ($.isFunction(settings.target)) {
+ var str = settings.target.apply(self, [input.val(), settings]);
+ $(self).html(str);
+ self.editing = false;
+ callback.apply(self, [self.innerHTML, settings]);
+ /* TODO: this is not dry */
+ if (!$.trim($(self).html())) {
+ $(self).html(settings.placeholder);
+ }
+ } else {
+ /* Add edited content and id of edited element to POST. */
+ var submitdata = {};
+ submitdata[settings.name] = input.val();
+ submitdata[settings.id] = self.id;
+ /* Add extra data to be POST:ed. */
+ if ($.isFunction(settings.submitdata)) {
+ $.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
+ } else {
+ $.extend(submitdata, settings.submitdata);
+ }
+
+ /* Quick and dirty PUT support. */
+ if ('PUT' == settings.method) {
+ submitdata['_method'] = 'put';
+ }
+
+ /* Show the saving indicator. */
+ $(self).html(settings.indicator);
+
+ /* Defaults for ajaxoptions. */
+ var ajaxoptions = {
+ type: 'POST',
+ data: submitdata,
+ dataType: 'html',
+ url: settings.target,
+ success: function (result, status) {
+ if (ajaxoptions.dataType == 'html') {
+ $(self).html(result);
+ }
+ self.editing = false;
+ callback.apply(self, [result, settings]);
+ if (!$.trim($(self).html())) {
+ $(self).html(settings.placeholder);
+ }
+ },
+ error: function (xhr, status, error) {
+ onerror.apply(form, [settings, self, xhr]);
+ }
+ };
+
+ /* Override with what is given in settings.ajaxoptions. */
+ $.extend(ajaxoptions, settings.ajaxoptions);
+ $.ajax(ajaxoptions);
+
+ }
}
}
- }
-
- /* Show tooltip again. */
- $(self).attr('title', settings.tooltip);
-
- return false;
- });
+
+ /* Show tooltip again. */
+ $(self).attr('title', settings.tooltip);
+
+ return false;
+ });
+ }
+
+
});
-
+
/* Privileged methods */
- this.reset = function(form) {
+ this.reset = function (form) {
/* Prevent calling reset twice when blurring. */
if (this.editing) {
/* Before reset hook, if it returns false abort reseting. */
- if (false !== onreset.apply(form, [settings, self])) {
+ if (false !== onreset.apply(form, [settings, self])) {
$(self).html(self.revert);
- self.editing = false;
+ self.editing = false;
if (!$.trim($(self).html())) {
$(self).html(settings.placeholder);
}
/* Show tooltip again. */
if (settings.tooltip) {
- $(self).attr('title', settings.tooltip);
+ $(self).attr('title', settings.tooltip);
}
- }
+ }
}
- };
+ };
});
};
@@ -398,31 +420,31 @@
$.editable = {
types: {
defaults: {
- element : function(settings, original) {
- var input = $('');
+ element: function (settings, original) {
+ var input = $('');
$(this).append(input);
return(input);
},
- content : function(string, settings, original) {
+ content: function (string, settings, original) {
$(':input:first', this).val(string);
},
- reset : function(settings, original) {
- original.reset(this);
+ reset: function (settings, original) {
+ original.reset(this);
},
- buttons : function(settings, original) {
+ buttons: function (settings, original) {
var form = this;
if (settings.submit) {
/* If given html string use that. */
if (settings.submit.match(/>$/)) {
- var submit = $(settings.submit).click(function() {
+ var submit = $(settings.submit).click(function () {
if (submit.attr("type") != "submit") {
form.submit();
}
});
- /* Otherwise use button with given string as text. */
+ /* Otherwise use button with given string as text. */
} else {
var submit = $('');
- submit.html(settings.submit);
+ submit.html(settings.submit);
}
$(this).append(submit);
}
@@ -430,18 +452,18 @@
/* If given html string use that. */
if (settings.cancel.match(/>$/)) {
var cancel = $(settings.cancel);
- /* otherwise use button with given string as text */
+ /* otherwise use button with given string as text */
} else {
var cancel = $('');
cancel.html(settings.cancel);
}
$(this).append(cancel);
- $(cancel).click(function(event) {
+ $(cancel).click(function (event) {
if ($.isFunction($.editable.types[settings.type].reset)) {
- var reset = $.editable.types[settings.type].reset;
+ var reset = $.editable.types[settings.type].reset;
} else {
- var reset = $.editable.types['defaults'].reset;
+ var reset = $.editable.types['defaults'].reset;
}
reset.apply(form, [settings, original]);
return false;
@@ -450,19 +472,23 @@
}
},
text: {
- element : function(settings, original) {
+ element: function (settings, original) {
var input = $('');
- if (settings.width != 'none') { input.attr('width', settings.width); }
- if (settings.height != 'none') { input.attr('height', settings.height); }
+ if (settings.width != 'none') {
+ input.attr('width', settings.width);
+ }
+ if (settings.height != 'none') {
+ input.attr('height', settings.height);
+ }
/* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
//input[0].setAttribute('autocomplete','off');
- input.attr('autocomplete','off');
+ input.attr('autocomplete', 'off');
$(this).append(input);
return(input);
}
},
textarea: {
- element : function(settings, original) {
+ element: function (settings, original) {
var textarea = $('');
if (settings.rows) {
textarea.attr('rows', settings.rows);
@@ -479,17 +505,18 @@
}
},
select: {
- element : function(settings, original) {
+ element: function (settings, original) {
var select = $('');
$(this).append(select);
return(select);
},
- content : function(data, settings, original) {
+ content: function (data, settings, original) {
/* If it is string assume it is json. */
- if (String == data.constructor) {
- eval ('var json = ' + data);
+ if (String == data.constructor) {
+ eval('var json = ' + data);
+
} else {
- /* Otherwise assume it is a hash already. */
+ /* Otherwise assume it is a hash already. */
var json = data;
}
for (var key in json) {
@@ -498,21 +525,24 @@
}
if ('selected' == key) {
continue;
- }
+ }
+ console.log(key, json[key]);
var option = $('').val(key).append(json[key]);
- $('select', this).append(option);
- }
- /* Loop option again to set selected. IE needed this... */
- $('select', this).children().each(function() {
- if ($(this).val() == json['selected'] ||
+
+ $('select', this).append(option);
+
+ }
+ /* Loop option again to set selected. IE needed this... */
+ $('select', this).children().each(function () {
+ if ($(this).val() == json['selected'] ||
$(this).text() == $.trim(original.revert)) {
- $(this).attr('selected', 'selected');
+ $(this).attr('selected', 'selected');
}
});
/* Submit on change if no submit button defined. */
if (!settings.submit) {
var form = this;
- $('select', this).change(function() {
+ $('select', this).change(function () {
form.submit();
});
}
@@ -521,25 +551,25 @@
},
/* Add new input type */
- addInputType: function(name, input) {
+ addInputType: function (name, input) {
$.editable.types[name] = input;
}
};
/* Publicly accessible defaults. */
$.fn.editable.defaults = {
- name : 'value',
- id : 'id',
- type : 'text',
- width : 'auto',
- height : 'auto',
- event : 'click.editable',
- onblur : 'cancel',
- loadtype : 'GET',
- loadtext : 'Loading...',
+ name: 'value',
+ id: 'id',
+ type: 'text',
+ width: 'auto',
+ height: 'auto',
+ event: 'click.editable',
+ onblur: 'cancel',
+ loadtype: 'GET',
+ loadtext: 'Loading...',
placeholder: 'Click to edit',
- loaddata : {},
- submitdata : {},
+ loaddata: {},
+ submitdata: {},
ajaxoptions: {}
};