Merge branch 'bootstrap-5.3'

This commit is contained in:
Micha 2025-02-21 17:25:47 +01:00
commit aab5a76501
31 changed files with 14529 additions and 340 deletions

@ -47,7 +47,28 @@ function getFiles() {
//don't build datetime lib, should be included manually //don't build datetime lib, should be included manually
//inputs+'datetime/bootstrap-datetimepicker/css/datetimepicker.css' //inputs+'datetime/bootstrap-datetimepicker/css/datetimepicker.css'
] ]
}, },
bootstrap5: {
filePrefix: 'bootstrap', //to have bootstrap-editable.js instead of bootstrap3-editable
form: [forms+'editable-form-bootstrap5.js'],
container: [containers+'editable-popover5.js'],
inputs: [
inputs+'date/bootstrap-datepicker/js/bootstrap-datepicker.js',
inputs+'date/date.js',
inputs+'date/datefield.js',
inputs+'datetime/datetime.js',
inputs+'datetime/datetimefield.js'
//don't build datetime lib, should be included manually
//inputs+'datetime/bootstrap-datetimepicker/js/bootstrap-datetimepicker.js',
//no typeahead in bs3
//inputs+'typeahead.js'
],
css: [
inputs+'date/bootstrap-datepicker/css/datepicker.css'
//don't build datetime lib, should be included manually
//inputs+'datetime/bootstrap-datetimepicker/css/datetimepicker.css'
]
},
jqueryui: { jqueryui: {
form: [forms+'editable-form-jqueryui.js'], form: [forms+'editable-form-jqueryui.js'],
container: [containers+'editable-tooltip.js'], container: [containers+'editable-tooltip.js'],
@ -165,7 +186,7 @@ module.exports = function(grunt) {
'* <%= pkg.description %>\n' + '* <%= pkg.description %>\n' +
'* <%= pkg.homepage %>\n' + '* <%= pkg.homepage %>\n' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n'; ' Licensed <%= _.map(pkg.licenses, "type").join(", ") %> */\n';
files.concat_files.options = {banner: banner}; files.concat_files.options = {banner: banner};
files.min_files.options = {banner: banner}; files.min_files.options = {banner: banner};
@ -232,6 +253,7 @@ module.exports = function(grunt) {
jshint: { jshint: {
options: { options: {
esversion: 6,
curly: true, curly: true,
eqeqeq: true, eqeqeq: true,
immed: true, immed: true,

138
README.md

@ -1,137 +1,3 @@
# X-editable This is a fork of: https://github.com/vitalets/x-editable
In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery.
> ### :warning: Deprecation notice I needed to work with Bootstrap 5
>
> This library is **deprecated** and will no longer receive any updates or support.
> Please consider migrating to alternative solutions. See [#610](https://github.com/vitalets/x-editable/issues/610) for details.
## Live Demo
**http://vitalets.github.io/x-editable/demo.html**
## Pull Requests
Please submit all Pull Requests to the `develop` branch: https://github.com/vitalets/x-editable/tree/develop
## Issue Tracker
Please report all issues here: https://github.com/vitalets/x-editable/issues
## Documentation
**http://vitalets.github.io/x-editable**
## Project Status
Actively maintained
## How to get it
### Manual download
Use **http://vitalets.github.io/x-editable** main page.
### Bower
````
bower install x-editable
````
### CDN
Bootstrap 3 build:
````html
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
````
Bootstrap 2 build:
````html
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap-editable/js/bootstrap-editable.min.js"></script>
````
jQuery UI build:
````html
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jqueryui-editable/css/jqueryui-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jqueryui-editable/js/jqueryui-editable.min.js"></script>
````
jQuery only build:
````html
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jquery-editable/css/jquery-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jquery-editable/js/jquery-editable-poshytip.min.js"></script>
````
## Reporting issues
Please **provide jsFiddle** when creating issues!
It's really saves much time. Use these as template:
1. [jsFiddle Bootstrap 3](http://jsfiddle.net/xBB5x/2265/)
2. [jsFiddle Bootstrap 2](http://jsfiddle.net/xBB5x/1817/)
3. [jsFiddle jQuery-ui](http://jsfiddle.net/xBB5x/2511/)
4. [jsFiddle jQuery](http://jsfiddle.net/xBB5x/197)
Your feedback is very appreciated!
## Contribution
A few steps how to start contributing.
Assuming you have [Node.js](http://nodejs.org/) already installed.
1.Fork *X-editable* on github and clone it to your local mashine:
````
git clone https://github.com/<your-github-name>/x-editable.git -b dev
````
2.Install *grunt-cli* globally (if not yet):
````
npm i -g grunt-cli
````
3.Install dependencies:
````
cd x-editable
npm i
````
4.Make your changes:
````
vim editable-form.js
````
5.Write some tests for your changes:
````
vim /test/unit/*.js
````
6.Run tests in cli:
````
grunt test
````
or directly in browser:
````
grunt server
````
and open http://127.0.0.1:8000/test
By default test run on bootstrap 3 popup version, but you can test any other build:
* bootstrap 3
* popup: http://127.0.0.1:8000/test/?f=bootstrap3&c=popup
* inline: http://127.0.0.1:8000/test/?f=bootstrap3&c=inline
* bootstrap 2
* popup: http://127.0.0.1:8000/test/?f=bootstrap2&c=popup
* inline: http://127.0.0.1:8000/test/?f=bootstrap2&c=inline
* jquery-ui
* popup: http://127.0.0.1:8000/test/?f=jqueryui&c=popup
* inline: http://127.0.0.1:8000/test/?f=jqueryui&c=inline
* jquery + poshytip
* popup: http://127.0.0.1:8000/test/?f=plain&c=popup
* inline: http://127.0.0.1:8000/test/?f=plain&c=inline
7.Commit and push back on github:
````
git add .
git commit -m'refactor editable form, fix #123'
git push origin
````
8.Make pull request on github (to `dev` branch).
Thanks for your support!
### Local build
To build x-editable locally please run:
````
grunt build
````
Result will appear in `dist` directory.
## License
Copyright (c) 2012 Vitaliy Potapov
Licensed under the MIT license.

BIN
dist/39795c0b4513de014cf8.woff vendored Normal file

Binary file not shown.

125
dist/README.md vendored

@ -1,124 +1,3 @@
# X-editable This is a fork of: https://github.com/vitalets/x-editable
In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery. I needed to work with Bootstrap 5
## Live demo
**http://vitalets.github.io/x-editable/demo.html**
## Documentation
**http://vitalets.github.io/x-editable**
## How to get it
### Manual download
Use **http://vitalets.github.io/x-editable** main page.
### Bower
````
bower install x-editable
````
### CDN
Bootstrap 3 build:
````js
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap3-editable/js/bootstrap-editable.min.js"></script>
````
Bootstrap 2 build:
````js
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap-editable/css/bootstrap-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/bootstrap-editable/js/bootstrap-editable.min.js"></script>
````
jQuery UI build:
````js
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jqueryui-editable/css/jqueryui-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jqueryui-editable/js/jqueryui-editable.min.js"></script>
````
jQuery only build:
````js
<link href="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jquery-editable/css/jquery-editable.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.0/jquery-editable/js/jquery-editable-poshytip.min.js"></script>
````
## Reporting issues
Please **provide jsFiddle** when creating issues!
It's really saves much time. Use these as template:
1. [jsFiddle Bootstrap 3](http://jsfiddle.net/xBB5x/2265/)
2. [jsFiddle Bootstrap 2](http://jsfiddle.net/xBB5x/1817/)
3. [jsFiddle jQuery-ui](http://jsfiddle.net/xBB5x/2511/)
4. [jsFiddle jQuery](http://jsfiddle.net/xBB5x/197)
Your feedback is very appreciated!
## Contribution
A few steps how to start contributing.
Assuming you have [Node.js](http://nodejs.org/) already installed.
1.Fork *X-editable* on github and clone it to your local mashine:
````
git clone https://github.com/<your-github-name>/x-editable.git -b dev
````
2.Install *grunt-cli* globally (if not yet):
````
npm i -g grunt-cli
````
3.Install dependencies:
````
cd x-editable
npm i
````
4.Make your changes:
````
vim editable-form.js
````
5.Write some tests for your changes:
````
vim /test/unit/*.js
````
6.Run tests in cli:
````
grunt test
````
or directly in browser:
````
grunt server
````
and open http://127.0.0.1:8000/test
By default test run on bootstrap 3 popup version, but you can test any other build:
* bootstrap 3
* popup: http://127.0.0.1:8000/test/?f=bootstrap3&c=popup
* inline: http://127.0.0.1:8000/test/?f=bootstrap3&c=inline
* bootstrap 2
* popup: http://127.0.0.1:8000/test/?f=bootstrap2&c=popup
* inline: http://127.0.0.1:8000/test/?f=bootstrap2&c=inline
* jquery-ui
* popup: http://127.0.0.1:8000/test/?f=jqueryui&c=popup
* inline: http://127.0.0.1:8000/test/?f=jqueryui&c=inline
* jquery + poshytip
* popup: http://127.0.0.1:8000/test/?f=plain&c=popup
* inline: http://127.0.0.1:8000/test/?f=plain&c=inline
7.Commit and push back on github:
````
git add .
git commit -m'refactor editable form, fix #123'
git push origin
````
8.Make pull request on github (to `dev` branch).
Thanks for your support!
### Local build
To build x-editable locally please run:
````
grunt build
````
Result will appear in `dist` directory.
## License
Copyright (c) 2012 Vitaliy Potapov
Licensed under the MIT license.

BIN
dist/b7bcc075b395c14ce8c2.woff2 vendored Normal file

Binary file not shown.

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
.editableform { .editableform {
margin-bottom: 0; /* overwrites bootstrap margin */ margin-bottom: 0; /* overwrites bootstrap margin */
} }
@ -12,6 +12,16 @@
line-height: 20px; /* overwriting bootstrap line-height. See #133 */ line-height: 20px; /* overwriting bootstrap line-height. See #133 */
} }
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/* /*
BS3 width:1005 for inputs breaks editable form in popup BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393 See: https://github.com/vitalets/x-editable/issues/393
@ -145,6 +155,7 @@
.editable-pre-wrapped { .editable-pre-wrapped {
white-space: pre-wrap; 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 */
} }

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
/** /**
Form with single input element, two buttons and two states: normal/loading. 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. Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@ -1040,7 +1040,7 @@ Applied as jQuery method.
.on({ .on({
save: $.proxy(this.save, this), //click on submit button (value changed) 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) 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() { show: $.proxy(function() {
if(this.delayedHide) { if(this.delayedHide) {
this.hide(this.delayedHide.reason); this.hide(this.delayedHide.reason);
@ -1630,16 +1630,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.options.display === false) { if(this.options.display === false) {
return; return;
} }
//if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded //if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded
if(this.input.value2htmlFinal) { if(this.input.value2htmlFinal) {
return this.input.value2html(this.value, this.$element[0], this.options.display, response); return this.input.value2html(this.value, this.$element[0], this.options.display, response);
//if display method defined --> use it //if display method defined --> use it
} else if(typeof this.options.display === 'function') { } else if(typeof this.options.display === 'function') {
return this.options.display.call(this.$element[0], this.value, response); return this.options.display.call(this.$element[0], this.value, response);
//else use input's original value2html() method //else use input's original value2html() method
} else { } else {
return this.input.value2html(this.value, this.$element[0]); return this.input.value2html(this.value, this.$element[0]);
} }
}, },
@ -2555,6 +2555,7 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, { $.extend(List.prototype, {
render: function () { render: function () {
var deferred = $.Deferred(); var deferred = $.Deferred();
this.error = null; this.error = null;
@ -3890,9 +3891,11 @@ $(function(){
}, },
destroy: function() { destroy: function() {
if(this.$input.data('select2')) { if(this.$input) {
this.$input.select2('destroy'); if(this.$input.data('select2')) {
} this.$input.select2('destroy');
}
}
} }
}); });
@ -4418,7 +4421,7 @@ $(function(){
//initial value, can be `new Date()` //initial value, can be `new Date()`
value: null, value: null,
minYear: 1970, minYear: 1970,
maxYear: 2015, maxYear: (new Date().getFullYear()),
yearDescending: true, yearDescending: true,
minuteStep: 5, minuteStep: 5,
secondStep: 1, secondStep: 1,
@ -4429,6 +4432,7 @@ $(function(){
}; };
}(window.jQuery)); }(window.jQuery));
/** /**
Combodate input - dropdown date and time picker. Combodate input - dropdown date and time picker.
Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com). Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com).

File diff suppressed because one or more lines are too long

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
.editableform { .editableform {
margin-bottom: 0; /* overwrites bootstrap margin */ margin-bottom: 0; /* overwrites bootstrap margin */
} }
@ -12,6 +12,16 @@
line-height: 20px; /* overwriting bootstrap line-height. See #133 */ line-height: 20px; /* overwriting bootstrap line-height. See #133 */
} }
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/* /*
BS3 width:1005 for inputs breaks editable form in popup BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393 See: https://github.com/vitalets/x-editable/issues/393
@ -145,6 +155,7 @@
.editable-pre-wrapped { .editable-pre-wrapped {
white-space: pre-wrap; 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 */
} }

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
/** /**
Form with single input element, two buttons and two states: normal/loading. 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. Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@ -1040,7 +1040,7 @@ Applied as jQuery method.
.on({ .on({
save: $.proxy(this.save, this), //click on submit button (value changed) 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) 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() { show: $.proxy(function() {
if(this.delayedHide) { if(this.delayedHide) {
this.hide(this.delayedHide.reason); this.hide(this.delayedHide.reason);
@ -1630,16 +1630,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.options.display === false) { if(this.options.display === false) {
return; return;
} }
//if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded //if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded
if(this.input.value2htmlFinal) { if(this.input.value2htmlFinal) {
return this.input.value2html(this.value, this.$element[0], this.options.display, response); return this.input.value2html(this.value, this.$element[0], this.options.display, response);
//if display method defined --> use it //if display method defined --> use it
} else if(typeof this.options.display === 'function') { } else if(typeof this.options.display === 'function') {
return this.options.display.call(this.$element[0], this.value, response); return this.options.display.call(this.$element[0], this.value, response);
//else use input's original value2html() method //else use input's original value2html() method
} else { } else {
return this.input.value2html(this.value, this.$element[0]); return this.input.value2html(this.value, this.$element[0]);
} }
}, },
@ -2555,6 +2555,7 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, { $.extend(List.prototype, {
render: function () { render: function () {
var deferred = $.Deferred(); var deferred = $.Deferred();
this.error = null; this.error = null;
@ -3890,9 +3891,11 @@ $(function(){
}, },
destroy: function() { destroy: function() {
if(this.$input.data('select2')) { if(this.$input) {
this.$input.select2('destroy'); if(this.$input.data('select2')) {
} this.$input.select2('destroy');
}
}
} }
}); });
@ -4418,7 +4421,7 @@ $(function(){
//initial value, can be `new Date()` //initial value, can be `new Date()`
value: null, value: null,
minYear: 1970, minYear: 1970,
maxYear: new Date().getFullYear(), maxYear: (new Date().getFullYear()),
yearDescending: true, yearDescending: true,
minuteStep: 5, minuteStep: 5,
secondStep: 1, secondStep: 1,
@ -4429,6 +4432,7 @@ $(function(){
}; };
}(window.jQuery)); }(window.jQuery));
/** /**
Combodate input - dropdown date and time picker. Combodate input - dropdown date and time picker.
Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com). Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com).
@ -6804,4 +6808,4 @@ Automatically shown in inline mode.
$.fn.editabletypes.datetimefield = DateTimeField; $.fn.editabletypes.datetimefield = DateTimeField;
}(window.jQuery)); }(window.jQuery));

File diff suppressed because one or more lines are too long

@ -0,0 +1,674 @@
/*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
.editableform .control-group {
margin-bottom: 0; /* overwrites bootstrap margin */
white-space: nowrap; /* prevent wrapping buttons on new line */
line-height: 20px; /* overwriting bootstrap line-height. See #133 */
}
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/*
BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393
*/
.editableform .form-control {
width: auto;
}
.editable-buttons {
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
vertical-align: top;
margin-left: 7px;
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-buttons.editable-buttons-bottom {
display: block;
margin-top: 7px;
margin-left: 0;
}
.editable-input {
vertical-align: top;
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
white-space: normal; /* reset white-space decalred in parent*/
/* display-inline emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-buttons .editable-cancel {
margin-left: 7px;
}
/*for jquery-ui buttons need set height to look more pretty*/
.editable-buttons button.ui-button-icon-only {
height: 24px;
width: 30px;
}
.editableform-loading {
background: url('../img/loading.gif') center center no-repeat;
height: 25px;
width: auto;
min-width: 25px;
}
.editable-inline .editableform-loading {
background-position: left 5px;
}
.editable-error-block {
max-width: 300px;
margin: 5px 0 0 0;
width: auto;
white-space: normal;
}
/*add padding for jquery ui*/
.editable-error-block.ui-state-error {
padding: 3px;
}
.editable-error {
color: red;
}
/* ---- For specific types ---- */
.editableform .editable-date {
padding: 0;
margin: 0;
float: left;
}
/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
.editable-inline .add-on .icon-th {
margin-top: 3px;
margin-left: 1px;
}
/* checklist vertical alignment */
.editable-checklist label input[type="checkbox"],
.editable-checklist label span {
vertical-align: middle;
margin: 0;
}
.editable-checklist label {
white-space: nowrap;
}
/* set exact width of textarea to fit buttons toolbar */
.editable-wysihtml5 {
width: 566px;
height: 250px;
}
/* clear button shown as link in date inputs */
.editable-clear {
clear: both;
font-size: 0.9em;
text-decoration: none;
text-align: right;
}
/* IOS-style clear button for text inputs */
.editable-clear-x {
background: url('../img/clear.png') center center no-repeat;
display: block;
width: 13px;
height: 13px;
position: absolute;
opacity: 0.6;
z-index: 100;
top: 50%;
right: 6px;
margin-top: -6px;
}
.editable-clear-x:hover {
opacity: 1;
}
.editable-pre-wrapped {
white-space: pre-wrap;
}
.editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
}
.editable-container.popover {
width: auto; /* without this rule popover does not stretch */
}
.editable-container.editable-inline {
display: inline-block;
vertical-align: middle;
width: auto;
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-container.ui-widget {
font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
}
.editable-click,
a.editable-click,
a.editable-click:hover {
text-decoration: none;
border-bottom: dashed 1px #0088cc;
}
.editable-click.editable-disabled,
a.editable-click.editable-disabled,
a.editable-click.editable-disabled:hover {
color: #585858;
cursor: default;
border-bottom: none;
}
.editable-empty, .editable-empty:hover, .editable-empty:focus{
font-style: italic;
color: #DD1144;
/* border-bottom: none; */
text-decoration: none;
}
.editable-unsaved {
font-weight: bold;
}
.editable-unsaved:after {
/* content: '*'*/
}
.editable-bg-transition {
-webkit-transition: background-color 1400ms ease-out;
-moz-transition: background-color 1400ms ease-out;
-o-transition: background-color 1400ms ease-out;
-ms-transition: background-color 1400ms ease-out;
transition: background-color 1400ms ease-out;
}
/*see https://github.com/vitalets/x-editable/issues/139 */
.form-horizontal .editable
{
padding-top: 5px;
display:inline-block;
}
/*!
* Datepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 6px;
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
top: -6px;
left: 7px;
}
.datepicker > div {
display: none;
}
.datepicker.days div.datepicker-days {
display: block;
}
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
}
.datepicker td,
.datepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(top, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #000;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active {
background-color: #fbf069 \9;
}
.datepicker table tr td.today:hover:hover {
color: #000;
}
.datepicker table tr td.today.active:hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
background-image: linear-gradient(top, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled] {
background-color: #f3e97a;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active {
background-color: #efe24b \9;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
background-color: #9e9e9e;
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
background-image: linear-gradient(top, #b3b3b3, #808080);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
border-color: #808080 #808080 #595959;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled] {
background-color: #808080;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active {
background-color: #666666 \9;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker th.datepicker-switch {
width: 145px;
}
.datepicker thead tr:first-child th,
.datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr:first-child th:hover,
.datepicker tfoot tr th:hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr:first-child th.cw {
cursor: default;
background-color: transparent;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i {
display: block;
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}
.input-daterange .add-on {
display: inline-block;
width: auto;
min-width: 16px;
height: 18px;
padding: 4px 5px;
font-weight: normal;
line-height: 18px;
text-align: center;
text-shadow: 0 1px 0 #ffffff;
vertical-align: middle;
background-color: #eeeeee;
border: 1px solid #ccc;
margin-left: -5px;
margin-right: -5px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1189
dist/bundle.js vendored Normal file

File diff suppressed because one or more lines are too long

68
dist/inputs-ext/slider/slider.js vendored Normal file

@ -0,0 +1,68 @@
/**
Slider, based on the Slider plugin by Stefan Petre (http://www.eyecon.ro/bootstrap-slider).
Make sure to include the plugin's code before using this editor.
@class slider
@extends text
@since 1.5.0
@final
**/
(function ($) {
"use strict";
var Constructor = function (options) {
this.init('slider', options, Constructor.defaults);
};
$.fn.editableutils.inherit(Constructor, $.fn.editabletypes.text);
$.extend(Constructor.prototype, {
render: function() {
// need to set kewdown handler before apply slider
// for correct autosubmit
this.isAutosubmit = false;
var that = this;
this.$input.on('keydown', function (e) {
if (!that.isAutosubmit) {
return;
}
if (e.which === 13) {
that.$input.closest('form').submit();
}
});
// apply slider
this.$input.slider(this.options.slider);
},
value2input: function(value) {
// make sure it's a number
if(typeof value!='number')
value=Number(value);
if(isNaN(value))
value=0;
this.$input.val(value);
this.$input.slider('setValue', value);
},
autosubmit: function() {
this.isAutosubmit = true;
}
});
Constructor.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
/**
@property tpl
@default <input type="text">
**/
tpl:'<input type="text">',
/**
**/
slider: null,
});
$.fn.editabletypes.slider = Constructor;
}(window.jQuery));

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
.editableform { .editableform {
margin-bottom: 0; /* overwrites bootstrap margin */ margin-bottom: 0; /* overwrites bootstrap margin */
} }
@ -12,6 +12,16 @@
line-height: 20px; /* overwriting bootstrap line-height. See #133 */ line-height: 20px; /* overwriting bootstrap line-height. See #133 */
} }
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/* /*
BS3 width:1005 for inputs breaks editable form in popup BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393 See: https://github.com/vitalets/x-editable/issues/393
@ -145,6 +155,7 @@
.editable-pre-wrapped { .editable-pre-wrapped {
white-space: pre-wrap; 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 */
} }

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
/** /**
Form with single input element, two buttons and two states: normal/loading. 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. Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@ -1040,7 +1040,7 @@ Applied as jQuery method.
.on({ .on({
save: $.proxy(this.save, this), //click on submit button (value changed) 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) 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() { show: $.proxy(function() {
if(this.delayedHide) { if(this.delayedHide) {
this.hide(this.delayedHide.reason); this.hide(this.delayedHide.reason);
@ -1630,16 +1630,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.options.display === false) { if(this.options.display === false) {
return; return;
} }
//if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded //if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded
if(this.input.value2htmlFinal) { if(this.input.value2htmlFinal) {
return this.input.value2html(this.value, this.$element[0], this.options.display, response); return this.input.value2html(this.value, this.$element[0], this.options.display, response);
//if display method defined --> use it //if display method defined --> use it
} else if(typeof this.options.display === 'function') { } else if(typeof this.options.display === 'function') {
return this.options.display.call(this.$element[0], this.value, response); return this.options.display.call(this.$element[0], this.value, response);
//else use input's original value2html() method //else use input's original value2html() method
} else { } else {
return this.input.value2html(this.value, this.$element[0]); return this.input.value2html(this.value, this.$element[0]);
} }
}, },
@ -2555,6 +2555,7 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, { $.extend(List.prototype, {
render: function () { render: function () {
var deferred = $.Deferred(); var deferred = $.Deferred();
this.error = null; this.error = null;
@ -3890,9 +3891,11 @@ $(function(){
}, },
destroy: function() { destroy: function() {
if(this.$input.data('select2')) { if(this.$input) {
this.$input.select2('destroy'); if(this.$input.data('select2')) {
} this.$input.select2('destroy');
}
}
} }
}); });
@ -4418,7 +4421,7 @@ $(function(){
//initial value, can be `new Date()` //initial value, can be `new Date()`
value: null, value: null,
minYear: 1970, minYear: 1970,
maxYear: 2015, maxYear: (new Date().getFullYear()),
yearDescending: true, yearDescending: true,
minuteStep: 5, minuteStep: 5,
secondStep: 1, secondStep: 1,
@ -4429,6 +4432,7 @@ $(function(){
}; };
}(window.jQuery)); }(window.jQuery));
/** /**
Combodate input - dropdown date and time picker. Combodate input - dropdown date and time picker.
Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com). Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com).

File diff suppressed because one or more lines are too long

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
.editableform { .editableform {
margin-bottom: 0; /* overwrites bootstrap margin */ margin-bottom: 0; /* overwrites bootstrap margin */
} }
@ -12,6 +12,16 @@
line-height: 20px; /* overwriting bootstrap line-height. See #133 */ line-height: 20px; /* overwriting bootstrap line-height. See #133 */
} }
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/* /*
BS3 width:1005 for inputs breaks editable form in popup BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393 See: https://github.com/vitalets/x-editable/issues/393
@ -145,6 +155,7 @@
.editable-pre-wrapped { .editable-pre-wrapped {
white-space: pre-wrap; 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 */
} }

@ -1,7 +1,7 @@
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable
* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ * Copyright (c) 2025 Vitaliy Potapov; Licensed MIT */
/** /**
Form with single input element, two buttons and two states: normal/loading. 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. Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
@ -1040,7 +1040,7 @@ Applied as jQuery method.
.on({ .on({
save: $.proxy(this.save, this), //click on submit button (value changed) 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) 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() { show: $.proxy(function() {
if(this.delayedHide) { if(this.delayedHide) {
this.hide(this.delayedHide.reason); this.hide(this.delayedHide.reason);
@ -1630,16 +1630,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.options.display === false) { if(this.options.display === false) {
return; return;
} }
//if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded //if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded
if(this.input.value2htmlFinal) { if(this.input.value2htmlFinal) {
return this.input.value2html(this.value, this.$element[0], this.options.display, response); return this.input.value2html(this.value, this.$element[0], this.options.display, response);
//if display method defined --> use it //if display method defined --> use it
} else if(typeof this.options.display === 'function') { } else if(typeof this.options.display === 'function') {
return this.options.display.call(this.$element[0], this.value, response); return this.options.display.call(this.$element[0], this.value, response);
//else use input's original value2html() method //else use input's original value2html() method
} else { } else {
return this.input.value2html(this.value, this.$element[0]); return this.input.value2html(this.value, this.$element[0]);
} }
}, },
@ -2555,6 +2555,7 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, { $.extend(List.prototype, {
render: function () { render: function () {
var deferred = $.Deferred(); var deferred = $.Deferred();
this.error = null; this.error = null;
@ -3890,9 +3891,11 @@ $(function(){
}, },
destroy: function() { destroy: function() {
if(this.$input.data('select2')) { if(this.$input) {
this.$input.select2('destroy'); if(this.$input.data('select2')) {
} this.$input.select2('destroy');
}
}
} }
}); });
@ -4418,7 +4421,7 @@ $(function(){
//initial value, can be `new Date()` //initial value, can be `new Date()`
value: null, value: null,
minYear: 1970, minYear: 1970,
maxYear: 2015, maxYear: (new Date().getFullYear()),
yearDescending: true, yearDescending: true,
minuteStep: 5, minuteStep: 5,
secondStep: 1, secondStep: 1,
@ -4429,6 +4432,7 @@ $(function(){
}; };
}(window.jQuery)); }(window.jQuery));
/** /**
Combodate input - dropdown date and time picker. Combodate input - dropdown date and time picker.
Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com). Based on [combodate](http://vitalets.github.com/combodate) plugin (included). To use it you should manually include [momentjs](http://momentjs.com).

File diff suppressed because one or more lines are too long

5233
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
{ {
"name": "X-editable", "name": "@24unix/x-editable",
"title": "X-editable", "title": "X-editable",
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery", "description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery",
"version": "1.5.1", "version": "1.5.1",
@ -21,17 +21,27 @@
"url": "https://github.com/vitalets/x-editable/blob/master/LICENSE-MIT" "url": "https://github.com/vitalets/x-editable/blob/master/LICENSE-MIT"
} }
], ],
"dependencies": {}, "dependencies": {
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3",
"jquery": "^3.7.1",
"jquery-ui": "^1.14.1",
"popper.js": "^1.16.1",
"webpack": "^5.98.0"
},
"devDependencies": { "devDependencies": {
"grunt": "~0.4.1", "css-loader": "^7.1.2",
"grunt-contrib-clean": "~0.5.0", "grunt": "^1.6.1",
"grunt-contrib-concat": "~0.3.0", "grunt-contrib-clean": "^2.0.1",
"grunt-contrib-uglify": "~0.2.2", "grunt-contrib-concat": "^2.1.0",
"grunt-contrib-qunit": "~0.2.2", "grunt-contrib-connect": "^5.0.1",
"grunt-contrib-connect": "~0.3.0", "grunt-contrib-copy": "^1.0.0",
"grunt-contrib-jshint": "~0.6.4", "grunt-contrib-jshint": "^3.2.0",
"grunt-contrib-copy": "~0.4.1", "grunt-contrib-qunit": "^10.1.1",
"grunt-contrib-requirejs": "~0.4.1" "grunt-contrib-requirejs": "^1.0.0",
"grunt-contrib-uglify": "^5.2.2",
"style-loader": "^4.0.0",
"webpack-cli": "^6.0.1"
}, },
"keywords": [] "keywords": []
} }

@ -0,0 +1,226 @@
/**
* Editable Popover3 (for Bootstrap 3)
* ---------------------
* requires bootstrap-popover.js
*/
(function ($) {
"use strict";
//extend methods
$.extend($.fn.editableContainer.Popup.prototype, {
containerName: 'popover',
containerDataName: 'bs.popover',
innerCss: '.popover-content',
defaults: $.fn.popover.Constructor.DEFAULTS,
initContainer: function(){
$.extend(this.containerOptions, {
trigger: 'manual',
selector: false,
content: ' ',
template: this.defaults.template
});
//as template property is used in inputs, hide it from popover
var t;
if(this.$element.data('template')) {
t = this.$element.data('template');
this.$element.removeData('template');
}
this.call(this.containerOptions);
if(t) {
//restore data('template')
this.$element.data('template', t);
}
},
/* show */
innerShow: function () {
this.call('show');
},
/* hide */
innerHide: function () {
this.call('hide');
},
/* destroy */
innerDestroy: function() {
this.call('destroy');
},
setContainerOption: function(key, value) {
this.container().options[key] = value;
},
/**
* move popover to new position. This function mainly copied from bootstrap-popover.
*/
/*jshint laxcomma: true, eqeqeq: false*/
setPosition: function () {
(function() {
/*
var $tip = this.tip()
, inside
, pos
, actualWidth
, actualHeight
, placement
, tp
, tpt
, tpb
, tpl
, tpr;
placement = typeof this.options.placement === 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement;
inside = /in/.test(placement);
$tip
// .detach()
//vitalets: remove any placement class because otherwise they dont influence on re-positioning of visible popover
.removeClass('top right bottom left')
.css({ top: 0, left: 0, display: 'block' });
// .insertAfter(this.$element);
pos = this.getPosition(inside);
actualWidth = $tip[0].offsetWidth;
actualHeight = $tip[0].offsetHeight;
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':
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;
case 'top':
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;
case 'left':
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;
case 'right':
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;
}
$tip
.offset(tp)
.addClass(placement)
.addClass('in');
*/
var $tip = this.tip();
var placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement;
var autoToken = /\s?auto?\s?/i;
var autoPlace = autoToken.test(placement);
if (autoPlace) {
placement = placement.replace(autoToken, '') || 'top';
}
var pos = this.getPosition();
var actualWidth = $tip[0].offsetWidth;
var actualHeight = $tip[0].offsetHeight;
if (autoPlace) {
var $parent = this.$element.parent();
var orgPlacement = placement;
var docScroll = document.documentElement.scrollTop || document.body.scrollTop;
var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth();
var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight();
var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left;
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
placement;
$tip
.removeClass(orgPlacement)
.addClass(placement);
}
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight);
this.applyPlacement(calculatedOffset, placement);
}).call(this.container());
/*jshint laxcomma: false, eqeqeq: true*/
}
});
}(window.jQuery));

@ -0,0 +1,64 @@
/*
Editableform based on Twitter Bootstrap 3
*/
(function ($) {
"use strict";
//store parent methods
const pInitInput = $.fn.editableform.Constructor.prototype.initInput;
$.extend($.fn.editableform.Constructor.prototype, {
// initTemplate: function() {
// this.$form = $($.fn.editableform.template);
// this.$form.find('.control-group').addClass('form-group');
// this.$form.find('.editable-error-block').addClass('help-block');
// },
initInput: function() {
pInitInput.apply(this);
//for bs3 set default class `input-sm` to standard inputs
const emptyInputClass = this.input.options.inputclass === null || this.input.options.inputclass === false;
const defaultClass = 'input-sm';
//bs3 add `form-control` class to standard inputs
const stdtypes = 'text,select,textarea,password,email,url,tel,number,range,time,typeaheadjs'.split(',');
if(~$.inArray(this.input.type, stdtypes)) {
this.input.$input.addClass('form-control editable');
if(emptyInputClass) {
this.input.options.inputclass = defaultClass;
this.input.$input.addClass(defaultClass);
}
}
// Automatically open select dropdown when clicked
if (this.input.type === 'select') {
setTimeout(() => {
this.input.$input.focus().click();
}, 50);
}
//apply bs3 size class also to buttons (to fit size of control)
const $btn = this.$form.find('.editable-buttons');
const classes = emptyInputClass ? [defaultClass] : this.input.options.inputclass.split(' ');
for(let i=0; i<classes.length; i++) {
if(classes[i].toLowerCase() === 'input-lg') {
$btn.find('button').removeClass('btn-sm').addClass('btn-lg');
}
}
}
});
//buttons
$.fn.editableform.buttons =
'<button type="submit" class="btn btn-primary btn-sm editable-submit">'+
'<i class="bi bi-check"></i>'+
'</button>'+
'<button type="button" class="btn btn-secondary btn-sm editable-cancel">'+
'<i class="bi bi-x"></i>'+
'</button>';
//error classes
$.fn.editableform.errorGroupClass = 'has-error';
$.fn.editableform.errorBlockClass = null;
//engine
$.fn.editableform.engine = 'bs3';
}(window.jQuery));

@ -170,16 +170,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.options.display === false) { if(this.options.display === false) {
return; return;
} }
//if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded //if input has `value2htmlFinal` method, we pass callback in third param to be called when source is loaded
if(this.input.value2htmlFinal) { if(this.input.value2htmlFinal) {
return this.input.value2html(this.value, this.$element[0], this.options.display, response); return this.input.value2html(this.value, this.$element[0], this.options.display, response);
//if display method defined --> use it //if display method defined --> use it
} else if(typeof this.options.display === 'function') { } else if(typeof this.options.display === 'function') {
return this.options.display.call(this.$element[0], this.value, response); return this.options.display.call(this.$element[0], this.value, response);
//else use input's original value2html() method //else use input's original value2html() method
} else { } else {
return this.input.value2html(this.value, this.$element[0]); return this.input.value2html(this.value, this.$element[0]);
} }
}, },

@ -15,6 +15,7 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, { $.extend(List.prototype, {
render: function () { render: function () {
var deferred = $.Deferred(); var deferred = $.Deferred();
this.error = null; this.error = null;

49
test.html Normal file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./dist/bootstrap3-editable/css/bootstrap-editable.css">
<script src="./node_modules/jquery/dist/jquery.js"></script>
<title>jQuery 3.7.1 & Bootstrap 5.3.3 Test</title>
</head>
<body>
<div class="container">
<h1 class="text-primary">jQuery 3.7.1 & Bootstrap 5.3.3 Test</h1>
</div>
<div class="container">
<h3>Test X-Editable Yes/No Switch</h3>
<p>Click on the text below to toggle Yes/No:</p>
<a href="#" id="yes-no-switch" class="editable editable-click" data-type="select" data-pk="1" data-url="/post" data-title="Select Yes/No">
Yes
</a>
</div>
<div id="debug"></div>
<script src="dist/bundle.js"></script>
<script type="module">
import './node_modules/bootstrap/dist/js/bootstrap.js';
import './dist/bootstrap5-editable/js/bootstrap-editable.js';
$(function() {
$.fn.editable.defaults.mode = 'inline'; // You can change to 'inline' if needed
$('#yes-no-switch').editable({
type: 'select',
source: [
{value: 'yes', text: 'Yes'},
{value: 'no', text: 'No'}
],
success: function(response, newValue) {
console.log("New value selected:", newValue);
}
});
});
</script>
</body>
</html>

10
test.js Normal file

@ -0,0 +1,10 @@
import $ from 'jquery';
window.jQuery = window.$ = $;
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap';
import 'bootstrap-icons/font/bootstrap-icons.css';
$(function () {
// do stuff
});

28
webpack.config.js Normal file

@ -0,0 +1,28 @@
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './test.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
mode: 'development',
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery'
})
]
};