typed-controls 0.12.7 → 0.12.8

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.
Files changed (3) hide show
  1. package/README.md +28 -29
  2. package/lib/typed-controls.js +1263 -1263
  3. package/package.json +30 -45
@@ -1,1263 +1,1263 @@
1
- "use strict";
2
-
3
- (function codenautasModuleDefinition(root, name, factory) {
4
- /* global define */
5
- /* istanbul ignore next */
6
- if(typeof root.globalModuleName !== 'string'){
7
- root.globalModuleName = name;
8
- }
9
- /* istanbul ignore next */
10
- if(typeof exports === 'object' && typeof module === 'object'){
11
- module.exports = factory();
12
- }else if(typeof define === 'function' && define.amd){
13
- define(factory);
14
- }else if(typeof exports === 'object'){
15
- exports[root.globalModuleName] = factory();
16
- }else{
17
- root[root.globalModuleName] = factory();
18
- }
19
- root.globalModuleName = null;
20
- })(/*jshint -W040 */this, 'TypedControls', function() {
21
- /*jshint +W040 */
22
-
23
- /*jshint -W004 */
24
- var TypedControls = {};
25
- /*jshint +W004 */
26
-
27
- TypedControls.ENABLE_SIGNALS4ALL = false;
28
- TypedControls.ENABLE_SIGNALS = false;
29
- TypedControls.SIGNAL_NO_DATA='--';
30
- TypedControls.SIGNAL_UNKNOWN_DATA='//';
31
-
32
- var likeAr = require('like-ar');
33
- var DialogPromise = require('dialog-promise');
34
-
35
- TypedControls.enablePasteCorrections=true;
36
- TypedControls.doubleClickExpands=false;
37
- TypedControls.showLupa=0.5;
38
- TypedControls.showOn={
39
- click:true,
40
- focus:false,
41
- };
42
-
43
- TypedControls.i18n={messages:{}};
44
- TypedControls.i18n.messages.en={
45
- Yes: 'Yes',
46
- No: 'No',
47
- Null: 'Null/Empty',
48
- pikaday: {
49
- previousMonth : 'Previous Month',
50
- nextMonth : 'Next Month',
51
- months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
52
- weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
53
- weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
54
- },
55
- unknownData: 'unknown data',
56
- noData: 'no data',
57
- };
58
- TypedControls.i18n.messages.es={
59
- Yes: 'Sí',
60
- No: 'No',
61
- Null: 'Nulo/Sin valor',
62
- pikaday: {
63
- previousMonth : 'mes anterior',
64
- nextMonth : 'próximo mes',
65
- months : ['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre'],
66
- weekdays : ['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],
67
- weekdaysShort : ['dom','lun','mar','mié','jue','vie','sáb']
68
- },
69
- unknownData: 'ns/nc',
70
- noData: 'sin dato',
71
- };
72
-
73
- TypedControls.messages = TypedControls.i18n.messages.en;
74
-
75
- var changing = require('best-globals').changing;
76
- var jsToHtml = require('js-to-html');
77
- var TypeStore = require('type-store');
78
- var Big = require('big.js');
79
- var Pikaday = require('pikaday');
80
-
81
- var html=jsToHtml.html;
82
- // var coalesce = bestGlobals.coalesce;
83
- // var changing = bestGlobals.changing;
84
-
85
- TypedControls.Form = function Form(formInfo, medium){
86
- this.info=formInfo;
87
- this.medium=medium;
88
- };
89
-
90
- TypedControls.Form.prototype.render = function render(container){
91
- var formHtml=html.div({id: JSON.stringify(this.medium.superId)},
92
- this.info.fields.map(function(field){
93
- return html.div({id:'div_'+field.name},[
94
- html.label({"for":field.name},field.name),
95
- html.input({id:field.name})
96
- ]);
97
- })
98
- );
99
- var div=formHtml.create();
100
- this.dom=div;
101
- if(!this.medium.forms){
102
- this.medium.forms=[];
103
- }
104
- this.medium.forms.push(this);
105
- container.appendChild(div);
106
- return Promise.resolve();
107
- };
108
-
109
- TypedControls.createForm = function createForm(formInfo, data){
110
- var form = new this.Form(formInfo, data);
111
- return form;
112
- };
113
-
114
- TypedControls.normalOnBlurListener = function normalOnBlurListener(event){
115
- if(!this.updatingSuspended){
116
- var currentValue=this.getTypedValue();
117
- if(this.validateWhileInput()){
118
- if(!bestGlobals.sameValue(this.previousValue, currentValue)){
119
- this.dispatchEvent(new CustomEvent('update'));
120
- this.previousValue=currentValue;
121
- }
122
- // TODO revisar que no se esté haciendo demasiadas veces, quizás haya que primero ver si es distinto.
123
- this.setValidatedTypedValue(currentValue);
124
- }
125
- }
126
- };
127
-
128
- (function () {
129
- function CustomEvent ( event, params ) {
130
- params = params || { bubbles: false, cancelable: false, detail: undefined };
131
- var evt = document.createEvent( 'CustomEvent' );
132
- evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
133
- return evt;
134
- }
135
- if(typeof(window.CustomEvent)!=='function'){
136
- CustomEvent.prototype = window.Event.prototype;
137
- window.CustomEvent = CustomEvent;
138
- }
139
- })();
140
-
141
- var BestControls = {};
142
-
143
- var iiiiiiid=1;
144
-
145
- TypedControls.optionsCtrl = function optionsCtrl(typeInfo){
146
- var options = typeInfo.options;
147
- return html.div({"typed-controls-option-group": 'simple-option'},
148
- options.map(function(option){
149
- return html.div([
150
- (typeInfo.showOption?html.label({"for-value": option.option},option.option):null),
151
- html.input({type:'radio', value:option.option}),
152
- html.label({"for-value": option.option},option.label),
153
- (option.more?html.span({"for-value": option.option, "class":"option-more-info"}):null)
154
- ]);
155
- })
156
- );
157
- };
158
-
159
- TypedControls.booleanCtrl = function booleanCtrl(){
160
- return TypedControls.optionsCtrl({options: BestControls.boolean.defaultOptions});
161
- };
162
-
163
- BestControls.div = {
164
- adapters:{
165
- getTypedValue: function getTypedValueDate(){
166
- var plainValue = this.getPlainValue();
167
- if(plainValue==null){
168
- return plainValue;
169
- }
170
- var typer=this.controledType;
171
- return typer.fromUserInput(plainValue);
172
- },
173
- setValidatedTypedValue: function setValidatedTypedValue(typedValue){
174
- var typer = this.controledType;
175
- if(typedValue==null){
176
- this.setPlainValue(typedValue);
177
- }else{
178
- this.setPlainValue(typer.toLocalString(typedValue));
179
- if(this.tagName!=='INPUT' && typer.toHtml){
180
- this.innerHTML='';
181
- this.appendChild(typer.toHtml(typedValue).create());
182
- }
183
- }
184
- },
185
- },
186
- listeners:{
187
- 'blur': TypedControls.normalOnBlurListener,
188
- 'keydown': function onKeyPressListenerForDiv(event){
189
- var element = this;
190
- setTimeout(function(){
191
- element.validateWhileInput();
192
- },300);
193
- },
194
- 'paste': function(event){
195
- if (TypedControls.enablePasteCorrections){
196
- let paste = (event.clipboardData || window.clipboardData).getData('text');
197
- paste = paste.replace(/\u00A0/g,' ');
198
- var element = event.target;
199
- if(element && (element.tagName == "INPUT" || element.tagName == "TEXTAREA")){
200
- var start = element.selectionStart;
201
- element.setRangeText(paste);
202
- var pos = (start||0) + paste.length
203
- element.setSelectionRange(pos, pos);
204
- }else{
205
- const selection = window.getSelection();
206
- if (!selection.rangeCount) return false;
207
- console.log(selection.rangeCount);
208
- for(var i=0; i<selection.rangeCount; i++) console.log('e',selection.getRangeAt(i))
209
- selection.deleteFromDocument();
210
- selection.getRangeAt(0).insertNode(document.createTextNode(paste));
211
- selection.collapseToEnd()
212
- }
213
- event.preventDefault();
214
- }
215
- },
216
- 'keypress': function onKeyPressListenerForDiv(event){
217
- var element = this;
218
- if(event.which>=32){
219
- var typer = this.controledType;
220
- var theChar = String.fromCharCode(event.which);
221
- if(typer.rejectedChar(theChar)){
222
- if(element.expander && element.expander.autoExpand){
223
- if(!element.displayingExpander){
224
- var opts = {initialKeystrokes:theChar};
225
- element.displayExpander(event, opts);
226
- element.displayingExpander=opts;
227
- }else{
228
- element.displayingExpander.initialKeystrokes+=theChar;
229
- }
230
- }
231
- event.preventDefault();
232
- }
233
- }
234
- },
235
- },
236
- domFixtures:[
237
- {tagName:'input' , attributes:{type:'text'}},
238
- ]
239
- };
240
-
241
- BestControls.text = {
242
- translates:{true:{
243
- '\n': '\u21b5'
244
- },false:{}},
245
- translatesRegExp:{},
246
- translatesRev:{},
247
- translate: function(right, textValue){
248
- return textValue.replace(new RegExp(BestControls.text.translatesRegExp[right],'g'),function(chartt){
249
- return BestControls.text.translates[right][chartt];
250
- });
251
- },
252
- adapters:{
253
- validateTypedData: function validateTypedDataNoObjectAccepted(typedValue){
254
- if(typedValue!==null && typeof typedValue !== 'string'){
255
- throw new Error("Not a text in input");
256
- }
257
- },
258
- getTypedValue: function getTypedValueText(){
259
- var typedValue = this.getPlainValue();
260
- if(this.tagName==='INPUT' && typedValue!==null){
261
- typedValue = BestControls.text.translate(false, typedValue);
262
- }
263
- if(typedValue==null && (this.valueEmpty || !this.controledType.nullable)){
264
- return '';
265
- }else{
266
- if(typedValue!=null){
267
- return typedValue.replace(/\n+$/,'');
268
- }
269
- return typedValue;
270
- }
271
- },
272
- setValidatedTypedValue: function setValidatedTypedValueText(typedValue){
273
- if(this.tagName==='INPUT' && typedValue!=null){
274
- typedValue = BestControls.text.translate(true, typedValue);
275
- }
276
- if(this.tagName==='TEXTAREA' && typedValue==null){
277
- this.setPlainValue('');
278
- }else{
279
- this.setPlainValue(typedValue);
280
- }
281
- this.valueEmpty = typedValue==='' || typedValue==null && !this.controledType.nullable;
282
- },
283
- },
284
- listeners:{
285
- 'keypress': function onKeyPressListenerForText(event){
286
- if(this.value===''){
287
- if(event.keyCode == 32){
288
- if(!this.valueEmpty){
289
- this.valueEmpty = true;
290
- event.preventDefault();
291
- }else{
292
- this.valueEmpty = false;
293
- }
294
- }
295
- }else{
296
- this.valueEmpty = false;
297
- }
298
- },
299
- 'blur': TypedControls.normalOnBlurListener
300
- },
301
- domFixtures:[
302
- {tagName:'input' , attributes:{type:'text'}, mainUpdateEventName:'blur'},
303
- {tagName:'div' , attributes:{} },
304
- {tagName:'textarea', attributes:{}},
305
- ]
306
- };
307
-
308
- for(var charToTranslate in BestControls.text.translates[true]){
309
- BestControls.text.translates[false][BestControls.text.translates[true][charToTranslate]] = charToTranslate;
310
- }
311
-
312
- for(var groups in BestControls.text.translates){
313
- BestControls.text.translatesRegExp[groups] = '['+Object.keys(BestControls.text.translates[groups])+']';
314
- }
315
-
316
- BestControls.text_no_empty = {
317
- adapters:{
318
- validateTypedData: function validateTypedDataTextNoEmpty(typedValue){
319
- BestControls.text.adapters.validateTypedData(typedValue);
320
- if(typedValue===''){
321
- throw new Error('text cannot be empty');
322
- }
323
- },
324
- getTypedValue: function getTypedValueText(){
325
- return this.getPlainValue();
326
- },
327
- setValidatedTypedValue: function setValidatedTypedValueTextNoEmpty(typedValue){
328
- if(this.tagName==='TEXTAREA' && typedValue==null){
329
- this.setPlainValue('');
330
- }else{
331
- this.setPlainValue(typedValue);
332
- }
333
- },
334
- },
335
- listeners:{
336
- 'blur': TypedControls.normalOnBlurListener
337
- },
338
- domFixtures:BestControls.text.domFixtures.concat({tagName:'input', attributes:{type:'password'}})
339
- };
340
-
341
- BestControls.number = {
342
- adapters:{
343
- setValidatedTypedValue: function setValidatedTypedValuePrettyNumber(typedValue){
344
- if(isNaN(typedValue) || typedValue==null){
345
- this.value='';
346
- }else{
347
- this.valueAsNumber = typedValue;
348
- }
349
- if(this.value.length>1 && /[.,]/.test(this.value[this.value.length-2])){
350
- this.value=this.value+'0';
351
- }
352
- },
353
- getTypedValue: function getTypedValue(){
354
- return isNaN(this.valueAsNumber)||this.value==''?null:this.valueAsNumber;
355
- },
356
- // setTypedValue: function setTypedValue(value){
357
- // this.valueAsNumber=value;
358
- // },
359
- },
360
- listeners:{
361
- 'blur': TypedControls.normalOnBlurListener,
362
- 'keydown': function onKeyPressListenerForDiv(event){
363
- var typer = this.controledType||{typeInfo:{}};
364
- if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
365
- var theKey=event.keyCode;
366
- // subtract or dash key
367
- if((theKey==109 || theKey==189) && (this.previousKey==109 || this.previousKey==189)){
368
- var valueNoData;
369
- if('valueNoData' in typer.typeInfo){
370
- valueNoData=typer.typeInfo.valueNoData;
371
- }else{
372
- valueNoData=TypedControls.VALUE_NO_DATA;
373
- }
374
- this.value=valueNoData;
375
- event.preventDefault();
376
- }
377
- //divide key or forward slash
378
- if((theKey==111 || theKey==191) && (this.previousKey==111 || this.previousKey==191)){
379
- var valueUnknownData;
380
- if('valueUnknownData' in typer.typeInfo){
381
- valueUnknownData=typer.typeInfo.valueUnknownData;
382
- }else{
383
- valueUnknownData=TypedControls.VALUE_UNKNOWN_DATA;
384
- }
385
- this.value=valueUnknownData;
386
- event.preventDefault();
387
- }
388
- var element = this;
389
- setTimeout(function(){
390
- element.validateWhileInput();
391
- },300);
392
- this.previousKey=theKey;
393
- }
394
- },
395
-
396
- /*
397
- 'keypress': function onKeyPressListenerForNumber(event){
398
- if( event.keyCode>=32 && event.keyCode<=43 ||
399
- event.keyCode>=47 && event.keyCode<=47 ||
400
- event.keyCode>=58
401
- ){
402
- event.preventDefault();
403
- }
404
- },
405
- 'keyup': function onKeyUpListenerForNumber(event){
406
- var targetName='value' in this?'value':'textContent';
407
- if(!this[targetName].match(/^-?[0-9]*\.?[0-9]*$/)){
408
- var negative=this[targetName][0]==='-';
409
- var newValue=this[targetName].replace(/[^0-9.]/g,'');
410
- newValue=newValue.replace(/[.]/,',');
411
- newValue=newValue.replace(/[.]/g,'');
412
- newValue=newValue.replace(/[,]/g,'.');
413
- this[targetName]=(negative?'-':'')+newValue;
414
- }
415
- }
416
- */
417
- },
418
- domFixtures:[
419
- {tagName:'input' , attributes:{type:'text'}},
420
- {tagName:'input' , attributes:{type:'number'}},
421
- {tagName:'div' , attributes:{}},
422
- ]
423
- };
424
-
425
- BestControls.boolean = {
426
- adapters:{
427
- validateTypedData: function validateTypedDataBoolean(typedValue){
428
- if(typedValue!==false && typedValue!==true && typedValue!=null){
429
- throw new Error('Not a boolean in input');
430
- }
431
- },
432
- getTypedValue: function getTypedValueBoolean(){
433
- var domElement=this;
434
- var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
435
- if(typedControlsOptionGroup){
436
- var typedValue = null;
437
- [true, false].forEach(function(value){
438
- if(domElement.optionControl[value].checked){
439
- typedValue = value;
440
- }
441
- });
442
- return typedValue;
443
- }else if(this.type==='checkbox'){
444
- return this.indeterminate?null:this.checked;
445
- }else{
446
- var value = this.getPlainValue();
447
- var falseInitials={'n':true,'N':true,'0':true,'2':true,'F':true,'f':true,'\u043d':true,'\u041d':true};
448
- if(value==null || value.trim()==''){
449
- return null;
450
- }else{
451
- return !falseInitials[value.trim()[0]];
452
- }
453
- }
454
- },
455
- setValidatedTypedValue: function setValidatedTypedValuePrettyBoolean(typedValue){
456
- var domElement=this;
457
- var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
458
- if(typedControlsOptionGroup){
459
- [true, false].forEach(function(value){
460
- domElement.optionControl[value].checked = value===typedValue;
461
- });
462
- }else if(this.type==='checkbox'){
463
- this.checked = typedValue;
464
- this.indeterminate = typedValue==null;
465
- }else{
466
- var plainValue = typedValue==null?'':(typedValue?TypedControls.messages.Yes:TypedControls.messages.No);
467
- this.setPlainValue(plainValue);
468
- if(this.tagName!=='INPUT'){
469
- if(typedValue!==null){
470
- this.innerHTML = html.span({"class": "bool_"+JSON.stringify(typedValue)}, plainValue).toHtmlText();
471
- }
472
- }
473
- }
474
- },
475
- },
476
- listeners:{
477
- 'keydown': function onKeyDownListenerForBoolean(event){
478
- if(this.type==='checkbox' && (
479
- event.keyCode == 8 || //backspace
480
- event.keyCode == 46 || //delete/Supr
481
- event.keyCode == 109 || //'-'/minus in keypad
482
- event.keyCode == 189 || //'-'/minus in keyboard
483
- event.keyCode == 190 //'.'/period in keyboard
484
- )){
485
- this.checked = false;
486
- this.indeterminate = true;
487
- event.preventDefault();
488
- }
489
- },
490
- 'click': function onClickListenerForBoolean(event){
491
- if(this.type==='checkbox'){
492
- if(document.activeElement!==this){
493
- // Safari 5.1.7 and other old browsers doesn't set activeElement
494
- this.focus();
495
- }
496
- }
497
- },
498
- 'blur': TypedControls.normalOnBlurListener,
499
- 'change': function onChangeListenerForBoolean(event) {
500
- this.dispatchEvent(new CustomEvent('update'));
501
- }
502
- },
503
- domFixtures:[
504
- {creatorFunction:TypedControls.booleanCtrl, attributes:{}},
505
- {tagName:'div' , attributes:{}},
506
- {tagName:'input' , attributes:{type:'text'}, mainUpdateEventName:'blur'},
507
- {tagName:'input' , attributes:{type:'checkbox'}, mainUpdateEventName:'change'},
508
- ],
509
- defaultOptions:[
510
- {option: true , labelId: 'Yes'},
511
- {option: false, labelId: 'No'},
512
- ]
513
- };
514
-
515
- BestControls.boolean.defaultOptions.forEach(function(optionDefinition){
516
- Object.defineProperty(optionDefinition, 'label',{
517
- get: function(){return TypedControls.messages[optionDefinition.labelId];}
518
- });
519
- });
520
-
521
- BestControls.date = {
522
- adapters:{
523
- validateTypedData: function validateTypedDataDate(typedValue){
524
- if(typedValue!=null){
525
- if(!(typedValue instanceof Date)){
526
- throw new Error('Not a date in input');
527
- // }else if(!(/[0 ]0:00:00/.test(typedValue.toLocaleString("local", {hour12:false})))){
528
- }else if(typedValue.getTime() != new Date(typedValue.getFullYear(), typedValue.getMonth(), typedValue.getDate()).getTime()){
529
- throw new Error('date must be an absolute date without time '+typedValue+' <> '+new Date(typedValue.getFullYear(), typedValue.getMonth(), typedValue.getDate()));
530
- }
531
- }
532
- },
533
- getTypedValue: function getTypedValueDate(){
534
- var plainValue = this.getPlainValue();
535
- var parts;
536
- if(plainValue==null){
537
- return null;
538
- }else if (this.type==='date') {
539
- parts = plainValue.split(/[-\/]/);
540
- return new Date(parts[0],parts[1]-1,parts[2]);
541
- }else{
542
- parts = plainValue.split(/[-\/]/);
543
- return new Date(parts[2],parts[1]-1,parts[0]);
544
- }
545
- },
546
- setValidatedTypedValue: function setValidatedTypedValuePrettyDate(typedValue){
547
- if(typedValue==null){
548
- this.setPlainValue(typedValue);
549
- }else if(this.type==='date'){
550
- this.value = typedValue.toISOString().substr(0,10);
551
- }else{
552
- var month = typedValue.getUTCMonth()+1;
553
- var day = typedValue.getUTCDate();
554
- var year = typedValue.getUTCFullYear();
555
- this.setPlainValue(day+'/'+month+'/'+year);
556
- if(this.tagName!=='INPUT'){
557
- var rta=[];
558
- rta.push(html.span({"class":"date_day"},day));
559
- rta.push(html.span({"class":"date_sep"},'/'));
560
- rta.push(html.span({"class":"date_month"},month));
561
- rta.push(html.span({"class":"date_sep"},'/'));
562
- rta.push(html.span({"class":"date_year"},year));
563
- rta = rta.map(function(x){ return x.toHtmlText(); }).join('');
564
- this.innerHTML = rta;
565
- }
566
- }
567
-
568
- },
569
- },
570
- listeners:{
571
- 'blur': TypedControls.normalOnBlurListener,
572
- 'keydown': function onKeyDownListenerForDate(event){
573
- if(event.keyCode == 72) { // key h
574
- var now=new Date();
575
- this.controledType.setTypedValue(new Date(now.getFullYear(),now.getMonth(),now.getDate()));
576
- event.preventDefault();
577
- }
578
- },
579
- },
580
- domFixtures:[
581
- {tagName:'input' , attributes:{type:'date'}},
582
- {tagName:'div' , attributes:{}},
583
- {tagName:'input' , attributes:{type:'text'}},
584
- ]
585
- };
586
-
587
- function markActive(element, display){
588
- while(element && element.tagName!='BODY'){
589
- if(element.getAttribute('display-if-active')){
590
- element.setAttribute('display-is-active',display?'1':'0');
591
- }
592
- element = element.parentNode;
593
- }
594
- }
595
-
596
- var BestControls_enum = {
597
- adapters:{
598
- validateTypedData: function validateTypedValue(typedValue){
599
- if(typedValue!=null && !this.typedControlsValidOptions[typedValue]){
600
- throw new Error('Not a enum in input');
601
- }
602
- },
603
- getTypedValue: function getTypedValueEnum(){
604
- var domElement=this;
605
- var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
606
- var typedValue = null;
607
- this.controledType.typeInfo.options.forEach(function(option){
608
- if(domElement.optionControl[option.option].checked){
609
- typedValue = option.option;
610
- }
611
- });
612
- if(typedValue==null){
613
- return null;
614
- }
615
- if(this.controledType.typeName=='bigint'){
616
- typedValue = Number(typedValue);
617
- }
618
- return typedValue;
619
- },
620
- setValidatedTypedValue: function setValidatedTypedValuePrettyBoolean(typedValue){
621
- var domElement = this;
622
- var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
623
- (domElement.shadowControl||{}).value=typedValue;
624
- this.controledType.typeInfo.options.forEach(function(option){
625
- domElement.optionControl[option.option].checked = option.option===typedValue;
626
- });
627
- this.refreshState();
628
- },
629
- refreshState: function refreshState(){
630
- this.controledType.typeInfo.options.forEach(function(option){
631
- var control = this.optionControl[option.option];
632
- Array.prototype.forEach.call(control.labelsElements, function(label){
633
- label.setAttribute('state-label-option',control.checked?'checked':'unchecked');
634
- markActive(label, control.checked);
635
- });
636
- },this);
637
- }
638
- },
639
- listeners:{
640
- /* TODO:
641
- 'keydown': function onKeyDownListenerForBoolean(event){
642
- },
643
- 'click': function onClickListenerForBoolean(event){
644
- },
645
- 'blur': TypedControls.normalOnBlurListener,
646
- */
647
- 'change': function onChangeListenerForBoolean(event) {
648
- this.dispatchEvent(new CustomEvent('update'));
649
- }
650
- },
651
- domFixtures:[
652
- {creatorFunction:TypedControls.optionsCtrl, attributes:{}},
653
- ]
654
- };
655
-
656
-
657
- TypedControls.completeTypeInfo = function completeTypeInfo(typeInfoMayBeIncompleteOrString){
658
- var typeInfo = typeInfoMayBeIncompleteOrString;
659
- if(typeof typeInfo === 'string'){
660
- typeInfo = {typeName:typeInfo};
661
- }
662
- if(typeInfo.typeName==='boolean' && !typeInfo.options){
663
- typeInfo.options=BestControls.boolean.defaultOptions;
664
- }
665
- return typeInfo;
666
- };
667
-
668
- TypedControls.bestCtrl = function bestCtrl(typeInfo){
669
- typeInfo = TypedControls.completeTypeInfo(typeInfo);
670
- var theElement = BestControls[typeInfo.typeName].domFixtures.reduce(function(elementoCreado, def){
671
- if(elementoCreado){
672
- return elementoCreado;
673
- }
674
- return TypedControls.createFromFixture(def, typeInfo);
675
- }, null);
676
- return theElement;
677
- };
678
-
679
- function getRect(element){
680
- var rect = {top:0, left:0, width:element.offsetWidth, height:element.offsetHeight};
681
- while( element != null ) {
682
- rect.top += element.offsetTop;
683
- rect.left += element.offsetLeft;
684
- element = element.offsetParent;
685
- }
686
- return rect;
687
- }
688
-
689
- TypedControls.path={
690
- img:''
691
- };
692
-
693
- TypedControls.adaptElement = function adaptElement(domElement, typerOrTypeInfo){
694
- // typeInfo = TypedControls.completeTypeInfo(typeInfo);
695
- if(typeof typerOrTypeInfo === 'string'){
696
- throw new Error("obsolete typeName in adaptElement "+typerOrTypeInfo);
697
- }
698
- var typer;
699
- if(typerOrTypeInfo instanceof TypeStore.TypeBase){
700
- typer=typerOrTypeInfo;
701
- }else{
702
- typer = TypeStore.typerFrom(typerOrTypeInfo);
703
- }
704
- var typeName = typer.typeName;
705
- var typedControlsOptionGroup=domElement.getAttribute("typed-controls-option-group");
706
- domElement.controledType = typer;
707
- var bestControl=BestControls.div;
708
- if(domElement.tagName=='INPUT' && domElement.type=='number'){
709
- bestControl=BestControls.number;
710
- }
711
- if(typedControlsOptionGroup){
712
- var inputTypeRadio=[];
713
- var idElement = domElement.id||'__id__'+iiiiiiid++;
714
- domElement.setAttribute("typed-controls-option-group",idElement);
715
- domElement.typedControlsValidOptions={};
716
- domElement.moreInfo={};
717
- // var childs=domElement.childNodes;
718
- domElement.optionControl={};
719
- var inputElement=domElement.getElementsByClassName('typed-control-input-for-options');
720
- inputElement = inputElement?inputElement[0]:null;
721
- if(inputElement){
722
- var setCheckbox=function(){
723
- var value = inputElement.value;
724
- if(value && domElement.optionControl[value]){
725
- domElement.optionControl[value].checked = true;
726
- var event = new Event('change');
727
- var elem = domElement.optionControl[value];
728
- elem.dispatchEvent(event);
729
- }else{
730
- likeAr(domElement.optionControl).forEach(function(option){ option.checked=false });
731
- domElement.dispatchEvent(new CustomEvent('update'));
732
- domElement.refreshState()
733
- }
734
- }
735
- inputElement.addEventListener('keydown',function(){
736
- if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
737
- var theKey=event.keyCode;
738
- // subtract or dash key
739
- if((theKey==109 || theKey==189) && (this.previousKey==109 || this.previousKey==189)){
740
- var valueNoData;
741
- if('valueNoData' in typer.typeInfo){
742
- valueNoData=typer.typeInfo.valueNoData;
743
- }else{
744
- valueNoData=TypedControls.VALUE_NO_DATA;
745
- }
746
- this.value=valueNoData;
747
- setCheckbox();
748
- event.preventDefault();
749
- }
750
- //divide key or forward slash
751
- if((theKey==111 || theKey==191) && (this.previousKey==111 || this.previousKey==191)){
752
- var valueUnknownData;
753
- if('valueUnknownData' in typer.typeInfo){
754
- valueUnknownData=typer.typeInfo.valueUnknownData;
755
- }else{
756
- valueUnknownData=TypedControls.VALUE_UNKNOWN_DATA;
757
- }
758
- this.value=valueUnknownData;
759
- setCheckbox();
760
- event.preventDefault();
761
- }
762
- this.previousKey=theKey;
763
- }
764
- })
765
- domElement.shadowControl = inputElement;
766
- inputElement.addEventListener('change',setCheckbox);
767
- domElement.focus = function focus(){
768
- inputElement.focus();
769
- }
770
- }
771
- typer.typeInfo.options.forEach(function(option){
772
- domElement.typedControlsValidOptions[option.option]={};
773
- domElement.moreInfo[option.option]={};
774
- var moreInfoElements=domElement.querySelectorAll('span.option-more-info[for-value="'+option.option+'"]');
775
- if(moreInfoElements.length>0){
776
- var moreInfo=moreInfoElements[0];
777
- domElement.moreInfo[option.option].className=moreInfo.className;
778
- domElement.moreInfo[option.option] =moreInfo;
779
- }
780
- var childElements=domElement.querySelectorAll('input[type=radio][value="'+option.option+'"]');
781
- if(childElements.length===0){
782
- throw new Error('incomplete options control (value='+option.option+')');
783
- }else if(childElements.length>1){
784
- throw new Error('duplicate options in options control (value="'+option.option+'")');
785
- }
786
- var childElement = childElements[0];
787
- domElement.optionControl[option.option]=childElement;
788
- inputTypeRadio.push(childElement);
789
- childElement.name=idElement;
790
- childElement.id=idElement+'-'+option.option;
791
- var labelsElements=domElement.querySelectorAll('label[for-value="'+option.option+'"]');
792
- childElement.labelsElements = labelsElements;
793
- Array.prototype.forEach.call(labelsElements, function(label){
794
- label.htmlFor=childElement.id;
795
- });
796
- childElement.addEventListener('change',function(){
797
- domElement.dispatchEvent(new CustomEvent('update'));
798
- domElement.refreshState();
799
- if(inputElement){
800
- inputElement.value = option.option;
801
- }
802
- });
803
- });
804
- var radioChilds=domElement.querySelectorAll('input[type=radio]');
805
- if(radioChilds.length!=typer.typeInfo.options.length){
806
- throw new Error('invalid options in options control');
807
- }
808
- domElement.disable=function(disabled){
809
- domElement.disabled=disabled;
810
- if(inputElement && inputElement !== domElement){
811
- inputElement.disabled=disabled;
812
- }
813
- inputTypeRadio.forEach(function(childElement){
814
- childElement.disabled=disabled;
815
- });
816
- };
817
- domElement.getTypedValue=BestControls_enum.adapters.getTypedValue;
818
- domElement.validateTypedData=BestControls_enum.adapters.validateTypedData;
819
- domElement.setValidatedTypedValue=BestControls_enum.adapters.setValidatedTypedValue;
820
- domElement.refreshState=BestControls_enum.adapters.refreshState;
821
- }else{
822
- domElement.dataAttr=domElement.tagName==='INPUT' || domElement.tagName==='TEXTAREA'?'value':'textContent';
823
- if(domElement.dataAttr=='textContent'){
824
- domElement.ritchHtmlContent=true;
825
- }
826
- if(domElement.getAttribute("typed-controls-direct-input") && domElement.getAttribute("typed-controls-direct-input")==='true'){
827
- domElement.contentEditable = true;
828
- domElement.disable=function(disabled){
829
- domElement.disabled=disabled;
830
- domElement.contentEditable = !disabled;
831
- };
832
- }else{
833
- domElement.disable=function(disabled){
834
- domElement.disabled=disabled;
835
- };
836
- }
837
- var editable=function(typer, expander, domElement){
838
- return ((typer.typeInfo.editable == null || typer.typeInfo.editable) && (domElement.contentEditable=='true' || !domElement.disabled || domElement.editOnlyFromList) || expander.whenReadOnly)
839
- }
840
- var expander = TypedControls.Expanders.find(function(expander){
841
- var typer = domElement.controledType;
842
- return editable(typer, expander, domElement) && expander.whenType(domElement);
843
- });
844
- if(expander){
845
- domElement.lupa=null;
846
- domElement.expander = expander;
847
- var reubicate = function reubicate(){
848
- if(domElement.lupaFija || (document.activeElement === domElement || domElement.disabled) && editable(typer, expander, domElement)){
849
- domElement.lupa.style.display='';
850
- domElement.lupa.style.opacity=1;
851
- var rect = getRect(domElement);
852
- var top=rect.top+rect.height-domElement.lupa.offsetHeight/2;
853
- var left=rect.left+rect.width*TypedControls.showLupa-domElement.lupa.offsetWidth/2
854
- if(Math.abs(top-domElement.lupa.style.top.replace('px',''))>1.2){
855
- domElement.lupa.style.top=top+'px';
856
- }
857
- if(Math.abs(left-domElement.lupa.style.left.replace('px',''))>1.2){
858
- domElement.lupa.style.left=left+'px';
859
- }
860
- }else if(domElement.lupa){
861
- if(domElement.lupa.timerReubicate){
862
- clearInterval(domElement.lupa.timerReubicate);
863
- }
864
- document.body.removeChild(domElement.lupa);
865
- domElement.lupa=null;
866
- }
867
- };
868
- domElement.ponerLupa = function ponerLupa(fija){
869
- domElement.lupa = html.img({src:TypedControls.path.img+(domElement.expander.img||'lookdown.png'), class:'img-lupa', style:'position:absolute; display:none'}).create();
870
- document.body.appendChild(domElement.lupa);
871
- domElement.lupa.addEventListener('load', reubicate);
872
- domElement.lupa.addEventListener('click',displayExpander);
873
- domElement.lupa.timerReubicate = setInterval(reubicate,500);
874
- domElement.lupaFija = fija;
875
- }
876
- var quitarLupa = function quitarLupa(domElement){
877
- if(domElement.lupa && !domElement.lupaFija){
878
- clearInterval(domElement.lupa.timerReubicate);
879
- domElement.lupa.timerReubicate=null;
880
- // domElement.lupa.timerReubicate = setInterval(reubicate,500);
881
- domElement.lupa.style.opacity=0.01;
882
- clearTimeout(domElement.lupa.timerClose);
883
- domElement.lupa.timerClose=null;
884
- }
885
- }
886
- var displayExpander = function displayExpander(event, opts){
887
- if(editable(typer, expander, domElement)){
888
- domElement.updatingSuspended=true;
889
- var dialogFinally = function dialogFinally(hasUpdated){
890
- domElement.updatingSuspended=false;
891
- domElement.focus();
892
- if(!domElement.disabled && !(hasUpdated instanceof Error)){
893
- domElement.dispatchEvent(new Event('input'));
894
- domElement.dispatchEvent(new CustomEvent('update'));
895
- }
896
- };
897
- domElement.expander.dialogInput(domElement, opts).then(dialogFinally,dialogFinally);
898
- event.preventDefault();
899
- quitarLupa(domElement);
900
- }
901
- };
902
- domElement.displayExpander = displayExpander;
903
- if(TypedControls.doubleClickExpands){
904
- domElement.addEventListener('dblclick',function(){
905
- if(domElement.textContent==''){
906
- displayExpander(event);
907
- }
908
- });
909
- }
910
- ['focus','click'].forEach(function(eventName){
911
- if(TypedControls.showLupa && TypedControls.showOn[eventName]){
912
- domElement.addEventListener(eventName, function(){
913
- if(!domElement.lupa){
914
- domElement.ponerLupa();
915
- }else if(domElement.lupa.timerClose){
916
- clearTimeout(domElement.lupa.timerClose);
917
- }
918
- domElement.lupa.timerClose = setTimeout(function(){
919
- quitarLupa(domElement);
920
- },5000);
921
- setTimeout(reubicate,10);
922
- });
923
- }
924
- });
925
- domElement.addEventListener('blur', function(){
926
- quitarLupa(domElement);
927
- });
928
- domElement.addEventListener('keydown', function(event){
929
- var domElement = this;
930
- if(event.keyCode == 120 && !event.shiftKey && !event.ctrlKey && !event.altKey
931
- || event.which == 40 && !event.shiftKey && !event.ctrlKey && event.altKey
932
- ){ //F9 alt down
933
- if(!domElement.updatingSuspended){
934
- displayExpander(event);
935
- }
936
- }
937
- });
938
- }
939
- domElement.setAttribute("type-align",typer.align);
940
- domElement.getPlainValue = function getPlainValue(){
941
- return this[this.dataAttr]===''?this.controledType.emptyValue:this[this.dataAttr];
942
- };
943
- domElement.setPlainValue = function setPlainValue(plainValue){
944
- if(this.tagName=='INPUT' && this.type=='number'){
945
- // alert('aca')
946
- }
947
- this[this.dataAttr] = plainValue;
948
- };
949
- domElement.setValidatedTypedValue = function setValidatedTypedValue(typedValue){
950
- var typer=this.controledType;
951
- this.setPlainValue(typedValue==null?'':typer.toLocalString(typedValue));
952
- if(this.ritchHtmlContent){
953
- this.innerHTML="";
954
- if(typedValue==null){
955
- this.appendChild(html.span({class:'null-value'}).create());
956
- }else{
957
- this.appendChild(typer.toHtml(typedValue).create());
958
- }
959
- }
960
- };
961
- domElement.validateWhileInput = function validateWhileInput(){
962
- var plainValue = this.getPlainValue();
963
- var typer = this.controledType||{typeInfo:{}};
964
- if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
965
- /* NO DATA SIGNAL */
966
- var valueNoData;
967
- if('valueNoData' in typer.typeInfo){
968
- valueNoData=typer.typeInfo.valueNoData;
969
- }else{
970
- valueNoData=TypedControls.VALUE_NO_DATA;
971
- }
972
- if(plainValue===TypedControls.SIGNAL_NO_DATA || plainValue===valueNoData){
973
- this.setAttribute('typed-controls-signal-no-data','1');
974
- if(plainValue===TypedControls.SIGNAL_NO_DATA){
975
- this.setPlainValue(valueNoData);
976
- }
977
- }else{
978
- this.removeAttribute('typed-controls-signal-no-data');
979
- }
980
- /* FIN NO DATA SIGNAL */
981
- /* UNKNONWN DATA SIGNAL */
982
- var valueUnknownData;
983
- if('valueUnknownData' in typer.typeInfo){
984
- valueUnknownData=typer.typeInfo.valueUnknownData;
985
- }else{
986
- valueUnknownData=TypedControls.VALUE_UNKNOWN_DATA;
987
- }
988
- if(plainValue===TypedControls.SIGNAL_UNKNOWN_DATA || plainValue===valueUnknownData){
989
- this.setAttribute('typed-controls-signal-unknown-data','1');
990
- if(plainValue===TypedControls.SIGNAL_UNKNOWN_DATA){
991
- this.setPlainValue(valueUnknownData);
992
- }
993
- }else{
994
- this.removeAttribute('typed-controls-signal-unknown-data');
995
- }
996
- /* FIN UNKNONWN DATA SIGNAL */
997
- }
998
- if(plainValue==null){
999
- this.setAttribute('typed-controls-status','null');
1000
- }else{
1001
- var typer = this.controledType; // eslint-disable-line no-redeclare
1002
- var reason = !typer.isValidLocalString(plainValue);
1003
- if(reason){
1004
- this.setAttribute('typed-controls-status','error');
1005
- }else{
1006
- this.setAttribute('typed-controls-status','ok');
1007
- }
1008
- }
1009
- return !reason;
1010
- }
1011
- for(var attr in bestControl.adapters){
1012
- domElement[attr] = bestControl.adapters[attr];
1013
- }
1014
- for(var listenerName in bestControl.listeners || {}){
1015
- domElement.addEventListener(listenerName, bestControl.listeners[listenerName]);
1016
- }
1017
- }
1018
- domElement.removeDialogPromiseSetup = function removeDialogPromiseSetup(){
1019
- this.dialogPromiseSetup = null
1020
- }
1021
-
1022
- domElement.setDialogPromiseSetup = function setDialogPromiseSetup(setup){
1023
- var defaultCatchFun = function(err){
1024
- console.log('catch from dialogPromise in typed-controls: ', err)
1025
- };
1026
- var preDialogFun = function(){
1027
- return Promise.resolve();
1028
- };
1029
- this.dialogPromiseSetup = changing({catchFun:defaultCatchFun, preDialogFun: preDialogFun}, setup);
1030
- }
1031
- domElement.setTypedValue = function setTypedValue(typedValue, fromUserInteraction){
1032
- var self = this
1033
- var isSameValue;
1034
- if(setup){
1035
- isSameValue = bestGlobals.sameValue(self.previousValue, typedValue);
1036
- }
1037
- var typer=self.controledType;
1038
- var setSignal = function(){
1039
- if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
1040
- var plainValue = typedValue && typer.typeInfo.typeName=='date'?typedValue.toLocaleDateString():typedValue;
1041
- if(plainValue==TypedControls.SIGNAL_UNKNOWN_DATA || plainValue==TypedControls.VALUE_UNKNOWN_DATA ||
1042
- (self.controledType.typeInfo.valueUnknownData && self.controledType.typeInfo.valueUnknownData == plainValue)){
1043
- self.setAttribute('typed-controls-signal-unknown-data','1');
1044
- }else{
1045
- self.removeAttribute('typed-controls-signal-unknown-data');
1046
- }
1047
- if(plainValue==TypedControls.SIGNAL_NO_DATA || plainValue==TypedControls.VALUE_NO_DATA ||
1048
- (self.controledType.typeInfo.valueNoData && self.controledType.typeInfo.valueNoData == plainValue)){
1049
- self.setAttribute('typed-controls-signal-no-data','1');
1050
- }else{
1051
- self.removeAttribute('typed-controls-signal-no-data');
1052
- }
1053
- }
1054
- }
1055
- var setTypedValueFun = function setTypedValueFun(){
1056
- typer.validateTypedData(typedValue);
1057
- if(!setup){
1058
- isSameValue = bestGlobals.sameValue(self.previousValue, typedValue);
1059
- }
1060
- setSignal();
1061
- self.setValidatedTypedValue(typedValue);
1062
- if(fromUserInteraction){
1063
- if(!isSameValue){
1064
- self.dispatchEvent(new CustomEvent('update'));
1065
- }
1066
- }
1067
- self.previousValue=typedValue;
1068
- }
1069
- var setup = self.dialogPromiseSetup;
1070
- if(setup && !isSameValue && !setup.ignoreValues.find(function(value){
1071
- return value==typedValue;
1072
- })){
1073
- switch(setup.dialogType){
1074
- case 'alertPromise':
1075
- setup.preDialogFun(self, typedValue).then(function(){
1076
- alertPromise(setup.message,setup.opts).then(function(){
1077
- setTypedValueFun();
1078
- }).catch(function(err){
1079
- setup.catchFun(err);
1080
- });
1081
- });
1082
- break;
1083
- case 'promptPromise':
1084
- setup.preDialogFun(self, typedValue).then(function(){
1085
- promptPromise(setup.message,setup.opts).then(function(text){
1086
- if(setup.expectedValue && text == setup.expectedValue){
1087
- setTypedValueFun();
1088
- }
1089
- }).catch(function(err){
1090
- setup.catchFun(err);
1091
- });
1092
- })
1093
- break;
1094
- default:
1095
- setup.preDialogFun(self, typedValue).then(function(){
1096
- confirmPromise(setup.message,setup.opts).then(function(){
1097
- setTypedValueFun();
1098
- }).catch(function(err){
1099
- setup.catchFun(err);
1100
- });
1101
- });
1102
- break;
1103
- }
1104
- }else{
1105
- setTypedValueFun();
1106
- }
1107
- };
1108
- };
1109
-
1110
- TypedControls.createFromFixture = function createFromFixture(fixture, typeInfo){
1111
- var thisModule = this;
1112
- if(fixture.creatorFunction){
1113
- return fixture.creatorFunction(typeInfo);
1114
- }else{
1115
- return html[fixture.tagName](fixture.attributes,(fixture.content||[]).map(function(subFixture){
1116
- return thisModule.createFromFixture(subFixture, typeInfo);
1117
- }));
1118
- }
1119
- };
1120
-
1121
- TypedControls.connect = function connect(opts){
1122
- opts.input.value = opts.almacen[opts.field];
1123
- };
1124
-
1125
- TypedControls.BestControls = BestControls;
1126
-
1127
- TypedControls.Expanders = [];
1128
-
1129
- TypedControls.pickDate = function pickDate(actualValue, label, opts){
1130
- return dialogPromise(function(dialogWindow, closeWindow){
1131
- var button=html.button(DialogPromise.messages.Ok).create();
1132
- var divPicker=html.div({id:'datepicker'}).create();
1133
- var picker = new Pikaday({
1134
- defaultDate: actualValue,
1135
- onSelect: function(date) {
1136
- closeWindow(bestGlobals.date(date));
1137
- },
1138
- i18n:TypedControls.messages.pikaday,
1139
- showDaysInNextAndPreviousMonths: true
1140
- });
1141
- divPicker.appendChild(picker.el);
1142
- button.addEventListener('click',function(){
1143
- closeWindow(actualValue);
1144
- });
1145
- dialogWindow.appendChild(html.div([
1146
- html.div(label),
1147
- html.div([divPicker]),
1148
- html.div([button])
1149
- ]).create());
1150
- }, opts)
1151
- }
1152
-
1153
- if(window.miniMenuPromise){
1154
- window.addEventListener('load', function(){
1155
- TypedControls.Expanders.push({
1156
- whenType: function(typedControl){
1157
- var typeInfo = typedControl.controledType.typeInfo;
1158
- return typeInfo.typeName === 'boolean';
1159
- },
1160
- dialogInput: function(typedControl){
1161
- var typeInfo = typedControl.controledType.typeInfo;
1162
- var opts=[
1163
- {value:true , label:TypedControls.messages.Yes},
1164
- {value:false, label:TypedControls.messages.No},
1165
- ];
1166
- if(typeInfo.nullable){
1167
- opts.push({value:null, label:TypedControls.messages.Null});
1168
- }
1169
- return miniMenuPromise(opts,{
1170
- underElement:typedControl,
1171
- withCloseButton:false,
1172
- }).then(function(value){
1173
- typedControl.setTypedValue(value);
1174
- typedControl.dispatchEvent(new CustomEvent('udpdate'));
1175
- });
1176
- }
1177
- });
1178
- TypedControls.Expanders.push({
1179
- whenType: function(typedControl){
1180
- var typeInfo = typedControl.controledType.typeInfo;
1181
- return typeInfo.options;
1182
- },
1183
- dialogInput: function(typedControl){
1184
- var typeInfo = typedControl.controledType.typeInfo;
1185
- var opts=typeInfo.options.map(function(opt, i){
1186
- if(typeof opt === 'string'){
1187
- return {value:opt, labels:[opt]};
1188
- }
1189
- return {value:opt.option, labels:[opt.option, opt.label]};
1190
- });
1191
- if(typeInfo.nullable){
1192
- opts.push({value:null, labels:['',TypedControls.messages.Null]});
1193
- }
1194
- return miniMenuPromise(opts,{
1195
- underElement:typedControl,
1196
- withCloseButton:false,
1197
- }).then(function(value){
1198
- typedControl.setTypedValue(value);
1199
- typedControl.dispatchEvent(new CustomEvent('udpdate'));
1200
- });
1201
- }
1202
- });
1203
- TypedControls.Expanders.push({
1204
- whenType: function(typedControl){
1205
- var typer = typedControl.controledType;
1206
- return typer.typeInfo.typeName == 'date';
1207
- },
1208
- img:'lookdown-calendar.png',
1209
- dialogInput: function(typedControl){
1210
- var typer = typedControl.controledType;
1211
- var actualValue = typedControl.getTypedValue();
1212
- return TypedControls.pickDate(actualValue, typer.typeInfo.label, {
1213
- underElement:typedControl,
1214
- withCloseButton:false,
1215
- }).then(function(value){
1216
- typedControl.setTypedValue(value);
1217
- typedControl.dispatchEvent(new CustomEvent('update'));
1218
- }).catch(function(err){
1219
- if(!DialogPromise){
1220
- return alertPromise(err.message);
1221
- }
1222
- });
1223
- }
1224
- });
1225
- TypedControls.Expanders.push({
1226
- whenType: function(typedControl){
1227
- var typer = typedControl.controledType;
1228
- return !typer.typeInfo.clientSide;
1229
- },
1230
- whenReadOnly:true,
1231
- img:'lookdown-zoom.png',
1232
- dialogInput: function(typedControl){
1233
- var typer = typedControl.controledType;
1234
- var value = typedControl.getTypedValue();
1235
- var actualValue = value==null?'':typer.toLocalString(value);
1236
- if(typedControl.disabled){
1237
- var div=html.div().create();
1238
- div.innerHTML=typedControl.innerHTML;
1239
- return alertPromise(div,{
1240
- underElement:typedControl,
1241
- withCloseButton:false,
1242
- }).then(function(){return false;});
1243
- }
1244
- return promptPromise(typer.typeInfo.label||'', actualValue,{
1245
- underElement:typedControl,
1246
- withCloseButton:false,
1247
- }).then(function(text){
1248
- var value=typer.fromLocalString(text);
1249
- typedControl.setTypedValue(value);
1250
- typedControl.dispatchEvent(new CustomEvent('update'));
1251
- }).catch(function(err){
1252
- if(!DialogPromise){
1253
- return alertPromise(err.message);
1254
- }
1255
- });
1256
- }
1257
- });
1258
- });
1259
- }
1260
-
1261
- return TypedControls;
1262
-
1263
- });
1
+ "use strict";
2
+
3
+ (function codenautasModuleDefinition(root, name, factory) {
4
+ /* global define */
5
+ /* istanbul ignore next */
6
+ if(typeof root.globalModuleName !== 'string'){
7
+ root.globalModuleName = name;
8
+ }
9
+ /* istanbul ignore next */
10
+ if(typeof exports === 'object' && typeof module === 'object'){
11
+ module.exports = factory();
12
+ }else if(typeof define === 'function' && define.amd){
13
+ define(factory);
14
+ }else if(typeof exports === 'object'){
15
+ exports[root.globalModuleName] = factory();
16
+ }else{
17
+ root[root.globalModuleName] = factory();
18
+ }
19
+ root.globalModuleName = null;
20
+ })(/*jshint -W040 */this, 'TypedControls', function() {
21
+ /*jshint +W040 */
22
+
23
+ /*jshint -W004 */
24
+ var TypedControls = {};
25
+ /*jshint +W004 */
26
+
27
+ TypedControls.ENABLE_SIGNALS4ALL = false;
28
+ TypedControls.ENABLE_SIGNALS = false;
29
+ TypedControls.SIGNAL_NO_DATA='--';
30
+ TypedControls.SIGNAL_UNKNOWN_DATA='//';
31
+
32
+ var likeAr = require('like-ar');
33
+ var DialogPromise = require('dialog-promise');
34
+
35
+ TypedControls.enablePasteCorrections=true;
36
+ TypedControls.doubleClickExpands=false;
37
+ TypedControls.showLupa=0.5;
38
+ TypedControls.showOn={
39
+ click:true,
40
+ focus:false,
41
+ };
42
+
43
+ TypedControls.i18n={messages:{}};
44
+ TypedControls.i18n.messages.en={
45
+ Yes: 'Yes',
46
+ No: 'No',
47
+ Null: 'Null/Empty',
48
+ pikaday: {
49
+ previousMonth : 'Previous Month',
50
+ nextMonth : 'Next Month',
51
+ months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
52
+ weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
53
+ weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
54
+ },
55
+ unknownData: 'unknown data',
56
+ noData: 'no data',
57
+ };
58
+ TypedControls.i18n.messages.es={
59
+ Yes: 'Sí',
60
+ No: 'No',
61
+ Null: 'Nulo/Sin valor',
62
+ pikaday: {
63
+ previousMonth : 'mes anterior',
64
+ nextMonth : 'próximo mes',
65
+ months : ['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre'],
66
+ weekdays : ['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],
67
+ weekdaysShort : ['dom','lun','mar','mié','jue','vie','sáb']
68
+ },
69
+ unknownData: 'ns/nc',
70
+ noData: 'sin dato',
71
+ };
72
+
73
+ TypedControls.messages = TypedControls.i18n.messages.en;
74
+
75
+ var changing = require('best-globals').changing;
76
+ var jsToHtml = require('js-to-html');
77
+ var TypeStore = require('type-store');
78
+ var Big = require('big.js');
79
+ var Pikaday = require('pikaday');
80
+
81
+ var html=jsToHtml.html;
82
+ // var coalesce = bestGlobals.coalesce;
83
+ // var changing = bestGlobals.changing;
84
+
85
+ TypedControls.Form = function Form(formInfo, medium){
86
+ this.info=formInfo;
87
+ this.medium=medium;
88
+ };
89
+
90
+ TypedControls.Form.prototype.render = function render(container){
91
+ var formHtml=html.div({id: JSON.stringify(this.medium.superId)},
92
+ this.info.fields.map(function(field){
93
+ return html.div({id:'div_'+field.name},[
94
+ html.label({"for":field.name},field.name),
95
+ html.input({id:field.name})
96
+ ]);
97
+ })
98
+ );
99
+ var div=formHtml.create();
100
+ this.dom=div;
101
+ if(!this.medium.forms){
102
+ this.medium.forms=[];
103
+ }
104
+ this.medium.forms.push(this);
105
+ container.appendChild(div);
106
+ return Promise.resolve();
107
+ };
108
+
109
+ TypedControls.createForm = function createForm(formInfo, data){
110
+ var form = new this.Form(formInfo, data);
111
+ return form;
112
+ };
113
+
114
+ TypedControls.normalOnBlurListener = function normalOnBlurListener(event){
115
+ if(!this.updatingSuspended){
116
+ var currentValue=this.getTypedValue();
117
+ if(this.validateWhileInput()){
118
+ if(!bestGlobals.sameValue(this.previousValue, currentValue)){
119
+ this.dispatchEvent(new CustomEvent('update'));
120
+ this.previousValue=currentValue;
121
+ }
122
+ // TODO revisar que no se esté haciendo demasiadas veces, quizás haya que primero ver si es distinto.
123
+ this.setValidatedTypedValue(currentValue);
124
+ }
125
+ }
126
+ };
127
+
128
+ (function () {
129
+ function CustomEvent ( event, params ) {
130
+ params = params || { bubbles: false, cancelable: false, detail: undefined };
131
+ var evt = document.createEvent( 'CustomEvent' );
132
+ evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
133
+ return evt;
134
+ }
135
+ if(typeof(window.CustomEvent)!=='function'){
136
+ CustomEvent.prototype = window.Event.prototype;
137
+ window.CustomEvent = CustomEvent;
138
+ }
139
+ })();
140
+
141
+ var BestControls = {};
142
+
143
+ var iiiiiiid=1;
144
+
145
+ TypedControls.optionsCtrl = function optionsCtrl(typeInfo){
146
+ var options = typeInfo.options;
147
+ return html.div({"typed-controls-option-group": 'simple-option'},
148
+ options.map(function(option){
149
+ return html.div([
150
+ (typeInfo.showOption?html.label({"for-value": option.option},option.option):null),
151
+ html.input({type:'radio', value:option.option}),
152
+ html.label({"for-value": option.option},option.label),
153
+ (option.more?html.span({"for-value": option.option, "class":"option-more-info"}):null)
154
+ ]);
155
+ })
156
+ );
157
+ };
158
+
159
+ TypedControls.booleanCtrl = function booleanCtrl(){
160
+ return TypedControls.optionsCtrl({options: BestControls.boolean.defaultOptions});
161
+ };
162
+
163
+ BestControls.div = {
164
+ adapters:{
165
+ getTypedValue: function getTypedValueDate(){
166
+ var plainValue = this.getPlainValue();
167
+ if(plainValue==null){
168
+ return plainValue;
169
+ }
170
+ var typer=this.controledType;
171
+ return typer.fromUserInput(plainValue);
172
+ },
173
+ setValidatedTypedValue: function setValidatedTypedValue(typedValue){
174
+ var typer = this.controledType;
175
+ if(typedValue==null){
176
+ this.setPlainValue(typedValue);
177
+ }else{
178
+ this.setPlainValue(typer.toLocalString(typedValue));
179
+ if(this.tagName!=='INPUT' && typer.toHtml){
180
+ this.innerHTML='';
181
+ this.appendChild(typer.toHtml(typedValue).create());
182
+ }
183
+ }
184
+ },
185
+ },
186
+ listeners:{
187
+ 'blur': TypedControls.normalOnBlurListener,
188
+ 'keydown': function onKeyPressListenerForDiv(event){
189
+ var element = this;
190
+ setTimeout(function(){
191
+ element.validateWhileInput();
192
+ },300);
193
+ },
194
+ 'paste': function(event){
195
+ if (TypedControls.enablePasteCorrections){
196
+ let paste = (event.clipboardData || window.clipboardData).getData('text');
197
+ paste = paste.replace(/\u00A0/g,' ');
198
+ var element = event.target;
199
+ if(element && (element.tagName == "INPUT" || element.tagName == "TEXTAREA")){
200
+ var start = element.selectionStart;
201
+ element.setRangeText(paste);
202
+ var pos = (start||0) + paste.length
203
+ element.setSelectionRange(pos, pos);
204
+ }else{
205
+ const selection = window.getSelection();
206
+ if (!selection.rangeCount) return false;
207
+ console.log(selection.rangeCount);
208
+ for(var i=0; i<selection.rangeCount; i++) console.log('e',selection.getRangeAt(i))
209
+ selection.deleteFromDocument();
210
+ selection.getRangeAt(0).insertNode(document.createTextNode(paste));
211
+ selection.collapseToEnd()
212
+ }
213
+ event.preventDefault();
214
+ }
215
+ },
216
+ 'keypress': function onKeyPressListenerForDiv(event){
217
+ var element = this;
218
+ if(event.which>=32){
219
+ var typer = this.controledType;
220
+ var theChar = String.fromCharCode(event.which);
221
+ if(typer.rejectedChar(theChar)){
222
+ if(element.expander && element.expander.autoExpand){
223
+ if(!element.displayingExpander){
224
+ var opts = {initialKeystrokes:theChar};
225
+ element.displayExpander(event, opts);
226
+ element.displayingExpander=opts;
227
+ }else{
228
+ element.displayingExpander.initialKeystrokes+=theChar;
229
+ }
230
+ }
231
+ event.preventDefault();
232
+ }
233
+ }
234
+ },
235
+ },
236
+ domFixtures:[
237
+ {tagName:'input' , attributes:{type:'text'}},
238
+ ]
239
+ };
240
+
241
+ BestControls.text = {
242
+ translates:{true:{
243
+ '\n': '\u21b5'
244
+ },false:{}},
245
+ translatesRegExp:{},
246
+ translatesRev:{},
247
+ translate: function(right, textValue){
248
+ return textValue.replace(new RegExp(BestControls.text.translatesRegExp[right],'g'),function(chartt){
249
+ return BestControls.text.translates[right][chartt];
250
+ });
251
+ },
252
+ adapters:{
253
+ validateTypedData: function validateTypedDataNoObjectAccepted(typedValue){
254
+ if(typedValue!==null && typeof typedValue !== 'string'){
255
+ throw new Error("Not a text in input");
256
+ }
257
+ },
258
+ getTypedValue: function getTypedValueText(){
259
+ var typedValue = this.getPlainValue();
260
+ if(this.tagName==='INPUT' && typedValue!==null){
261
+ typedValue = BestControls.text.translate(false, typedValue);
262
+ }
263
+ if(typedValue==null && (this.valueEmpty || !this.controledType.nullable)){
264
+ return '';
265
+ }else{
266
+ if(typedValue!=null){
267
+ return typedValue.replace(/\n+$/,'');
268
+ }
269
+ return typedValue;
270
+ }
271
+ },
272
+ setValidatedTypedValue: function setValidatedTypedValueText(typedValue){
273
+ if(this.tagName==='INPUT' && typedValue!=null){
274
+ typedValue = BestControls.text.translate(true, typedValue);
275
+ }
276
+ if(this.tagName==='TEXTAREA' && typedValue==null){
277
+ this.setPlainValue('');
278
+ }else{
279
+ this.setPlainValue(typedValue);
280
+ }
281
+ this.valueEmpty = typedValue==='' || typedValue==null && !this.controledType.nullable;
282
+ },
283
+ },
284
+ listeners:{
285
+ 'keypress': function onKeyPressListenerForText(event){
286
+ if(this.value===''){
287
+ if(event.keyCode == 32){
288
+ if(!this.valueEmpty){
289
+ this.valueEmpty = true;
290
+ event.preventDefault();
291
+ }else{
292
+ this.valueEmpty = false;
293
+ }
294
+ }
295
+ }else{
296
+ this.valueEmpty = false;
297
+ }
298
+ },
299
+ 'blur': TypedControls.normalOnBlurListener
300
+ },
301
+ domFixtures:[
302
+ {tagName:'input' , attributes:{type:'text'}, mainUpdateEventName:'blur'},
303
+ {tagName:'div' , attributes:{} },
304
+ {tagName:'textarea', attributes:{}},
305
+ ]
306
+ };
307
+
308
+ for(var charToTranslate in BestControls.text.translates[true]){
309
+ BestControls.text.translates[false][BestControls.text.translates[true][charToTranslate]] = charToTranslate;
310
+ }
311
+
312
+ for(var groups in BestControls.text.translates){
313
+ BestControls.text.translatesRegExp[groups] = '['+Object.keys(BestControls.text.translates[groups])+']';
314
+ }
315
+
316
+ BestControls.text_no_empty = {
317
+ adapters:{
318
+ validateTypedData: function validateTypedDataTextNoEmpty(typedValue){
319
+ BestControls.text.adapters.validateTypedData(typedValue);
320
+ if(typedValue===''){
321
+ throw new Error('text cannot be empty');
322
+ }
323
+ },
324
+ getTypedValue: function getTypedValueText(){
325
+ return this.getPlainValue();
326
+ },
327
+ setValidatedTypedValue: function setValidatedTypedValueTextNoEmpty(typedValue){
328
+ if(this.tagName==='TEXTAREA' && typedValue==null){
329
+ this.setPlainValue('');
330
+ }else{
331
+ this.setPlainValue(typedValue);
332
+ }
333
+ },
334
+ },
335
+ listeners:{
336
+ 'blur': TypedControls.normalOnBlurListener
337
+ },
338
+ domFixtures:BestControls.text.domFixtures.concat({tagName:'input', attributes:{type:'password'}})
339
+ };
340
+
341
+ BestControls.number = {
342
+ adapters:{
343
+ setValidatedTypedValue: function setValidatedTypedValuePrettyNumber(typedValue){
344
+ if(isNaN(typedValue) || typedValue==null){
345
+ this.value='';
346
+ }else{
347
+ this.valueAsNumber = typedValue;
348
+ }
349
+ if(this.value.length>1 && /[.,]/.test(this.value[this.value.length-2])){
350
+ this.value=this.value+'0';
351
+ }
352
+ },
353
+ getTypedValue: function getTypedValue(){
354
+ return isNaN(this.valueAsNumber)||this.value==''?null:this.valueAsNumber;
355
+ },
356
+ // setTypedValue: function setTypedValue(value){
357
+ // this.valueAsNumber=value;
358
+ // },
359
+ },
360
+ listeners:{
361
+ 'blur': TypedControls.normalOnBlurListener,
362
+ 'keydown': function onKeyPressListenerForDiv(event){
363
+ var typer = this.controledType||{typeInfo:{}};
364
+ if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
365
+ var theKey=event.keyCode;
366
+ // subtract or dash key
367
+ if((theKey==109 || theKey==189) && (this.previousKey==109 || this.previousKey==189)){
368
+ var valueNoData;
369
+ if('valueNoData' in typer.typeInfo){
370
+ valueNoData=typer.typeInfo.valueNoData;
371
+ }else{
372
+ valueNoData=TypedControls.VALUE_NO_DATA;
373
+ }
374
+ this.value=valueNoData;
375
+ event.preventDefault();
376
+ }
377
+ //divide key or forward slash
378
+ if((theKey==111 || theKey==191) && (this.previousKey==111 || this.previousKey==191)){
379
+ var valueUnknownData;
380
+ if('valueUnknownData' in typer.typeInfo){
381
+ valueUnknownData=typer.typeInfo.valueUnknownData;
382
+ }else{
383
+ valueUnknownData=TypedControls.VALUE_UNKNOWN_DATA;
384
+ }
385
+ this.value=valueUnknownData;
386
+ event.preventDefault();
387
+ }
388
+ var element = this;
389
+ setTimeout(function(){
390
+ element.validateWhileInput();
391
+ },300);
392
+ this.previousKey=theKey;
393
+ }
394
+ },
395
+
396
+ /*
397
+ 'keypress': function onKeyPressListenerForNumber(event){
398
+ if( event.keyCode>=32 && event.keyCode<=43 ||
399
+ event.keyCode>=47 && event.keyCode<=47 ||
400
+ event.keyCode>=58
401
+ ){
402
+ event.preventDefault();
403
+ }
404
+ },
405
+ 'keyup': function onKeyUpListenerForNumber(event){
406
+ var targetName='value' in this?'value':'textContent';
407
+ if(!this[targetName].match(/^-?[0-9]*\.?[0-9]*$/)){
408
+ var negative=this[targetName][0]==='-';
409
+ var newValue=this[targetName].replace(/[^0-9.]/g,'');
410
+ newValue=newValue.replace(/[.]/,',');
411
+ newValue=newValue.replace(/[.]/g,'');
412
+ newValue=newValue.replace(/[,]/g,'.');
413
+ this[targetName]=(negative?'-':'')+newValue;
414
+ }
415
+ }
416
+ */
417
+ },
418
+ domFixtures:[
419
+ {tagName:'input' , attributes:{type:'text'}},
420
+ {tagName:'input' , attributes:{type:'number'}},
421
+ {tagName:'div' , attributes:{}},
422
+ ]
423
+ };
424
+
425
+ BestControls.boolean = {
426
+ adapters:{
427
+ validateTypedData: function validateTypedDataBoolean(typedValue){
428
+ if(typedValue!==false && typedValue!==true && typedValue!=null){
429
+ throw new Error('Not a boolean in input');
430
+ }
431
+ },
432
+ getTypedValue: function getTypedValueBoolean(){
433
+ var domElement=this;
434
+ var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
435
+ if(typedControlsOptionGroup){
436
+ var typedValue = null;
437
+ [true, false].forEach(function(value){
438
+ if(domElement.optionControl[value].checked){
439
+ typedValue = value;
440
+ }
441
+ });
442
+ return typedValue;
443
+ }else if(this.type==='checkbox'){
444
+ return this.indeterminate?null:this.checked;
445
+ }else{
446
+ var value = this.getPlainValue();
447
+ var falseInitials={'n':true,'N':true,'0':true,'2':true,'F':true,'f':true,'\u043d':true,'\u041d':true};
448
+ if(value==null || value.trim()==''){
449
+ return null;
450
+ }else{
451
+ return !falseInitials[value.trim()[0]];
452
+ }
453
+ }
454
+ },
455
+ setValidatedTypedValue: function setValidatedTypedValuePrettyBoolean(typedValue){
456
+ var domElement=this;
457
+ var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
458
+ if(typedControlsOptionGroup){
459
+ [true, false].forEach(function(value){
460
+ domElement.optionControl[value].checked = value===typedValue;
461
+ });
462
+ }else if(this.type==='checkbox'){
463
+ this.checked = typedValue;
464
+ this.indeterminate = typedValue==null;
465
+ }else{
466
+ var plainValue = typedValue==null?'':(typedValue?TypedControls.messages.Yes:TypedControls.messages.No);
467
+ this.setPlainValue(plainValue);
468
+ if(this.tagName!=='INPUT'){
469
+ if(typedValue!==null){
470
+ this.innerHTML = html.span({"class": "bool_"+JSON.stringify(typedValue)}, plainValue).toHtmlText();
471
+ }
472
+ }
473
+ }
474
+ },
475
+ },
476
+ listeners:{
477
+ 'keydown': function onKeyDownListenerForBoolean(event){
478
+ if(this.type==='checkbox' && (
479
+ event.keyCode == 8 || //backspace
480
+ event.keyCode == 46 || //delete/Supr
481
+ event.keyCode == 109 || //'-'/minus in keypad
482
+ event.keyCode == 189 || //'-'/minus in keyboard
483
+ event.keyCode == 190 //'.'/period in keyboard
484
+ )){
485
+ this.checked = false;
486
+ this.indeterminate = true;
487
+ event.preventDefault();
488
+ }
489
+ },
490
+ 'click': function onClickListenerForBoolean(event){
491
+ if(this.type==='checkbox'){
492
+ if(document.activeElement!==this){
493
+ // Safari 5.1.7 and other old browsers doesn't set activeElement
494
+ this.focus();
495
+ }
496
+ }
497
+ },
498
+ 'blur': TypedControls.normalOnBlurListener,
499
+ 'change': function onChangeListenerForBoolean(event) {
500
+ this.dispatchEvent(new CustomEvent('update'));
501
+ }
502
+ },
503
+ domFixtures:[
504
+ {creatorFunction:TypedControls.booleanCtrl, attributes:{}},
505
+ {tagName:'div' , attributes:{}},
506
+ {tagName:'input' , attributes:{type:'text'}, mainUpdateEventName:'blur'},
507
+ {tagName:'input' , attributes:{type:'checkbox'}, mainUpdateEventName:'change'},
508
+ ],
509
+ defaultOptions:[
510
+ {option: true , labelId: 'Yes'},
511
+ {option: false, labelId: 'No'},
512
+ ]
513
+ };
514
+
515
+ BestControls.boolean.defaultOptions.forEach(function(optionDefinition){
516
+ Object.defineProperty(optionDefinition, 'label',{
517
+ get: function(){return TypedControls.messages[optionDefinition.labelId];}
518
+ });
519
+ });
520
+
521
+ BestControls.date = {
522
+ adapters:{
523
+ validateTypedData: function validateTypedDataDate(typedValue){
524
+ if(typedValue!=null){
525
+ if(!(typedValue instanceof Date)){
526
+ throw new Error('Not a date in input');
527
+ // }else if(!(/[0 ]0:00:00/.test(typedValue.toLocaleString("local", {hour12:false})))){
528
+ }else if(typedValue.getTime() != new Date(typedValue.getFullYear(), typedValue.getMonth(), typedValue.getDate()).getTime()){
529
+ throw new Error('date must be an absolute date without time '+typedValue+' <> '+new Date(typedValue.getFullYear(), typedValue.getMonth(), typedValue.getDate()));
530
+ }
531
+ }
532
+ },
533
+ getTypedValue: function getTypedValueDate(){
534
+ var plainValue = this.getPlainValue();
535
+ var parts;
536
+ if(plainValue==null){
537
+ return null;
538
+ }else if (this.type==='date') {
539
+ parts = plainValue.split(/[-\/]/);
540
+ return new Date(parts[0],parts[1]-1,parts[2]);
541
+ }else{
542
+ parts = plainValue.split(/[-\/]/);
543
+ return new Date(parts[2],parts[1]-1,parts[0]);
544
+ }
545
+ },
546
+ setValidatedTypedValue: function setValidatedTypedValuePrettyDate(typedValue){
547
+ if(typedValue==null){
548
+ this.setPlainValue(typedValue);
549
+ }else if(this.type==='date'){
550
+ this.value = typedValue.toISOString().substr(0,10);
551
+ }else{
552
+ var month = typedValue.getUTCMonth()+1;
553
+ var day = typedValue.getUTCDate();
554
+ var year = typedValue.getUTCFullYear();
555
+ this.setPlainValue(day+'/'+month+'/'+year);
556
+ if(this.tagName!=='INPUT'){
557
+ var rta=[];
558
+ rta.push(html.span({"class":"date_day"},day));
559
+ rta.push(html.span({"class":"date_sep"},'/'));
560
+ rta.push(html.span({"class":"date_month"},month));
561
+ rta.push(html.span({"class":"date_sep"},'/'));
562
+ rta.push(html.span({"class":"date_year"},year));
563
+ rta = rta.map(function(x){ return x.toHtmlText(); }).join('');
564
+ this.innerHTML = rta;
565
+ }
566
+ }
567
+
568
+ },
569
+ },
570
+ listeners:{
571
+ 'blur': TypedControls.normalOnBlurListener,
572
+ 'keydown': function onKeyDownListenerForDate(event){
573
+ if(event.keyCode == 72) { // key h
574
+ var now=new Date();
575
+ this.controledType.setTypedValue(new Date(now.getFullYear(),now.getMonth(),now.getDate()));
576
+ event.preventDefault();
577
+ }
578
+ },
579
+ },
580
+ domFixtures:[
581
+ {tagName:'input' , attributes:{type:'date'}},
582
+ {tagName:'div' , attributes:{}},
583
+ {tagName:'input' , attributes:{type:'text'}},
584
+ ]
585
+ };
586
+
587
+ function markActive(element, display){
588
+ while(element && element.tagName!='BODY'){
589
+ if(element.getAttribute('display-if-active')){
590
+ element.setAttribute('display-is-active',display?'1':'0');
591
+ }
592
+ element = element.parentNode;
593
+ }
594
+ }
595
+
596
+ var BestControls_enum = {
597
+ adapters:{
598
+ validateTypedData: function validateTypedValue(typedValue){
599
+ if(typedValue!=null && !this.typedControlsValidOptions[typedValue]){
600
+ throw new Error('Not a enum in input');
601
+ }
602
+ },
603
+ getTypedValue: function getTypedValueEnum(){
604
+ var domElement=this;
605
+ var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
606
+ var typedValue = null;
607
+ this.controledType.typeInfo.options.forEach(function(option){
608
+ if(domElement.optionControl[option.option].checked){
609
+ typedValue = option.option;
610
+ }
611
+ });
612
+ if(typedValue==null){
613
+ return null;
614
+ }
615
+ if(this.controledType.typeName=='bigint'){
616
+ typedValue = Number(typedValue);
617
+ }
618
+ return typedValue;
619
+ },
620
+ setValidatedTypedValue: function setValidatedTypedValuePrettyBoolean(typedValue){
621
+ var domElement = this;
622
+ var typedControlsOptionGroup=this.getAttribute("typed-controls-option-group");
623
+ (domElement.shadowControl||{}).value=typedValue;
624
+ this.controledType.typeInfo.options.forEach(function(option){
625
+ domElement.optionControl[option.option].checked = option.option===typedValue;
626
+ });
627
+ this.refreshState();
628
+ },
629
+ refreshState: function refreshState(){
630
+ this.controledType.typeInfo.options.forEach(function(option){
631
+ var control = this.optionControl[option.option];
632
+ Array.prototype.forEach.call(control.labelsElements, function(label){
633
+ label.setAttribute('state-label-option',control.checked?'checked':'unchecked');
634
+ markActive(label, control.checked);
635
+ });
636
+ },this);
637
+ }
638
+ },
639
+ listeners:{
640
+ /* TODO:
641
+ 'keydown': function onKeyDownListenerForBoolean(event){
642
+ },
643
+ 'click': function onClickListenerForBoolean(event){
644
+ },
645
+ 'blur': TypedControls.normalOnBlurListener,
646
+ */
647
+ 'change': function onChangeListenerForBoolean(event) {
648
+ this.dispatchEvent(new CustomEvent('update'));
649
+ }
650
+ },
651
+ domFixtures:[
652
+ {creatorFunction:TypedControls.optionsCtrl, attributes:{}},
653
+ ]
654
+ };
655
+
656
+
657
+ TypedControls.completeTypeInfo = function completeTypeInfo(typeInfoMayBeIncompleteOrString){
658
+ var typeInfo = typeInfoMayBeIncompleteOrString;
659
+ if(typeof typeInfo === 'string'){
660
+ typeInfo = {typeName:typeInfo};
661
+ }
662
+ if(typeInfo.typeName==='boolean' && !typeInfo.options){
663
+ typeInfo.options=BestControls.boolean.defaultOptions;
664
+ }
665
+ return typeInfo;
666
+ };
667
+
668
+ TypedControls.bestCtrl = function bestCtrl(typeInfo){
669
+ typeInfo = TypedControls.completeTypeInfo(typeInfo);
670
+ var theElement = BestControls[typeInfo.typeName].domFixtures.reduce(function(elementoCreado, def){
671
+ if(elementoCreado){
672
+ return elementoCreado;
673
+ }
674
+ return TypedControls.createFromFixture(def, typeInfo);
675
+ }, null);
676
+ return theElement;
677
+ };
678
+
679
+ function getRect(element){
680
+ var rect = {top:0, left:0, width:element.offsetWidth, height:element.offsetHeight};
681
+ while( element != null ) {
682
+ rect.top += element.offsetTop;
683
+ rect.left += element.offsetLeft;
684
+ element = element.offsetParent;
685
+ }
686
+ return rect;
687
+ }
688
+
689
+ TypedControls.path={
690
+ img:''
691
+ };
692
+
693
+ TypedControls.adaptElement = function adaptElement(domElement, typerOrTypeInfo){
694
+ // typeInfo = TypedControls.completeTypeInfo(typeInfo);
695
+ if(typeof typerOrTypeInfo === 'string'){
696
+ throw new Error("obsolete typeName in adaptElement "+typerOrTypeInfo);
697
+ }
698
+ var typer;
699
+ if(typerOrTypeInfo instanceof TypeStore.TypeBase){
700
+ typer=typerOrTypeInfo;
701
+ }else{
702
+ typer = TypeStore.typerFrom(typerOrTypeInfo);
703
+ }
704
+ var typeName = typer.typeName;
705
+ var typedControlsOptionGroup=domElement.getAttribute("typed-controls-option-group");
706
+ domElement.controledType = typer;
707
+ var bestControl=BestControls.div;
708
+ if(domElement.tagName=='INPUT' && domElement.type=='number'){
709
+ bestControl=BestControls.number;
710
+ }
711
+ if(typedControlsOptionGroup){
712
+ var inputTypeRadio=[];
713
+ var idElement = domElement.id||'__id__'+iiiiiiid++;
714
+ domElement.setAttribute("typed-controls-option-group",idElement);
715
+ domElement.typedControlsValidOptions={};
716
+ domElement.moreInfo={};
717
+ // var childs=domElement.childNodes;
718
+ domElement.optionControl={};
719
+ var inputElement=domElement.getElementsByClassName('typed-control-input-for-options');
720
+ inputElement = inputElement?inputElement[0]:null;
721
+ if(inputElement){
722
+ var setCheckbox=function(){
723
+ var value = inputElement.value;
724
+ if(value && domElement.optionControl[value]){
725
+ domElement.optionControl[value].checked = true;
726
+ var event = new Event('change');
727
+ var elem = domElement.optionControl[value];
728
+ elem.dispatchEvent(event);
729
+ }else{
730
+ likeAr(domElement.optionControl).forEach(function(option){ option.checked=false });
731
+ domElement.dispatchEvent(new CustomEvent('update'));
732
+ domElement.refreshState()
733
+ }
734
+ }
735
+ inputElement.addEventListener('keydown',function(){
736
+ if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
737
+ var theKey=event.keyCode;
738
+ // subtract or dash key
739
+ if((theKey==109 || theKey==189) && (this.previousKey==109 || this.previousKey==189)){
740
+ var valueNoData;
741
+ if('valueNoData' in typer.typeInfo){
742
+ valueNoData=typer.typeInfo.valueNoData;
743
+ }else{
744
+ valueNoData=TypedControls.VALUE_NO_DATA;
745
+ }
746
+ this.value=valueNoData;
747
+ setCheckbox();
748
+ event.preventDefault();
749
+ }
750
+ //divide key or forward slash
751
+ if((theKey==111 || theKey==191) && (this.previousKey==111 || this.previousKey==191)){
752
+ var valueUnknownData;
753
+ if('valueUnknownData' in typer.typeInfo){
754
+ valueUnknownData=typer.typeInfo.valueUnknownData;
755
+ }else{
756
+ valueUnknownData=TypedControls.VALUE_UNKNOWN_DATA;
757
+ }
758
+ this.value=valueUnknownData;
759
+ setCheckbox();
760
+ event.preventDefault();
761
+ }
762
+ this.previousKey=theKey;
763
+ }
764
+ })
765
+ domElement.shadowControl = inputElement;
766
+ inputElement.addEventListener('change',setCheckbox);
767
+ domElement.focus = function focus(){
768
+ inputElement.focus();
769
+ }
770
+ }
771
+ typer.typeInfo.options.forEach(function(option){
772
+ domElement.typedControlsValidOptions[option.option]={};
773
+ domElement.moreInfo[option.option]={};
774
+ var moreInfoElements=domElement.querySelectorAll('span.option-more-info[for-value="'+option.option+'"]');
775
+ if(moreInfoElements.length>0){
776
+ var moreInfo=moreInfoElements[0];
777
+ domElement.moreInfo[option.option].className=moreInfo.className;
778
+ domElement.moreInfo[option.option] =moreInfo;
779
+ }
780
+ var childElements=domElement.querySelectorAll('input[type=radio][value="'+option.option+'"]');
781
+ if(childElements.length===0){
782
+ throw new Error('incomplete options control (value='+option.option+')');
783
+ }else if(childElements.length>1){
784
+ throw new Error('duplicate options in options control (value="'+option.option+'")');
785
+ }
786
+ var childElement = childElements[0];
787
+ domElement.optionControl[option.option]=childElement;
788
+ inputTypeRadio.push(childElement);
789
+ childElement.name=idElement;
790
+ childElement.id=idElement+'-'+option.option;
791
+ var labelsElements=domElement.querySelectorAll('label[for-value="'+option.option+'"]');
792
+ childElement.labelsElements = labelsElements;
793
+ Array.prototype.forEach.call(labelsElements, function(label){
794
+ label.htmlFor=childElement.id;
795
+ });
796
+ childElement.addEventListener('change',function(){
797
+ domElement.dispatchEvent(new CustomEvent('update'));
798
+ domElement.refreshState();
799
+ if(inputElement){
800
+ inputElement.value = option.option;
801
+ }
802
+ });
803
+ });
804
+ var radioChilds=domElement.querySelectorAll('input[type=radio]');
805
+ if(radioChilds.length!=typer.typeInfo.options.length){
806
+ throw new Error('invalid options in options control');
807
+ }
808
+ domElement.disable=function(disabled){
809
+ domElement.disabled=disabled;
810
+ if(inputElement && inputElement !== domElement){
811
+ inputElement.disabled=disabled;
812
+ }
813
+ inputTypeRadio.forEach(function(childElement){
814
+ childElement.disabled=disabled;
815
+ });
816
+ };
817
+ domElement.getTypedValue=BestControls_enum.adapters.getTypedValue;
818
+ domElement.validateTypedData=BestControls_enum.adapters.validateTypedData;
819
+ domElement.setValidatedTypedValue=BestControls_enum.adapters.setValidatedTypedValue;
820
+ domElement.refreshState=BestControls_enum.adapters.refreshState;
821
+ }else{
822
+ domElement.dataAttr=domElement.tagName==='INPUT' || domElement.tagName==='TEXTAREA'?'value':'textContent';
823
+ if(domElement.dataAttr=='textContent'){
824
+ domElement.ritchHtmlContent=true;
825
+ }
826
+ if(domElement.getAttribute("typed-controls-direct-input") && domElement.getAttribute("typed-controls-direct-input")==='true'){
827
+ domElement.contentEditable = true;
828
+ domElement.disable=function(disabled){
829
+ domElement.disabled=disabled;
830
+ domElement.contentEditable = !disabled;
831
+ };
832
+ }else{
833
+ domElement.disable=function(disabled){
834
+ domElement.disabled=disabled;
835
+ };
836
+ }
837
+ var editable=function(typer, expander, domElement){
838
+ return ((typer.typeInfo.editable == null || typer.typeInfo.editable) && (domElement.contentEditable=='true' || !domElement.disabled || domElement.editOnlyFromList) || expander.whenReadOnly)
839
+ }
840
+ var expander = TypedControls.Expanders.find(function(expander){
841
+ var typer = domElement.controledType;
842
+ return editable(typer, expander, domElement) && expander.whenType(domElement);
843
+ });
844
+ if(expander){
845
+ domElement.lupa=null;
846
+ domElement.expander = expander;
847
+ var reubicate = function reubicate(){
848
+ if(domElement.lupaFija || (document.activeElement === domElement || domElement.disabled) && editable(typer, expander, domElement)){
849
+ domElement.lupa.style.display='';
850
+ domElement.lupa.style.opacity=1;
851
+ var rect = getRect(domElement);
852
+ var top=rect.top+rect.height-domElement.lupa.offsetHeight/2;
853
+ var left=rect.left+rect.width*TypedControls.showLupa-domElement.lupa.offsetWidth/2
854
+ if(Math.abs(top-domElement.lupa.style.top.replace('px',''))>1.2){
855
+ domElement.lupa.style.top=top+'px';
856
+ }
857
+ if(Math.abs(left-domElement.lupa.style.left.replace('px',''))>1.2){
858
+ domElement.lupa.style.left=left+'px';
859
+ }
860
+ }else if(domElement.lupa){
861
+ if(domElement.lupa.timerReubicate){
862
+ clearInterval(domElement.lupa.timerReubicate);
863
+ }
864
+ document.body.removeChild(domElement.lupa);
865
+ domElement.lupa=null;
866
+ }
867
+ };
868
+ domElement.ponerLupa = function ponerLupa(fija){
869
+ domElement.lupa = html.img({src:TypedControls.path.img+(domElement.expander.img||'lookdown.png'), class:'img-lupa', style:'position:absolute; display:none'}).create();
870
+ document.body.appendChild(domElement.lupa);
871
+ domElement.lupa.addEventListener('load', reubicate);
872
+ domElement.lupa.addEventListener('click',displayExpander);
873
+ domElement.lupa.timerReubicate = setInterval(reubicate,500);
874
+ domElement.lupaFija = fija;
875
+ }
876
+ var quitarLupa = function quitarLupa(domElement){
877
+ if(domElement.lupa && !domElement.lupaFija){
878
+ clearInterval(domElement.lupa.timerReubicate);
879
+ domElement.lupa.timerReubicate=null;
880
+ // domElement.lupa.timerReubicate = setInterval(reubicate,500);
881
+ domElement.lupa.style.opacity=0.01;
882
+ clearTimeout(domElement.lupa.timerClose);
883
+ domElement.lupa.timerClose=null;
884
+ }
885
+ }
886
+ var displayExpander = function displayExpander(event, opts){
887
+ if(editable(typer, expander, domElement)){
888
+ domElement.updatingSuspended=true;
889
+ var dialogFinally = function dialogFinally(hasUpdated){
890
+ domElement.updatingSuspended=false;
891
+ domElement.focus();
892
+ if(!domElement.disabled && !(hasUpdated instanceof Error)){
893
+ domElement.dispatchEvent(new Event('input'));
894
+ domElement.dispatchEvent(new CustomEvent('update'));
895
+ }
896
+ };
897
+ domElement.expander.dialogInput(domElement, opts).then(dialogFinally,dialogFinally);
898
+ event.preventDefault();
899
+ quitarLupa(domElement);
900
+ }
901
+ };
902
+ domElement.displayExpander = displayExpander;
903
+ if(TypedControls.doubleClickExpands){
904
+ domElement.addEventListener('dblclick',function(){
905
+ if(domElement.textContent==''){
906
+ displayExpander(event);
907
+ }
908
+ });
909
+ }
910
+ ['focus','click'].forEach(function(eventName){
911
+ if(TypedControls.showLupa && TypedControls.showOn[eventName]){
912
+ domElement.addEventListener(eventName, function(){
913
+ if(!domElement.lupa){
914
+ domElement.ponerLupa();
915
+ }else if(domElement.lupa.timerClose){
916
+ clearTimeout(domElement.lupa.timerClose);
917
+ }
918
+ domElement.lupa.timerClose = setTimeout(function(){
919
+ quitarLupa(domElement);
920
+ },5000);
921
+ setTimeout(reubicate,10);
922
+ });
923
+ }
924
+ });
925
+ domElement.addEventListener('blur', function(){
926
+ quitarLupa(domElement);
927
+ });
928
+ domElement.addEventListener('keydown', function(event){
929
+ var domElement = this;
930
+ if(event.keyCode == 120 && !event.shiftKey && !event.ctrlKey && !event.altKey
931
+ || event.which == 40 && !event.shiftKey && !event.ctrlKey && event.altKey
932
+ ){ //F9 alt down
933
+ if(!domElement.updatingSuspended){
934
+ displayExpander(event);
935
+ }
936
+ }
937
+ });
938
+ }
939
+ domElement.setAttribute("type-align",typer.align);
940
+ domElement.getPlainValue = function getPlainValue(){
941
+ return this[this.dataAttr]===''?this.controledType.emptyValue:this[this.dataAttr];
942
+ };
943
+ domElement.setPlainValue = function setPlainValue(plainValue){
944
+ if(this.tagName=='INPUT' && this.type=='number'){
945
+ // alert('aca')
946
+ }
947
+ this[this.dataAttr] = plainValue;
948
+ };
949
+ domElement.setValidatedTypedValue = function setValidatedTypedValue(typedValue){
950
+ var typer=this.controledType;
951
+ this.setPlainValue(typedValue==null?'':typer.toLocalString(typedValue));
952
+ if(this.ritchHtmlContent){
953
+ this.innerHTML="";
954
+ if(typedValue==null){
955
+ this.appendChild(html.span({class:'null-value'}).create());
956
+ }else{
957
+ this.appendChild(typer.toHtml(typedValue).create());
958
+ }
959
+ }
960
+ };
961
+ domElement.validateWhileInput = function validateWhileInput(){
962
+ var plainValue = this.getPlainValue();
963
+ var typer = this.controledType||{typeInfo:{}};
964
+ if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
965
+ /* NO DATA SIGNAL */
966
+ var valueNoData;
967
+ if('valueNoData' in typer.typeInfo){
968
+ valueNoData=typer.typeInfo.valueNoData;
969
+ }else{
970
+ valueNoData=TypedControls.VALUE_NO_DATA;
971
+ }
972
+ if(plainValue===TypedControls.SIGNAL_NO_DATA || plainValue===valueNoData){
973
+ this.setAttribute('typed-controls-signal-no-data','1');
974
+ if(plainValue===TypedControls.SIGNAL_NO_DATA){
975
+ this.setPlainValue(valueNoData);
976
+ }
977
+ }else{
978
+ this.removeAttribute('typed-controls-signal-no-data');
979
+ }
980
+ /* FIN NO DATA SIGNAL */
981
+ /* UNKNONWN DATA SIGNAL */
982
+ var valueUnknownData;
983
+ if('valueUnknownData' in typer.typeInfo){
984
+ valueUnknownData=typer.typeInfo.valueUnknownData;
985
+ }else{
986
+ valueUnknownData=TypedControls.VALUE_UNKNOWN_DATA;
987
+ }
988
+ if(plainValue===TypedControls.SIGNAL_UNKNOWN_DATA || plainValue===valueUnknownData){
989
+ this.setAttribute('typed-controls-signal-unknown-data','1');
990
+ if(plainValue===TypedControls.SIGNAL_UNKNOWN_DATA){
991
+ this.setPlainValue(valueUnknownData);
992
+ }
993
+ }else{
994
+ this.removeAttribute('typed-controls-signal-unknown-data');
995
+ }
996
+ /* FIN UNKNONWN DATA SIGNAL */
997
+ }
998
+ if(plainValue==null){
999
+ this.setAttribute('typed-controls-status','null');
1000
+ }else{
1001
+ var typer = this.controledType; // eslint-disable-line no-redeclare
1002
+ var reason = !typer.isValidLocalString(plainValue);
1003
+ if(reason){
1004
+ this.setAttribute('typed-controls-status','error');
1005
+ }else{
1006
+ this.setAttribute('typed-controls-status','ok');
1007
+ }
1008
+ }
1009
+ return !reason;
1010
+ }
1011
+ for(var attr in bestControl.adapters){
1012
+ domElement[attr] = bestControl.adapters[attr];
1013
+ }
1014
+ for(var listenerName in bestControl.listeners || {}){
1015
+ domElement.addEventListener(listenerName, bestControl.listeners[listenerName]);
1016
+ }
1017
+ }
1018
+ domElement.removeDialogPromiseSetup = function removeDialogPromiseSetup(){
1019
+ this.dialogPromiseSetup = null
1020
+ }
1021
+
1022
+ domElement.setDialogPromiseSetup = function setDialogPromiseSetup(setup){
1023
+ var defaultCatchFun = function(err){
1024
+ console.log('catch from dialogPromise in typed-controls: ', err)
1025
+ };
1026
+ var preDialogFun = function(){
1027
+ return Promise.resolve();
1028
+ };
1029
+ this.dialogPromiseSetup = changing({catchFun:defaultCatchFun, preDialogFun: preDialogFun}, setup);
1030
+ }
1031
+ domElement.setTypedValue = function setTypedValue(typedValue, fromUserInteraction){
1032
+ var self = this
1033
+ var isSameValue;
1034
+ if(setup){
1035
+ isSameValue = bestGlobals.sameValue(self.previousValue, typedValue);
1036
+ }
1037
+ var typer=self.controledType;
1038
+ var setSignal = function(){
1039
+ if(TypedControls.ENABLE_SIGNALS && typer.typeInfo.typeName!='text' || TypedControls.ENABLE_SIGNALS4ALL){
1040
+ var plainValue = typedValue && typer.typeInfo.typeName=='date'?typedValue.toLocaleDateString():typedValue;
1041
+ if(plainValue==TypedControls.SIGNAL_UNKNOWN_DATA || plainValue==TypedControls.VALUE_UNKNOWN_DATA ||
1042
+ (self.controledType.typeInfo.valueUnknownData && self.controledType.typeInfo.valueUnknownData == plainValue)){
1043
+ self.setAttribute('typed-controls-signal-unknown-data','1');
1044
+ }else{
1045
+ self.removeAttribute('typed-controls-signal-unknown-data');
1046
+ }
1047
+ if(plainValue==TypedControls.SIGNAL_NO_DATA || plainValue==TypedControls.VALUE_NO_DATA ||
1048
+ (self.controledType.typeInfo.valueNoData && self.controledType.typeInfo.valueNoData == plainValue)){
1049
+ self.setAttribute('typed-controls-signal-no-data','1');
1050
+ }else{
1051
+ self.removeAttribute('typed-controls-signal-no-data');
1052
+ }
1053
+ }
1054
+ }
1055
+ var setTypedValueFun = function setTypedValueFun(){
1056
+ typer.validateTypedData(typedValue);
1057
+ if(!setup){
1058
+ isSameValue = bestGlobals.sameValue(self.previousValue, typedValue);
1059
+ }
1060
+ setSignal();
1061
+ self.setValidatedTypedValue(typedValue);
1062
+ if(fromUserInteraction){
1063
+ if(!isSameValue){
1064
+ self.dispatchEvent(new CustomEvent('update'));
1065
+ }
1066
+ }
1067
+ self.previousValue=typedValue;
1068
+ }
1069
+ var setup = self.dialogPromiseSetup;
1070
+ if(setup && !isSameValue && !setup.ignoreValues.find(function(value){
1071
+ return value==typedValue;
1072
+ })){
1073
+ switch(setup.dialogType){
1074
+ case 'alertPromise':
1075
+ setup.preDialogFun(self, typedValue).then(function(){
1076
+ alertPromise(setup.message,setup.opts).then(function(){
1077
+ setTypedValueFun();
1078
+ }).catch(function(err){
1079
+ setup.catchFun(err);
1080
+ });
1081
+ });
1082
+ break;
1083
+ case 'promptPromise':
1084
+ setup.preDialogFun(self, typedValue).then(function(){
1085
+ promptPromise(setup.message,setup.opts).then(function(text){
1086
+ if(setup.expectedValue && text == setup.expectedValue){
1087
+ setTypedValueFun();
1088
+ }
1089
+ }).catch(function(err){
1090
+ setup.catchFun(err);
1091
+ });
1092
+ })
1093
+ break;
1094
+ default:
1095
+ setup.preDialogFun(self, typedValue).then(function(){
1096
+ confirmPromise(setup.message,setup.opts).then(function(){
1097
+ setTypedValueFun();
1098
+ }).catch(function(err){
1099
+ setup.catchFun(err);
1100
+ });
1101
+ });
1102
+ break;
1103
+ }
1104
+ }else{
1105
+ setTypedValueFun();
1106
+ }
1107
+ };
1108
+ };
1109
+
1110
+ TypedControls.createFromFixture = function createFromFixture(fixture, typeInfo){
1111
+ var thisModule = this;
1112
+ if(fixture.creatorFunction){
1113
+ return fixture.creatorFunction(typeInfo);
1114
+ }else{
1115
+ return html[fixture.tagName](fixture.attributes,(fixture.content||[]).map(function(subFixture){
1116
+ return thisModule.createFromFixture(subFixture, typeInfo);
1117
+ }));
1118
+ }
1119
+ };
1120
+
1121
+ TypedControls.connect = function connect(opts){
1122
+ opts.input.value = opts.almacen[opts.field];
1123
+ };
1124
+
1125
+ TypedControls.BestControls = BestControls;
1126
+
1127
+ TypedControls.Expanders = [];
1128
+
1129
+ TypedControls.pickDate = function pickDate(actualValue, label, opts){
1130
+ return dialogPromise(function(dialogWindow, closeWindow){
1131
+ var button=html.button(DialogPromise.messages.Ok).create();
1132
+ var divPicker=html.div({id:'datepicker'}).create();
1133
+ var picker = new Pikaday({
1134
+ defaultDate: actualValue,
1135
+ onSelect: function(date) {
1136
+ closeWindow(bestGlobals.date(date));
1137
+ },
1138
+ i18n:TypedControls.messages.pikaday,
1139
+ showDaysInNextAndPreviousMonths: true
1140
+ });
1141
+ divPicker.appendChild(picker.el);
1142
+ button.addEventListener('click',function(){
1143
+ closeWindow(actualValue);
1144
+ });
1145
+ dialogWindow.appendChild(html.div([
1146
+ html.div(label),
1147
+ html.div([divPicker]),
1148
+ html.div([button])
1149
+ ]).create());
1150
+ }, opts)
1151
+ }
1152
+
1153
+ if(window.miniMenuPromise){
1154
+ window.addEventListener('load', function(){
1155
+ TypedControls.Expanders.push({
1156
+ whenType: function(typedControl){
1157
+ var typeInfo = typedControl.controledType.typeInfo;
1158
+ return typeInfo.typeName === 'boolean';
1159
+ },
1160
+ dialogInput: function(typedControl){
1161
+ var typeInfo = typedControl.controledType.typeInfo;
1162
+ var opts=[
1163
+ {value:true , label:TypedControls.messages.Yes},
1164
+ {value:false, label:TypedControls.messages.No},
1165
+ ];
1166
+ if(typeInfo.nullable){
1167
+ opts.push({value:null, label:TypedControls.messages.Null});
1168
+ }
1169
+ return miniMenuPromise(opts,{
1170
+ underElement:typedControl,
1171
+ withCloseButton:false,
1172
+ }).then(function(value){
1173
+ typedControl.setTypedValue(value);
1174
+ typedControl.dispatchEvent(new CustomEvent('udpdate'));
1175
+ });
1176
+ }
1177
+ });
1178
+ TypedControls.Expanders.push({
1179
+ whenType: function(typedControl){
1180
+ var typeInfo = typedControl.controledType.typeInfo;
1181
+ return typeInfo.options;
1182
+ },
1183
+ dialogInput: function(typedControl){
1184
+ var typeInfo = typedControl.controledType.typeInfo;
1185
+ var opts=typeInfo.options.map(function(opt, i){
1186
+ if(typeof opt === 'string'){
1187
+ return {value:opt, labels:[opt]};
1188
+ }
1189
+ return {value:opt.option, labels:[opt.option, opt.label]};
1190
+ });
1191
+ if(typeInfo.nullable){
1192
+ opts.push({value:null, labels:['',TypedControls.messages.Null]});
1193
+ }
1194
+ return miniMenuPromise(opts,{
1195
+ underElement:typedControl,
1196
+ withCloseButton:false,
1197
+ }).then(function(value){
1198
+ typedControl.setTypedValue(value);
1199
+ typedControl.dispatchEvent(new CustomEvent('udpdate'));
1200
+ });
1201
+ }
1202
+ });
1203
+ TypedControls.Expanders.push({
1204
+ whenType: function(typedControl){
1205
+ var typer = typedControl.controledType;
1206
+ return typer.typeInfo.typeName == 'date';
1207
+ },
1208
+ img:'lookdown-calendar.png',
1209
+ dialogInput: function(typedControl){
1210
+ var typer = typedControl.controledType;
1211
+ var actualValue = typedControl.getTypedValue();
1212
+ return TypedControls.pickDate(actualValue, typer.typeInfo.label, {
1213
+ underElement:typedControl,
1214
+ withCloseButton:false,
1215
+ }).then(function(value){
1216
+ typedControl.setTypedValue(value);
1217
+ typedControl.dispatchEvent(new CustomEvent('update'));
1218
+ }).catch(function(err){
1219
+ if(!DialogPromise){
1220
+ return alertPromise(err.message);
1221
+ }
1222
+ });
1223
+ }
1224
+ });
1225
+ TypedControls.Expanders.push({
1226
+ whenType: function(typedControl){
1227
+ var typer = typedControl.controledType;
1228
+ return !typer.typeInfo.clientSide;
1229
+ },
1230
+ whenReadOnly:true,
1231
+ img:'lookdown-zoom.png',
1232
+ dialogInput: function(typedControl){
1233
+ var typer = typedControl.controledType;
1234
+ var value = typedControl.getTypedValue();
1235
+ var actualValue = value==null?'':typer.toLocalString(value);
1236
+ if(typedControl.disabled){
1237
+ var div=html.div().create();
1238
+ div.innerHTML=typedControl.innerHTML;
1239
+ return alertPromise(div,{
1240
+ underElement:typedControl,
1241
+ withCloseButton:false,
1242
+ }).then(function(){return false;});
1243
+ }
1244
+ return promptPromise(typer.typeInfo.label||'', actualValue,{
1245
+ underElement:typedControl,
1246
+ withCloseButton:false,
1247
+ }).then(function(text){
1248
+ var value=typer.fromLocalString(text);
1249
+ typedControl.setTypedValue(value);
1250
+ typedControl.dispatchEvent(new CustomEvent('update'));
1251
+ }).catch(function(err){
1252
+ if(!DialogPromise){
1253
+ return alertPromise(err.message);
1254
+ }
1255
+ });
1256
+ }
1257
+ });
1258
+ });
1259
+ }
1260
+
1261
+ return TypedControls;
1262
+
1263
+ });