@lemonadejs/calendar 5.2.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -88
- package/dist/index.d.ts +1 -1
- package/dist/index.js +268 -139
- package/dist/style.css +4 -4
- package/package.json +23 -23
package/README.md
CHANGED
|
@@ -1,88 +1,90 @@
|
|
|
1
|
-
# JavaScript Calendar
|
|
2
|
-
|
|
3
|
-
[Official JavaScript Calendar Documenation](https://lemonadejs.com/docs/plugins/calendar)
|
|
4
|
-
|
|
5
|
-
Compatible with Vanilla JavaScript, LemonadeJS, React, VueJS or Angular.
|
|
6
|
-
|
|
7
|
-
# JavaScript Calendar
|
|
8
|
-
|
|
9
|
-
Leverage the power of the LemonadeJS Calendar, a lightweight and versatile JavaScript component compatible with React, VueJS, and Angular. Designed to enhance web applications, it offers an embeddable calendar for easy date, time, and range selections. Key features include:
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
## Getting Started
|
|
17
|
-
|
|
18
|
-
You can install using NPM or using directly from a CDN.
|
|
19
|
-
|
|
20
|
-
### npm Installation
|
|
21
|
-
|
|
22
|
-
To install it in your project using npm, run the following command:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
$ npm install @lemonadejs/calendar
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### CDN
|
|
29
|
-
|
|
30
|
-
For immediate use without NPM, include these script tags in your HTML for access to the calendar and its dependencies:
|
|
31
|
-
|
|
32
|
-
```html
|
|
33
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/style.min.css" />
|
|
34
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/calendar/dist/style.min.css" />
|
|
35
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
|
|
36
|
-
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
|
|
37
|
-
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/index.min.js"></script>
|
|
38
|
-
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/calendar/dist/index.min.js"></script>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Usage
|
|
42
|
-
|
|
43
|
-
Quick example with ReactJS.
|
|
44
|
-
|
|
45
|
-
```javascript
|
|
46
|
-
import React, { useRef } from 'react';
|
|
47
|
-
import Calendar from '@lemonadejs/calendar/dist/react';
|
|
48
|
-
|
|
49
|
-
import
|
|
50
|
-
import
|
|
51
|
-
|
|
52
|
-
export default function App() {
|
|
53
|
-
const calendarRef = useRef();
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
# JavaScript Calendar
|
|
2
|
+
|
|
3
|
+
[Official JavaScript Calendar Documenation](https://lemonadejs.com/docs/plugins/calendar)
|
|
4
|
+
|
|
5
|
+
Compatible with Vanilla JavaScript, LemonadeJS, React, VueJS or Angular.
|
|
6
|
+
|
|
7
|
+
# JavaScript Calendar
|
|
8
|
+
|
|
9
|
+
Leverage the power of the LemonadeJS Calendar, a lightweight and versatile JavaScript component compatible with React, VueJS, and Angular. Designed to enhance web applications, it offers an embeddable calendar for easy date, time, and range selections. Key features include:
|
|
10
|
+
|
|
11
|
+
- Intuitive keyboard navigation.
|
|
12
|
+
- A reactive and responsive design for seamless device adaptation.
|
|
13
|
+
- Flexible range selection for various applications.
|
|
14
|
+
- Customizable options to match your project needs.
|
|
15
|
+
|
|
16
|
+
## Getting Started
|
|
17
|
+
|
|
18
|
+
You can install using NPM or using directly from a CDN.
|
|
19
|
+
|
|
20
|
+
### npm Installation
|
|
21
|
+
|
|
22
|
+
To install it in your project using npm, run the following command:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
$ npm install @lemonadejs/calendar
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### CDN
|
|
29
|
+
|
|
30
|
+
For immediate use without NPM, include these script tags in your HTML for access to the calendar and its dependencies:
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/style.min.css" />
|
|
34
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/calendar/dist/style.min.css" />
|
|
35
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
|
|
36
|
+
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
|
|
37
|
+
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/index.min.js"></script>
|
|
38
|
+
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/calendar/dist/index.min.js"></script>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Usage
|
|
42
|
+
|
|
43
|
+
Quick example with ReactJS.
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
import React, { useRef } from 'react';
|
|
47
|
+
import Calendar from '@lemonadejs/calendar/dist/react';
|
|
48
|
+
|
|
49
|
+
import '@lemonadejs/calendar/dist/style.css';
|
|
50
|
+
import '@lemonadejs/modal/dist/style.css';
|
|
51
|
+
|
|
52
|
+
export default function App() {
|
|
53
|
+
const calendarRef = useRef();
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<>
|
|
57
|
+
<Calendar type={'inline'} ref={calendarRef} value={new Date()} />
|
|
58
|
+
</>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Configuration
|
|
64
|
+
|
|
65
|
+
You can configure things such as calendar starting date, calendar events, and customize functions.
|
|
66
|
+
|
|
67
|
+
#### Calendar Properties
|
|
68
|
+
|
|
69
|
+
| Attribute | Type | Description |
|
|
70
|
+
| --------- | ---------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| type? | string | Determines the rendering type for the calendar. Options: 'inline', 'default'. |
|
|
72
|
+
| range? | boolean | Enables the range mode for date selection. |
|
|
73
|
+
| value? | number or string | Represents the currently selected date. |
|
|
74
|
+
| numeric? | boolean | Enables the use of numeric dates, treating them as serial numbers. |
|
|
75
|
+
| input? | HTML element | An optional reference to control the calendar opening. The value is automatically bound when using this property. |
|
|
76
|
+
|
|
77
|
+
### Calendar Events
|
|
78
|
+
|
|
79
|
+
| Event | Description |
|
|
80
|
+
| -------------------------------- | ----------------------------------- |
|
|
81
|
+
| onchange?: (self, value) => void | Called when a new date is selected. |
|
|
82
|
+
|
|
83
|
+
## License
|
|
84
|
+
|
|
85
|
+
The LemonadeJS [Reactive JavaScript Calendar](https://lemonadejs.com/docs/plugins/calendar) is released under the MIT.
|
|
86
|
+
|
|
87
|
+
## Other Tools
|
|
88
|
+
|
|
89
|
+
- [jSuites Plugins - JavaScript Calendar](https://jsuites.net/docs/javascript-calendar)
|
|
90
|
+
- [Jspreadsheet - JavaScript Spreadsheet](https://jspreadsheet.com/)
|
package/dist/index.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ declare namespace Calendar {
|
|
|
37
37
|
/** Update view on mouse wheel. Default: true */
|
|
38
38
|
wheel?: boolean;
|
|
39
39
|
/** Bind the calendar to na HTML input element */
|
|
40
|
-
input?:
|
|
40
|
+
input?: HTMLInputElement | 'auto';
|
|
41
41
|
/** Create events and assing the calendar classes for the input. Default true */
|
|
42
42
|
initInput?: boolean;
|
|
43
43
|
/** Change value event */
|
package/dist/index.js
CHANGED
|
@@ -51,7 +51,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const Helpers = (function() {
|
|
54
|
+
const Helpers = (function () {
|
|
55
55
|
const component = {};
|
|
56
56
|
|
|
57
57
|
// Excel like dates
|
|
@@ -60,22 +60,22 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
60
60
|
const millisecondsPerDay = 86400000;
|
|
61
61
|
|
|
62
62
|
// Transform in two digits
|
|
63
|
-
component.two = function(value) {
|
|
63
|
+
component.two = function (value) {
|
|
64
64
|
value = '' + value;
|
|
65
65
|
if (value.length === 1) {
|
|
66
66
|
value = '0' + value;
|
|
67
67
|
}
|
|
68
68
|
return value;
|
|
69
|
-
}
|
|
69
|
+
};
|
|
70
70
|
|
|
71
|
-
component.isValidDate = function(d) {
|
|
71
|
+
component.isValidDate = function (d) {
|
|
72
72
|
return d instanceof Date && !isNaN(d.getTime());
|
|
73
|
-
}
|
|
73
|
+
};
|
|
74
74
|
|
|
75
|
-
component.isValidDateFormat = function(date
|
|
75
|
+
component.isValidDateFormat = function(date) {
|
|
76
76
|
if (typeof date === 'string') {
|
|
77
77
|
// Check format: YYYY-MM-DD using regex
|
|
78
|
-
const match = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
78
|
+
const match = date.substring(0, 10).match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
79
79
|
if (match) {
|
|
80
80
|
const year = Number(match[1]);
|
|
81
81
|
const month = Number(match[2]) - 1;
|
|
@@ -105,7 +105,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
105
105
|
i = date[4];
|
|
106
106
|
s = date[5];
|
|
107
107
|
} else {
|
|
108
|
-
if (!
|
|
108
|
+
if (!date) {
|
|
109
109
|
date = new Date();
|
|
110
110
|
}
|
|
111
111
|
y = date.getUTCFullYear();
|
|
@@ -119,12 +119,14 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
119
119
|
if (dateOnly === true) {
|
|
120
120
|
return component.two(y) + '-' + component.two(m) + '-' + component.two(d);
|
|
121
121
|
} else {
|
|
122
|
-
return
|
|
122
|
+
return (
|
|
123
|
+
component.two(y) + '-' + component.two(m) + '-' + component.two(d) + ' ' + component.two(h) + ':' + component.two(i) + ':' + component.two(s)
|
|
124
|
+
);
|
|
123
125
|
}
|
|
124
|
-
}
|
|
126
|
+
};
|
|
125
127
|
|
|
126
128
|
component.toArray = function (value) {
|
|
127
|
-
let date = value.split(
|
|
129
|
+
let date = value.split(value.indexOf('T') !== -1 ? 'T' : ' ');
|
|
128
130
|
let time = date[1];
|
|
129
131
|
|
|
130
132
|
date = date[0].split('-');
|
|
@@ -140,14 +142,14 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
140
142
|
i = parseInt(time[1]);
|
|
141
143
|
}
|
|
142
144
|
return [y, m, d, h, i, 0];
|
|
143
|
-
}
|
|
145
|
+
};
|
|
144
146
|
|
|
145
|
-
component.arrayToStringDate = function(arr) {
|
|
147
|
+
component.arrayToStringDate = function (arr) {
|
|
146
148
|
return component.toString(arr, false);
|
|
147
|
-
}
|
|
149
|
+
};
|
|
148
150
|
|
|
149
|
-
component.dateToNum = function(jsDate) {
|
|
150
|
-
if (typeof
|
|
151
|
+
component.dateToNum = function (jsDate) {
|
|
152
|
+
if (typeof jsDate === 'string') {
|
|
151
153
|
jsDate = new Date(jsDate + ' GMT+0');
|
|
152
154
|
}
|
|
153
155
|
let jsDateInMilliseconds = jsDate.getTime();
|
|
@@ -157,9 +159,9 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
157
159
|
jsDateInMilliseconds -= excelInitialTime;
|
|
158
160
|
|
|
159
161
|
return jsDateInMilliseconds / millisecondsPerDay;
|
|
160
|
-
}
|
|
162
|
+
};
|
|
161
163
|
|
|
162
|
-
component.numToDate = function(excelSerialNumber, asArray) {
|
|
164
|
+
component.numToDate = function (excelSerialNumber, asArray) {
|
|
163
165
|
// allow 0; only bail on null/undefined/empty
|
|
164
166
|
if (excelSerialNumber === null || excelSerialNumber === undefined || excelSerialNumber === '') {
|
|
165
167
|
return '';
|
|
@@ -196,10 +198,10 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
196
198
|
];
|
|
197
199
|
|
|
198
200
|
return asArray ? arr : component.toString(arr, false);
|
|
199
|
-
}
|
|
201
|
+
};
|
|
200
202
|
|
|
201
203
|
component.prettify = function (d, texts) {
|
|
202
|
-
if (!
|
|
204
|
+
if (!texts) {
|
|
203
205
|
texts = {
|
|
204
206
|
justNow: 'Just now',
|
|
205
207
|
xMinutesAgo: '{0}m ago',
|
|
@@ -208,7 +210,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
208
210
|
xWeeksAgo: '{0}w ago',
|
|
209
211
|
xMonthsAgo: '{0} mon ago',
|
|
210
212
|
xYearsAgo: '{0}y ago',
|
|
211
|
-
}
|
|
213
|
+
};
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
if (d.indexOf('GMT') === -1 && d.indexOf('Z') === -1) {
|
|
@@ -221,24 +223,29 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
221
223
|
|
|
222
224
|
const format = (t, o) => {
|
|
223
225
|
return t.replace('{0}', o);
|
|
224
|
-
}
|
|
226
|
+
};
|
|
225
227
|
|
|
226
|
-
if (!
|
|
228
|
+
if (!total) {
|
|
227
229
|
return texts.justNow;
|
|
228
230
|
} else if (total < 90) {
|
|
229
231
|
return format(texts.xMinutesAgo, total);
|
|
230
|
-
} else if (total < 1440) {
|
|
232
|
+
} else if (total < 1440) {
|
|
233
|
+
// One day
|
|
231
234
|
return format(texts.xHoursAgo, Math.round(total / 60));
|
|
232
|
-
} else if (total < 20160) {
|
|
235
|
+
} else if (total < 20160) {
|
|
236
|
+
// 14 days
|
|
233
237
|
return format(texts.xDaysAgo, Math.round(total / 1440));
|
|
234
|
-
} else if (total < 43200) {
|
|
238
|
+
} else if (total < 43200) {
|
|
239
|
+
// 30 days
|
|
235
240
|
return format(texts.xWeeksAgo, Math.round(total / 10080));
|
|
236
|
-
} else if (total < 1036800) {
|
|
241
|
+
} else if (total < 1036800) {
|
|
242
|
+
// 24 months
|
|
237
243
|
return format(texts.xMonthsAgo, Math.round(total / 43200));
|
|
238
|
-
} else {
|
|
244
|
+
} else {
|
|
245
|
+
// 24 months+
|
|
239
246
|
return format(texts.xYearsAgo, Math.round(total / 525600));
|
|
240
247
|
}
|
|
241
|
-
}
|
|
248
|
+
};
|
|
242
249
|
|
|
243
250
|
component.prettifyAll = function () {
|
|
244
251
|
let elements = document.querySelectorAll('.prettydate');
|
|
@@ -253,7 +260,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
253
260
|
}
|
|
254
261
|
}
|
|
255
262
|
}
|
|
256
|
-
}
|
|
263
|
+
};
|
|
257
264
|
|
|
258
265
|
// Compatibility with jSuites
|
|
259
266
|
component.now = component.toString;
|
|
@@ -261,17 +268,17 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
261
268
|
const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
262
269
|
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
263
270
|
|
|
264
|
-
const translate = function(t) {
|
|
265
|
-
if (typeof
|
|
271
|
+
const translate = function (t) {
|
|
272
|
+
if (typeof document !== 'undefined' && document.dictionary) {
|
|
266
273
|
return document.dictionary[t] || t;
|
|
267
274
|
} else {
|
|
268
275
|
return t;
|
|
269
276
|
}
|
|
270
|
-
}
|
|
277
|
+
};
|
|
271
278
|
|
|
272
279
|
Object.defineProperty(component, 'weekdays', {
|
|
273
280
|
get: function () {
|
|
274
|
-
return weekdays.map(function(v) {
|
|
281
|
+
return weekdays.map(function (v) {
|
|
275
282
|
return translate(v);
|
|
276
283
|
});
|
|
277
284
|
},
|
|
@@ -279,15 +286,15 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
279
286
|
|
|
280
287
|
Object.defineProperty(component, 'weekdaysShort', {
|
|
281
288
|
get: function () {
|
|
282
|
-
return weekdays.map(function(v) {
|
|
283
|
-
return translate(v).substring(0,3);
|
|
289
|
+
return weekdays.map(function (v) {
|
|
290
|
+
return translate(v).substring(0, 3);
|
|
284
291
|
});
|
|
285
292
|
},
|
|
286
293
|
});
|
|
287
294
|
|
|
288
295
|
Object.defineProperty(component, 'months', {
|
|
289
296
|
get: function () {
|
|
290
|
-
return months.map(function(v) {
|
|
297
|
+
return months.map(function (v) {
|
|
291
298
|
return translate(v);
|
|
292
299
|
});
|
|
293
300
|
},
|
|
@@ -295,8 +302,8 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
295
302
|
|
|
296
303
|
Object.defineProperty(component, 'monthsShort', {
|
|
297
304
|
get: function () {
|
|
298
|
-
return months.map(function(v) {
|
|
299
|
-
return translate(v).substring(0,3);
|
|
305
|
+
return months.map(function (v) {
|
|
306
|
+
return translate(v).substring(0, 3);
|
|
300
307
|
});
|
|
301
308
|
},
|
|
302
309
|
});
|
|
@@ -304,7 +311,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
304
311
|
return component;
|
|
305
312
|
})();
|
|
306
313
|
|
|
307
|
-
const Mask = (function() {
|
|
314
|
+
const Mask = (function Mask() {
|
|
308
315
|
// Currency
|
|
309
316
|
const tokens = {
|
|
310
317
|
// Text
|
|
@@ -325,6 +332,33 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
325
332
|
general: [ 'A', '0', '\\?', '\\*', ',,M', ',,,B', '[0-9a-zA-Z\\$]+', '_\\(', '_\\)', '\\(', '\\)', '_-', '.']
|
|
326
333
|
}
|
|
327
334
|
|
|
335
|
+
// All expressions
|
|
336
|
+
const allExpressions = [].concat(tokens.fraction, tokens.currency, tokens.datetime, tokens.percentage, tokens.scientific, tokens.numeric, tokens.text, tokens.general).join('|');
|
|
337
|
+
|
|
338
|
+
// Pre-compile all regexes once at initialization for better performance
|
|
339
|
+
const compiledTokens = {};
|
|
340
|
+
const tokenPriority = ['fraction', 'currency', 'scientific', 'percentage', 'numeric', 'datetime', 'text', 'general'];
|
|
341
|
+
|
|
342
|
+
// Initialize compiled regexes
|
|
343
|
+
for (const type of tokenPriority) {
|
|
344
|
+
compiledTokens[type] = tokens[type].map(pattern => ({
|
|
345
|
+
regex: new RegExp('^' + pattern + '$', 'gi'),
|
|
346
|
+
method: pattern
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Pre-compile regex for getTokens function
|
|
351
|
+
const allExpressionsRegex = new RegExp(allExpressions, 'gi');
|
|
352
|
+
|
|
353
|
+
// Pre-compile currency symbol regexes for autoCastingCurrency
|
|
354
|
+
const knownSymbols = ['$', '€', '£', '¥', '₹', '₽', '₩', '₫', 'R$', 'CHF', 'AED'];
|
|
355
|
+
const currencyRegexes = knownSymbols.map(s => ({
|
|
356
|
+
symbol: s,
|
|
357
|
+
regex: new RegExp(`^${s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}(\\s?)`)
|
|
358
|
+
}));
|
|
359
|
+
|
|
360
|
+
const hiddenCaret = "\u200B";
|
|
361
|
+
|
|
328
362
|
// Labels
|
|
329
363
|
const weekDaysFull = Helpers.weekdays;
|
|
330
364
|
const weekDays = Helpers.weekdaysShort;
|
|
@@ -333,6 +367,29 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
333
367
|
|
|
334
368
|
// Helpers
|
|
335
369
|
|
|
370
|
+
const focus = function(el) {
|
|
371
|
+
if (el.textContent.length) {
|
|
372
|
+
// Handle contenteditable elements
|
|
373
|
+
const range = document.createRange();
|
|
374
|
+
const sel = window.getSelection();
|
|
375
|
+
|
|
376
|
+
let node = el;
|
|
377
|
+
// Go as deep as possible to the last text node
|
|
378
|
+
while (node.lastChild) node = node.lastChild;
|
|
379
|
+
// Ensure it's a text node
|
|
380
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
381
|
+
range.setStart(node, node.length);
|
|
382
|
+
} else {
|
|
383
|
+
range.setStart(node, node.childNodes.length);
|
|
384
|
+
}
|
|
385
|
+
range.collapse(true);
|
|
386
|
+
sel.removeAllRanges();
|
|
387
|
+
sel.addRange(range);
|
|
388
|
+
|
|
389
|
+
el.scrollLeft = el.scrollWidth;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
336
393
|
/**
|
|
337
394
|
* Returns if the given value is considered blank
|
|
338
395
|
*/
|
|
@@ -461,7 +518,6 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
461
518
|
const setCaret = function(index) {
|
|
462
519
|
if (typeof index !== 'number') index = Number(index) || 0;
|
|
463
520
|
|
|
464
|
-
// Inputs/Textareas
|
|
465
521
|
if (this.tagName !== 'DIV' || this.isContentEditable !== true) {
|
|
466
522
|
const n = this.value ?? '';
|
|
467
523
|
if (index < 0) index = 0;
|
|
@@ -648,14 +704,18 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
648
704
|
}
|
|
649
705
|
} else {
|
|
650
706
|
if (this.values[this.index] == 1 && parseInt(v) < 3) {
|
|
651
|
-
this.
|
|
707
|
+
this.values[this.index] += v;
|
|
652
708
|
commit();
|
|
653
709
|
} else if (this.values[this.index] == 0 && parseInt(v) > 0 && parseInt(v) < 10) {
|
|
654
|
-
this.
|
|
710
|
+
this.values[this.index] += v;
|
|
655
711
|
commit();
|
|
656
712
|
} else {
|
|
657
713
|
let test = parseInt(this.values[this.index]);
|
|
658
714
|
if (test > 0 && test <= 12) {
|
|
715
|
+
if (! single) {
|
|
716
|
+
test = '0' + test;
|
|
717
|
+
}
|
|
718
|
+
this.values[this.index] = test;
|
|
659
719
|
commit();
|
|
660
720
|
return false;
|
|
661
721
|
}
|
|
@@ -706,6 +766,10 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
706
766
|
} else {
|
|
707
767
|
let test = parseInt(this.values[this.index]);
|
|
708
768
|
if (test > 0 && test <= 31) {
|
|
769
|
+
if (! single) {
|
|
770
|
+
test = '0' + test;
|
|
771
|
+
}
|
|
772
|
+
this.values[this.index] = test;
|
|
709
773
|
commit();
|
|
710
774
|
return false;
|
|
711
775
|
}
|
|
@@ -935,10 +999,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
935
999
|
}
|
|
936
1000
|
this.values[this.index] += this.decimal;
|
|
937
1001
|
}
|
|
938
|
-
} else if (v === "\u200B") {
|
|
939
|
-
this.values[this.index] += v;
|
|
940
1002
|
}
|
|
941
|
-
|
|
942
1003
|
},
|
|
943
1004
|
'[0#]+([.,]{1}0*#*)?%': function(v) {
|
|
944
1005
|
parseMethods['[0#]+([.,]{1}0*#*)?'].call(this, v);
|
|
@@ -1094,7 +1155,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1094
1155
|
// Add the value
|
|
1095
1156
|
this.values[this.index] += v;
|
|
1096
1157
|
// Only if caret is before the change
|
|
1097
|
-
let current = this.values[this.index]
|
|
1158
|
+
let current = this.values[this.index];
|
|
1098
1159
|
// Add token to the values
|
|
1099
1160
|
if (current !== word.substring(0,current.length)) {
|
|
1100
1161
|
this.values[this.index] = word;
|
|
@@ -1121,7 +1182,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1121
1182
|
this.index++;
|
|
1122
1183
|
}
|
|
1123
1184
|
},
|
|
1124
|
-
'\\*': function(
|
|
1185
|
+
'\\*': function() {
|
|
1125
1186
|
this.values[this.index] = '';
|
|
1126
1187
|
this.index++;
|
|
1127
1188
|
return false;
|
|
@@ -1160,17 +1221,17 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1160
1221
|
}
|
|
1161
1222
|
this.values[this.index] += v;
|
|
1162
1223
|
},
|
|
1163
|
-
'_\\(': function(
|
|
1224
|
+
'_\\(': function() {
|
|
1164
1225
|
this.values[this.index] = ' ';
|
|
1165
1226
|
this.index++;
|
|
1166
1227
|
return false;
|
|
1167
1228
|
},
|
|
1168
|
-
'_\\)': function(
|
|
1229
|
+
'_\\)': function() {
|
|
1169
1230
|
this.values[this.index] = ' ';
|
|
1170
1231
|
this.index++;
|
|
1171
1232
|
return false;
|
|
1172
1233
|
},
|
|
1173
|
-
'\\(': function(
|
|
1234
|
+
'\\(': function() {
|
|
1174
1235
|
if (this.type === 'currency' && this.parenthesisForNegativeNumbers) {
|
|
1175
1236
|
this.values[this.index] = '';
|
|
1176
1237
|
} else {
|
|
@@ -1179,7 +1240,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1179
1240
|
this.index++;
|
|
1180
1241
|
return false;
|
|
1181
1242
|
},
|
|
1182
|
-
'\\)': function(
|
|
1243
|
+
'\\)': function() {
|
|
1183
1244
|
if (this.type === 'currency' && this.parenthesisForNegativeNumbers) {
|
|
1184
1245
|
this.values[this.index] = '';
|
|
1185
1246
|
} else {
|
|
@@ -1188,17 +1249,17 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1188
1249
|
this.index++;
|
|
1189
1250
|
return false;
|
|
1190
1251
|
},
|
|
1191
|
-
'_-': function(
|
|
1252
|
+
'_-': function() {
|
|
1192
1253
|
this.values[this.index] = ' ';
|
|
1193
1254
|
this.index++;
|
|
1194
1255
|
return false;
|
|
1195
1256
|
},
|
|
1196
|
-
',,M': function(
|
|
1257
|
+
',,M': function() {
|
|
1197
1258
|
this.values[this.index] = 'M';
|
|
1198
1259
|
this.index++;
|
|
1199
1260
|
return false;
|
|
1200
1261
|
},
|
|
1201
|
-
',,,B': function(
|
|
1262
|
+
',,,B': function() {
|
|
1202
1263
|
this.values[this.index] = 'B';
|
|
1203
1264
|
this.index++;
|
|
1204
1265
|
return false;
|
|
@@ -1243,9 +1304,8 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1243
1304
|
// Types TODO: Generate types so we can garantee that text,scientific, numeric,percentage, current are not duplicates. If they are, it will be general or broken.
|
|
1244
1305
|
|
|
1245
1306
|
const getTokens = function(str) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
return str.match(new RegExp(expressions.join('|'), 'gi'));
|
|
1307
|
+
allExpressionsRegex.lastIndex = 0; // Reset for global regex
|
|
1308
|
+
return str.match(allExpressionsRegex);
|
|
1249
1309
|
}
|
|
1250
1310
|
|
|
1251
1311
|
/**
|
|
@@ -1253,35 +1313,23 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1253
1313
|
*/
|
|
1254
1314
|
const getMethod = function(str, temporary) {
|
|
1255
1315
|
str = str.toString().toUpperCase();
|
|
1256
|
-
const types = Object.keys(tokens);
|
|
1257
1316
|
|
|
1258
1317
|
// Check for datetime mask
|
|
1259
|
-
|
|
1260
|
-
for (let i = 0; i < temporary.length; i++) {
|
|
1261
|
-
let type = temporary[i].type;
|
|
1262
|
-
if (! (type === 'datetime' || type === 'general')) {
|
|
1263
|
-
datetime = false;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
// Remove date time from the possible types
|
|
1268
|
-
if (datetime !== true) {
|
|
1269
|
-
let index = types.indexOf('datetime');
|
|
1270
|
-
types.splice(index, 1);
|
|
1271
|
-
}
|
|
1318
|
+
const datetime = temporary.every(t => t.type === 'datetime' || t.type === 'general');
|
|
1272
1319
|
|
|
1273
|
-
//
|
|
1274
|
-
for (
|
|
1275
|
-
|
|
1320
|
+
// Use priority order for faster matching with pre-compiled regexes
|
|
1321
|
+
for (const type of tokenPriority) {
|
|
1322
|
+
if (!datetime && type === 'datetime') continue;
|
|
1276
1323
|
|
|
1277
|
-
for (
|
|
1278
|
-
let
|
|
1279
|
-
|
|
1280
|
-
if (
|
|
1281
|
-
return { type: type, method:
|
|
1324
|
+
for (const compiled of compiledTokens[type]) {
|
|
1325
|
+
let regex = compiled.regex;
|
|
1326
|
+
regex.lastIndex = 0; // Reset regex state
|
|
1327
|
+
if (regex.test(str)) {
|
|
1328
|
+
return { type: type, method: compiled.method };
|
|
1282
1329
|
}
|
|
1283
1330
|
}
|
|
1284
1331
|
}
|
|
1332
|
+
return null;
|
|
1285
1333
|
}
|
|
1286
1334
|
|
|
1287
1335
|
const fixMinuteToken = function(t) {
|
|
@@ -1417,7 +1465,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1417
1465
|
|
|
1418
1466
|
const isNumber = function(num) {
|
|
1419
1467
|
if (typeof(num) === 'string') {
|
|
1420
|
-
num = num.
|
|
1468
|
+
num = num.trim();
|
|
1421
1469
|
}
|
|
1422
1470
|
return !isNaN(num) && num !== null && num !== '';
|
|
1423
1471
|
}
|
|
@@ -1711,7 +1759,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1711
1759
|
}
|
|
1712
1760
|
|
|
1713
1761
|
const extractDateAndTime = function(value) {
|
|
1714
|
-
value =
|
|
1762
|
+
value = value.toString().substring(0,19);
|
|
1715
1763
|
let splitStr = (value.indexOf('T') !== -1) ? 'T' : ' ';
|
|
1716
1764
|
value = value.split(splitStr);
|
|
1717
1765
|
|
|
@@ -1759,11 +1807,20 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1759
1807
|
// Walk every character on the value
|
|
1760
1808
|
let method;
|
|
1761
1809
|
while (method = getMethodByPosition(control)) {
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1810
|
+
let char = control.value[control.position];
|
|
1811
|
+
if (char === hiddenCaret) {
|
|
1812
|
+
control.caret = {
|
|
1813
|
+
index: control.index,
|
|
1814
|
+
position: control.values[control.index]?.length ?? 0,
|
|
1815
|
+
}
|
|
1766
1816
|
control.position++;
|
|
1817
|
+
} else {
|
|
1818
|
+
// Get the method name to handle the current token
|
|
1819
|
+
let ret = method.call(control, char);
|
|
1820
|
+
// Next position
|
|
1821
|
+
if (ret !== false) {
|
|
1822
|
+
control.position++;
|
|
1823
|
+
}
|
|
1767
1824
|
}
|
|
1768
1825
|
}
|
|
1769
1826
|
|
|
@@ -1785,6 +1842,13 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1785
1842
|
}
|
|
1786
1843
|
}
|
|
1787
1844
|
}
|
|
1845
|
+
if (control.caret) {
|
|
1846
|
+
let index = control.caret.index;
|
|
1847
|
+
let position = control.caret.position;
|
|
1848
|
+
let value = control.values[index] ?? '';
|
|
1849
|
+
// Re-apply the caret to the original position
|
|
1850
|
+
control.values[index] = value.substring(0, position) + hiddenCaret + value.substring(position);
|
|
1851
|
+
}
|
|
1788
1852
|
|
|
1789
1853
|
control.value = getValue(control);
|
|
1790
1854
|
|
|
@@ -1897,7 +1961,6 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
1897
1961
|
const parts = str.split('-');
|
|
1898
1962
|
const p1 = parseInt(parts[0]);
|
|
1899
1963
|
const p2 = parseInt(parts[1]);
|
|
1900
|
-
const p3 = parseInt(parts[2]);
|
|
1901
1964
|
|
|
1902
1965
|
if (p1 <= 12 && p2 <= 31 && p2 > 12) {
|
|
1903
1966
|
patterns.push('mm-dd-yyyy', 'mm-dd-yy', 'm-d-yyyy', 'm-d-yy');
|
|
@@ -2085,13 +2148,10 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2085
2148
|
const hasParens = /^\s*\(.+\)\s*$/.test(original);
|
|
2086
2149
|
let value = original.replace(/[()\-]/g, '').trim();
|
|
2087
2150
|
|
|
2088
|
-
//
|
|
2089
|
-
const knownSymbols = ['$', '€', '£', '¥', '₹', '₽', '₩', '₫', 'R$', 'CHF', 'AED'];
|
|
2151
|
+
// Use pre-compiled currency regexes
|
|
2090
2152
|
let symbol = '';
|
|
2091
2153
|
|
|
2092
|
-
for (let s of
|
|
2093
|
-
const escaped = s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
2094
|
-
const regex = new RegExp(`^${escaped}(\\s?)`);
|
|
2154
|
+
for (let {symbol: s, regex} of currencyRegexes) {
|
|
2095
2155
|
const match = value.match(regex);
|
|
2096
2156
|
if (match) {
|
|
2097
2157
|
symbol = s + (match[1] || '');
|
|
@@ -2441,8 +2501,6 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2441
2501
|
return returnObject ? o : result;
|
|
2442
2502
|
};
|
|
2443
2503
|
|
|
2444
|
-
// TODO: We have a large number like 1000000 and I want format it to 1,00 or 1M or… (display million/thousands/full numbers). In the excel we can do that with custom format cell “0,00..” However, when I tried applying similar formatting with the mask cell of Jspreadsheet, it didn't work. Could you advise how we can achieve this?
|
|
2445
|
-
|
|
2446
2504
|
Component.render = function(value, options, fullMask) {
|
|
2447
2505
|
// Nothing to render
|
|
2448
2506
|
if (value === '' || value === undefined || value === null) {
|
|
@@ -2531,7 +2589,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2531
2589
|
} else {
|
|
2532
2590
|
options.input.value = value;
|
|
2533
2591
|
}
|
|
2534
|
-
|
|
2592
|
+
focus(options.input);
|
|
2535
2593
|
}
|
|
2536
2594
|
|
|
2537
2595
|
return value;
|
|
@@ -2564,6 +2622,11 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2564
2622
|
return '';
|
|
2565
2623
|
}
|
|
2566
2624
|
|
|
2625
|
+
// Tokens
|
|
2626
|
+
const dateTokens = ['DAY', 'WD', 'DDDD', 'DDD', 'DD', 'D', 'Q', 'HH24', 'HH12', 'HH', '\\[H\\]', 'H', 'AM/PM', 'MI', 'SS', 'MS', 'YYYY', 'YYY', 'YY', 'Y', 'MONTH', 'MON', 'MMMMM', 'MMMM', 'MMM', 'MM', 'M', '.'];
|
|
2627
|
+
// All date tokens
|
|
2628
|
+
const allDateTokens = dateTokens.join('|')
|
|
2629
|
+
|
|
2567
2630
|
Component.getDateString = function(value, options) {
|
|
2568
2631
|
if (! options) {
|
|
2569
2632
|
options = {};
|
|
@@ -2595,11 +2658,9 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2595
2658
|
value = Helpers.numToDate(value);
|
|
2596
2659
|
}
|
|
2597
2660
|
|
|
2598
|
-
// Tokens
|
|
2599
|
-
let tokens = ['DAY', 'WD', 'DDDD', 'DDD', 'DD', 'D', 'Q', 'HH24', 'HH12', 'HH', '\\[H\\]', 'H', 'AM/PM', 'MI', 'SS', 'MS', 'YYYY', 'YYY', 'YY', 'Y', 'MONTH', 'MON', 'MMMMM', 'MMMM', 'MMM', 'MM', 'M', '.'];
|
|
2600
2661
|
|
|
2601
2662
|
// Expression to extract all tokens from the string
|
|
2602
|
-
let e = new RegExp(
|
|
2663
|
+
let e = new RegExp(allDateTokens, 'gi');
|
|
2603
2664
|
// Extract
|
|
2604
2665
|
let t = format.match(e);
|
|
2605
2666
|
|
|
@@ -2793,7 +2854,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2793
2854
|
// Keep the current caret position
|
|
2794
2855
|
let caret = getCaret(element);
|
|
2795
2856
|
if (caret) {
|
|
2796
|
-
value = value.substring(0, caret) +
|
|
2857
|
+
value = value.substring(0, caret) + hiddenCaret + value.substring(caret);
|
|
2797
2858
|
}
|
|
2798
2859
|
|
|
2799
2860
|
// Run mask
|
|
@@ -2804,15 +2865,17 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2804
2865
|
// Apply the result back to the element
|
|
2805
2866
|
if (newValue !== value && ! e.inputType.includes('delete')) {
|
|
2806
2867
|
// Set the caret to the position before transformation
|
|
2807
|
-
let caret = newValue.indexOf(
|
|
2868
|
+
let caret = newValue.indexOf(hiddenCaret);
|
|
2808
2869
|
if (caret !== -1) {
|
|
2809
2870
|
// Apply value
|
|
2810
|
-
element[property] = newValue.replace(
|
|
2871
|
+
element[property] = newValue.replace(hiddenCaret, "");
|
|
2811
2872
|
// Set caret
|
|
2812
2873
|
setCaret.call(element, caret);
|
|
2813
2874
|
} else {
|
|
2814
2875
|
// Apply value
|
|
2815
2876
|
element[property] = newValue;
|
|
2877
|
+
// Make sure the caret is positioned in the end
|
|
2878
|
+
focus(element);
|
|
2816
2879
|
}
|
|
2817
2880
|
}
|
|
2818
2881
|
}
|
|
@@ -2822,7 +2885,10 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
2822
2885
|
Component.adjustPrecision = adjustPrecision;
|
|
2823
2886
|
|
|
2824
2887
|
return Component;
|
|
2825
|
-
}
|
|
2888
|
+
}());
|
|
2889
|
+
|
|
2890
|
+
// Aditional Helpers
|
|
2891
|
+
Helpers.getDate = Mask.getDate;
|
|
2826
2892
|
|
|
2827
2893
|
const isNumber = function (num) {
|
|
2828
2894
|
if (typeof(num) === 'string') {
|
|
@@ -3098,13 +3164,26 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3098
3164
|
// Update the headers of the calendar
|
|
3099
3165
|
let value = d.toISOString().substring(0,10).split('-');
|
|
3100
3166
|
let time = d.toISOString().substring(11,19).split(':');
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
self.
|
|
3107
|
-
|
|
3167
|
+
let month = Helpers.months[parseInt(value[1])-1];
|
|
3168
|
+
let year = parseInt(value[0]);
|
|
3169
|
+
let hour = parseInt(time[0]);
|
|
3170
|
+
let minute = parseInt(time[1]);
|
|
3171
|
+
|
|
3172
|
+
if (self.month !== month) {
|
|
3173
|
+
// Update the month label
|
|
3174
|
+
self.month = month;
|
|
3175
|
+
}
|
|
3176
|
+
if (self.year !== year) {
|
|
3177
|
+
// Update the year label
|
|
3178
|
+
self.year = year;
|
|
3179
|
+
|
|
3180
|
+
}
|
|
3181
|
+
if (self.hour !== hour) {
|
|
3182
|
+
self.hour = hour;
|
|
3183
|
+
}
|
|
3184
|
+
if (self.minute !== minute) {
|
|
3185
|
+
self.minute = minute;
|
|
3186
|
+
}
|
|
3108
3187
|
|
|
3109
3188
|
// Load data
|
|
3110
3189
|
if (! self.view) {
|
|
@@ -3304,7 +3383,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3304
3383
|
|
|
3305
3384
|
const renderValue = function() {
|
|
3306
3385
|
let value = null;
|
|
3307
|
-
if (self.range) {
|
|
3386
|
+
if (self.range === true) {
|
|
3308
3387
|
if (Array.isArray(self.rangeValues)) {
|
|
3309
3388
|
if (self.numeric) {
|
|
3310
3389
|
value = self.rangeValues;
|
|
@@ -3325,7 +3404,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3325
3404
|
}
|
|
3326
3405
|
|
|
3327
3406
|
const updateValue = function(v) {
|
|
3328
|
-
if (self.range) {
|
|
3407
|
+
if (self.range === true) {
|
|
3329
3408
|
if (v) {
|
|
3330
3409
|
if (! Array.isArray(v)) {
|
|
3331
3410
|
v = v.toString().split(',');
|
|
@@ -3385,12 +3464,30 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3385
3464
|
let input = getInput();
|
|
3386
3465
|
let value = self.value;
|
|
3387
3466
|
if (input) {
|
|
3467
|
+
let v = value;
|
|
3388
3468
|
if (input.tagName === 'INPUT' || input.tagName === 'TEXTAREA') {
|
|
3389
3469
|
isEditable = !input.hasAttribute('readonly') && !input.hasAttribute('disabled');
|
|
3390
|
-
|
|
3470
|
+
v = input.value;
|
|
3391
3471
|
} else if (input.isContentEditable) {
|
|
3392
3472
|
isEditable = true;
|
|
3393
|
-
|
|
3473
|
+
v = input.textContent;
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
let ret = v;
|
|
3477
|
+
if (ret && Number(ret) == ret) {
|
|
3478
|
+
ret = Helpers.numToDate(ret);
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
// Try a formatted date
|
|
3482
|
+
if (ret && ! Helpers.isValidDateFormat(ret)) {
|
|
3483
|
+
let tmp = Mask.extractDateFromString(ret, self.format);
|
|
3484
|
+
if (tmp) {
|
|
3485
|
+
ret = tmp;
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
if (ret !== value) {
|
|
3490
|
+
value = ret;
|
|
3394
3491
|
}
|
|
3395
3492
|
}
|
|
3396
3493
|
|
|
@@ -3625,30 +3722,46 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3625
3722
|
}
|
|
3626
3723
|
|
|
3627
3724
|
self.setValue = function(v) {
|
|
3628
|
-
// Destroy range
|
|
3629
|
-
destroyRange();
|
|
3630
|
-
// Update the internal controllers
|
|
3631
|
-
updateValue(v);
|
|
3632
3725
|
// Events
|
|
3633
3726
|
if (v !== self.value) {
|
|
3634
3727
|
// Update value
|
|
3635
3728
|
self.value = v;
|
|
3636
|
-
|
|
3637
|
-
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
|
|
3732
|
+
const dispatchOnChangeEvent = function() {
|
|
3733
|
+
// Destroy range
|
|
3734
|
+
destroyRange();
|
|
3735
|
+
// Update the internal controllers
|
|
3736
|
+
updateValue(self.value);
|
|
3737
|
+
// Events
|
|
3738
|
+
Dispatch.call(self, change, 'change', {
|
|
3739
|
+
instance: self,
|
|
3740
|
+
value: self.value,
|
|
3741
|
+
});
|
|
3742
|
+
// Update input
|
|
3743
|
+
let input = getInput();
|
|
3744
|
+
if (input) {
|
|
3745
|
+
let v = self.value;
|
|
3746
|
+
if (self.format && v) {
|
|
3747
|
+
if (self.range === true) {
|
|
3748
|
+
if (v[0]) {
|
|
3749
|
+
v[0] = Mask.render(v[0], self.format);
|
|
3750
|
+
}
|
|
3751
|
+
if (v[1]) {
|
|
3752
|
+
v[1] = Mask.render(v[1], self.format);
|
|
3753
|
+
}
|
|
3754
|
+
} else {
|
|
3755
|
+
v = Mask.render(v, self.format);
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
// Update input value
|
|
3759
|
+
input.value = v;
|
|
3760
|
+
// Dispatch event
|
|
3761
|
+
Dispatch.call(input, null, 'change', {
|
|
3638
3762
|
instance: self,
|
|
3639
3763
|
value: self.value,
|
|
3640
3764
|
});
|
|
3641
|
-
// Update input
|
|
3642
|
-
let input = getInput();
|
|
3643
|
-
if (input) {
|
|
3644
|
-
// Update input value
|
|
3645
|
-
input.value = Mask.render(v, self.format);
|
|
3646
|
-
// Dispatch event
|
|
3647
|
-
Dispatch.call(input, null, 'change', {
|
|
3648
|
-
instance: self,
|
|
3649
|
-
value: self.value,
|
|
3650
|
-
});
|
|
3651
|
-
}
|
|
3652
3765
|
}
|
|
3653
3766
|
}
|
|
3654
3767
|
|
|
@@ -3660,6 +3773,8 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3660
3773
|
}
|
|
3661
3774
|
}
|
|
3662
3775
|
|
|
3776
|
+
self.helpers = Helpers;
|
|
3777
|
+
|
|
3663
3778
|
onchange(function(prop) {
|
|
3664
3779
|
if (prop === 'view') {
|
|
3665
3780
|
if (typeof(views[self.view]) === 'function') {
|
|
@@ -3667,12 +3782,18 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3667
3782
|
self.options = views[self.view].call(self, date);
|
|
3668
3783
|
}
|
|
3669
3784
|
} else if (prop === 'value') {
|
|
3670
|
-
|
|
3785
|
+
dispatchOnChangeEvent();
|
|
3671
3786
|
} else if (prop === 'startingDay') {
|
|
3672
|
-
self.weekdays = getWeekdays(self.startingDay);
|
|
3787
|
+
self.weekdays = getWeekdays(self.startingDay ?? 0);
|
|
3673
3788
|
}
|
|
3674
3789
|
});
|
|
3675
3790
|
|
|
3791
|
+
// Input
|
|
3792
|
+
if (self.input === 'auto') {
|
|
3793
|
+
self.input = document.createElement('input');
|
|
3794
|
+
self.input.type = 'text';
|
|
3795
|
+
}
|
|
3796
|
+
|
|
3676
3797
|
onload(function() {
|
|
3677
3798
|
if (self.type !== "inline") {
|
|
3678
3799
|
// Create modal instance
|
|
@@ -3695,11 +3816,11 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3695
3816
|
self.range = true;
|
|
3696
3817
|
}
|
|
3697
3818
|
|
|
3819
|
+
let ret;
|
|
3820
|
+
|
|
3698
3821
|
// Create input controls
|
|
3699
3822
|
if (self.input && self.initInput !== false) {
|
|
3700
|
-
if (self.input
|
|
3701
|
-
self.input = document.createElement('input');
|
|
3702
|
-
self.input.type = 'text';
|
|
3823
|
+
if (! self.input.parentNode) {
|
|
3703
3824
|
self.el.parentNode.insertBefore(self.input, self.el);
|
|
3704
3825
|
}
|
|
3705
3826
|
|
|
@@ -3723,13 +3844,21 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3723
3844
|
if (self.value) {
|
|
3724
3845
|
input.value = self.value;
|
|
3725
3846
|
} else if (input.value && input.value !== self.value) {
|
|
3726
|
-
|
|
3847
|
+
// Correct format
|
|
3848
|
+
if (self.format) {
|
|
3849
|
+
input.value = Helpers.getDate(input.value, self.format);
|
|
3850
|
+
}
|
|
3851
|
+
ret = input.value;
|
|
3727
3852
|
}
|
|
3728
3853
|
}
|
|
3729
3854
|
}
|
|
3730
3855
|
|
|
3731
3856
|
// Update the internal date values
|
|
3732
|
-
|
|
3857
|
+
if (ret) {
|
|
3858
|
+
self.value = ret;
|
|
3859
|
+
} else {
|
|
3860
|
+
updateValue(self.value);
|
|
3861
|
+
}
|
|
3733
3862
|
|
|
3734
3863
|
/**
|
|
3735
3864
|
* Handler keyboard
|
|
@@ -3812,7 +3941,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3812
3941
|
const hours = views.hours();
|
|
3813
3942
|
const minutes = views.minutes();
|
|
3814
3943
|
|
|
3815
|
-
return render => render`<div class="lm-calendar" :value="self.value" data-grid="{{self.grid}}" data-type="{{self.type}}" data-disabled="{{self.disabled}}">
|
|
3944
|
+
return render => render`<div class="lm-calendar" :value="self.value" data-grid="{{self.grid}}" data-type="{{self.type}}" data-disabled="{{self.disabled}}" data-starting-day="{{self.startingDay}}">
|
|
3816
3945
|
<div class="lm-calendar-options">
|
|
3817
3946
|
<button type="button" onclick="self.reset">${T('Reset')}</button>
|
|
3818
3947
|
<button type="button" onclick="${update}">${T('Done')}</button>
|
|
@@ -3833,7 +3962,7 @@ if (! Modal && typeof (require) === 'function') {
|
|
|
3833
3962
|
</div>
|
|
3834
3963
|
<div class="lm-calendar-footer" data-visible="{{self.footer}}">
|
|
3835
3964
|
<div class="lm-calendar-time" data-visible="{{self.time}}"><select :loop="${hours}" :bind="self.hour" class="lm-calendar-control"><option value="{{self.value}}">{{self.title}}</option></select>:<select :loop="${minutes}" :bind="self.minute" class="lm-calendar-control"><option value="{{self.value}}">{{self.title}}</option></select></div>
|
|
3836
|
-
<div class="lm-calendar-update"><input type="button" value="${T('Update')}" onclick="${update}" class="lm-ripple"></div>
|
|
3965
|
+
<div class="lm-calendar-update"><input type="button" value="${T('Update')}" onclick="${update}" class="lm-ripple lm-input"></div>
|
|
3837
3966
|
</div>
|
|
3838
3967
|
</div>
|
|
3839
3968
|
</div>`
|
package/dist/style.css
CHANGED
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
padding: 4px;
|
|
70
70
|
background-color: transparent;
|
|
71
71
|
font-weight: bold;
|
|
72
|
+
color: var(--lm-font-color);
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
.lm-calendar-navigation {
|
|
@@ -78,7 +79,7 @@
|
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
.lm-calendar-navigation i:hover {
|
|
81
|
-
background-color: var(--lm-background-color-
|
|
82
|
+
background-color: var(--lm-background-color-highlight, #ebebeb);
|
|
82
83
|
color: #000;
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -126,6 +127,7 @@
|
|
|
126
127
|
cursor: pointer;
|
|
127
128
|
border-radius: 100px;
|
|
128
129
|
background-origin: padding-box;
|
|
130
|
+
min-width: 38px;
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
.lm-calendar-content > div[data-disabled="true"] {
|
|
@@ -242,8 +244,6 @@
|
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
.lm-calendar-footer input {
|
|
245
|
-
border: transparent;
|
|
246
|
-
padding: 8px;
|
|
247
247
|
width: 100%;
|
|
248
248
|
cursor: pointer;
|
|
249
249
|
background-color: var(--lm-border-color-light, #e9e9e9);
|
|
@@ -324,7 +324,7 @@
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
.lm-ripple:hover {
|
|
327
|
-
background: var(--lm-background-color-
|
|
327
|
+
background: var(--lm-background-color-highlight, #ebebeb) radial-gradient(circle, transparent 1%, var(--lm-background-color-highlight, #ebebeb) 1%) center/15000%;
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
.lm-ripple:active {
|
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lemonadejs/calendar",
|
|
3
|
-
"title": "LemonadeJS calendar",
|
|
4
|
-
"description": "LemonadeJS reactive JavaScript calendar plugin",
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "Contact <contact@lemonadejs.net>",
|
|
7
|
-
"url": "https://lemonadejs.net"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"javascript calendar",
|
|
11
|
-
"lemonadejs plugins",
|
|
12
|
-
"js",
|
|
13
|
-
"library",
|
|
14
|
-
"javascript plugins"
|
|
15
|
-
],
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"lemonadejs": "^5.
|
|
18
|
-
"@lemonadejs/modal": "^5.
|
|
19
|
-
},
|
|
20
|
-
"main": "dist/index.js",
|
|
21
|
-
"types": "dist/index.d.ts",
|
|
22
|
-
"version": "5.
|
|
23
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@lemonadejs/calendar",
|
|
3
|
+
"title": "LemonadeJS calendar",
|
|
4
|
+
"description": "LemonadeJS reactive JavaScript calendar plugin",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Contact <contact@lemonadejs.net>",
|
|
7
|
+
"url": "https://lemonadejs.net"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"javascript calendar",
|
|
11
|
+
"lemonadejs plugins",
|
|
12
|
+
"js",
|
|
13
|
+
"library",
|
|
14
|
+
"javascript plugins"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"lemonadejs": "^5.3.1",
|
|
18
|
+
"@lemonadejs/modal": "^5.3.0"
|
|
19
|
+
},
|
|
20
|
+
"main": "dist/index.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"version": "5.3.0"
|
|
23
|
+
}
|