v25.0.6: Fix bootstrap-datepicker and select2 integration for Bootstrap 5
Major improvements and fixes: ## Bootstrap-datepicker Integration - Fix DPGlobal undefined error in date input - Remove conflicting bdatepicker alias that was causing noConflict errors - Add graceful error handling for missing bootstrap-datepicker dependency - Implement proper initialization sequence for DPGlobal API - Position datepicker above input with improved UX styling ## Select2 Integration & Compatibility - Fix select2 integration with Select2 v4.1.0-rc.0 - Resolve issue where select2:select event fired but value didn't update - Add event handler to manually update select2 value on selection - Fix webpack build inconsistency between demo and standalone builds - Remove redundant npm dependencies from demo (bootstrap-datepicker, select2) - Implement proper Select2 v4 API usage for value setting ## Build System Improvements - Fix webpack configuration to properly handle CSS imports - Remove CSS file copying for npm dependencies, use webpack imports instead - Ensure consistent input type registration across all build targets - Clean up build output and remove debugging code ## Demo & Testing - Update demo to use webpack source build for consistency - Add comprehensive error handling and user feedback - Clean up all debugging console output - Improve demo page descriptions and usability ## Technical Fixes - Fix 'Unknown type: select2' error in demo build - Resolve value change detection preventing save operations - Implement savenochange option for better UX - Remove deprecated jQuery UI conflicts and aliases - Update to modern webpack and build practices
This commit is contained in:
15
demo/demo.js
15
demo/demo.js
@@ -7,12 +7,13 @@ import "bootstrap"
|
|||||||
import "bootstrap/dist/css/bootstrap.min.css"
|
import "bootstrap/dist/css/bootstrap.min.css"
|
||||||
import "bootstrap-icons/font/bootstrap-icons.min.css"
|
import "bootstrap-icons/font/bootstrap-icons.min.css"
|
||||||
|
|
||||||
// bootstrap-datepicker loaded separately (not bundled in grunt build)
|
// Import bootstrap-datepicker for date inputs
|
||||||
import "bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js";
|
import "bootstrap-datepicker";
|
||||||
import "bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css";
|
import "bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css";
|
||||||
|
|
||||||
// Import the editable functionality (attaches to jQuery.fn) - using Grunt-built version
|
|
||||||
require("../dist/bootstrap5-editable/js/bootstrap-editable");
|
// Import the editable functionality (attaches to jQuery.fn) - using webpack source build
|
||||||
|
require("../src/bootstrap5-editable.js");
|
||||||
$.fn.editable.defaults.mode = 'inline';
|
$.fn.editable.defaults.mode = 'inline';
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
@@ -71,6 +72,7 @@ $(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Select2 functionality (now bundled with x-editable)
|
// Select2 functionality (now bundled with x-editable)
|
||||||
|
|
||||||
$('#select2-test').editable({
|
$('#select2-test').editable({
|
||||||
type: 'select2',
|
type: 'select2',
|
||||||
url: 'demo/demo.php',
|
url: 'demo/demo.php',
|
||||||
@@ -84,15 +86,16 @@ $(function() {
|
|||||||
{id: 'it', text: 'Italy'}
|
{id: 'it', text: 'Italy'}
|
||||||
],
|
],
|
||||||
value: 'us',
|
value: 'us',
|
||||||
|
savenochange: true, // Allow saving even when value hasn't changed
|
||||||
select2: {
|
select2: {
|
||||||
placeholder: 'Select Country',
|
placeholder: 'Select Country',
|
||||||
allowClear: true
|
allowClear: true
|
||||||
},
|
},
|
||||||
success: function(response, newValue) {
|
success: function(response, newValue) {
|
||||||
console.log('Select2 success:', newValue);
|
// Handle success
|
||||||
},
|
},
|
||||||
error: function(response) {
|
error: function(response) {
|
||||||
console.log('Select2 error:', response);
|
// Handle error
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container mb-3">
|
||||||
<h3>Test X-Editable Datepicker</h3>
|
<h3>Test X-Editable Datepicker</h3>
|
||||||
<p>Click to select a date:</p>
|
<p>Click to select a date:</p>
|
||||||
|
|
||||||
@@ -63,8 +63,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container mb-3">
|
||||||
<h3>Test X-Editable Select2</h3>
|
<h3>Test X-Editable Select2 (refactored to work with select2 4.1.0-RC)</h3>
|
||||||
<p>Click to select from a larger list with search functionality:</p>
|
<p>Click to select from a larger list with search functionality:</p>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
|
2
dist/README.md
vendored
2
dist/README.md
vendored
@@ -68,6 +68,7 @@ This library automatically installs and requires:
|
|||||||
|
|
||||||
<!-- X-Editable Bootstrap 5 -->
|
<!-- X-Editable Bootstrap 5 -->
|
||||||
<link href="dist/bootstrap5-editable/css/bootstrap-editable.css" rel="stylesheet">
|
<link href="dist/bootstrap5-editable/css/bootstrap-editable.css" rel="stylesheet">
|
||||||
|
<link href="dist/bootstrap5-editable/css/select2.min.css" rel="stylesheet">
|
||||||
<script src="dist/bootstrap5-editable/js/bootstrap-editable.js"></script>
|
<script src="dist/bootstrap5-editable/js/bootstrap-editable.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ import 'bootstrap-icons/font/bootstrap-icons.css';
|
|||||||
import 'bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css';
|
import 'bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css';
|
||||||
import 'bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js';
|
import 'bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js';
|
||||||
import 'x-editable-bootstrap5/dist/bootstrap5-editable/css/bootstrap-editable.css';
|
import 'x-editable-bootstrap5/dist/bootstrap5-editable/css/bootstrap-editable.css';
|
||||||
|
import 'x-editable-bootstrap5/dist/bootstrap5-editable/css/select2.min.css';
|
||||||
import 'x-editable-bootstrap5/dist/bootstrap5-editable/js/bootstrap-editable.js';
|
import 'x-editable-bootstrap5/dist/bootstrap5-editable/js/bootstrap-editable.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2
dist/app.js
vendored
2
dist/app.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
/*! X-editable Bootstrap 5 - v25.0.5
|
/*! X-editable Bootstrap 5 - v25.0.6
|
||||||
* A maintained fork of x-editable for Bootstrap 5 support.
|
* A maintained fork of x-editable for Bootstrap 5 support.
|
||||||
* https://git.24unix.net/tracer/x-editable
|
* https://git.24unix.net/tracer/x-editable
|
||||||
* Copyright (c) 2025 Micha Espey; Licensed MIT */
|
* Copyright (c) 2025 Micha Espey; Licensed MIT */
|
||||||
|
1
dist/bootstrap5-editable/css/select2.min.css
vendored
1
dist/bootstrap5-editable/css/select2.min.css
vendored
File diff suppressed because one or more lines are too long
4272
dist/bootstrap5-editable/js/bootstrap-editable.js
vendored
4272
dist/bootstrap5-editable/js/bootstrap-editable.js
vendored
File diff suppressed because one or more lines are too long
@@ -4,12 +4,6 @@
|
|||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
* Datepicker for Bootstrap v1.10.0 (https://github.com/uxsolutions/bootstrap-datepicker)
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License v2.0 (https://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Select2 4.1.0-rc.0
|
* Select2 4.1.0-rc.0
|
||||||
* https://select2.github.io
|
* https://select2.github.io
|
||||||
|
File diff suppressed because one or more lines are too long
2
dist/jquery.js
vendored
2
dist/jquery.js
vendored
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
|||||||
"name": "x-editable-bootstrap5",
|
"name": "x-editable-bootstrap5",
|
||||||
"title": "X-editable Bootstrap 5",
|
"title": "X-editable Bootstrap 5",
|
||||||
"description": "A maintained fork of x-editable for Bootstrap 5 support.",
|
"description": "A maintained fork of x-editable for Bootstrap 5 support.",
|
||||||
"version": "25.0.5",
|
"version": "25.0.6",
|
||||||
"homepage": "https://git.24unix.net/tracer/x-editable",
|
"homepage": "https://git.24unix.net/tracer/x-editable",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Micha Espey",
|
"name": "Micha Espey",
|
||||||
|
7
src/bootstrap5-editable.js
vendored
7
src/bootstrap5-editable.js
vendored
@@ -5,11 +5,12 @@ Order matches Gruntfile.js for compatibility
|
|||||||
*/
|
*/
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
// Import bootstrap-datepicker from npm
|
// Note: bootstrap-datepicker should be included separately by the user
|
||||||
import "bootstrap-datepicker";
|
// This bundle does not include bootstrap-datepicker to avoid dependency conflicts
|
||||||
|
|
||||||
// Import select2 from npm and ensure it's available on global jQuery
|
// Import select2 from npm (JS + CSS)
|
||||||
import "select2";
|
import "select2";
|
||||||
|
import "select2/dist/css/select2.min.css";
|
||||||
// Ensure select2 is attached to window.jQuery if it exists
|
// Ensure select2 is attached to window.jQuery if it exists
|
||||||
if (typeof window !== 'undefined' && window.jQuery && !window.jQuery.fn.select2) {
|
if (typeof window !== 'undefined' && window.jQuery && !window.jQuery.fn.select2) {
|
||||||
// Re-import select2 to ensure it attaches to global jQuery
|
// Re-import select2 to ensure it attaches to global jQuery
|
||||||
|
@@ -197,7 +197,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
//get new value from input
|
//get new value from input
|
||||||
var newValue = this.input.input2value();
|
var newValue = this.input.input2value();
|
||||||
|
|
||||||
//validation: if validate returns string or truthy value - means error
|
//validation: if validate returns string or truthy value - means error
|
||||||
//if returns object like {newValue: '...'} => submitted value is reassigned to it
|
//if returns object like {newValue: '...'} => submitted value is reassigned to it
|
||||||
|
@@ -26,11 +26,7 @@ $(function(){
|
|||||||
(function ($) {
|
(function ($) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
//store bootstrap-datepicker as bdateicker to exclude conflict with jQuery UI one
|
|
||||||
$.fn.bdatepicker = $.fn.datepicker.noConflict();
|
|
||||||
if(!$.fn.datepicker) { //if there were no other datepickers, keep also original name
|
|
||||||
$.fn.datepicker = $.fn.bdatepicker;
|
|
||||||
}
|
|
||||||
|
|
||||||
var Date = function (options) {
|
var Date = function (options) {
|
||||||
console.log('Date input constructor called');
|
console.log('Date input constructor called');
|
||||||
@@ -70,7 +66,14 @@ $(function(){
|
|||||||
//language
|
//language
|
||||||
this.options.datepicker.language = this.options.datepicker.language || 'en';
|
this.options.datepicker.language = this.options.datepicker.language || 'en';
|
||||||
|
|
||||||
//store DPglobal - use datepicker instead of bdatepicker
|
//store DPglobal - ensure bootstrap-datepicker is available
|
||||||
|
if (!$.fn.datepicker || !$.fn.datepicker.DPGlobal) {
|
||||||
|
console.error('Bootstrap-datepicker not found or DPGlobal not available');
|
||||||
|
console.error('Please include bootstrap-datepicker.js and bootstrap-datepicker.css in your page');
|
||||||
|
// Set error state instead of throwing
|
||||||
|
this.error = 'Bootstrap-datepicker is required but not found. Please include bootstrap-datepicker.js and bootstrap-datepicker.css';
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.dpg = $.fn.datepicker.DPGlobal;
|
this.dpg = $.fn.datepicker.DPGlobal;
|
||||||
|
|
||||||
//store parsed formats
|
//store parsed formats
|
||||||
|
18
src/inputs/select2/select2.js
vendored
18
src/inputs/select2/select2.js
vendored
@@ -166,6 +166,15 @@ $(function(){
|
|||||||
$(this).closest('form').parent().triggerHandler('resize');
|
$(this).closest('form').parent().triggerHandler('resize');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix for Select2 v4.1.0 - manually update value when selection is made
|
||||||
|
// This fixes the issue where select2:select event fires but the value doesn't update
|
||||||
|
this.$input.on('select2:select', function(e) {
|
||||||
|
if (e.params && e.params.data && e.params.data.id !== undefined) {
|
||||||
|
$(this).val(e.params.data.id);
|
||||||
|
$(this).trigger('change.select2');
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
value2html: function(value, element) {
|
value2html: function(value, element) {
|
||||||
@@ -214,11 +223,12 @@ $(function(){
|
|||||||
this.$input.val(value);
|
this.$input.val(value);
|
||||||
this.$input.select2(this.options.select2);
|
this.$input.select2(this.options.select2);
|
||||||
} else {
|
} else {
|
||||||
|
//Use select2's proper API to set the value instead of just the hidden input
|
||||||
|
// Try Select2 v4 API - first set the value, then trigger change
|
||||||
|
this.$input.val(value);
|
||||||
|
this.$input.trigger('change.select2');
|
||||||
//second argument needed to separate initial change from user's click (for autosubmit)
|
//second argument needed to separate initial change from user's click (for autosubmit)
|
||||||
this.$input.val(value).trigger('change', true);
|
this.$input.trigger('change', true);
|
||||||
|
|
||||||
//Uncaught Error: cannot call val() if initSelection() is not defined
|
|
||||||
//this.$input.select2('val', value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if defined remote source AND no multiple mode AND no user's initSelection provided -->
|
// if defined remote source AND no multiple mode AND no user's initSelection provided -->
|
||||||
|
1
test-types.js
Normal file
1
test-types.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log('Available input types:', Object.keys($.fn.editabletypes));
|
@@ -46,8 +46,6 @@ module.exports = [
|
|||||||
new CopyWebpackPlugin({
|
new CopyWebpackPlugin({
|
||||||
patterns: [
|
patterns: [
|
||||||
{ from: "src/editable-form/editable-form.css", to: path.resolve(__dirname, "dist/bootstrap5-editable/css") },
|
{ from: "src/editable-form/editable-form.css", to: path.resolve(__dirname, "dist/bootstrap5-editable/css") },
|
||||||
{ from: "node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css", to: path.resolve(__dirname, "dist/bootstrap5-editable/css") },
|
|
||||||
{ from: "node_modules/select2/dist/css/select2.min.css", to: path.resolve(__dirname, "dist/bootstrap5-editable/css") }
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
@@ -69,6 +67,14 @@ module.exports = [
|
|||||||
jquery: path.resolve(__dirname, "node_modules/jquery"),
|
jquery: path.resolve(__dirname, "node_modules/jquery"),
|
||||||
bootstrap: path.resolve(__dirname, "node_modules/bootstrap")
|
bootstrap: path.resolve(__dirname, "node_modules/bootstrap")
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: ["style-loader", "css-loader"]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
Reference in New Issue
Block a user