input-duration 2.0.11 → 2.1.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/docs/index.html CHANGED
@@ -19,7 +19,6 @@
19
19
 
20
20
  <h1 class="page-title">Home</h1>
21
21
 
22
- <h2>A ChronlyHMS class is everything it is, read all about it -> </h2>
23
22
 
24
23
 
25
24
 
@@ -51,16 +50,16 @@
51
50
  </div>
52
51
 
53
52
  <nav>
54
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-ChronlyHMS%2520Module.html">ChronlyHMS Module</a></li></ul><h3>Classes</h3><ul><li><a href="module-ChronlyHMS%2520Module-ChronlyHMS.html">ChronlyHMS</a></li></ul><h3>Global</h3><ul><li><a href="global.html#ChronlyFlag">ChronlyFlag</a></li><li><a href="global.html#ChronlyHMS">ChronlyHMS</a></li></ul>
53
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="InputDuration.html">InputDuration</a></li></ul>
55
54
  </nav>
56
55
 
57
56
  <br class="clear">
58
57
 
59
58
  <footer>
60
- Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.0</a> on Fri Jan 20 2023 10:29:02 GMT+0000 (Coordinated Universal Time)
59
+ Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> on Thu Jul 06 2023 13:53:14 GMT+0000 (GMT)
61
60
  </footer>
62
61
 
63
62
  <script> prettyPrint(); </script>
64
63
  <script src="scripts/linenumber.js"> </script>
65
64
  </body>
66
- </html>
65
+ </html>
@@ -0,0 +1,660 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>JSDoc: Source: index.js</title>
6
+
7
+ <script src="scripts/prettify/prettify.js"> </script>
8
+ <script src="scripts/prettify/lang-css.js"> </script>
9
+ <!--[if lt IE 9]>
10
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11
+ <![endif]-->
12
+ <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
13
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
14
+ </head>
15
+
16
+ <body>
17
+
18
+ <div id="main">
19
+
20
+ <h1 class="page-title">Source: index.js</h1>
21
+
22
+
23
+
24
+
25
+
26
+
27
+ <section>
28
+ <article>
29
+ <pre class="prettyprint source linenums"><code>/**
30
+ * Class for the Input-Duration webcomponent
31
+ * @class InputDuration
32
+ * @extends HTMLElement
33
+ */
34
+
35
+ class InputDuration extends HTMLElement {
36
+ constructor() {
37
+
38
+ super();
39
+
40
+ this.myElement = this.attachShadow({ mode: 'open' });
41
+
42
+ // needed for setting inputs when value attribute is added to chronlyHMS
43
+ // &lt;chronly-hms id="bobPrepop" value="99:09:09.999">&lt;/chronly-hms>
44
+
45
+ this.value = this.getAttribute('value');
46
+
47
+ this.boot();
48
+
49
+ } // end constructor
50
+
51
+
52
+ /**
53
+ * get the input-duration value, pulls values from each input
54
+ * so in js use var x = document.querySelector("#bobPrepop").value;
55
+ * @return {duration}
56
+ */
57
+
58
+ get value() {
59
+
60
+ // return this.getAttribute('value');
61
+
62
+ if (this.myElement.querySelector('input[name="startHours"]') !== null) {
63
+
64
+ return this.myElement.querySelector('input[name="startHours"]').value +
65
+ ':' + this.myElement.querySelector('input[name="startMinutes"]').value +
66
+ ':' + this.myElement.querySelector('input[name="startSeconds"]').value +
67
+ '.' + this.myElement.querySelector('input[name="startMilliSecs"]').value;
68
+
69
+ }
70
+ else {
71
+
72
+ return null;
73
+
74
+ }
75
+ }
76
+
77
+
78
+ /**
79
+ * set the input-duration value
80
+ * so in js use document.querySelector("#bobPrepop").value = "05:05:05.005"
81
+ * @return {duration}
82
+ * @param {duration} can be html attribute or set in js
83
+ */
84
+
85
+ set value(val) {
86
+
87
+ // for setting the value in js (like document.querySelector("#bobPrepop").value = "05:05:05.005")
88
+ if (val) {
89
+
90
+
91
+ console.log(val);
92
+
93
+
94
+ if (/(^[0-9][0-9]):([0-5][0-9]):([0-5][0-9])\.([0-9][0-9][0-9]$)/.exec(val)) {
95
+
96
+
97
+ // split val
98
+
99
+ var timeArray = val.split(/[.:]+/);
100
+
101
+ console.log('time array is ' + timeArray[0] + ':' + timeArray[1] + ':' + timeArray[2] + ':' + timeArray[3]);
102
+
103
+ console.log('this.id = ' + this.id);
104
+
105
+ setTimeout(() => {
106
+
107
+ this.myElement.querySelector('input[name="startHours"]').value = timeArray[0];
108
+ this.myElement.querySelector('input[name="startMinutes"]').value = timeArray[1];
109
+ this.myElement.querySelector('input[name="startSeconds"]').value = timeArray[2];
110
+ this.myElement.querySelector('input[name="startMilliSecs"]').value = timeArray[3];
111
+
112
+ }, 0);
113
+
114
+
115
+ this.setAttribute('value', val);
116
+
117
+ }
118
+
119
+ else {
120
+
121
+ console.warn(`The specified value ${val} does not conform to the required format. The format is "HH:mm:ss.SSS" where HH is 00-99, mm is 00-59, ss is 00-59, and SSS is 000-999.`);
122
+
123
+ }
124
+
125
+ // I think this is for empty string to clear value
126
+ // gives a False bool and removes value from Webcomponent chronlyHMS
127
+
128
+ } else {
129
+
130
+ setTimeout(() => {
131
+
132
+ this.myElement.querySelector('input[name="startHours"]').value = '00';
133
+ this.myElement.querySelector('input[name="startMinutes"]').value = '00';
134
+ this.myElement.querySelector('input[name="startSeconds"]').value = '00';
135
+ this.myElement.querySelector('input[name="startMilliSecs"]').value = '000';
136
+
137
+ }, 0);
138
+
139
+ this.removeAttribute('value');
140
+
141
+ }
142
+ }
143
+
144
+
145
+ /**
146
+ * Called from constructor, sets up the html and event listeners
147
+ * @method
148
+ */
149
+
150
+ boot() {
151
+
152
+ this.addHTML();
153
+
154
+ // // set up event listeners
155
+ this.add0s();
156
+ this.addNumberLooping();
157
+ this.addArrowKeyInput();
158
+ this.addNumericInput();
159
+ this.addClicksToActivate();
160
+ this.nonNumericBugInHTML();
161
+
162
+ }
163
+
164
+
165
+ /**
166
+ * eventlistener that adds arrow key input of values (up/down) and place toggling (left/right) triggered by
167
+ * the change event of the input
168
+ * @method
169
+ * @see boot()
170
+ */
171
+
172
+ addArrowKeyInput() {
173
+
174
+ console.log('1 this: ' + this);
175
+ console.log('1 this.myElement: ' + this.myElement);
176
+ console.log('1 this.myElement active: ' + this.myElement);
177
+
178
+ var mE = this.myElement;
179
+
180
+ // Left and Right arrow key toggle between HMSmS
181
+ // this depends on data-attributes ex. data-tp="1" in HTML
182
+
183
+ this.myElement.querySelector("div.timeCase")
184
+ .addEventListener('keydown', function (event) {
185
+
186
+ var et = event.target;
187
+ var tp_active = mE.activeElement.dataset.tp;
188
+
189
+ switch (true) {
190
+
191
+ case event.key == "ArrowLeft":
192
+
193
+ if (tp_active >= 2) {
194
+ tp_active--;
195
+ }
196
+
197
+ et.parentElement.querySelector("[data-tp='" + tp_active + "']").focus();
198
+ setTimeout(function () { et.parentElement.querySelector("[data-tp='" + tp_active + "']").select(); }, 5);
199
+
200
+ break;
201
+
202
+ case event.key == "ArrowRight":
203
+ // tp_active = this.myElement.shadowRoot.activeElement.dataset.tp;
204
+
205
+ if (tp_active &lt;= 3) {
206
+ tp_active++;
207
+ }
208
+
209
+ et.parentElement.querySelector("[data-tp='" + tp_active + "']").focus();
210
+ setTimeout(function () { et.parentElement.querySelector("[data-tp='" + tp_active + "']").select(); }, 5);
211
+
212
+ break;
213
+
214
+ // these keep the input selected
215
+ case event.key == "ArrowUp":
216
+
217
+ setTimeout(function () { mE.activeElement.select(); }, 5);
218
+
219
+ break;
220
+
221
+ case event.key == "ArrowDown":
222
+
223
+ setTimeout(function () { mE.activeElement.select(); }, 5);
224
+
225
+ break;
226
+
227
+ // this is good for testing, to determine whether a key press is detected
228
+ case /^([0-9]?)$/.test(event.key):
229
+
230
+ break;
231
+
232
+ }
233
+ });
234
+ }
235
+
236
+
237
+ /**
238
+ * updates inputs-duration marked with shadow html and css
239
+ * @method
240
+ * @see boot()
241
+ */
242
+
243
+ addHTML() {
244
+
245
+ var spanIn = document.createElement("div");
246
+
247
+ spanIn.classList.add('timeCase');
248
+
249
+ var template = document.createElement('template');
250
+
251
+ template.innerHTML = `
252
+ &lt;input id="inShadow" type="number" class="sH D2 ts_digit" name="startHours" data-tp="1" min="-1" max="100" value="00" >
253
+ &lt;span class="bds-h">:&lt;/span>
254
+ &lt;input type="number" class="sM D2 ts_digit" name="startMinutes" data-tp="2" min="-1" max="60" value="00">
255
+ &lt;span class="bds-m">:&lt;/span>
256
+ &lt;input type="number" class="sS D2 ts_digit" name="startSeconds" data-tp="3" min="-1" max="60" value="00">
257
+ &lt;span class="bds-s">.&lt;/span>
258
+ &lt;input type="number" class="sMS D3 ts_digit" name="startMilliSecs" data-tp="4" min="-10" max="1010" step="10" value="000">
259
+ &lt;div id="svgContainer">
260
+ &lt;svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true"
261
+ focusable="false" data-prefix="fal" data-icon="stopwatch" class="svg-inline--fa fa-stopwatch fa-w-14"
262
+ role="img" viewBox="0 0 448 512">
263
+ &lt;path xmlns="http://www.w3.org/2000/svg" fill="currentColor" d="M393.9 184l22.6-22.6c4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0l-20.7 20.7c-31.1-27.5-70.4-45.9-113.8-50.8V48h28c6.6 0 12-5.4 12-12V12c0-6.6-5.4-12-12-12H172c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12h28v49.4C96.4 109.3 16 197.2 16 304c0 114.9 93.1 208 208 208s208-93.1 208-208c0-44.7-14.1-86.1-38.1-120zM224 464c-88.4 0-160-71.6-160-160s71.6-160 160-160 160 71.6 160 160-71.6 160-160 160zm12-112h-24c-6.6 0-12-5.4-12-12V204c0-6.6 5.4-12 12-12h24c6.6 0 12 5.4 12 12v136c0 6.6-5.4 12-12 12z"/>
264
+ &lt;/svg>
265
+ &lt;/div>
266
+ &lt;style>
267
+ *:focus {
268
+ outline: none;
269
+ }
270
+
271
+
272
+ div.timeCase{
273
+ display: inline-flex;
274
+ flex-direction: row;
275
+ max-width: 300px;
276
+ padding: 3px;
277
+ border-style: solid;
278
+ border-width: 1px;
279
+ border-radius: 2px;
280
+ }
281
+
282
+
283
+ /* Each input width set and blinking cursor 'caret' removed */
284
+ div.timeCase input{
285
+ caret-color: transparent;
286
+ width: 15px;
287
+ padding-top:1px;
288
+ }
289
+
290
+
291
+ div.timeCase .D3{
292
+ width: 25px;
293
+ }
294
+
295
+
296
+ /* Hiding the up and down arrow */
297
+ /*https://www.w3schools.com/howto/howto_css_hide_arrow_number.asp*/
298
+ /* Chrome, Safari, Edge, Opera */
299
+
300
+ input::-webkit-outer-spin-button,
301
+ input::-webkit-inner-spin-button {
302
+ -webkit-appearance: none;
303
+ margin: 0;
304
+ }
305
+
306
+
307
+ /* Firefox */
308
+
309
+ input[type=number] {
310
+ /* -moz-appearance: textfield; */
311
+ -moz-appearance: textarea;
312
+ -webkit-appearance: textarea;
313
+ }
314
+
315
+
316
+ div.timeCase:focus-within {
317
+ border: 2px solid black;
318
+ padding: 2px;
319
+ }
320
+
321
+
322
+ .ts_digit {
323
+ border: none;
324
+ }
325
+
326
+ /* between digit span */
327
+ .bds{
328
+ padding-bottom: 1px;
329
+ }
330
+
331
+ #svgContainer {
332
+ width: 12px;
333
+ height: 12px;
334
+ padding-top: 1px;
335
+ padding-right: 2px;
336
+ color: black;
337
+ }
338
+
339
+ *:disabled {
340
+ background-color: grey;
341
+ color: lightgrey;
342
+ opacity: .6;
343
+ }
344
+ &lt;/style> `
345
+
346
+ spanIn.appendChild(template.content);
347
+
348
+ this.myElement.appendChild(spanIn);
349
+
350
+ }
351
+
352
+
353
+ /**
354
+ * eventlistener that adds number looping for up and down keys triggered by
355
+ * the change event of the input
356
+ * @method
357
+ * @see boot()
358
+ */
359
+
360
+ addNumberLooping() {
361
+
362
+ // Numeric Value looping (eventually this can be 'parameterised' refactored)
363
+ // ex. 99 uparrow to 0 hours, 59 uparrow to 0 minutes and seconds, 990 uparrow to 010, downarrow 000 milliseconds
364
+
365
+ const sH = this.myElement.querySelector("input.sH");
366
+ sH.addEventListener('change', function (event) {
367
+
368
+ if (sH.value == 100) {
369
+ sH.value = '00';
370
+ }
371
+ if (sH.value == -1) {
372
+ sH.value = 99;
373
+ }
374
+
375
+ });
376
+
377
+ const sM = this.myElement.querySelector("input.sM");
378
+ sM.addEventListener('change', function (event) {
379
+
380
+ if (sM.value == 60) {
381
+ sM.value = '00';
382
+ }
383
+ if (sM.value == -1) {
384
+ sM.value = 59;
385
+ }
386
+
387
+ });
388
+
389
+ const sS = this.myElement.querySelector("input.sS");
390
+ sS.addEventListener('change', function (event) {
391
+
392
+ if (sS.value == 60) {
393
+ sS.value = '00';
394
+ }
395
+
396
+ if (sS.value == -1) {
397
+ sS.value = 59;
398
+ }
399
+
400
+ });
401
+
402
+ const sMS = this.myElement.querySelector("input.sMS");
403
+ sMS.addEventListener('change', function (event) {
404
+
405
+ if (sMS.value == 1000) {
406
+ sMS.value = "010";
407
+ }
408
+
409
+ if (sMS.value == -10) {
410
+ sMS.value = 990;
411
+ }
412
+
413
+ if (sMS.value == 0) {
414
+ }
415
+
416
+ });
417
+ }
418
+
419
+
420
+ /**
421
+ * eventlistener that adds number input for keyed values triggered by the keyup event
422
+ * @method
423
+ * @see boot()
424
+ */
425
+
426
+ addNumericInput() {
427
+
428
+ const mE = this.myElement;
429
+
430
+ // https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input
431
+ // Digit input 0-9 (typed in by user)
432
+
433
+ function setInputFilter(inputElement, inputFilter) {
434
+ // this sets a listener and immediately updates the value of the input number (note: can update this from input text, like by removing setSelectionRange )
435
+
436
+ console.log('inputElement: ' + inputElement);
437
+ window.inputElement = inputElement;
438
+
439
+ inputElement.addEventListener('keyup', function (event) {
440
+
441
+ window.kue = event;
442
+
443
+ if (/^([0-9]?)$/.test(event.key)) {
444
+ if (inputFilter(this.value)) {
445
+ this.oldValue = this.value;
446
+ this.oldSelectionStart = this.selectionStart;
447
+ this.oldSelectionEnd = this.selectionEnd;
448
+ } else if (this.hasOwnProperty("oldValue")) {
449
+ this.value = this.oldValue;
450
+ // this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
451
+ } else {
452
+ this.value = "";
453
+ }
454
+ }
455
+ });
456
+ }
457
+
458
+ // three filters, hours or minutes and seconds (are the same) but milliseconds is different
459
+
460
+ var sH = this.myElement.querySelector('input.sH');
461
+
462
+ setInputFilter(sH, function (value) {
463
+
464
+ var newV = /^([0-9]?|[0-9][0-9]?)$/.test(value);
465
+
466
+
467
+ if (value.length === 2) {
468
+
469
+ mE.querySelector('input.sM').focus();
470
+ mE.querySelector('input.sM').select();
471
+
472
+ }
473
+
474
+ return newV;
475
+
476
+ });
477
+
478
+ var sM = this.myElement.querySelector('input.sM');
479
+ setInputFilter(sM, function (value) {
480
+
481
+
482
+ var newV = /^([0-9]?|[0-5][0-9]?)$/.test(value);
483
+
484
+ if (value > 5 || value.length === 2) {
485
+
486
+ mE.querySelector('input.sS').focus();
487
+ mE.querySelector('input.sS').select();
488
+
489
+ }
490
+
491
+ return newV;
492
+
493
+ });
494
+
495
+ var sS = this.myElement.querySelector('input.sS');
496
+ setInputFilter(sS, function (value) {
497
+
498
+ var newV = /^([0-9]?|[0-5][0-9]?)$/.test(value);
499
+
500
+ if (value > 5 || value.length === 2) {
501
+
502
+ mE.querySelector('input.sMS').focus();
503
+ mE.querySelector('input.sMS').select();
504
+
505
+ }
506
+
507
+ return newV;
508
+
509
+ });
510
+
511
+
512
+ var sMS = this.myElement.querySelector('input.sMS');
513
+ setInputFilter(sMS, function (value) {
514
+
515
+ var newV = /^([0-9]?|[0-9][0-9]?|[0-9][0-9][0-9]?)$/.test(value);
516
+
517
+
518
+ if (value.length === 3) {
519
+
520
+ mE.querySelector('input.sMS').blur();
521
+
522
+ }
523
+
524
+ return newV;
525
+
526
+ });
527
+ }
528
+
529
+
530
+ /**
531
+ * eventlistener that adds 0s to preface numbers less than 10 triggered by
532
+ * the change event of the input
533
+ * @method
534
+ * @see boot()
535
+ */
536
+
537
+ add0s() {
538
+
539
+ // input for hours, minutes, seconds
540
+ this.myElement.querySelectorAll('input').forEach(i => i.addEventListener('change', function () {
541
+ if (!isNaN(this.value) &amp;&amp; this.value.length === 1) {
542
+ this.value = '0' + this.value;
543
+ }
544
+ }));
545
+
546
+ // milliseconds
547
+ this.myElement.querySelectorAll("input.sMS").forEach(i => i.addEventListener('change', function () {
548
+
549
+ if (!isNaN(this.value) &amp;&amp; this.value.length === 2) {
550
+ this.value = '0' + this.value;
551
+ }
552
+
553
+ }));
554
+
555
+ }
556
+
557
+
558
+ /**
559
+ * eventlistener that adds click to activate input of values by the keyboard triggered by
560
+ * the click event of the input
561
+ * @method
562
+ * @see boot()
563
+ */
564
+
565
+ addClicksToActivate() {
566
+
567
+ this.myElement.querySelectorAll('input').forEach(i => i.addEventListener("click", function () { this.select(); }))
568
+ }
569
+
570
+
571
+ /**
572
+ * eventlistener that adds key filtering to stop letters (or other non-numerics) from being input triggered by
573
+ * the keypress event of the input
574
+ * @method
575
+ * @see boot()
576
+ */
577
+
578
+ nonNumericBugInHTML() {
579
+
580
+ this.myElement.querySelectorAll(".timeCase input").forEach(item =>
581
+
582
+ item.addEventListener('keypress', function (e) {
583
+
584
+ e = e || window.event;
585
+ var charCode = (typeof e.which == "undefined") ? e.keyCode : e.which;
586
+ var charStr = String.fromCharCode(charCode);
587
+
588
+ if (!charStr.match(/^[0-9]+$/))
589
+ e.preventDefault();
590
+
591
+ }));
592
+ }
593
+
594
+
595
+ // formatting and behaviour options
596
+
597
+ /**
598
+ * disables entire control => read-only
599
+ * @method
600
+ */
601
+
602
+ disable() {
603
+
604
+ var closure = this;
605
+
606
+ // disable chronly inputs on page
607
+
608
+ closure.shadowRoot.querySelectorAll(".timeCase input").forEach(el => el.disabled = 'true')
609
+
610
+ }
611
+
612
+
613
+ /**
614
+ * removes the hours, so the display is mm:ss.uuu
615
+ * @method
616
+ */
617
+
618
+ noHours() {
619
+
620
+ var closure = this;
621
+
622
+ // hide chronly hours inputs on page
623
+
624
+ closure.shadowRoot.querySelectorAll(".timeCase input.sH").forEach(el => el.style.display = 'none');
625
+
626
+
627
+ // hide the hours colon on page
628
+
629
+ closure.shadowRoot.querySelectorAll(".timeCase span.bds-h").forEach(el => el.style.display = 'none');
630
+
631
+ }
632
+ }
633
+ // end class
634
+
635
+
636
+ export default customElements.define('input-duration', InputDuration);
637
+
638
+ // an option is to make all above an IIFE</code></pre>
639
+ </article>
640
+ </section>
641
+
642
+
643
+
644
+
645
+ </div>
646
+
647
+ <nav>
648
+ <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="InputDuration.html">InputDuration</a></li></ul>
649
+ </nav>
650
+
651
+ <br class="clear">
652
+
653
+ <footer>
654
+ Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> on Thu Jul 06 2023 13:53:14 GMT+0000 (GMT)
655
+ </footer>
656
+
657
+ <script> prettyPrint(); </script>
658
+ <script src="scripts/linenumber.js"> </script>
659
+ </body>
660
+ </html>