Fix datepicker functionality for Bootstrap 5 x-editable

- Updated Gruntfile to use npm bootstrap-datepicker instead of bundled version
- Fixed DPGlobal reference from bdatepicker to datepicker
- Changed mode from inline to popup to ensure date input type is used
- Fixed missing type assignment in editable element initialization
- Enhanced input2value function with fallback logic to extract dates from dates array
- Added comprehensive debugging and error handling
- Datepicker now properly opens, captures selections, and submits formatted dates
This commit is contained in:
Micha
2025-07-26 14:25:39 +02:00
parent 1dbf4d2fa7
commit f4dc8a3dd0
20 changed files with 571 additions and 38 deletions

8
.idea/.gitignore generated vendored Executable file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

31
.idea/cake_config_setting_v0_6.xml generated Executable file
View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CakeStormCakeSettings">
<option name="cakeVersionAbsorption">
<map>
<entry key="Controller" value="/controllers/" />
<entry key="View" value="/views/" />
<entry key="Model" value="/models/" />
<entry key="Helper" value="/views/helpers/" />
<entry key="Component" value="/controllers/components/" />
<entry key="Behavior" value="/models/behaviors/" />
<entry key="Plugin" value="plugins/" />
<entry key="Shell" value="/vendors/shell" />
<entry key="Task" value="/vendors/Shell/Task" />
<entry key="ControllerTest" value="/tests/cases/controllers/" />
<entry key="ModelTest" value="/tests/cases/models/" />
<entry key="BehaviorTest" value="/tests/cases/behaviors/" />
<entry key="ComponentTest" value="/tests/cases/components/" />
<entry key="HelperTest" value="/tests/cases/helpers/" />
<entry key="TestFile" value="test" />
<entry key="FileSeparator" value="." />
<entry key="FileWordSeparator" value="_" />
<entry key="Fixture" value="/tests/fixtures/" />
<entry key="Element" value="elements/" />
<entry key="FixtureFile" value="fixture" />
<entry key="Layout" value="layouts/" />
</map>
</option>
<option name="cakeVersion" value="1" />
</component>
</project>

8
.idea/modules.xml generated Executable file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/x-editable.iml" filepath="$PROJECT_DIR$/.idea/x-editable.iml" />
</modules>
</component>
</project>

19
.idea/php.xml generated Executable file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

6
.idea/vcs.xml generated Executable file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

8
.idea/x-editable.iml generated Executable file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -53,7 +53,7 @@ function getFiles() {
form: [forms+'editable-form-bootstrap5.js'],
container: [containers+'editable-popover5.js'],
inputs: [
inputs+'date/bootstrap-datepicker/js/bootstrap-datepicker.js',
// Bootstrap-datepicker now loaded from npm, not bundled
inputs+'date/date.js',
inputs+'date/datefield.js',
inputs+'datetime/datetime.js',
@@ -64,7 +64,7 @@ function getFiles() {
//inputs+'typeahead.js'
],
css: [
inputs+'date/bootstrap-datepicker/css/datepicker.css'
// Bootstrap-datepicker CSS now loaded from npm, not bundled
//don't build datetime lib, should be included manually
//inputs+'datetime/bootstrap-datetimepicker/css/datetimepicker.css'
]

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

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,15 @@
/*!
* Bootstrap v5.3.3 (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* 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)
*/
/*!
* jQuery JavaScript Library v3.7.1
* https://jquery.com/

File diff suppressed because one or more lines are too long

256
package-lock.json generated
View File

@@ -8,6 +8,7 @@
"name": "@24unix/x-editable",
"version": "1.5.2",
"dependencies": {
"@anthropic-ai/claude-code": "^1.0.61",
"bootstrap": "^5.3.3",
"bootstrap-datepicker": "^1.10.0",
"bootstrap-icons": "^1.11.3",
@@ -32,6 +33,26 @@
"webpack-cli": "^6.0.1"
}
},
"node_modules/@anthropic-ai/claude-code": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.61.tgz",
"integrity": "sha512-+gjKzY1hsWfHoH52SgKR6E0ujCDPyyRsjyRShtZfS0urKd8VQq3D/DF3hvT3P4JJeW0YuWp5Dep0aSRON+/FFA==",
"license": "SEE LICENSE IN README.md",
"bin": {
"claude": "cli.js"
},
"engines": {
"node": ">=18.0.0"
},
"optionalDependencies": {
"@img/sharp-darwin-arm64": "^0.33.5",
"@img/sharp-darwin-x64": "^0.33.5",
"@img/sharp-linux-arm": "^0.33.5",
"@img/sharp-linux-arm64": "^0.33.5",
"@img/sharp-linux-x64": "^0.33.5",
"@img/sharp-win32-x64": "^0.33.5"
}
},
"node_modules/@babel/code-frame": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
@@ -67,6 +88,215 @@
"node": ">=14.17.0"
}
},
"node_modules/@img/sharp-darwin-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
"integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-darwin-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
"integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-darwin-x64": "1.0.4"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
"integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
"integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"darwin"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
"integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
"cpu": [
"arm"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
"integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
"cpu": [
"arm64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
"integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
"cpu": [
"x64"
],
"license": "LGPL-3.0-or-later",
"optional": true,
"os": [
"linux"
],
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-linux-arm": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
"integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
"cpu": [
"arm"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm": "1.0.5"
}
},
"node_modules/@img/sharp-linux-arm64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
"integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-arm64": "1.0.4"
}
},
"node_modules/@img/sharp-linux-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
"integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
"@img/sharp-libvips-linux-x64": "1.0.4"
}
},
"node_modules/@img/sharp-win32-x64": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
"integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND LGPL-3.0-or-later",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
@@ -801,9 +1031,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3409,9 +3639,9 @@
"license": "MIT"
},
"node_modules/morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz",
"integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3419,7 +3649,7 @@
"debug": "2.6.9",
"depd": "~2.0.0",
"on-finished": "~2.3.0",
"on-headers": "~1.0.2"
"on-headers": "~1.1.0"
},
"engines": {
"node": ">= 0.8.0"
@@ -3562,9 +3792,9 @@
}
},
"node_modules/on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
"integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4850,9 +5080,9 @@
}
},
"node_modules/tar-fs": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz",
"integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz",
"integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -33,6 +33,7 @@
"module": "dist/bootstrap5-editable/js/bootstrap-editable.esm.js",
"style": "dist/bootstrap5-editable/css/bootstrap-editable.css",
"dependencies": {
"@anthropic-ai/claude-code": "^1.0.61",
"bootstrap": "^5.3.3",
"bootstrap-datepicker": "^1.10.0",
"bootstrap-icons": "^1.11.3",

32
src/bootstrap5-editable.js vendored Normal file
View File

@@ -0,0 +1,32 @@
/*
X-Editable Bootstrap 5 - Complete Bundle
Uses npm bootstrap-datepicker instead of bundled version
Order matches Gruntfile.js for compatibility
*/
import $ from "jquery";
// Import bootstrap-datepicker from npm
import "bootstrap-datepicker";
// Core editable functionality - EXACT ORDER from Gruntfile
import "./editable-form/editable-form.js";
import "./editable-form/editable-form-utils.js";
import "./containers/editable-container.js";
import "./containers/editable-inline.js";
import "./element/editable-element.js";
import "./inputs/abstract.js";
import "./inputs/list.js";
import "./inputs/text.js";
import "./inputs/textarea.js";
import "./inputs/select.js";
// Date input (now uses npm bootstrap-datepicker)
import "./inputs/date/date.js";
import "./inputs/date/datefield.js";
// Bootstrap 5 specific containers and forms
import "./containers/editable-popover5.js";
import "./editable-form/editable-form-bootstrap5.js";
// Export jQuery for compatibility
export default $;

View File

@@ -38,7 +38,10 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.input = $.fn.editableutils.createInput(this.options);
if(!this.input) {
return;
}
}
// Set the editable's type from the input's type
this.type = this.input.type;
//set value from settings or by element's text
if (this.options.value === undefined || this.options.value === null) {

View File

@@ -33,14 +33,27 @@ $(function(){
}
var Date = function (options) {
console.log("Date constructor called with options:", options);
this.init('date', options, Date.defaults);
this.initPicker(options, Date.defaults);
// Ensure type is set correctly
this.type = 'date';
console.log("Date constructor completed, type set to:", this.type);
};
$.fn.editableutils.inherit(Date, $.fn.editabletypes.abstractinput);
$.extend(Date.prototype, {
prerender: function() {
console.log("Date.prerender() called");
// Call parent prerender
Date.superclass.prerender.call(this);
console.log("Date.prerender() completed, $input:", this.$input[0]);
},
initPicker: function(options, defaults) {
console.log("Date.initPicker() called");
//'format' is set directly from settings or data-* attributes
//by default viewformat equals to format
@@ -60,8 +73,8 @@ $(function(){
//language
this.options.datepicker.language = this.options.datepicker.language || 'en';
//store DPglobal
this.dpg = $.fn.bdatepicker.DPGlobal;
//store DPglobal - use datepicker instead of bdatepicker
this.dpg = $.fn.datepicker.DPGlobal;
//store parsed formats
this.parsedFormat = this.dpg.parseFormat(this.options.format);
@@ -69,7 +82,31 @@ $(function(){
},
render: function () {
this.$input.bdatepicker(this.options.datepicker);
// Debug: Check if render is being called
console.log("Date.render() called, options:", this.options.datepicker);
console.log("Input element for datepicker:", this.$input[0]);
// Ensure we have an input element
if (!this.$input || !this.$input.length) {
console.error("No input element found in render()");
return;
}
// Initialize datepicker immediately
try {
console.log("Attempting datepicker initialization in render()...");
this.$input.datepicker(this.options.datepicker);
console.log("Datepicker initialized successfully in render()");
console.log("Datepicker data after render:", this.$input.data('datepicker'));
// Force set the initial value if we have one
if (this.value) {
console.log("Setting initial value in render():", this.value);
this.$input.datepicker('setDate', this.value);
}
} catch (error) {
console.error("Error initializing datepicker in render():", error);
}
//"clear" link
if(this.options.clear) {
@@ -105,11 +142,60 @@ $(function(){
},
value2input: function(value) {
this.$input.bdatepicker('update', value);
console.log("Date.value2input() called with value:", value);
console.log("Input element in value2input:", this.$input[0]);
console.log("Datepicker data in value2input:", this.$input.data('datepicker'));
// Ensure datepicker is initialized before trying to update
if (!this.$input.data('datepicker')) {
console.log("Datepicker not initialized in value2input, initializing now...");
this.$input.datepicker(this.options.datepicker);
console.log("Datepicker data after manual init in value2input:", this.$input.data('datepicker'));
}
this.$input.datepicker('update', value);
},
input2value: function() {
return this.$input.data('datepicker').date;
console.log("Date.input2value() called");
var datepicker = this.$input.data('datepicker');
console.log("Datepicker object in input2value:", datepicker);
if (datepicker) {
console.log("Datepicker.date:", datepicker.date);
console.log("Datepicker.dates:", datepicker.dates);
console.log("Datepicker.getDate():", typeof datepicker.getDate === 'function' ? datepicker.getDate() : 'getDate not available');
if (datepicker.date) {
console.log("Returning datepicker.date:", datepicker.date);
return datepicker.date;
}
// Try getting date from dates array
if (datepicker.dates && datepicker.dates.length > 0) {
console.log("Returning from dates array:", datepicker.dates[0]);
return datepicker.dates[0];
}
// Try using getDate method
if (typeof datepicker.getDate === 'function') {
var dateFromMethod = datepicker.getDate();
console.log("Returning from getDate():", dateFromMethod);
return dateFromMethod;
}
}
// Fallback: try to parse the input value directly
var inputVal = this.$input.val();
console.log("Input value fallback:", inputVal);
if (inputVal) {
var parsedDate = this.parseDate(inputVal, this.parsedViewFormat);
console.log("Parsed date fallback:", parsedDate);
return parsedDate;
}
console.log("input2value returning null - no valid date found");
return null;
},
activate: function() {

View File

@@ -26,6 +26,7 @@
href="#"
id="yes-no-switch"
class="editable editable-click"
data-pk="101"
>
Yes
</a>
@@ -39,7 +40,7 @@
id="yes-no-switch-json"
class="editable editable-click"
data-type="select"
data-pk="1"
data-pk="102"
data-title="Select Yes/No"
>
Yes
@@ -55,10 +56,10 @@
id="datepicker"
class="editable editable-click"
data-type="date"
data-pk="1"
data-pk="103"
data-title="Select Date"
>
Yes
Click to select date
</a>
</div>

100
test.js
View File

@@ -8,12 +8,16 @@ import "bootstrap"
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap-icons/font/bootstrap-icons.min.css"
// bootstrap-datepicker loaded separately (not bundled in grunt build)
import "bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js";
import "bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css";
const Editable = require("bootstrap5-editable/js/bootstrap-editable");
console.log("Editable:", Editable);
$.fn.editable.defaults.mode = 'inline';
// Import the editable functionality (attaches to jQuery.fn) - using Grunt-built version
require("./dist/bootstrap5-editable/js/bootstrap-editable");
console.log("$.fn.editable available:", typeof $.fn.editable);
console.log("$.fn.datepicker available:", typeof $.fn.datepicker);
console.log("$.fn.bdatepicker available:", typeof $.fn.bdatepicker);
$.fn.editable.defaults.mode = 'popup';
$(function() {
@@ -58,6 +62,7 @@ $(function() {
$('#datepicker').editable({
type: 'date',
url: 'test.php', // URL to send the POST request
value: new Date().toISOString().split('T')[0], // Set to current date (YYYY-MM-DD)
format: 'yyyy-mm-dd', // Date format
viewformat: 'dd/mm/yyyy', // How the user sees it
datepicker: {
@@ -67,17 +72,92 @@ $(function() {
},
success: (response, newValue)=> {
console.log("Date saved successfully:", response);
console.log("New value received:", newValue);
},
error: (response) => {
console.error("Date save error:", response);
}
}).on('shown', (e, editable)=> {
console.log("Datepicker shown:", editable);
$(editable.input.$input).datepicker({
weekStart: 1,
autoclose: true,
todayHighlight: true
}).datepicker('show')
}).on('save', function(e, params) {
console.log("Date save event:", params);
console.log("Value being saved:", params.newValue);
console.log("Submit value:", params.submitValue);
}).on('shown', function(e, editable) {
console.log("Datepicker shown event fired", editable);
// Check if the type is now set
if (editable && editable.input) {
console.log("Input type after shown:", editable.input.type);
console.log("Editable type after shown:", editable.type);
}
// Debug: Check if datepicker elements exist in DOM
console.log("Looking for datepicker in DOM...");
console.log("Datepicker elements found:", $('.datepicker').length);
console.log("Bootstrap datepicker elements found:", $('.bootstrap-datepicker').length);
console.log("All datepicker classes:", $('[class*="datepicker"]').length);
// Check if any datepicker elements are visible
$('.datepicker, .bootstrap-datepicker, [class*="datepicker"]').each(function(i, el) {
console.log(`Datepicker element ${i}:`, {
class: el.className,
visible: $(el).is(':visible'),
display: $(el).css('display'),
position: $(el).css('position'),
zIndex: $(el).css('z-index')
});
});
// Debug the input element that should have datepicker
if (editable && editable.input && editable.input.$input) {
console.log("Input element:", editable.input.$input[0]);
console.log("Input datepicker data:", editable.input.$input.data('datepicker'));
// Check if bootstrap-datepicker functions are available on the input
console.log("Input $input.datepicker available:", typeof editable.input.$input.datepicker);
console.log("Input $input.bdatepicker available:", typeof editable.input.$input.bdatepicker);
// Try to manually initialize datepicker to see if it works
try {
console.log("Attempting manual datepicker initialization...");
editable.input.$input.datepicker({
weekStart: 1,
autoclose: true,
todayHighlight: true
});
console.log("Manual datepicker initialization successful!");
console.log("Input datepicker data after manual init:", editable.input.$input.data('datepicker'));
// Try setting a date value manually
editable.input.$input.datepicker('setDate', new Date());
console.log("Set manual date, datepicker data now:", editable.input.$input.data('datepicker'));
} catch (error) {
console.error("Manual datepicker initialization failed:", error);
}
}
}).on('hidden', function(e, reason) {
console.log("Datepicker hidden event fired, reason:", reason);
});
console.log("Datepicker element setup complete:", $('#datepicker').data('editable'));
// Wait a bit for initialization and then check again
setTimeout(function() {
console.log("=== CHECKING DATEPICKER AFTER TIMEOUT ===");
const datepickerEd = $('#datepicker').data('editable');
if (datepickerEd) {
console.log("DATEPICKER TYPE:", datepickerEd.type, "OPTIONS:", datepickerEd.options);
console.log("DATEPICKER INPUT:", datepickerEd.input);
if (datepickerEd.input) {
console.log("DATEPICKER INPUT TYPE:", typeof datepickerEd.input);
console.log("DATEPICKER INPUT CONSTRUCTOR:", datepickerEd.input.constructor.name);
console.log("DATEPICKER INPUT internal type:", datepickerEd.input.type);
}
} else {
console.log("NO DATEPICKER EDITABLE DATA FOUND!");
}
// Also check available input types
console.log("Available input types:", Object.keys($.fn.editabletypes || {}));
}, 100);
})

View File

@@ -46,6 +46,7 @@ module.exports = [
new CopyWebpackPlugin({
patterns: [
{ 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/bootstrap-icons/font/fonts", to: path.resolve(__dirname, "dist/fonts") }
]
})
@@ -54,7 +55,7 @@ module.exports = [
// X-Editable Plugin (Bootstrap 5)
{
entry: "./src/editable-form/editable-form-bootstrap5.js",
entry: "./src/bootstrap5-editable.js",
output: {
path: path.resolve(__dirname, "dist/bootstrap5-editable/js"), // X-Editable stays here
filename: "bootstrap-editable.js",