diff --git a/package-lock.json b/package-lock.json
index 744ad22..0c0fb12 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "3.0.0",
"license": "MIT",
"dependencies": {
+ "flatpickr": "^4.6.13",
"front-matter": "^4.0.2",
"handlebars": "^4.7.7",
"html-entities": "^2.3.2",
@@ -5407,6 +5408,12 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/flatpickr": {
+ "version": "4.6.13",
+ "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz",
+ "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==",
+ "license": "MIT"
+ },
"node_modules/flatted": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
@@ -14419,8 +14426,7 @@
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
"integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"acorn-walk": {
"version": "7.2.0",
@@ -14486,15 +14492,13 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"ansi-colors": {
"version": "4.1.1",
@@ -17030,6 +17034,11 @@
"rimraf": "^3.0.2"
}
},
+ "flatpickr": {
+ "version": "4.6.13",
+ "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz",
+ "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw=="
+ },
"flatted": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
@@ -18521,8 +18530,7 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"jest-regex-util": {
"version": "27.0.6",
@@ -22683,8 +22691,7 @@
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"xml-name-validator": {
"version": "3.0.0",
diff --git a/package.json b/package.json
index a135cfc..e720439 100644
--- a/package.json
+++ b/package.json
@@ -51,6 +51,7 @@
"yargs": "^16.2.0"
},
"dependencies": {
+ "flatpickr": "^4.6.13",
"front-matter": "^4.0.2",
"handlebars": "^4.7.7",
"html-entities": "^2.3.2",
diff --git a/src/parser.ts b/src/parser.ts
index 8234bce..4de23bb 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -7,6 +7,7 @@ import { Note } from "./utils/templates";
import { notEmpty } from "./utils/typescript";
import { getVariableFromDefinition } from "./variables/parser";
import { CustomVariable } from "./variables/types/base";
+import { DateCustomVariable } from "./variables/types/date";
import { setTemplateVariablesView } from "./views/templateVariables";
import { HelperFactory } from "./helpers";
@@ -90,6 +91,14 @@ export class Parser {
variableObjects[variableName] = getVariableFromDefinition(variableName, variables[variableName]);
});
+ // Inject the user's Joplin date format into each DateCustomVariable
+ // so the placeholder matches their configured format (fixes issue #112).
+ for (const variable of Object.values(variableObjects)) {
+ if (variable instanceof DateCustomVariable) {
+ variable.setDateFormat(this.utils.getDateFormat());
+ }
+ }
+
await setTemplateVariablesView(this.dialog, title, variableObjects);
const dialogResponse = (await joplin.views.dialogs.open(this.dialog));
diff --git a/src/variables/types/date.ts b/src/variables/types/date.ts
index 9647faf..b6be00b 100644
--- a/src/variables/types/date.ts
+++ b/src/variables/types/date.ts
@@ -5,12 +5,30 @@ import { CustomVariable } from "./base";
export class DateCustomVariable extends CustomVariable {
static definitionName = "date";
+ // The Joplin date format (e.g. "YYYY-MM-DD"), injected by parser.ts before rendering.
+ private dateFormat = "YYYY-MM-DD";
+
+ /**
+ * Called by parser.ts before the dialog is rendered so the flatpickr
+ * date picker can use the user's configured Joplin date format.
+ */
+ public setDateFormat(format: string): void {
+ this.dateFormat = format;
+ }
+
public processInput(input: string, dateAndTimeUtils: DateAndTimeUtils): string {
- const inputDate = new Date(input);
- return dateAndTimeUtils.formatMsToLocal(inputDate.getTime(), dateAndTimeUtils.getDateFormat());
+ // Parse the typed/picked date using Joplin's date format, then
+ // re-format it consistently with the same format.
+ return dateAndTimeUtils.formatMsToLocal(
+ dateAndTimeUtils.formatLocalToJoplinCompatibleUnixTime(input, dateAndTimeUtils.getDateFormat()),
+ dateAndTimeUtils.getDateFormat()
+ );
}
protected inputHTML(): string {
- return ``;
+ // Use type="text" so flatpickr (loaded in the dialog webview) can
+ // attach its custom calendar UI. The data-datepicker-format attribute
+ // tells datepicker.js which Joplin format to use (fixes issue #112).
+ return ``;
}
}
diff --git a/src/views/datepicker.js b/src/views/datepicker.js
new file mode 100644
index 0000000..1b1ca2f
--- /dev/null
+++ b/src/views/datepicker.js
@@ -0,0 +1,88 @@
+// datepicker.js — initializes flatpickr on all date inputs in the template dialog.
+// Runs inside Joplin's dialog webview (Electron/Chromium).
+
+(function () {
+ /**
+ * Converts a Joplin/moment.js date format string to a flatpickr format string.
+ * Only covers the date formats supported by Joplin's settings.
+ */
+ function momentToFlatpickr(momentFormat) {
+ return momentFormat
+ .replace(/YYYY/g, 'Y') // 4-digit year
+ .replace(/YY/g, 'y') // 2-digit year
+ .replace(/MM/g, 'm') // 2-digit month
+ .replace(/M/g, 'n') // 1-digit month (no leading zero)
+ .replace(/DD/g, 'd') // 2-digit day
+ .replace(/D/g, 'j'); // 1-digit day (no leading zero)
+ }
+
+ /**
+ * Replaces the flatpickr year with a