38 Commits
Author SHA1 Message Date
MarQuis Knox 9c4b22fd1f Merge pull request #953 from PerformanceHorizonGroup/implement-activate-method
implement the activate() method so the editor will receive focus
2016-12-18 22:41:05 +01:00
Georgi Kostov 161a6e3c29 implement the activate() method so the editor will receive focus when
opened
2016-12-06 14:43:12 +00:00
Tim Uy f464a31550 Merge remote-tracking branch 'origin/master' into dev 2015-11-11 08:18:34 -08:00
Tim Uy e47e74dfe2 Merge remote-tracking branch 'origin/master' into dev 2015-11-11 08:13:05 -08:00
Tim Uy 51391ebcd3 Merge remote-tracking branch 'origin/master' into dev 2015-11-11 08:09:08 -08:00
Tim Uy 3a5d1b2256 allow IE and FF to use setSelectionRange on number and email 2015-11-10 12:50:57 -08:00
Tim Uy 7dd39853f2 remove email from setcursorpos types per change in Chrome to fix #835 - may want to revisit and selectively enable in IE/FF 2015-11-10 12:30:35 -08:00
Tim Uy 8486d71013 implement value2str to fix issue #834 2015-11-10 11:49:37 -08:00
Tim Uy c52c1f7baf Merge pull request #490 from PerformanceHorizonGroup/add-missing-cancel-flag
Missing "cancel" flag
2015-11-10 10:39:53 -08:00
Tim Uy 17d25d2775 Merge pull request #833 from kittee/master
fix live editables with inner html bug
2015-11-10 09:36:24 -08:00
Tim Uy d1b421344b Merge pull request #831 from jcope2013/dev
update combodate to 1.1.0
2015-11-10 08:05:09 -08:00
Tim Uy 9d89c53de6 Merge pull request #832 from Nerian/patch-1
Update text.js
2015-11-10 08:04:06 -08:00
Gonzalo Rodríguez-Baltanás Díaz 5ad1b715d6 Update text.js 2015-11-10 10:30:22 +01:00
Josh Cope ea84c85354 update combodate to 1.1.0 2015-11-09 23:13:30 -05:00
Tim Uy c054d55888 version bump to 1.5.3 2015-11-09 18:32:47 -08:00
Tim Uy d33965ebde Merge pull request #745 from ins429/dev
use strict eq(===) to check on the new value equals to the old value, #744
2015-11-09 18:20:05 -08:00
Tim Uy 054e40b727 Add .orig to .gitignore 2015-11-09 17:12:46 -08:00
Tim Uy 025b7083e5 Merge remote-tracking branch 'origin/master' into dev
Conflicts:
	bower.json
2015-11-09 17:11:58 -08:00
E. Timothy Uy f2ec6e3241 Merge pull request #785 from iDev0urer/dev
Add main section to bower.json, Issue #784
2015-11-09 17:11:06 -08:00
E. Timothy Uy 904feb163c Merge pull request #820 from loqu8/nuspecfix
nuspec fix ,bump 1.5.2
2015-09-26 22:32:02 -07:00
Tim Uy 54d312af6f Forgot to update github link 2015-09-26 06:52:40 -07:00
Tim Uy 0d0428ffab Strip Loqu8 from nuget id 2015-09-26 06:51:45 -07:00
Tim Uy 2532598350 Fix up nuspec, increment to 1.5.2 2015-09-26 06:42:24 -07:00
E. Timothy Uy d22c880337 Merge pull request #1 from pablo/master
Fix a typo
2015-09-26 05:04:20 -07:00
Chris Watson ff2940f30e Add main section to bower.json, Issue #784 2015-07-06 16:23:54 -06:00
Peter Lee 9a82044a82 use strict eq(===) to check on the new value equals to the old value, #744 2015-04-08 12:20:14 -07:00
Igor Savchuk 77f267967c fix live editables with inner html bug
This fixes bug, which happens when live-editable element conains inner html (see http://stackoverflow.com/questions/26338514/x-editable-child-click-when-using-selector-option)
2014-10-28 18:08:42 +03:00
Georgi Kostov b7fc1d77fa Add missing "cancel" flag when hiding on the Escape key 2014-01-09 14:55:55 +02:00
vitalets 345b78d955 fix #347: do not call cursor methods for input checkbox and etc 2013-11-10 10:27:58 +04:00
vitalets 33421694e5 comments 2013-11-10 10:17:57 +04:00
vitalets bfcfab9383 dev build 2013-11-09 20:25:06 +04:00
vitalets 6ddb6ee16f fix #433: typeaheadjs with showbuttons: false 2013-11-09 20:24:35 +04:00
vitalets c5b05a5922 dev build 2013-11-09 16:04:53 +04:00
vitalets e8a32a09f6 fix #266:escape option not work for select/checklist items 2013-11-09 16:04:38 +04:00
vitalets a5715027ee list: improve docs, fix #428 2013-11-09 14:27:28 +04:00
vitalets 4954683c68 build dev 1.5.2 2013-11-09 14:13:46 +04:00
vitalets 6569275583 bump 1.5.2 2013-11-09 14:05:18 +04:00
vitalets 825cf190e6 fix #262, fix #390 select2 extra body click in IE 2013-11-09 14:03:45 +04:00
38 changed files with 647 additions and 304 deletions
+2 -1
View File
@@ -1,3 +1,4 @@
node_modules
test/instrumented/
*.nupkg
*.nupkg
*.orig
+10
View File
@@ -1,6 +1,16 @@
X-editable changelog
=============================
Version 1.5.3 Nov 9, 2015
----------------------------
Working through various PRs to ultimately move dev to master
Version 1.5.2 wip
----------------------------
[bug #433] typeaheadjs with showbuttons: false (vitalets)
[bug #266] `escape` option not work for select/checklist items (vitalets)
[bug #261] select2 disappears in IE when dropdown clicked (vitalets)
Version 1.5.1 Nov 4, 2013
----------------------------
+7 -5
View File
@@ -2,20 +2,22 @@
<package >
<metadata>
<id>x-editable</id>
<version>1.5.1</version>
<version>1.5.3</version>
<authors>Vitaliy Potapov</authors>
<owners>Vitaliy Potapov</owners>
<licenseUrl>https://github.com/vitalets/x-editable/blob/master/LICENSE-MIT</licenseUrl>
<projectUrl>http://vitalets.github.com/x-editable</projectUrl>
<projectUrl>http://github.com/vitalets/x-editable</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery</description>
<releaseNotes>Date and select2 minor fixes</releaseNotes>
<copyright>Copyright 2012-2013</copyright>
<copyright>Copyright 2012-2015</copyright>
<tags>edit-in-place editable click-to-edit bootstrap jquery</tags>
<dependencies>
</dependencies>
</metadata>
<files>
<file src="dist\**" target="\" />
<file src="dist\*" target="\" />
<file src="dist\**\*.js" target="content\Scripts" />
<file src="dist\**" target="content\Content" exclude="**\*.js;**\*.txt;**\*.md;**\*-MIT" />
</files>
</package>
</package>
+14 -1
View File
@@ -1,5 +1,18 @@
{
"name": "x-editable",
"main": [
"./dist/bootstrap3-editable/css/bootstrap-editable.css",
"./dist/bootstrap3-editable/js/bootstrap-editable.min.js",
"./dist/bootstrap-editable/css/bootstrap-editable.css",
"./dist/bootstrap-editable/js/bootstrap-editable.min.js",
"./dist/jqueryui-editable/css/jqueryui-editable.css",
"./dist/jqueryui-editable/js/jqueryui-editable.min.js",
"./dist/jquery-editable/css/jquery-editable.css",
"./dist/jquery-editable/js/jquery-editable-poshytip.min.js"
],
"ignore": [
"CHANGELOG.txt",
"Gruntfile.js",
@@ -15,5 +28,5 @@
],
"dependencies": {
"jquery": ">=1.6"
}
}
}
+2 -3
View File
@@ -1,7 +1,7 @@
{
"name": "vitalets/x-editable",
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery.",
"version": "1.4.5",
"version": "1.5.3",
"homepage": "http://github.com/vitalets/x-editable",
"authors": [
{
@@ -34,7 +34,6 @@
},
"require-dev": {
"grunt": "~0.3.11",
"grunt-contrib": "0.1.1"
"grunt": "~0.4.0"
}
}
+10
View File
@@ -1,6 +1,16 @@
X-editable changelog
=============================
Version 1.5.3 Nov 9, 2015
----------------------------
Working through various PRs to ultimately move dev to master
Version 1.5.2 wip
----------------------------
[bug #433] typeaheadjs with showbuttons: false (vitalets)
[bug #266] `escape` option not work for select/checklist items (vitalets)
[bug #261] select2 disappears in IE when dropdown clicked (vitalets)
Version 1.5.1 Nov 4, 2013
----------------------------
+7 -1
View File
@@ -2,6 +2,12 @@
In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery.
## Project status
Unfortunately, **project is currently frozen**, as I don't have enough time for it.
You could try use it as is, but there may be some bugs with newer versions of dependend libraries (e.g. bootstrap).
I would really appreciate if someone take care of it.. See [#610](https://github.com/vitalets/x-editable/issues/610).
Vitalets.
## Live demo
**http://vitalets.github.io/x-editable/demo.html**
@@ -121,4 +127,4 @@ Result will appear in `dist` directory.
## License
Copyright (c) 2012 Vitaliy Potapov
Licensed under the MIT license.
Licensed under the MIT license.
+2 -2
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
+46 -19
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
/**
Form with single input element, two buttons and two states: normal/loading.
Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@@ -222,7 +222,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//if value not changed --> trigger 'nochange' event and return
/*jslint eqeq: true*/
if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
if (!this.options.savenochange && this.input.value2str(newValue) === this.input.value2str(this.value)) {
/*jslint eqeq: false*/
/**
Fired when value not changed but form is submitted. Requires savenochange = false.
@@ -530,9 +530,10 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
/**
Success callback. Called when value successfully sent on server and **response status = 200**.
Usefull to work with json response. For example, if your backend response can be <code>{success: true}</code>
or <code>{success: false, msg: "server error"}</code> you can check it inside this callback.
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** <code>{newValue: &lt;something&gt;}</code> - it overwrites value, submitted by user.
If it returns **object like** `{newValue: &lt;something&gt;}` - it overwrites value, submitted by user
(useful when server changes value).
Otherwise newValue simply rendered into element.
@property success
@@ -956,17 +957,23 @@ Applied as jQuery method.
'.bootstrap-wysihtml5-insert-image-modal',
'.bootstrap-wysihtml5-insert-link-modal'
];
// select2 has extra body click in IE
// see: https://github.com/ivaynberg/select2/issues/1058
if ($('.select2-drop-mask').is(':visible')) {
return;
}
//check if element is detached. It occurs when clicking in bootstrap datepicker
if (!$.contains(document.documentElement, e.target)) {
return;
return;
}
//for some reason FF 20 generates extra event (click) in select2 widget with e.target = document
//we need to filter it via construction below. See https://github.com/vitalets/x-editable/issues/199
//Possibly related to http://stackoverflow.com/questions/10119793/why-does-firefox-react-differently-from-webkit-and-ie-to-click-event-on-selec
if($target.is(document)) {
return;
return;
}
//if click inside one of exclude classes --> no nothing
@@ -1040,7 +1047,7 @@ Applied as jQuery method.
.on({
save: $.proxy(this.save, this), //click on submit button (value changed)
nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on cancel button
show: $.proxy(function() {
if(this.delayedHide) {
this.hide(this.delayedHide.reason);
@@ -2823,8 +2830,15 @@ List - abstract class for inputs that have source option loaded from js array or
If **function**, it should return data in format above (since 1.4.0).
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only).
`[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]`
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only):
@example
[
{text: "group1", children: [
{value: 1, text: "text1"},
{value: 2, text: "text2"}
]},
...
]
@property source
@@ -2849,7 +2863,7 @@ List - abstract class for inputs that have source option loaded from js array or
**/
sourceError: 'Error when loading list',
/**
if <code>true</code> and source is **string url** - results will be cached for fields with the same source.
if `true` and source is **string url** - results will be cached for fields with the same source.
Usefull for editable column in grid to prevent extra requests.
@property sourceCache
@@ -2860,12 +2874,18 @@ List - abstract class for inputs that have source option loaded from js array or
sourceCache: true,
/**
Additional ajax options to be used in $.ajax() when loading list from server.
Useful to send extra parameters (`data` key) or change request method (`type` key).
Useful to send extra parameters or change request method.
@property sourceOptions
@type object|function
@default null
@since 1.5.0
@example
sourceOptions: {
data: {param: 123},
type: 'post'
}
**/
sourceOptions: null
});
@@ -2910,7 +2930,9 @@ $(function(){
activate: function() {
if(this.$input.is(':visible')) {
this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"]')) {
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
}
if(this.toggleClear) {
this.toggleClear();
}
@@ -3154,6 +3176,7 @@ $(function(){
$.extend(Select.prototype, {
renderList: function() {
this.$input.empty();
var escape = this.options.escape;
var fillItems = function($el, data) {
var attr;
@@ -3168,7 +3191,9 @@ $(function(){
if(data[i].disabled) {
attr.disabled = true;
}
$el.append($('<option>', attr).text(data[i].text));
var $option = $('<option>', attr);
$option[escape ? 'text' : 'html'](data[i].text);
$el.append($option);
}
}
}
@@ -3263,12 +3288,14 @@ $(function(){
$label = $('<label>').append($('<input>', {
type: 'checkbox',
value: this.sourceData[i].value
}))
.append($('<span>').text(' '+this.sourceData[i].text));
}));
var $option = $('<span>');
$option[this.options.escape ? 'text' : 'html'](' '+this.sourceData[i].text);
$label.append($option);
$('<div>').append($label).appendTo(this.$tpl);
}
this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();
},
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
+46 -19
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
/**
Form with single input element, two buttons and two states: normal/loading.
Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@@ -222,7 +222,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//if value not changed --> trigger 'nochange' event and return
/*jslint eqeq: true*/
if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
if (!this.options.savenochange && this.input.value2str(newValue) === this.input.value2str(this.value)) {
/*jslint eqeq: false*/
/**
Fired when value not changed but form is submitted. Requires savenochange = false.
@@ -530,9 +530,10 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
/**
Success callback. Called when value successfully sent on server and **response status = 200**.
Usefull to work with json response. For example, if your backend response can be <code>{success: true}</code>
or <code>{success: false, msg: "server error"}</code> you can check it inside this callback.
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** <code>{newValue: &lt;something&gt;}</code> - it overwrites value, submitted by user.
If it returns **object like** `{newValue: &lt;something&gt;}` - it overwrites value, submitted by user
(useful when server changes value).
Otherwise newValue simply rendered into element.
@property success
@@ -956,17 +957,23 @@ Applied as jQuery method.
'.bootstrap-wysihtml5-insert-image-modal',
'.bootstrap-wysihtml5-insert-link-modal'
];
// select2 has extra body click in IE
// see: https://github.com/ivaynberg/select2/issues/1058
if ($('.select2-drop-mask').is(':visible')) {
return;
}
//check if element is detached. It occurs when clicking in bootstrap datepicker
if (!$.contains(document.documentElement, e.target)) {
return;
return;
}
//for some reason FF 20 generates extra event (click) in select2 widget with e.target = document
//we need to filter it via construction below. See https://github.com/vitalets/x-editable/issues/199
//Possibly related to http://stackoverflow.com/questions/10119793/why-does-firefox-react-differently-from-webkit-and-ie-to-click-event-on-selec
if($target.is(document)) {
return;
return;
}
//if click inside one of exclude classes --> no nothing
@@ -1040,7 +1047,7 @@ Applied as jQuery method.
.on({
save: $.proxy(this.save, this), //click on submit button (value changed)
nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on cancel button
show: $.proxy(function() {
if(this.delayedHide) {
this.hide(this.delayedHide.reason);
@@ -2823,8 +2830,15 @@ List - abstract class for inputs that have source option loaded from js array or
If **function**, it should return data in format above (since 1.4.0).
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only).
`[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]`
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only):
@example
[
{text: "group1", children: [
{value: 1, text: "text1"},
{value: 2, text: "text2"}
]},
...
]
@property source
@@ -2849,7 +2863,7 @@ List - abstract class for inputs that have source option loaded from js array or
**/
sourceError: 'Error when loading list',
/**
if <code>true</code> and source is **string url** - results will be cached for fields with the same source.
if `true` and source is **string url** - results will be cached for fields with the same source.
Usefull for editable column in grid to prevent extra requests.
@property sourceCache
@@ -2860,12 +2874,18 @@ List - abstract class for inputs that have source option loaded from js array or
sourceCache: true,
/**
Additional ajax options to be used in $.ajax() when loading list from server.
Useful to send extra parameters (`data` key) or change request method (`type` key).
Useful to send extra parameters or change request method.
@property sourceOptions
@type object|function
@default null
@since 1.5.0
@example
sourceOptions: {
data: {param: 123},
type: 'post'
}
**/
sourceOptions: null
});
@@ -2910,7 +2930,9 @@ $(function(){
activate: function() {
if(this.$input.is(':visible')) {
this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"]')) {
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
}
if(this.toggleClear) {
this.toggleClear();
}
@@ -3154,6 +3176,7 @@ $(function(){
$.extend(Select.prototype, {
renderList: function() {
this.$input.empty();
var escape = this.options.escape;
var fillItems = function($el, data) {
var attr;
@@ -3168,7 +3191,9 @@ $(function(){
if(data[i].disabled) {
attr.disabled = true;
}
$el.append($('<option>', attr).text(data[i].text));
var $option = $('<option>', attr);
$option[escape ? 'text' : 'html'](data[i].text);
$el.append($option);
}
}
}
@@ -3263,12 +3288,14 @@ $(function(){
$label = $('<label>').append($('<input>', {
type: 'checkbox',
value: this.sourceData[i].value
}))
.append($('<span>').text(' '+this.sourceData[i].text));
}));
var $option = $('<span>');
$option[this.options.escape ? 'text' : 'html'](' '+this.sourceData[i].text);
$label.append($option);
$('<div>').append($label).appendTo(this.$tpl);
}
this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();
},
File diff suppressed because one or more lines are too long
+21 -1
View File
@@ -42,6 +42,22 @@ $(function(){
this.renderClear();
this.setClass();
this.setAttr('placeholder');
// need to set kewdown handler before apply typeahead
// for correct autosubmit
this.isAutosubmit = false;
var that = this;
this.$input.on('keydown', function (e) {
if (!that.isAutosubmit) {
return;
}
var $dropdown = that.$input.closest('.editable-input').find('.tt-dropdown-menu');
if (!$dropdown.is(':visible') && e.which === 13) {
that.$input.closest('form').submit();
}
});
// apply typeaheadjs
this.$input.typeahead(this.options.typeahead);
// copy `input-sm | input-lg` classes to placeholder input
@@ -53,7 +69,11 @@ $(function(){
this.$input.siblings('input.tt-hint').addClass('input-lg');
}
}
}
},
autosubmit: function() {
this.isAutosubmit = true;
}
});
Constructor.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
+2 -2
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
+46 -19
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
/**
Form with single input element, two buttons and two states: normal/loading.
Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@@ -222,7 +222,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//if value not changed --> trigger 'nochange' event and return
/*jslint eqeq: true*/
if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
if (!this.options.savenochange && this.input.value2str(newValue) === this.input.value2str(this.value)) {
/*jslint eqeq: false*/
/**
Fired when value not changed but form is submitted. Requires savenochange = false.
@@ -530,9 +530,10 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
/**
Success callback. Called when value successfully sent on server and **response status = 200**.
Usefull to work with json response. For example, if your backend response can be <code>{success: true}</code>
or <code>{success: false, msg: "server error"}</code> you can check it inside this callback.
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** <code>{newValue: &lt;something&gt;}</code> - it overwrites value, submitted by user.
If it returns **object like** `{newValue: &lt;something&gt;}` - it overwrites value, submitted by user
(useful when server changes value).
Otherwise newValue simply rendered into element.
@property success
@@ -956,17 +957,23 @@ Applied as jQuery method.
'.bootstrap-wysihtml5-insert-image-modal',
'.bootstrap-wysihtml5-insert-link-modal'
];
// select2 has extra body click in IE
// see: https://github.com/ivaynberg/select2/issues/1058
if ($('.select2-drop-mask').is(':visible')) {
return;
}
//check if element is detached. It occurs when clicking in bootstrap datepicker
if (!$.contains(document.documentElement, e.target)) {
return;
return;
}
//for some reason FF 20 generates extra event (click) in select2 widget with e.target = document
//we need to filter it via construction below. See https://github.com/vitalets/x-editable/issues/199
//Possibly related to http://stackoverflow.com/questions/10119793/why-does-firefox-react-differently-from-webkit-and-ie-to-click-event-on-selec
if($target.is(document)) {
return;
return;
}
//if click inside one of exclude classes --> no nothing
@@ -1040,7 +1047,7 @@ Applied as jQuery method.
.on({
save: $.proxy(this.save, this), //click on submit button (value changed)
nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on cancel button
show: $.proxy(function() {
if(this.delayedHide) {
this.hide(this.delayedHide.reason);
@@ -2823,8 +2830,15 @@ List - abstract class for inputs that have source option loaded from js array or
If **function**, it should return data in format above (since 1.4.0).
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only).
`[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]`
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only):
@example
[
{text: "group1", children: [
{value: 1, text: "text1"},
{value: 2, text: "text2"}
]},
...
]
@property source
@@ -2849,7 +2863,7 @@ List - abstract class for inputs that have source option loaded from js array or
**/
sourceError: 'Error when loading list',
/**
if <code>true</code> and source is **string url** - results will be cached for fields with the same source.
if `true` and source is **string url** - results will be cached for fields with the same source.
Usefull for editable column in grid to prevent extra requests.
@property sourceCache
@@ -2860,12 +2874,18 @@ List - abstract class for inputs that have source option loaded from js array or
sourceCache: true,
/**
Additional ajax options to be used in $.ajax() when loading list from server.
Useful to send extra parameters (`data` key) or change request method (`type` key).
Useful to send extra parameters or change request method.
@property sourceOptions
@type object|function
@default null
@since 1.5.0
@example
sourceOptions: {
data: {param: 123},
type: 'post'
}
**/
sourceOptions: null
});
@@ -2910,7 +2930,9 @@ $(function(){
activate: function() {
if(this.$input.is(':visible')) {
this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"]')) {
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
}
if(this.toggleClear) {
this.toggleClear();
}
@@ -3154,6 +3176,7 @@ $(function(){
$.extend(Select.prototype, {
renderList: function() {
this.$input.empty();
var escape = this.options.escape;
var fillItems = function($el, data) {
var attr;
@@ -3168,7 +3191,9 @@ $(function(){
if(data[i].disabled) {
attr.disabled = true;
}
$el.append($('<option>', attr).text(data[i].text));
var $option = $('<option>', attr);
$option[escape ? 'text' : 'html'](data[i].text);
$el.append($option);
}
}
}
@@ -3263,12 +3288,14 @@ $(function(){
$label = $('<label>').append($('<input>', {
type: 'checkbox',
value: this.sourceData[i].value
}))
.append($('<span>').text(' '+this.sourceData[i].text));
}));
var $option = $('<span>');
$option[this.options.escape ? 'text' : 'html'](' '+this.sourceData[i].text);
$label.append($option);
$('<div>').append($label).appendTo(this.$tpl);
}
this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();
},
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
+46 -19
View File
@@ -1,7 +1,7 @@
/*! X-editable - v1.5.1
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */
* Copyright (c) 2015 Vitaliy Potapov; Licensed MIT */
/**
Form with single input element, two buttons and two states: normal/loading.
Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@@ -222,7 +222,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//if value not changed --> trigger 'nochange' event and return
/*jslint eqeq: true*/
if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
if (!this.options.savenochange && this.input.value2str(newValue) === this.input.value2str(this.value)) {
/*jslint eqeq: false*/
/**
Fired when value not changed but form is submitted. Requires savenochange = false.
@@ -530,9 +530,10 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
/**
Success callback. Called when value successfully sent on server and **response status = 200**.
Usefull to work with json response. For example, if your backend response can be <code>{success: true}</code>
or <code>{success: false, msg: "server error"}</code> you can check it inside this callback.
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** <code>{newValue: &lt;something&gt;}</code> - it overwrites value, submitted by user.
If it returns **object like** `{newValue: &lt;something&gt;}` - it overwrites value, submitted by user
(useful when server changes value).
Otherwise newValue simply rendered into element.
@property success
@@ -956,17 +957,23 @@ Applied as jQuery method.
'.bootstrap-wysihtml5-insert-image-modal',
'.bootstrap-wysihtml5-insert-link-modal'
];
// select2 has extra body click in IE
// see: https://github.com/ivaynberg/select2/issues/1058
if ($('.select2-drop-mask').is(':visible')) {
return;
}
//check if element is detached. It occurs when clicking in bootstrap datepicker
if (!$.contains(document.documentElement, e.target)) {
return;
return;
}
//for some reason FF 20 generates extra event (click) in select2 widget with e.target = document
//we need to filter it via construction below. See https://github.com/vitalets/x-editable/issues/199
//Possibly related to http://stackoverflow.com/questions/10119793/why-does-firefox-react-differently-from-webkit-and-ie-to-click-event-on-selec
if($target.is(document)) {
return;
return;
}
//if click inside one of exclude classes --> no nothing
@@ -1040,7 +1047,7 @@ Applied as jQuery method.
.on({
save: $.proxy(this.save, this), //click on submit button (value changed)
nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on cancel button
show: $.proxy(function() {
if(this.delayedHide) {
this.hide(this.delayedHide.reason);
@@ -2823,8 +2830,15 @@ List - abstract class for inputs that have source option loaded from js array or
If **function**, it should return data in format above (since 1.4.0).
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only).
`[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]`
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only):
@example
[
{text: "group1", children: [
{value: 1, text: "text1"},
{value: 2, text: "text2"}
]},
...
]
@property source
@@ -2849,7 +2863,7 @@ List - abstract class for inputs that have source option loaded from js array or
**/
sourceError: 'Error when loading list',
/**
if <code>true</code> and source is **string url** - results will be cached for fields with the same source.
if `true` and source is **string url** - results will be cached for fields with the same source.
Usefull for editable column in grid to prevent extra requests.
@property sourceCache
@@ -2860,12 +2874,18 @@ List - abstract class for inputs that have source option loaded from js array or
sourceCache: true,
/**
Additional ajax options to be used in $.ajax() when loading list from server.
Useful to send extra parameters (`data` key) or change request method (`type` key).
Useful to send extra parameters or change request method.
@property sourceOptions
@type object|function
@default null
@since 1.5.0
@example
sourceOptions: {
data: {param: 123},
type: 'post'
}
**/
sourceOptions: null
});
@@ -2910,7 +2930,9 @@ $(function(){
activate: function() {
if(this.$input.is(':visible')) {
this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"]')) {
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
}
if(this.toggleClear) {
this.toggleClear();
}
@@ -3154,6 +3176,7 @@ $(function(){
$.extend(Select.prototype, {
renderList: function() {
this.$input.empty();
var escape = this.options.escape;
var fillItems = function($el, data) {
var attr;
@@ -3168,7 +3191,9 @@ $(function(){
if(data[i].disabled) {
attr.disabled = true;
}
$el.append($('<option>', attr).text(data[i].text));
var $option = $('<option>', attr);
$option[escape ? 'text' : 'html'](data[i].text);
$el.append($option);
}
}
}
@@ -3263,12 +3288,14 @@ $(function(){
$label = $('<label>').append($('<input>', {
type: 'checkbox',
value: this.sourceData[i].value
}))
.append($('<span>').text(' '+this.sourceData[i].text));
}));
var $option = $('<span>');
$option[this.options.escape ? 'text' : 'html'](' '+this.sourceData[i].text);
$label.append($option);
$('<div>').append($label).appendTo(this.$tpl);
}
this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();
},
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "X-editable",
"title": "X-editable",
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery",
"version": "1.5.1",
"version": "1.5.3",
"homepage": "http://github.com/vitalets/x-editable",
"author": {
"name": "Vitaliy Potapov",
+10 -4
View File
@@ -50,7 +50,7 @@ Applied as jQuery method.
//close all on escape
$(document).on('keyup.editable', function (e) {
if (e.which === 27) {
$('.editable-open').editableContainer('hide');
$('.editable-open').editableContainer('hide', 'cancel');
//todo: return focus on element
}
});
@@ -66,17 +66,23 @@ Applied as jQuery method.
'.bootstrap-wysihtml5-insert-image-modal',
'.bootstrap-wysihtml5-insert-link-modal'
];
// select2 has extra body click in IE
// see: https://github.com/ivaynberg/select2/issues/1058
if ($('.select2-drop-mask').is(':visible')) {
return;
}
//check if element is detached. It occurs when clicking in bootstrap datepicker
if (!$.contains(document.documentElement, e.target)) {
return;
return;
}
//for some reason FF 20 generates extra event (click) in select2 widget with e.target = document
//we need to filter it via construction below. See https://github.com/vitalets/x-editable/issues/199
//Possibly related to http://stackoverflow.com/questions/10119793/why-does-firefox-react-differently-from-webkit-and-ie-to-click-event-on-selec
if($target.is(document)) {
return;
return;
}
//if click inside one of exclude classes --> no nothing
+1 -1
View File
@@ -23,7 +23,7 @@
*/
setCursorPosition: function(elem, pos) {
if (elem.setSelectionRange) {
elem.setSelectionRange(pos, pos);
try { elem.setSelectionRange(pos, pos); } catch (e) {}
} else if (elem.createTextRange) {
var range = elem.createTextRange();
range.collapse(true);
+4 -3
View File
@@ -218,7 +218,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
//if value not changed --> trigger 'nochange' event and return
/*jslint eqeq: true*/
if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
if (!this.options.savenochange && this.input.value2str(newValue) === this.input.value2str(this.value)) {
/*jslint eqeq: false*/
/**
Fired when value not changed but form is submitted. Requires savenochange = false.
@@ -526,9 +526,10 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
/**
Success callback. Called when value successfully sent on server and **response status = 200**.
Usefull to work with json response. For example, if your backend response can be <code>{success: true}</code>
or <code>{success: false, msg: "server error"}</code> you can check it inside this callback.
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** <code>{newValue: &lt;something&gt;}</code> - it overwrites value, submitted by user.
If it returns **object like** `{newValue: &lt;something&gt;}` - it overwrites value, submitted by user
(useful when server changes value).
Otherwise newValue simply rendered into element.
@property success
+1 -1
View File
@@ -146,7 +146,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.options.autotext = 'never';
//listen toggle events
this.$element.on(this.options.toggle + '.editable', selector, $.proxy(function(e){
var $target = $(e.target);
var $target = $(e.target).closest(selector);
if(!$target.data('editable')) {
//if delegated element initially empty, we need to clear it's text (that was manually set to `empty` by user)
//see https://github.com/vitalets/x-editable/issues/137
+21 -1
View File
@@ -42,6 +42,22 @@ $(function(){
this.renderClear();
this.setClass();
this.setAttr('placeholder');
// need to set kewdown handler before apply typeahead
// for correct autosubmit
this.isAutosubmit = false;
var that = this;
this.$input.on('keydown', function (e) {
if (!that.isAutosubmit) {
return;
}
var $dropdown = that.$input.closest('.editable-input').find('.tt-dropdown-menu');
if (!$dropdown.is(':visible') && e.which === 13) {
that.$input.closest('form').submit();
}
});
// apply typeaheadjs
this.$input.typeahead(this.options.typeahead);
// copy `input-sm | input-lg` classes to placeholder input
@@ -53,7 +69,11 @@ $(function(){
this.$input.siblings('input.tt-hint').addClass('input-lg');
}
}
}
},
autosubmit: function() {
this.isAutosubmit = true;
}
});
Constructor.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
+1 -1
View File
@@ -74,7 +74,7 @@ To create your own input you can inherit from this class.
@returns {string}
**/
value2str: function(value) {
return value;
return String(value);
},
/**
+6 -4
View File
@@ -43,12 +43,14 @@ $(function(){
$label = $('<label>').append($('<input>', {
type: 'checkbox',
value: this.sourceData[i].value
}))
.append($('<span>').text(' '+this.sourceData[i].text));
}));
var $option = $('<span>');
$option[this.options.escape ? 'text' : 'html'](' '+this.sourceData[i].text);
$label.append($option);
$('<div>').append($label).appendTo(this.$tpl);
}
this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();
},
+167 -129
View File
@@ -1,20 +1,20 @@
/**
* Combodate - 1.0.5
* Combodate - 1.1.0
* Dropdown date and time picker.
* Converts text input into dropdowns to pick day, month, year, hour, minute and second.
* Uses momentjs as datetime library http://momentjs.com.
* For i18n include corresponding file from https://github.com/timrwood/moment/tree/master/lang
* For i18n include corresponding file from https://github.com/timrwood/moment/tree/master/lang
*
* Confusion at noon and midnight - see http://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight
* In combodate:
* In combodate:
* 12:00 pm --> 12:00 (24-h format, midday)
* 12:00 am --> 00:00 (24-h format, midnight, start of day)
*
*
* Differs from momentjs parse rules:
* 00:00 pm, 12:00 pm --> 12:00 (24-h format, day not change)
* 00:00 am, 12:00 am --> 00:00 (24-h format, day not change)
*
*
*
*
* Author: Vitaliy Potapov
* Project page: http://github.com/vitalets/combodate
* Copyright (c) 2012 Vitaliy Potapov. Released under MIT License.
@@ -28,28 +28,31 @@
return;
}
this.options = $.extend({}, $.fn.combodate.defaults, options, this.$element.data());
this.init();
this.init();
};
Combodate.prototype = {
constructor: Combodate,
constructor: Combodate,
init: function () {
this.map = {
//key regexp moment.method
day: ['D', 'date'],
month: ['M', 'month'],
year: ['Y', 'year'],
day: ['D', 'date'],
month: ['M', 'month'],
year: ['Y', 'year'],
hour: ['[Hh]', 'hours'],
minute: ['m', 'minutes'],
minute: ['m', 'minutes'],
second: ['s', 'seconds'],
ampm: ['[Aa]', '']
ampm: ['[Aa]', '']
};
this.$widget = $('<span class="combodate"></span>').html(this.getTemplate());
this.initCombos();
//update original input on change
// internal momentjs instance
this.datetime = null;
//update original input on change
this.$widget.on('change', 'select', $.proxy(function(e) {
this.$element.val(this.getValue()).change();
// update days count if month or year changes
@@ -59,28 +62,30 @@
}
}
}, this));
this.$widget.find('select').css('width', 'auto');
// hide original input and insert widget
// hide original input and insert widget
this.$element.hide().after(this.$widget);
// set initial value
this.setValue(this.$element.val() || this.options.value);
},
/*
Replace tokens in template with <select> elements
*/
Replace tokens in template with <select> elements
*/
getTemplate: function() {
var tpl = this.options.template;
var inputDisabled = this.$element.prop('disabled');
var customClass = this.options.customClass;
//first pass
$.each(this.map, function(k, v) {
v = v[0];
v = v[0];
var r = new RegExp(v+'+'),
token = v.length > 1 ? v.substring(1, 2) : v;
tpl = tpl.replace(r, '{'+token+'}');
});
@@ -91,16 +96,17 @@
$.each(this.map, function(k, v) {
v = v[0];
var token = v.length > 1 ? v.substring(1, 2) : v;
tpl = tpl.replace('{'+token+'}', '<select class="'+k+'"></select>');
});
tpl = tpl.replace('{'+token+'}', '<select class="'+k+' '+customClass +'"'+
(inputDisabled ? ' disabled="disabled"' : '')+'></select>');
});
return tpl;
},
/*
Initialize combos that presents in template
*/
Initialize combos that presents in template
*/
initCombos: function() {
for (var k in this.map) {
var $c = this.$widget.find('.'+k);
@@ -112,8 +118,8 @@
},
/*
Fill combo with items
*/
Fill combo with items
*/
fillCombo: function(k) {
var $combo = this['$'+k];
if (!$combo) {
@@ -121,7 +127,7 @@
}
// define method name to fill items, e.g `fillDays`
var f = 'fill' + k.charAt(0).toUpperCase() + k.slice(1);
var f = 'fill' + k.charAt(0).toUpperCase() + k.slice(1);
var items = this[f]();
var value = $combo.val();
@@ -134,24 +140,28 @@
},
/*
Initialize items of combos. Handles `firstItem` option
Initialize items of combos. Handles `firstItem` option
*/
fillCommon: function(key) {
var values = [],
relTime;
if(this.options.firstItem === 'name') {
//need both to support moment ver < 2 and >= 2
relTime = moment.relativeTime || moment.langData()._relativeTime;
if (moment.localeData) {
relTime = moment.localeData()._relativeTime;
} else {
relTime = moment.relativeTime || moment.langData()._relativeTime;
}
var header = typeof relTime[key] === 'function' ? relTime[key](1, true, key, false) : relTime[key];
//take last entry (see momentjs lang files structure)
header = header.split(' ').reverse()[0];
//take last entry (see momentjs lang files structure)
header = header.split(' ').reverse()[0];
values.push(['', header]);
} else if(this.options.firstItem === 'empty') {
values.push(['', '']);
}
return values;
},
},
/*
@@ -177,20 +187,26 @@
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
return items;
},
/*
fill month
*/
fillMonth: function() {
var items = this.fillCommon('M'), name, i,
var items = this.fillCommon('M'), name, i,
longNamesNum = this.options.template.indexOf('MMMMMM') !== -1,
shortNamesNum = this.options.template.indexOf('MMMMM') !== -1,
longNames = this.options.template.indexOf('MMMM') !== -1,
shortNames = this.options.template.indexOf('MMM') !== -1,
twoDigit = this.options.template.indexOf('MM') !== -1;
for(i=0; i<=11; i++) {
if(longNames) {
if (longNamesNum) {
name = moment().date(1).month(i).format('MM - MMMM');
} else if (shortNamesNum) {
name = moment().date(1).month(i).format('MM - MMM');
} else if(longNames) {
//see https://github.com/timrwood/momentjs.com/pull/36
name = moment().date(1).month(i).format('MMMM');
} else if(shortNames) {
@@ -201,27 +217,27 @@
name = i+1;
}
items.push([i, name]);
}
}
return items;
},
},
/*
fill year
*/
fillYear: function() {
var items = [], name, i,
var items = [], name, i,
longNames = this.options.template.indexOf('YYYY') !== -1;
for(i=this.options.maxYear; i>=this.options.minYear; i--) {
name = longNames ? i : (i+'').substring(2);
items[this.options.yearDescending ? 'push' : 'unshift']([i, name]);
}
items = this.fillCommon('y').concat(items);
return items;
},
return items;
},
/*
fill hour
*/
@@ -230,16 +246,16 @@
h12 = this.options.template.indexOf('h') !== -1,
h24 = this.options.template.indexOf('H') !== -1,
twoDigit = this.options.template.toLowerCase().indexOf('hh') !== -1,
min = h12 ? 1 : 0,
min = h12 ? 1 : 0,
max = h12 ? 12 : 23;
for(i=min; i<=max; i++) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
}
return items;
},
/*
fill minute
*/
@@ -250,10 +266,10 @@
for(i=0; i<=59; i+= this.options.minuteStep) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
}
return items;
},
/*
fill second
*/
@@ -264,85 +280,103 @@
for(i=0; i<=59; i+= this.options.secondStep) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
}
return items;
},
/*
fill ampm
*/
fillAmpm: function() {
var ampmL = this.options.template.indexOf('a') !== -1,
ampmU = this.options.template.indexOf('A') !== -1,
ampmU = this.options.template.indexOf('A') !== -1,
items = [
['am', ampmL ? 'am' : 'AM'],
['pm', ampmL ? 'pm' : 'PM']
];
return items;
},
return items;
},
/*
Returns current date value from combos.
Returns current date value from combos.
If format not specified - `options.format` used.
If format = `null` - Moment object returned.
*/
getValue: function(format) {
var dt, values = {},
var dt, values = {},
that = this,
notSelected = false;
//getting selected values
//getting selected values
$.each(this.map, function(k, v) {
if(k === 'ampm') {
return;
}
var def = k === 'day' ? 1 : 0;
values[k] = that['$'+k] ? parseInt(that['$'+k].val(), 10) : def;
// if combo exists, use it's value, otherwise use default
if (that['$'+k]) {
values[k] = parseInt(that['$'+k].val(), 10);
} else {
var defaultValue;
if (that.datetime) {
defaultValue = that.datetime[v[1]]();
} else {
defaultValue = k === 'day' ? 1 : 0;
}
values[k] = defaultValue;
}
if(isNaN(values[k])) {
notSelected = true;
return false;
return false;
}
});
//if at least one visible combo not selected - return empty string
if(notSelected) {
return '';
}
//convert hours 12h --> 24h
//convert hours 12h --> 24h
if(this.$ampm) {
//12:00 pm --> 12:00 (24-h format, midday), 12:00 am --> 00:00 (24-h format, midnight, start of day)
if(values.hour === 12) {
values.hour = this.$ampm.val() === 'am' ? 0 : 12;
values.hour = this.$ampm.val() === 'am' ? 0 : 12;
} else {
values.hour = this.$ampm.val() === 'am' ? values.hour : values.hour+12;
}
}
dt = moment([values.year, values.month, values.day, values.hour, values.minute, values.second]);
}
dt = moment([
values.year,
values.month,
values.day,
values.hour,
values.minute,
values.second
]);
//highlight invalid date
this.highlight(dt);
format = format === undefined ? this.options.format : format;
if(format === null) {
return dt.isValid() ? dt : null;
return dt.isValid() ? dt : null;
} else {
return dt.isValid() ? dt.format(format) : '';
}
return dt.isValid() ? dt.format(format) : '';
}
},
setValue: function(value) {
if(!value) {
return;
}
var dt = typeof value === 'string' ? moment(value, this.options.format) : moment(value),
// parse in strict mode (third param `true`)
var dt = typeof value === 'string' ? moment(value, this.options.format, true) : moment(value),
that = this,
values = {};
//function to find nearest value in select options
function getNearest($select, value) {
var delta = {};
@@ -351,23 +385,23 @@
distance;
if(optValue === '') return;
distance = Math.abs(optValue - value);
distance = Math.abs(optValue - value);
if(typeof delta.distance === 'undefined' || distance < delta.distance) {
delta = {value: optValue, distance: distance};
}
});
}
});
return delta.value;
}
}
if(dt.isValid()) {
//read values from date object
$.each(this.map, function(k, v) {
if(k === 'ampm') {
return;
return;
}
values[k] = dt[v[1]]();
});
if(this.$ampm) {
//12:00 pm --> 12:00 (24-h format, midday), 12:00 am --> 00:00 (24-h format, midnight, start of day)
if(values.hour >= 12) {
@@ -380,21 +414,21 @@
if(values.hour === 0) {
values.hour = 12;
}
}
}
}
$.each(values, function(k, v) {
//call val() for each existing combo, e.g. this.$hour.val()
if(that['$'+k]) {
if(k === 'minute' && that.options.minuteStep > 1 && that.options.roundTime) {
v = getNearest(that['$'+k], v);
}
if(k === 'second' && that.options.secondStep > 1 && that.options.roundTime) {
v = getNearest(that['$'+k], v);
}
}
that['$'+k].val(v);
}
});
@@ -403,11 +437,14 @@
if (this.options.smartDays) {
this.fillCombo('day');
}
this.$element.val(dt.format(this.options.format)).change();
this.$element.val(dt.format(this.options.format)).change();
this.datetime = dt;
} else {
this.datetime = null;
}
},
/*
highlight combos if date is invalid
*/
@@ -418,29 +455,29 @@
} else {
//store original border color
if(!this.borderColor) {
this.borderColor = this.$widget.find('select').css('border-color');
this.borderColor = this.$widget.find('select').css('border-color');
}
this.$widget.find('select').css('border-color', 'red');
}
}
} else {
if(this.options.errorClass) {
this.$widget.removeClass(this.options.errorClass);
} else {
this.$widget.find('select').css('border-color', this.borderColor);
}
}
}
},
leadZero: function(v) {
return v <= 9 ? '0' + v : v;
return v <= 9 ? '0' + v : v;
},
destroy: function() {
this.$widget.remove();
this.$element.removeData('combodate').show();
}
//todo: clear method
//todo: clear method
};
$.fn.combodate = function ( option ) {
@@ -450,8 +487,8 @@
//getValue returns date as string / object (not jQuery object)
if(option === 'getValue' && this.length && (d = this.eq(0).data('combodate'))) {
return d.getValue.apply(d, args);
}
}
return this.each(function () {
var $this = $(this),
data = $this.data('combodate'),
@@ -463,15 +500,15 @@
data[option].apply(data, args);
}
});
};
};
$.fn.combodate.defaults = {
//in this format value stored in original input
format: 'DD-MM-YYYY HH:mm',
format: 'DD-MM-YYYY HH:mm',
//in this format items in dropdowns are displayed
template: 'D / MMM / YYYY H : mm',
//initial value, can be `new Date()`
value: null,
//initial value, can be `new Date()`
value: null,
minYear: 1970,
maxYear: 2015,
yearDescending: true,
@@ -479,6 +516,7 @@
secondStep: 1,
firstItem: 'empty', //'name', 'empty', 'none'
errorClass: null,
customClass: '',
roundTime: true, // whether to round minutes and seconds if step > 1
smartDays: false // whether days in combo depend on selected month: 31, 30, 28
};
+17 -4
View File
@@ -283,8 +283,15 @@ List - abstract class for inputs that have source option loaded from js array or
If **function**, it should return data in format above (since 1.4.0).
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only).
`[{text: "group1", children: [{value: 1, text: "text1"}, {value: 2, text: "text2"}]}, ...]`
Since 1.4.1 key `children` supported to render OPTGROUP (for **select** input only):
@example
[
{text: "group1", children: [
{value: 1, text: "text1"},
{value: 2, text: "text2"}
]},
...
]
@property source
@@ -309,7 +316,7 @@ List - abstract class for inputs that have source option loaded from js array or
**/
sourceError: 'Error when loading list',
/**
if <code>true</code> and source is **string url** - results will be cached for fields with the same source.
if `true` and source is **string url** - results will be cached for fields with the same source.
Usefull for editable column in grid to prevent extra requests.
@property sourceCache
@@ -320,12 +327,18 @@ List - abstract class for inputs that have source option loaded from js array or
sourceCache: true,
/**
Additional ajax options to be used in $.ajax() when loading list from server.
Useful to send extra parameters (`data` key) or change request method (`type` key).
Useful to send extra parameters or change request method.
@property sourceOptions
@type object|function
@default null
@since 1.5.0
@example
sourceOptions: {
data: {param: 123},
type: 'post'
}
**/
sourceOptions: null
});
+4 -1
View File
@@ -31,6 +31,7 @@ $(function(){
$.extend(Select.prototype, {
renderList: function() {
this.$input.empty();
var escape = this.options.escape;
var fillItems = function($el, data) {
var attr;
@@ -45,7 +46,9 @@ $(function(){
if(data[i].disabled) {
attr.disabled = true;
}
$el.append($('<option>', attr).text(data[i].text));
var $option = $('<option>', attr);
$option[escape ? 'text' : 'html'](data[i].text);
$el.append($option);
}
}
}
+4
View File
@@ -293,6 +293,10 @@ $(function(){
return source;
},
activate: function() {
this.$input.select2('open');
},
destroy: function() {
if(this.$input) {
if(this.$input.data('select2')) {
+33 -29
View File
@@ -17,7 +17,7 @@ $(function(){
**/
(function ($) {
"use strict";
var Text = function (options) {
this.init('text', options, Text.defaults);
};
@@ -30,17 +30,21 @@ $(function(){
this.setClass();
this.setAttr('placeholder');
},
activate: function() {
if(this.$input.is(':visible')) {
this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
// if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"],[type="number"],[type="email"]')) {
if (this.$input.is('input,textarea') && !this.$input.is('[type="checkbox"],[type="range"]')) {
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
}
if(this.toggleClear) {
this.toggleClear();
}
}
},
//render clear button
renderClear: function() {
if (this.options.clear) {
@@ -51,21 +55,21 @@ $(function(){
//arrows, enter, tab, etc
if(~$.inArray(e.keyCode, [40,38,9,13,27])) {
return;
}
}
clearTimeout(this.t);
var that = this;
this.t = setTimeout(function() {
that.toggleClear(e);
}, 100);
}, this))
.parent().css('position', 'relative');
this.$clear.click($.proxy(this.clear, this));
}
this.$clear.click($.proxy(this.clear, this));
}
},
postrender: function() {
/*
//now `clear` is positioned via css
@@ -74,57 +78,57 @@ $(function(){
// var h = this.$input.outerHeight(true) || 20,
var h = this.$clear.parent().height(),
delta = (h - this.$clear.height()) / 2;
//this.$clear.css({bottom: delta, right: delta});
}
*/
*/
},
//show / hide clear button
toggleClear: function(e) {
if(!this.$clear) {
return;
}
var len = this.$input.val().length,
visible = this.$clear.is(':visible');
if(len && !visible) {
this.$clear.show();
}
}
if(!len && visible) {
this.$clear.hide();
}
}
},
clear: function() {
this.$clear.hide();
this.$input.val('').focus();
}
}
});
Text.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
/**
@property tpl
@property tpl
@default <input type="text">
**/
**/
tpl: '<input type="text">',
/**
Placeholder attribute of input. Shown when input is empty.
@property placeholder
@property placeholder
@type string
@default null
**/
**/
placeholder: null,
/**
Whether to show `clear` button
@property clear
Whether to show `clear` button
@property clear
@type boolean
@default true
@default true
**/
clear: true
});
+1 -1
View File
@@ -20,7 +20,7 @@
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="qunit-fixture1"></div>
<div id="qunit-fixture1" style="margin: 100px"></div>
<div id="async-fixture" style="padding-left:300px"></div>
<script src="libs/qunit/qunit-1.12.0.js"></script>
</body>
+26
View File
@@ -73,5 +73,31 @@ $(function () {
var p = tip(e);
equal(p.find('input[type="checkbox"]:checked').length, 1, 'checked count ok');
});
test("`escape` option", function () {
var t = '<b>hello</b>',
esc = '&lt;b&gt;hello&lt;/b&gt;',
e = $('<a href="#" data-type="checklist"></a>').appendTo('#qunit-fixture').editable({
source: [{value: 'a', text: esc}],
value: ['a'],
escape: true
}),
e1 = $('<a href="#" data-type="checklist"></a>').appendTo('#qunit-fixture').editable({
source: [{value: 'a', text: esc}],
value: ['a'],
escape: false
});
equal(e.text(), esc, 'html escaped');
e.click();
var p = tip(e);
equal($.trim(p.find('label > span').eq(0).text()), esc, 'option escaped');
e.remove();
equal(e1.text(), t, 'html not escaped');
e1.click();
var p1 = tip(e1);
equal($.trim(p1.find('label > span').eq(0).text()), t, 'option not escaped');
});
});
+16 -6
View File
@@ -793,19 +793,29 @@ $(function () {
});
test("`escape` option", function () {
var e = $('<a href="#" data-type="select"></a>').appendTo('#qunit-fixture').editable({
source: [{value: 'a', text: '<b>hello</b>'}],
var t = '<b>hello</b>',
esc = '&lt;b&gt;hello&lt;/b&gt;',
e = $('<a href="#" data-type="select"></a>').appendTo('#qunit-fixture').editable({
source: [{value: 'a', text: esc}],
value: 'a',
escape: true
}),
e1 = $('<a href="#" data-type="select"></a>').appendTo('#qunit-fixture').editable({
source: [{value: 'a', text: '<b>hello</b>'}],
source: [{value: 'a', text: esc}],
value: 'a',
escape: false
});
equal(e.html(), '&lt;b&gt;hello&lt;/b&gt;', 'html escaped');
equal(e1.html(), '<b>hello</b>', 'html not escaped');
equal(e.text(), esc, 'text equals, html escaped');
e.click();
var p = tip(e);
equal(p.find('select').find('option').eq(0).text(), esc, 'option escaped');
e.remove();
equal(e1.text(), t, 'html not escaped');
e1.click();
var p1 = tip(e1);
equal(p1.find('select').find('option').eq(0).text(), t, 'option not escaped');
});
asyncTest("sourceOptions", function () {
+16 -2
View File
@@ -576,6 +576,20 @@ $(function () {
ok(p.find('input').length, 'input exists');
equal(p.find('input').val(), 'qwe', 'default text not set as element not empty');
});
test("should able to submit a value which changed 0 to ''(empty string)", function () {
var e = $('<a href="#" data-name="text1"></a>').appendTo('#qunit-fixture').editable({
value: '0'
});
//empty text
e.click();
var p = tip(e);
equal(p.find('input').val(), '0', 'text value is 0 ok');
p.find('input').val('');
p.find('form').submit();
e.click();
equal(p.find('input').val(), '', 'text changed to \'\' ok');
});
});
});
+35 -2
View File
@@ -30,8 +30,8 @@ $(function () {
equal(e.data().editable.value, v, 'initial value ok');
e.click();
var p = tip(e),
$input = p.find('input.tt-query');
var p = tip(e);
var $input = p.find('input.tt-query');
ok(p.is(':visible'), 'popup visible');
ok($input.length, 'input exists');
@@ -62,5 +62,38 @@ $(function () {
}, timeout);
});
test("autosubmit ", function () {
var v = 'ru',
e = $('<a href="#" data-name="text1" data-type="typeaheadjs"></a>').appendTo(sfx).editable({
value: v,
showbuttons: false,
typeahead: {
name: 'country',
local: [
{value: 'ru', tokens: ['Russia']},
{value: 'gb', tokens: ['Great Britain']},
{value: 'us', tokens: ['United States']}
],
template: function(item) {
return item.tokens[0] + ' (' + item.value + ')';
}
}
}),
newText = 'abc';
e.click();
var p = tip(e);
var $input = p.find('input.tt-query');
// simutale <enter>
var ev = jQuery.Event("keydown");
ev.which = 13;
$input.val(newText).trigger(ev);
ok(!p.is(':visible'), 'popup closed');
equal(e.data('editable').value, newText, 'new text saved to value');
equal(e.text(), newText, 'new text shown');
});
});