dev build 1.4.6

This commit is contained in:
vitalets 2013-08-07 11:26:03 +04:00
parent 0e7fea42d7
commit d27e43c0cf
12 changed files with 412 additions and 42 deletions

7
dist/CHANGELOG.txt vendored

@ -3,6 +3,13 @@ X-editable changelog
Version 1.4.6 wip Version 1.4.6 wip
---------------------------- ----------------------------
[bug #312] can't apply selector more than once (vitalets)
[enh #48] textarea: use `white-space: pre-wrap` instead of nl2br conversion (vitalets)
[enh #286] added HTML5 time input (Doggie52)
[enh] add `defaultValue` option (vitalets)
[enh #313] add composer support (masim)
[enh #300] Fix 'bootstrap popover falls off page if editable is too close to window edge' (belerweb)
[enh #302] allow data-datepicker and data-datetimepicker (vitalets)
[enh #287] add option to disable item in select (vitalets) [enh #287] add option to disable item in select (vitalets)
[enh #281] add collision flag to adjust tooltip position (vitalets) [enh #281] add collision flag to adjust tooltip position (vitalets)
[bug #279] fix jQuery UI tooltip z-index to be less than select2 dropdown (vitalets) [bug #279] fix jQuery UI tooltip z-index to be less than select2 dropdown (vitalets)

2
dist/README.md vendored

@ -27,7 +27,7 @@ bower install x-editable
## Reporting issues ## Reporting issues
When creating issues please provide [jsFiddle](http://jsfiddle.net) example. You can easily fork one of following: When creating issues please provide [jsFiddle](http://jsfiddle.net) example. You can easily fork one of following:
1. [jsFiddle bootstrap template](http://jsfiddle.net/xBB5x/195) 1. [jsFiddle bootstrap template](http://jsfiddle.net/xBB5x/1817)
2. [jsFiddle jqueryui template](http://jsfiddle.net/xBB5x/196) 2. [jsFiddle jqueryui template](http://jsfiddle.net/xBB5x/196)
3. [jsFiddle jquery template](http://jsfiddle.net/xBB5x/197) 3. [jsFiddle jquery template](http://jsfiddle.net/xBB5x/197)
Your feedback is very appreciated! Your feedback is very appreciated!

@ -134,6 +134,10 @@
.editable-clear-x:hover { .editable-clear-x:hover {
opacity: 1; opacity: 1;
} }
.editable-pre-wrapped {
white-space: pre-wrap;
}
.editable-container.editable-popup { .editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */ max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
} }

@ -107,7 +107,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
this.error(false); this.error(false);
this.input.$input.removeAttr('disabled'); this.input.$input.removeAttr('disabled');
this.$form.find('.editable-submit').removeAttr('disabled'); this.$form.find('.editable-submit').removeAttr('disabled');
this.input.value2input(this.value); var value = (this.value === null || this.value === undefined || this.value === '') ? this.options.defaultValue : this.value;
this.input.value2input(value);
//attach submit handler //attach submit handler
this.$form.submit($.proxy(this.submit, this)); this.$form.submit($.proxy(this.submit, this));
} }
@ -482,8 +483,17 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
**/ **/
value: null, value: null,
/** /**
Strategy for sending data on server. Can be <code>auto|always|never</code>. Value that will be displayed in input if original field value is empty (`null|undefined|''`).
When 'auto' data will be sent on server only if pk defined, otherwise new value will be stored in element.
@property defaultValue
@type string|object
@default null
@since 1.4.6
**/
defaultValue: null,
/**
Strategy for sending data on server. Can be `auto|always|never`.
When 'auto' data will be sent on server **only if pk and url defined**, otherwise new value will be stored locally.
@property send @property send
@type string @type string
@ -772,7 +782,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
result.push(o); result.push(o);
} }
} else { } else {
if(value == (o && typeof o === 'object' ? valueProp(o) : o)) { var itemValue = (o && (typeof o === 'object')) ? valueProp(o) : o;
if(value == itemValue) {
result.push(o); result.push(o);
} }
} }
@ -1483,6 +1494,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//add 'editable' class to every editable element //add 'editable' class to every editable element
this.$element.addClass('editable'); this.$element.addClass('editable');
//specifically for "textarea" add class .editable-pre-wrapped to keep linebreaks
if(this.input.type === 'textarea') {
this.$element.addClass('editable-pre-wrapped');
}
//attach handler activating editable. In disabled mode it just prevent default action (useful for links) //attach handler activating editable. In disabled mode it just prevent default action (useful for links)
if(this.options.toggle !== 'manual') { if(this.options.toggle !== 'manual') {
this.$element.addClass('editable-click'); this.$element.addClass('editable-click');
@ -2038,6 +2054,14 @@ Makes editable any HTML element on the page. Applied as jQuery method.
data = $this.data(datakey), data = $this.data(datakey),
options = typeof option === 'object' && option; options = typeof option === 'object' && option;
//for delegated targets do not store `editable` object for element
//it's allows several different selectors.
//see: https://github.com/vitalets/x-editable/issues/312
if(options && options.selector) {
data = new Editable(this, options);
return;
}
if (!data) { if (!data) {
$this.data(datakey, (data = new Editable(this, options))); $this.data(datakey, (data = new Editable(this, options)));
} }
@ -2926,7 +2950,9 @@ $(function(){
}); });
}, },
value2html: function(value, element) { //using `white-space: pre-wrap` solves \n <--> BR conversion very elegant!
/*
value2html: function(value, element) {
var html = '', lines; var html = '', lines;
if(value) { if(value) {
lines = value.split("\n"); lines = value.split("\n");
@ -2956,7 +2982,7 @@ $(function(){
} }
return lines.join("\n"); return lines.join("\n");
}, },
*/
activate: function() { activate: function() {
$.fn.editabletypes.text.prototype.activate.call(this); $.fn.editabletypes.text.prototype.activate.call(this);
} }
@ -3254,6 +3280,7 @@ Following types are supported:
* tel * tel
* number * number
* range * range
* time
Learn more about html5 inputs: Learn more about html5 inputs:
http://www.w3.org/wiki/HTML5_form_additions http://www.w3.org/wiki/HTML5_form_additions
@ -3439,6 +3466,29 @@ Range (inherit from number)
}); });
$.fn.editabletypes.range = Range; $.fn.editabletypes.range = Range;
}(window.jQuery)); }(window.jQuery));
/*
Time
*/
(function ($) {
"use strict";
var Time = function (options) {
this.init('time', options, Time.defaults);
};
//inherit from abstract, as inheritance from text gives selection error.
$.fn.editableutils.inherit(Time, $.fn.editabletypes.abstractinput);
$.extend(Time.prototype, {
render: function() {
this.setClass();
}
});
Time.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
tpl: '<input type="time">'
});
$.fn.editabletypes.time = Time;
}(window.jQuery));
/** /**
Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2. Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options. Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options.
@ -3466,6 +3516,7 @@ You need initially put both `data-value` and element's text youself:
<a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a> <a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a>
<script> <script>
$(function(){ $(function(){
//local source
$('#country').editable({ $('#country').editable({
source: [ source: [
{id: 'gb', text: 'Great Britain'}, {id: 'gb', text: 'Great Britain'},
@ -3476,6 +3527,42 @@ $(function(){
multiple: true multiple: true
} }
}); });
//remote source (simple)
$('#country').editable({
source: '/getCountries'
});
//remote source (advanced)
$('#country').editable({
select2: {
placeholder: 'Select Country',
allowClear: true,
minimumInputLength: 3,
id: function (item) {
return item.CountryId;
},
ajax: {
url: '/getCountries',
dataType: 'json',
data: function (term, page) {
return { query: term };
},
results: function (data, page) {
return { results: data };
}
},
formatResult: function (item) {
return item.CountryName;
},
formatSelection: function (item) {
return item.CountryName;
},
initSelection: function (element, callback) {
return $.get('/getCountryById', { query: element.val() }, function (data) {
callback(data);
});
}
}
});
}); });
</script> </script>
**/ **/
@ -3572,6 +3659,7 @@ $(function(){
if(this.options.select2.tags) { //in tags mode just assign value if(this.options.select2.tags) { //in tags mode just assign value
data = value; data = value;
//data = $.fn.editableutils.itemsByValue(value, this.options.select2.tags, this.idFunc);
} else if(this.sourceData) { } else if(this.sourceData) {
data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc); data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc);
} else { } else {
@ -4460,7 +4548,11 @@ Editableform based on Twitter Bootstrap
, actualWidth , actualWidth
, actualHeight , actualHeight
, placement , placement
, tp; , tp
, tpt
, tpb
, tpl
, tpr;
placement = typeof this.options.placement === 'function' ? placement = typeof this.options.placement === 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement.call(this, $tip[0], this.$element[0]) :
@ -4480,18 +4572,78 @@ Editableform based on Twitter Bootstrap
actualWidth = $tip[0].offsetWidth; actualWidth = $tip[0].offsetWidth;
actualHeight = $tip[0].offsetHeight; actualHeight = $tip[0].offsetHeight;
switch (inside ? placement.split(' ')[1] : placement) { placement = inside ? placement.split(' ')[1] : placement;
tpb = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2};
tpt = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2};
tpl = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth};
tpr = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width};
switch (placement) {
case 'bottom': case 'bottom':
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}; if ((tpb.top + actualHeight) > ($(window).scrollTop() + $(window).height())) {
if (tpt.top > $(window).scrollTop()) {
placement = 'top';
} else if ((tpr.left + actualWidth) < ($(window).scrollLeft() + $(window).width())) {
placement = 'right';
} else if (tpl.left > $(window).scrollLeft()) {
placement = 'left';
} else {
placement = 'right';
}
}
break; break;
case 'top': case 'top':
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}; if (tpt.top < $(window).scrollTop()) {
if ((tpb.top + actualHeight) < ($(window).scrollTop() + $(window).height())) {
placement = 'bottom';
} else if ((tpr.left + actualWidth) < ($(window).scrollLeft() + $(window).width())) {
placement = 'right';
} else if (tpl.left > $(window).scrollLeft()) {
placement = 'left';
} else {
placement = 'right';
}
}
break; break;
case 'left': case 'left':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}; if (tpl.left < $(window).scrollLeft()) {
if ((tpr.left + actualWidth) < ($(window).scrollLeft() + $(window).width())) {
placement = 'right';
} else if (tpt.top > $(window).scrollTop()) {
placement = 'top';
} else if (tpt.top > $(window).scrollTop()) {
placement = 'bottom';
} else {
placement = 'right';
}
}
break; break;
case 'right': case 'right':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}; if ((tpr.left + actualWidth) > ($(window).scrollLeft() + $(window).width())) {
if (tpl.left > $(window).scrollLeft()) {
placement = 'left';
} else if (tpt.top > $(window).scrollTop()) {
placement = 'top';
} else if (tpt.top > $(window).scrollTop()) {
placement = 'bottom';
}
}
break;
}
switch (placement) {
case 'bottom':
tp = tpb;
break;
case 'top':
tp = tpt;
break;
case 'left':
tp = tpl;
break;
case 'right':
tp = tpr;
break; break;
} }
@ -4506,6 +4658,7 @@ Editableform based on Twitter Bootstrap
}); });
}(window.jQuery)); }(window.jQuery));
/* ========================================================= /* =========================================================
* bootstrap-datepicker.js * bootstrap-datepicker.js
* http://www.eyecon.ro/bootstrap-datepicker * http://www.eyecon.ro/bootstrap-datepicker
@ -5811,6 +5964,9 @@ $(function(){
this.options.viewformat = this.options.format; this.options.viewformat = this.options.format;
} }
//try parse datepicker config defined as json string in data-datepicker
options.datepicker = $.fn.editableutils.tryParseJson(options.datepicker, true);
//overriding datepicker config (as by default jQuery extend() is not recursive) //overriding datepicker config (as by default jQuery extend() is not recursive)
//since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only //since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, { this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, {
@ -6118,6 +6274,9 @@ $(function(){
this.options.viewformat = this.options.format; this.options.viewformat = this.options.format;
} }
//try parse datetimepicker config defined as json string in data-datetimepicker
options.datetimepicker = $.fn.editableutils.tryParseJson(options.datetimepicker, true);
//overriding datetimepicker config (as by default jQuery extend() is not recursive) //overriding datetimepicker config (as by default jQuery extend() is not recursive)
//since 1.4 datetimepicker internally uses viewformat instead of format. Format is for submit only //since 1.4 datetimepicker internally uses viewformat instead of format. Format is for submit only
this.options.datetimepicker = $.extend({}, defaults.datetimepicker, options.datetimepicker, { this.options.datetimepicker = $.extend({}, defaults.datetimepicker, options.datetimepicker, {

File diff suppressed because one or more lines are too long

@ -1,10 +1,13 @@
/** /**
Bootstrap wysihtml5 editor. Based on [bootstrap-wysihtml5](https://github.com/jhollingworth/bootstrap-wysihtml5). Bootstrap wysihtml5 editor. Based on [bootstrap-wysihtml5](https://github.com/jhollingworth/bootstrap-wysihtml5).
You should include this input **manually** with dependent js and css files from `inputs-ext` directory. You should include **manually** distributives of `wysihtml5` and `bootstrap-wysihtml5`:
<link href="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.css" rel="stylesheet" type="text/css"></link> <link href="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.css" rel="stylesheet" type="text/css"></link>
<script src="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/wysihtml5-0.3.0.min.js"></script> <script src="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/wysihtml5-0.3.0.min.js"></script>
<script src="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.min.js"></script> <script src="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.min.js"></script>
And also include `wysihtml5.js` from `inputs-ext` directory of x-editable:
<script src="js/inputs-ext/wysihtml5/wysihtml5.js"></script> <script src="js/inputs-ext/wysihtml5/wysihtml5.js"></script>
**Note:** It's better to use fresh bootstrap-wysihtml5 from it's [master branch](https://github.com/jhollingworth/bootstrap-wysihtml5/tree/master/src) as there is update for correct image insertion. **Note:** It's better to use fresh bootstrap-wysihtml5 from it's [master branch](https://github.com/jhollingworth/bootstrap-wysihtml5/tree/master/src) as there is update for correct image insertion.

@ -134,6 +134,10 @@
.editable-clear-x:hover { .editable-clear-x:hover {
opacity: 1; opacity: 1;
} }
.editable-pre-wrapped {
white-space: pre-wrap;
}
.editable-container.editable-popup { .editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */ max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
} }

@ -107,7 +107,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
this.error(false); this.error(false);
this.input.$input.removeAttr('disabled'); this.input.$input.removeAttr('disabled');
this.$form.find('.editable-submit').removeAttr('disabled'); this.$form.find('.editable-submit').removeAttr('disabled');
this.input.value2input(this.value); var value = (this.value === null || this.value === undefined || this.value === '') ? this.options.defaultValue : this.value;
this.input.value2input(value);
//attach submit handler //attach submit handler
this.$form.submit($.proxy(this.submit, this)); this.$form.submit($.proxy(this.submit, this));
} }
@ -482,8 +483,17 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
**/ **/
value: null, value: null,
/** /**
Strategy for sending data on server. Can be <code>auto|always|never</code>. Value that will be displayed in input if original field value is empty (`null|undefined|''`).
When 'auto' data will be sent on server only if pk defined, otherwise new value will be stored in element.
@property defaultValue
@type string|object
@default null
@since 1.4.6
**/
defaultValue: null,
/**
Strategy for sending data on server. Can be `auto|always|never`.
When 'auto' data will be sent on server **only if pk and url defined**, otherwise new value will be stored locally.
@property send @property send
@type string @type string
@ -772,7 +782,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
result.push(o); result.push(o);
} }
} else { } else {
if(value == (o && typeof o === 'object' ? valueProp(o) : o)) { var itemValue = (o && (typeof o === 'object')) ? valueProp(o) : o;
if(value == itemValue) {
result.push(o); result.push(o);
} }
} }
@ -1483,6 +1494,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//add 'editable' class to every editable element //add 'editable' class to every editable element
this.$element.addClass('editable'); this.$element.addClass('editable');
//specifically for "textarea" add class .editable-pre-wrapped to keep linebreaks
if(this.input.type === 'textarea') {
this.$element.addClass('editable-pre-wrapped');
}
//attach handler activating editable. In disabled mode it just prevent default action (useful for links) //attach handler activating editable. In disabled mode it just prevent default action (useful for links)
if(this.options.toggle !== 'manual') { if(this.options.toggle !== 'manual') {
this.$element.addClass('editable-click'); this.$element.addClass('editable-click');
@ -2038,6 +2054,14 @@ Makes editable any HTML element on the page. Applied as jQuery method.
data = $this.data(datakey), data = $this.data(datakey),
options = typeof option === 'object' && option; options = typeof option === 'object' && option;
//for delegated targets do not store `editable` object for element
//it's allows several different selectors.
//see: https://github.com/vitalets/x-editable/issues/312
if(options && options.selector) {
data = new Editable(this, options);
return;
}
if (!data) { if (!data) {
$this.data(datakey, (data = new Editable(this, options))); $this.data(datakey, (data = new Editable(this, options)));
} }
@ -2926,7 +2950,9 @@ $(function(){
}); });
}, },
value2html: function(value, element) { //using `white-space: pre-wrap` solves \n <--> BR conversion very elegant!
/*
value2html: function(value, element) {
var html = '', lines; var html = '', lines;
if(value) { if(value) {
lines = value.split("\n"); lines = value.split("\n");
@ -2956,7 +2982,7 @@ $(function(){
} }
return lines.join("\n"); return lines.join("\n");
}, },
*/
activate: function() { activate: function() {
$.fn.editabletypes.text.prototype.activate.call(this); $.fn.editabletypes.text.prototype.activate.call(this);
} }
@ -3254,6 +3280,7 @@ Following types are supported:
* tel * tel
* number * number
* range * range
* time
Learn more about html5 inputs: Learn more about html5 inputs:
http://www.w3.org/wiki/HTML5_form_additions http://www.w3.org/wiki/HTML5_form_additions
@ -3439,6 +3466,29 @@ Range (inherit from number)
}); });
$.fn.editabletypes.range = Range; $.fn.editabletypes.range = Range;
}(window.jQuery)); }(window.jQuery));
/*
Time
*/
(function ($) {
"use strict";
var Time = function (options) {
this.init('time', options, Time.defaults);
};
//inherit from abstract, as inheritance from text gives selection error.
$.fn.editableutils.inherit(Time, $.fn.editabletypes.abstractinput);
$.extend(Time.prototype, {
render: function() {
this.setClass();
}
});
Time.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
tpl: '<input type="time">'
});
$.fn.editabletypes.time = Time;
}(window.jQuery));
/** /**
Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2. Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options. Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options.
@ -3466,6 +3516,7 @@ You need initially put both `data-value` and element's text youself:
<a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a> <a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a>
<script> <script>
$(function(){ $(function(){
//local source
$('#country').editable({ $('#country').editable({
source: [ source: [
{id: 'gb', text: 'Great Britain'}, {id: 'gb', text: 'Great Britain'},
@ -3476,6 +3527,42 @@ $(function(){
multiple: true multiple: true
} }
}); });
//remote source (simple)
$('#country').editable({
source: '/getCountries'
});
//remote source (advanced)
$('#country').editable({
select2: {
placeholder: 'Select Country',
allowClear: true,
minimumInputLength: 3,
id: function (item) {
return item.CountryId;
},
ajax: {
url: '/getCountries',
dataType: 'json',
data: function (term, page) {
return { query: term };
},
results: function (data, page) {
return { results: data };
}
},
formatResult: function (item) {
return item.CountryName;
},
formatSelection: function (item) {
return item.CountryName;
},
initSelection: function (element, callback) {
return $.get('/getCountryById', { query: element.val() }, function (data) {
callback(data);
});
}
}
});
}); });
</script> </script>
**/ **/
@ -3572,6 +3659,7 @@ $(function(){
if(this.options.select2.tags) { //in tags mode just assign value if(this.options.select2.tags) { //in tags mode just assign value
data = value; data = value;
//data = $.fn.editableutils.itemsByValue(value, this.options.select2.tags, this.idFunc);
} else if(this.sourceData) { } else if(this.sourceData) {
data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc); data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc);
} else { } else {

File diff suppressed because one or more lines are too long

@ -134,6 +134,10 @@
.editable-clear-x:hover { .editable-clear-x:hover {
opacity: 1; opacity: 1;
} }
.editable-pre-wrapped {
white-space: pre-wrap;
}
.editable-container.editable-popup { .editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */ max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
} }

@ -107,7 +107,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
this.error(false); this.error(false);
this.input.$input.removeAttr('disabled'); this.input.$input.removeAttr('disabled');
this.$form.find('.editable-submit').removeAttr('disabled'); this.$form.find('.editable-submit').removeAttr('disabled');
this.input.value2input(this.value); var value = (this.value === null || this.value === undefined || this.value === '') ? this.options.defaultValue : this.value;
this.input.value2input(value);
//attach submit handler //attach submit handler
this.$form.submit($.proxy(this.submit, this)); this.$form.submit($.proxy(this.submit, this));
} }
@ -482,8 +483,17 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
**/ **/
value: null, value: null,
/** /**
Strategy for sending data on server. Can be <code>auto|always|never</code>. Value that will be displayed in input if original field value is empty (`null|undefined|''`).
When 'auto' data will be sent on server only if pk defined, otherwise new value will be stored in element.
@property defaultValue
@type string|object
@default null
@since 1.4.6
**/
defaultValue: null,
/**
Strategy for sending data on server. Can be `auto|always|never`.
When 'auto' data will be sent on server **only if pk and url defined**, otherwise new value will be stored locally.
@property send @property send
@type string @type string
@ -772,7 +782,8 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
result.push(o); result.push(o);
} }
} else { } else {
if(value == (o && typeof o === 'object' ? valueProp(o) : o)) { var itemValue = (o && (typeof o === 'object')) ? valueProp(o) : o;
if(value == itemValue) {
result.push(o); result.push(o);
} }
} }
@ -1483,6 +1494,11 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//add 'editable' class to every editable element //add 'editable' class to every editable element
this.$element.addClass('editable'); this.$element.addClass('editable');
//specifically for "textarea" add class .editable-pre-wrapped to keep linebreaks
if(this.input.type === 'textarea') {
this.$element.addClass('editable-pre-wrapped');
}
//attach handler activating editable. In disabled mode it just prevent default action (useful for links) //attach handler activating editable. In disabled mode it just prevent default action (useful for links)
if(this.options.toggle !== 'manual') { if(this.options.toggle !== 'manual') {
this.$element.addClass('editable-click'); this.$element.addClass('editable-click');
@ -2038,6 +2054,14 @@ Makes editable any HTML element on the page. Applied as jQuery method.
data = $this.data(datakey), data = $this.data(datakey),
options = typeof option === 'object' && option; options = typeof option === 'object' && option;
//for delegated targets do not store `editable` object for element
//it's allows several different selectors.
//see: https://github.com/vitalets/x-editable/issues/312
if(options && options.selector) {
data = new Editable(this, options);
return;
}
if (!data) { if (!data) {
$this.data(datakey, (data = new Editable(this, options))); $this.data(datakey, (data = new Editable(this, options)));
} }
@ -2926,7 +2950,9 @@ $(function(){
}); });
}, },
value2html: function(value, element) { //using `white-space: pre-wrap` solves \n <--> BR conversion very elegant!
/*
value2html: function(value, element) {
var html = '', lines; var html = '', lines;
if(value) { if(value) {
lines = value.split("\n"); lines = value.split("\n");
@ -2956,7 +2982,7 @@ $(function(){
} }
return lines.join("\n"); return lines.join("\n");
}, },
*/
activate: function() { activate: function() {
$.fn.editabletypes.text.prototype.activate.call(this); $.fn.editabletypes.text.prototype.activate.call(this);
} }
@ -3254,6 +3280,7 @@ Following types are supported:
* tel * tel
* number * number
* range * range
* time
Learn more about html5 inputs: Learn more about html5 inputs:
http://www.w3.org/wiki/HTML5_form_additions http://www.w3.org/wiki/HTML5_form_additions
@ -3439,6 +3466,29 @@ Range (inherit from number)
}); });
$.fn.editabletypes.range = Range; $.fn.editabletypes.range = Range;
}(window.jQuery)); }(window.jQuery));
/*
Time
*/
(function ($) {
"use strict";
var Time = function (options) {
this.init('time', options, Time.defaults);
};
//inherit from abstract, as inheritance from text gives selection error.
$.fn.editableutils.inherit(Time, $.fn.editabletypes.abstractinput);
$.extend(Time.prototype, {
render: function() {
this.setClass();
}
});
Time.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
tpl: '<input type="time">'
});
$.fn.editabletypes.time = Time;
}(window.jQuery));
/** /**
Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2. Select2 input. Based on amazing work of Igor Vaynberg https://github.com/ivaynberg/select2.
Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options. Please see [original select2 docs](http://ivaynberg.github.com/select2) for detailed description and options.
@ -3466,6 +3516,7 @@ You need initially put both `data-value` and element's text youself:
<a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a> <a href="#" id="country" data-type="select2" data-pk="1" data-value="ru" data-url="/post" data-title="Select country"></a>
<script> <script>
$(function(){ $(function(){
//local source
$('#country').editable({ $('#country').editable({
source: [ source: [
{id: 'gb', text: 'Great Britain'}, {id: 'gb', text: 'Great Britain'},
@ -3476,6 +3527,42 @@ $(function(){
multiple: true multiple: true
} }
}); });
//remote source (simple)
$('#country').editable({
source: '/getCountries'
});
//remote source (advanced)
$('#country').editable({
select2: {
placeholder: 'Select Country',
allowClear: true,
minimumInputLength: 3,
id: function (item) {
return item.CountryId;
},
ajax: {
url: '/getCountries',
dataType: 'json',
data: function (term, page) {
return { query: term };
},
results: function (data, page) {
return { results: data };
}
},
formatResult: function (item) {
return item.CountryName;
},
formatSelection: function (item) {
return item.CountryName;
},
initSelection: function (element, callback) {
return $.get('/getCountryById', { query: element.val() }, function (data) {
callback(data);
});
}
}
});
}); });
</script> </script>
**/ **/
@ -3572,6 +3659,7 @@ $(function(){
if(this.options.select2.tags) { //in tags mode just assign value if(this.options.select2.tags) { //in tags mode just assign value
data = value; data = value;
//data = $.fn.editableutils.itemsByValue(value, this.options.select2.tags, this.idFunc);
} else if(this.sourceData) { } else if(this.sourceData) {
data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc); data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc);
} else { } else {
@ -4417,6 +4505,12 @@ Editableform based on jQuery UI
splitOptions: function() { splitOptions: function() {
this.containerOptions = {}; this.containerOptions = {};
this.formOptions = {}; this.formOptions = {};
//check that jQueryUI build contains tooltip widget
if(!$.ui[this.containerName]) {
$.error('Please use jQueryUI with "tooltip" widget! http://jqueryui.com/download');
return;
}
//defaults for tooltip //defaults for tooltip
var cDef = $.ui[this.containerName].prototype.options; var cDef = $.ui[this.containerName].prototype.options;
for(var k in this.options) { for(var k in this.options) {
@ -4446,7 +4540,14 @@ Editableform based on jQuery UI
this.call(this.containerOptions); this.call(this.containerOptions);
//disable standart triggering tooltip event //disable standart triggering tooltip event
this.container()._off(this.container().element, 'mouseover focusin'); //for some versions of jQueryUI it gives error:
//TypeError: this.container(...)._off is not a function
//see: https://github.com/vitalets/x-editable/issues/32
if(this.container()._off) {
this.container()._off(this.container().element, 'mouseover focusin');
} else {
$.error('this.container()._off is not a function. jQuery UI: ' + $.ui.version);
}
}, },
tip: function() { tip: function() {

File diff suppressed because one or more lines are too long