/
Input.js
3083 lines (2661 loc) · 92.9 KB
/
Input.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*!
* ${copyright}
*/
// Provides control sap.m.Input.
sap.ui.define([
'./InputBase',
'./Popover',
'sap/ui/core/Item',
'./ColumnListItem',
'./GroupHeaderListItem',
'./StandardListItem',
'sap/ui/core/SeparatorItem',
'./List',
'./Table',
'./library',
'sap/ui/core/IconPool',
'sap/ui/Device',
'sap/ui/core/Control',
'./SuggestionsPopover',
'./Toolbar',
'./ToolbarSpacer',
'./Button',
"sap/ui/core/ResizeHandler",
"sap/ui/dom/containsOrEquals",
"sap/base/assert",
"sap/base/util/deepEqual",
"sap/m/inputUtils/wordStartsWithValue",
"sap/m/inputUtils/inputsDefaultFilter",
"sap/m/inputUtils/highlightDOMElements",
"sap/m/inputUtils/typeAhead",
"sap/ui/events/KeyCodes",
"sap/m/inputUtils/filterItems",
"sap/m/inputUtils/ListHelpers",
"./InputRenderer",
"sap/ui/thirdparty/jquery",
// jQuery Plugin "selectText"
"sap/ui/dom/jquery/selectText"
],
function(
InputBase,
Popover,
Item,
ColumnListItem,
GroupHeaderListItem,
StandardListItem,
SeparatorItem,
List,
Table,
library,
IconPool,
Device,
Control,
SuggestionsPopover,
Toolbar,
ToolbarSpacer,
Button,
ResizeHandler,
containsOrEquals,
assert,
deepEqual,
wordStartsWithValue,
inputsDefaultFilter,
highlightDOMElements,
typeAhead,
KeyCodes,
filterItems,
ListHelpers,
InputRenderer,
jQuery
) {
"use strict";
// shortcut for sap.m.ListType
var ListType = library.ListType;
// shortcut for sap.m.InputTextFormatMode
var InputTextFormatMode = library.InputTextFormatMode;
// shortcut for sap.m.InputType
var InputType = library.InputType;
// shortcut for sap.m.ListMode
var ListMode = library.ListMode;
// shortcut for sap.m.ListSeparators
var ListSeparators = library.ListSeparators;
/**
* Constructor for a new <code>Input</code>.
*
* @param {string} [sId] ID for the new control, generated automatically if no ID is given
* @param {object} [mSettings] Initial settings for the new control
*
* @class
* Allows the user to enter and edit text or numeric values in one line.
*
* <h3>Overview</h3>
*
* You can enable the autocomplete suggestion feature and the value help option to easily enter a valid value.
*
* <h3>Guidelines</h3>
*
* <ul>
* <li> Always provide a meaningful label for any input field </li>
* <li> Limit the length of the input field. This will visually emphasize the constraints for the field. </li>
* <li> Do not use the <code>placeholder</code> property as a label.</li>
* <li> Use the <code>description</code> property only for small fields with no placeholders (i.e. for currencies).</li>
* </ul>
*
* <h3>Structure</h3>
*
* The controls inherits from {@link sap.m.InputBase} which controls the core properties like:
* <ul>
* <li> editable / read-only </li>
* <li> enabled / disabled</li>
* <li> placeholder</li>
* <li> text direction</li>
* <li> value states</li>
* </ul>
* To aid the user during input, you can enable value help (<code>showValueHelp</code>) or autocomplete (<code>showSuggestion</code>).
* <strong>Value help</strong> will open a new dialog where you can refine your input.
* <strong>Autocomplete</strong> has three types of suggestions:
* <ul>
* <li> Single value - a list of suggestions of type <code>sap.ui.core.Item</code> or <code>sap.ui.core.ListItem</code> </li>
* <li> Two values - a list of two suggestions (ID and description) of type <code>sap.ui.core.Item</code> or <code>sap.ui.core.ListItem</code> </li>
* <li> Tabular suggestions of type <code>sap.m.ColumnListItem</code> </li>
* </ul>
* The suggestions are stored in two aggregations <code>suggestionItems</code> (for single and double values) and <code>suggestionRows</code> (for tabular values).
*
* <h3>Usage</h3>
*
* <b>When to use:</b>
* Use the control for short inputs like emails, phones, passwords, fields for assisted value selection.
*
* <b>When not to use:</b>
* Don't use the control for long texts, dates, designated search fields, fields for multiple selection.
*
* <h3>Known Limitations</h3>
*
* If <code>showValueHelp</code> or if <code>showSuggestion</code> is <code>true</code>, the native browser autofill will not fire a change event.
*
* <h4>Note:</h4>
* The control has the following behavior regarding the <code>selectedKey</code> and <code>value</code> properties:
* <ul>
* <li> On initial loading, if the control has a <code>selectedKey</code> set which corresponds to a matching item, and a set <code>value</code>, the <code>value</code> will be updated to the matching item's text. </li>
* <li> If a <code>selectedKey</code> is set and the user types an input which corresponds to an item's text, the <code>selectedKey</code> will be updated with the matching item's key. </li>
* <li> If a <code>selectedKey</code> is set and the user types an input which does not correspond to any item's text, the <code>selectedKey</code> will be set to an empty string ("") </li>
* <li> If a <code>selectedKey</code> is set and the user selects an item, the <code>selectedKey</code> will be updated to match the selected item's key. </li>
* <li> If a <code>selectedKey</code> is bound and the user types before the data is loaded, the user's input will be overwritten by the binding update. </li>
* </ul>
*
* @extends sap.m.InputBase
* @author SAP SE
* @version ${version}
*
* @constructor
* @public
* @alias sap.m.Input
* @see {@link fiori:https://experience.sap.com/fiori-design-web/input-field/ Input}
* @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
*/
var Input = InputBase.extend("sap.m.Input", /** @lends sap.m.Input.prototype */ { metadata : {
library : "sap.m",
properties : {
/**
* HTML type of the internal <code>input</code> tag (e.g. Text, Number, Email, Phone).
* The particular effect of this property differs depending on the browser and the current language settings,
* especially for the type Number.<br>
* This parameter is intended to be used with touch devices that use different soft keyboard layouts depending on the given input type.<br>
* Only the default value <code>sap.m.InputType.Text</code> may be used in combination with data model formats.
* <code>sap.ui.model</code> defines extended formats that are mostly incompatible with normal HTML
* representations for numbers and dates.
*/
type : {type : "sap.m.InputType", group : "Data", defaultValue : InputType.Text},
/**
* Maximum number of characters. Value '0' means the feature is switched off.
* This parameter is not compatible with the input type <code>sap.m.InputType.Number</code>.
* If the input type is set to <code>Number</code>, the <code>maxLength</code> value is ignored.
*/
maxLength : {type : "int", group : "Behavior", defaultValue : 0},
/**
* Only used if type=date and no datepicker is available.
* The data is displayed and the user input is parsed according to this format.
* <b>Note:</b> The value property is always of the form RFC 3339 (YYYY-MM-dd).
* @deprecated Since version 1.9.1.
* <code>sap.m.DatePicker</code>, <code>sap.m.TimePicker</code> or <code>sap.m.DateTimePicker</code> should be used for date/time inputs and formating.
*/
dateFormat : {type : "string", group : "Misc", defaultValue : 'YYYY-MM-dd', deprecated: true},
/**
* If set to true, a value help indicator will be displayed inside the control. When clicked the event "valueHelpRequest" will be fired.
* @since 1.16
*/
showValueHelp : {type : "boolean", group : "Behavior", defaultValue : false},
/**
* Set custom value help icon.
* @since 1.84.0
*/
valueHelpIconSrc : {type : "sap.ui.core.URI", group : "Behavior", defaultValue : "sap-icon://value-help"},
/**
* If this is set to true, suggest event is fired when user types in the input. Changing the suggestItems aggregation in suggest event listener will show suggestions within a popup. When runs on phone, input will first open a dialog where the input and suggestions are shown. When runs on a tablet, the suggestions are shown in a popup next to the input.
* @since 1.16.1
*/
showSuggestion : {type : "boolean", group : "Behavior", defaultValue : false},
/**
* If set to true, direct text input is disabled and the control will trigger the event "valueHelpRequest" for all user interactions. The properties "showValueHelp", "editable", and "enabled" must be set to true, otherwise the property will have no effect
* @since 1.21.0
*/
valueHelpOnly : {type : "boolean", group : "Behavior", defaultValue : false},
/**
* Defines whether to filter the provided suggestions before showing them to the user.
*/
filterSuggests : {type : "boolean", group : "Behavior", defaultValue : true},
/**
* If set, the value of this parameter will control the horizontal size of the suggestion list to display more data. This allows suggestion lists to be wider than the input field if there is enough space available. By default, the suggestion list is always as wide as the input field.
* <b>Note:</b> The value will be ignored if the actual width of the input field is larger than the specified parameter value.
* @since 1.21.1
*/
maxSuggestionWidth : {type : "sap.ui.core.CSSSize", group : "Appearance", defaultValue : null},
/**
* Minimum length of the entered text in input before suggest event is fired. The default value is 1 which means the suggest event is fired after user types in input.
*
* <b>Note:</b> When it's set to 0, suggest event is fired when input with no text gets focus. In this case no suggestion popup will open.
* @since 1.21.2
*/
startSuggestion : {type : "int", group : "Behavior", defaultValue : 1},
/**
* For tabular suggestions, this flag will show/hide the button at the end of the suggestion table that triggers the event "valueHelpRequest" when pressed. The default value is true.
*
* <b>Note:</b> If suggestions are not tabular or no suggestions are used, the button will not be displayed and this flag is without effect.
* @since 1.22.1
*/
showTableSuggestionValueHelp : {type : "boolean", group : "Behavior", defaultValue : true},
/**
* The description is a text after the input field, e.g. units of measurement, currencies.
*/
description: { type: "string", group: "Misc", defaultValue: null },
/**
* This property only takes effect if the description property is set. It controls the distribution of space between the input field and the description text. The default value is 50% leaving the other 50% for the description.
*/
fieldWidth: { type: "sap.ui.core.CSSSize", group: "Appearance", defaultValue: '50%' },
/**
* Indicates when the value gets updated with the user changes: At each keystroke (true) or first when the user presses enter or tabs out (false).
*
* <b>Note:</b> When set to true and the value of the Input control is bound to a model, the change event becomes obsolete and will not be fired, as the value in the model will be updated each time the user provides input. In such cases, subscription to the liveChange event is more appropriate, as it corresponds to the way the underlying model gets updated.
* @since 1.24
*/
valueLiveUpdate : {type : "boolean", group : "Behavior", defaultValue : false},
/**
* Defines the key of the selected item.
*
* <b>Note:</b> If duplicate keys exist, the first item matching the key is used.
* @since 1.44
*/
selectedKey: {type: "string", group: "Data", defaultValue: ""},
/**
* Defines the display text format mode.
* @since 1.44
*/
textFormatMode: {type: "sap.m.InputTextFormatMode", group: "Misc", defaultValue: InputTextFormatMode.Value},
/**
* Defines the display text formatter function.
* @since 1.44
*/
textFormatter: {type: "any", group: "Misc", defaultValue: ""},
/**
* Defines the validation callback function called when a suggestion row gets selected.
* @since 1.44
*/
suggestionRowValidator: {type: "any", group: "Misc", defaultValue: ""},
/**
* Specifies whether the suggestions highlighting is enabled.
* @since 1.46
*/
enableSuggestionsHighlighting: {type: "boolean", group: "Behavior", defaultValue: true},
/**
* Specifies whether autocomplete is enabled.
* Works only if "showSuggestion" property is set to true.
* <b>Note:</b> The autocomplete feature is disabled on Android devices due to a OS specific issue.
* @since 1.61
*/
autocomplete: {type: "boolean", group: "Behavior", defaultValue: true}
},
defaultAggregation : "suggestionItems",
aggregations : {
/**
* Defines the items displayed in the suggestion popup. Changing this aggregation
* (by calling <code>addSuggestionItem</code>, <code>insertSuggestionItem</code>,
* <code>removeSuggestionItem</code>, <code>removeAllSuggestionItems</code>, or
* <code>destroySuggestionItems</code>) after <code>Input</code> is rendered
* opens/closes the suggestion popup.
*
* To display suggestions with two text values, add <code>sap.ui.core.ListItem</code>
* as <code>SuggestionItems</code> (since 1.21.1). For the selected
* <code>ListItem</code>, only the first value is returned to the input field.
*
* <b>Note:</b> Only <code>text</code> and <code>additionalText</code> property values
* of the item are displayed. For example, if an <code>icon</code> is set, it is
* ignored. To display more information per item (including icons), you can use the
* <code>suggestionRows</code> aggregation.
*
* <b>Note:</b> Disabled items are not visualized in the list with the suggestions,
* however they can still be accessed through the aggregation.
*
* @since 1.16.1
*/
suggestionItems : {type : "sap.ui.core.Item", multiple : true, singularName : "suggestionItem"},
/**
* The suggestionColumns and suggestionRows are for tabular input suggestions. This aggregation allows for binding the table columns; for more details see the aggregation "suggestionRows".
* @since 1.21.1
*/
suggestionColumns : {type : "sap.m.Column", multiple : true, singularName : "suggestionColumn", bindable : "bindable", forwarding: {getter:"_getSuggestionsTable", aggregation: "columns"}},
/**
* The suggestionColumns and suggestionRows are for tabular input suggestions. This aggregation allows for binding the table cells.
* The items of this aggregation are to be bound directly or to set in the suggest event method.
* <b>Note:</b> If this aggregation is filled, the aggregation suggestionItems will be ignored.
* @since 1.21.1
*/
suggestionRows : {type : "sap.m.ColumnListItem", altTypes: ["sap.m.GroupHeaderListItem"], multiple : true, singularName : "suggestionRow", bindable : "bindable", forwarding: {getter: "_getSuggestionsTable", aggregation: "items"}},
/**
* The suggestion popup (can be a Dialog or Popover); aggregation needed to also propagate the model and bindings to the content of the popover
*/
_suggestionPopup : {type : "sap.ui.core.Control", multiple: false, visibility: "hidden"},
/**
* The icon on the right side of the Input
*/
_valueHelpIcon : {type : "sap.ui.core.Icon", multiple: false, visibility: "hidden"}
},
associations: {
/**
* Sets or retrieves the selected item from the suggestionItems.
* @since 1.44
*/
selectedItem: {type: "sap.ui.core.Item", multiple: false},
/**
* Sets or retrieves the selected row from the suggestionRows.
* @since 1.44
*/
selectedRow: {type: "sap.m.ColumnListItem", multiple: false}
},
events : {
/**
* Fired when the value of the input is changed by user interaction - each keystroke, delete, paste, etc.
*
* <b>Note:</b> Browsing autocomplete suggestions does not fires the event.
*/
liveChange : {
parameters : {
/**
* The current value of the input, after a live change event.
*/
value : {type : "string"},
/**
* Indicates that ESC key triggered the event. <b>Note:</b> This parameter will not be sent unless the ESC key is pressed.
* @since 1.48
*/
escPressed : {type : "boolean"},
/**
* The value of the input before pressing ESC key. <b>Note:</b> This parameter will not be sent unless the ESC key is pressed.
* @since 1.48
*/
previousValue : {type : "string"}
}
},
/**
* When the value help indicator is clicked, this event will be fired.
* @since 1.16
*/
valueHelpRequest : {
parameters : {
/**
* The event parameter is set to true, when the button at the end of the suggestion table is clicked, otherwise false. It can be used to determine whether the "value help" trigger or the "show all items" trigger has been pressed.
*/
fromSuggestions : {type : "boolean"}
}
},
/**
* This event is fired when user types in the input and showSuggestion is set to true. Changing the suggestItems aggregation will show the suggestions within a popup.
* @since 1.16.1
*/
suggest : {
parameters : {
/**
* The current value which has been typed in the input.
*/
suggestValue : {type : "string"},
/**
* The suggestion list is passed to this event for convenience. If you use list-based or tabular suggestions, fill the suggestionList with the items you want to suggest. Otherwise, directly add the suggestions to the "suggestionItems" aggregation of the input control.
*/
suggestionColumns : {type : "sap.m.ListBase"}
}
},
/**
* This event is fired when suggestionItem shown in suggestion popup are selected. This event is only fired when showSuggestion is set to true and there are suggestionItems shown in the suggestion popup.
* @since 1.16.3
*/
suggestionItemSelected : {
parameters : {
/**
* This is the item selected in the suggestion popup for one and two-value suggestions. For tabular suggestions, this value will not be set.
*/
selectedItem : {type : "sap.ui.core.Item"},
/**
* This is the row selected in the tabular suggestion popup represented as a ColumnListItem. For one and two-value suggestions, this value will not be set.
*
* <b>Note:</b> The row result function to select a result value for the string is already executed at this time. To pick different value for the input field or to do follow up steps after the item has been selected.
* @since 1.21.1
*/
selectedRow : {type : "sap.m.ColumnListItem"}
}
},
/**
* This event is fired when user presses the <kbd>Enter</kbd> key on the input.
*
* <b>Notes:</b>
* <ul>
* <li>The event is fired independent of whether there was a change before or not. If a change was performed, the event is fired after the change event.</li>
* <li>The event is also fired when an item of the select list is selected via <kbd>Enter</kbd>.</li>
* <li>The event is only fired on an input which allows text input (<code>editable</code>, <code>enabled</code> and not <code>valueHelpOnly</code>).</li>
* </ul>
*
* @since 1.33.0
*/
submit : {
parameters: {
/**
* The new value of the input.
*/
value: { type: "string" }
}
}
},
designtime: "sap/m/designtime/Input.designtime"
}});
IconPool.insertFontFaceStyle();
/**
* The default filter function for tabular suggestions. It checks whether some item text begins with the typed value.
*
* @private
* @param {string} sValue the current filter string.
* @param {sap.m.ColumnListItem} oColumnListItem The filtered list item.
* @returns {boolean} true for items that start with the parameter sValue, false for non matching items.
*/
Input._DEFAULTFILTER_TABULAR = function(sValue, oColumnListItem) {
var aCells = oColumnListItem.getCells(),
i = 0;
for (; i < aCells.length; i++) {
if (aCells[i].getText) {
if (wordStartsWithValue(aCells[i].getText(), sValue)) {
return true;
}
}
}
return false;
};
/**
* The default result function for tabular suggestions. It returns the value of the first cell with a "text" property.
*
* @private
* @param {sap.m.ColumnListItem} oColumnListItem The selected list item.
* @returns {string} The value to be displayed in the input field.
*/
Input._DEFAULTRESULT_TABULAR = function (oColumnListItem) {
var aCells = oColumnListItem.getCells(),
i = 0;
for (; i < aCells.length; i++) {
// take first cell with a text method and compare value
if (aCells[i].getText) {
return aCells[i].getText();
}
}
return "";
};
/**
* Initializes the control.
*
* @private
*/
Input.prototype.init = function() {
InputBase.prototype.init.call(this);
this._fnFilter = inputsDefaultFilter;
// Show suggestions in a full screen dialog on phones:
this._bFullScreen = Device.system.phone;
// Counter for concurrent issues with setValue:
this._iSetCount = 0;
// TypeAhead's suggested text. It's always executed in the context of the "root" Input and never in the Dialog's instance!
this._sProposedItemText = null;
this._oRb = sap.ui.getCore().getLibraryResourceBundle("sap.m");
};
/**
* Destroys the Input.
*
* @private
*/
Input.prototype.exit = function() {
InputBase.prototype.exit.call(this);
this._deregisterEvents();
// clear delayed calls
this.cancelPendingSuggest();
if (this._iRefreshListTimeout) {
clearTimeout(this._iRefreshListTimeout);
this._iRefreshListTimeout = null;
}
if (this._oSuggestionTable) {
this._oSuggestionTable.destroy();
this._oSuggestionTable = null;
}
if (this._oSuggPopover) {
this._oSuggPopover.destroy();
this._oSuggPopover = null;
}
if (this._oShowMoreButton) {
this._oShowMoreButton.destroy();
this._oShowMoreButton = null;
}
if (this._oButtonToolbar) {
this._oButtonToolbar.destroy();
this._oButtonToolbar = null;
}
// Unregister custom events handlers after migration to semantic rendering
this.$().off("click");
};
/**
* Overwrites the onBeforeRendering.
*
* @public
*/
Input.prototype.onBeforeRendering = function() {
var sSelectedKey = this.getSelectedKey(),
bShowIcon = this.getShowValueHelp() && this.getEnabled() && this.getEditable(),
aEndIcons = this.getAggregation("_endIcon") || [],
oIcon = aEndIcons[0],
oPopupInput,
bSuggestionsPopoverIsOpen = this._isSuggestionsPopoverOpen(),
sValueStateHeaderText = bSuggestionsPopoverIsOpen ? this._oSuggPopover._getValueStateHeader().getText() : null,
sValueStateHeaderValueState = bSuggestionsPopoverIsOpen ? this._oSuggPopover._getValueStateHeader().getValueState() : "";
InputBase.prototype.onBeforeRendering.call(this);
this._deregisterEvents();
if (sSelectedKey) {
this.setSelectedKey(sSelectedKey);
}
if (this.getShowSuggestion()) {
if (this.getShowTableSuggestionValueHelp()) {
this._addShowMoreButton();
} else {
this._removeShowMoreButton();
}
oPopupInput = this._oSuggPopover._oPopupInput;
// setting the property "type" of the Input inside the Suggestion popover
if (oPopupInput) {
oPopupInput.setType(this.getType());
}
}
if (bShowIcon) {
// ensure the creation of an icon
oIcon = this._getValueHelpIcon();
oIcon.setProperty("visible", true, true);
} else if (oIcon) {
// if the icon should not be shown and has never be initialized - do nothing
oIcon.setProperty("visible", false, true);
}
if (!this.getWidth()) {
this.setProperty("width", "100%", true);
}
this._resetTypeAhead();
if (bSuggestionsPopoverIsOpen && ((this.getValueStateText() && sValueStateHeaderText !== this.getValueStateText()) ||
(this.getValueState() !== sValueStateHeaderValueState) ||
(this.getFormattedValueStateText()))) {
/* If new value state, value state plain text or FormattedText is set
while the suggestions popover is open update the value state header.
If the input has FormattedText aggregation while the suggestions popover is open then
it's new, because the old is already switched to have the value state header as parent */
this._updateSuggestionsPopoverValueState();
}
};
/**
* Returns input display text.
*
* @private
* @param {sap.ui.core.Item} oItem The displayed item.
* @returns {string} The key for the text format mode.
*/
Input.prototype._getDisplayText = function(oItem) {
var fTextFormatter = this.getTextFormatter();
if (fTextFormatter) {
return fTextFormatter(oItem);
}
var sText = oItem.getText(),
sKey = oItem.getKey(),
textFormatMode = this.getTextFormatMode();
switch (textFormatMode) {
case InputTextFormatMode.Key:
return sKey;
case InputTextFormatMode.ValueKey:
return sText + ' (' + sKey + ')';
case InputTextFormatMode.KeyValue:
return '(' + sKey + ') ' + sText;
default:
return sText;
}
};
/**
* Handles value updates.
*
* @private
* @param {string} newValue The new selected value.
*/
Input.prototype._onValueUpdated = function (newValue) {
if (this._bSelectingItem || newValue === this._sSelectedValue) {
return;
}
var sKey = this.getSelectedKey(),
bHasSelectedItem,
oList = this._oSuggPopover && this._oSuggPopover.getItemsContainer();
if (sKey === '') {
return;
}
if (this._hasTabularSuggestions()) {
bHasSelectedItem = this._oSuggestionTable && !!this._oSuggestionTable.getSelectedItem();
} else {
bHasSelectedItem = oList && !!oList.getSelectedItem();
}
if (bHasSelectedItem) {
return;
}
this.setProperty("selectedKey", '', true);
this.setAssociation("selectedRow", null, true);
this.setAssociation("selectedItem", null, true);
this.fireSuggestionItemSelected({
selectedItem: null,
selectedRow: null
});
};
/**
* Updates selectedItem or selectedRow from the suggestion list or table.
*
* @private
* @returns {boolean} Indicates if an item or row is selected
*/
Input.prototype._updateSelectionFromList = function () {
if (this._oSuggPopover._iPopupListSelectedIndex < 0) {
return false;
}
var oList = this._oSuggPopover.getItemsContainer(),
oSelectedItem = oList && oList.getSelectedItem();
if (oSelectedItem) {
if (this._hasTabularSuggestions()) {
this.setSelectionRow(oSelectedItem, true);
} else {
this.setSelectionItem(ListHelpers.getItemByListItem(this.getSuggestionItems(), oSelectedItem), true);
}
}
return true;
};
/**
* Updates and synchronizes the <code>selectedItem</code> association and <code>selectedKey</code> properties.
*
* @private
* @param {sap.ui.core.Item | null} oItem Selected item.
* @param {boolean} bInteractionChange Specifies if the change is triggered by user interaction.
*/
Input.prototype.setSelectionItem = function (oItem, bInteractionChange) {
this._bSelectingItem = true;
if (!oItem) {
this.setAssociation("selectedItem", null, true);
this.setValue('');
return;
}
this._oSuggPopover._iPopupListSelectedIndex = -1;
var iCount = this._iSetCount,
sNewValue;
this.setAssociation("selectedItem", oItem, true);
this.setProperty("selectedKey", oItem.getKey(), true);
// fire suggestion item select event
if (bInteractionChange) {
this.fireSuggestionItemSelected({
selectedItem: oItem
});
}
// choose which field should be used for the value
if (iCount !== this._iSetCount) {
// if the event handler modified the input value we take this one as new value
sNewValue = this.getValue();
} else {
sNewValue = this._getDisplayText(oItem);
}
this._sSelectedValue = sNewValue;
this.updateInputField(sNewValue);
// don't continue if the input is destroyed after firing change event through updateInputField
if (this.bIsDestroyed) {
return;
}
if (!(this.isMobileDevice() && this instanceof sap.m.MultiInput)) {
this._closeSuggestionPopup();
}
this._bSelectingItem = false;
};
/**
* Adds a sap.m.GroupHeaderListItem item to the aggregation named <code>suggestionRows</code>.
*
* @param {sap.ui.core.Item} oGroup Item of that group
* @param {sap.ui.core.SeparatorItem} oHeader The item to be added
* @param {boolean} bSuppressInvalidate Flag indicating whether invalidation should be suppressed
* @returns {sap.m.GroupHeaderListItem} The group header
* @private
*/
Input.prototype.addSuggestionRowGroup = function(oGroup, oHeader, bSuppressInvalidate) {
oHeader = oHeader || new GroupHeaderListItem({
title: oGroup.text || oGroup.key
});
this.addAggregation("suggestionRows", oHeader, bSuppressInvalidate);
return oHeader;
};
/**
* Adds a sap.ui.core.SeparatorItem item to the aggregation named <code>suggestions</code>.
*
* @param {sap.ui.core.Item} oGroup Item of that group
* @param {sap.ui.core.SeparatorItem} oHeader The item to be added
* @param {boolean} bSuppressInvalidate Flag indicating whether invalidation should be suppressed
* @returns {sap.m.GroupHeaderListItem} The group header
* @private
*/
Input.prototype.addSuggestionItemGroup = function(oGroup, oHeader, bSuppressInvalidate) {
oHeader = oHeader || new SeparatorItem({
text: oGroup.text || oGroup.key
});
this.addAggregation("suggestionItems", oHeader, bSuppressInvalidate);
return oHeader;
};
/**
* Sets the <code>selectedItem</code> association.
*
*
* @public
* @param {sap.ui.core.Item} [oItem=null] New value for the <code>selectedItem</code> association.
* If an ID of a <code>sap.ui.core.Item</code> is given, the item with this ID becomes the
* <code>selectedItem</code> association.
* Alternatively, a <code>sap.ui.core.Item</code> instance may be given or <code>null</code> to clear
* the selection.
* @returns {sap.m.Input} <code>this</code> to allow method chaining.
* @since 1.44
*/
Input.prototype.setSelectedItem = function(oItem) {
if (typeof oItem === "string") {
oItem = sap.ui.getCore().byId(oItem);
}
if (oItem !== null && !(oItem instanceof Item)) {
return this;
}
this.setSelectionItem(oItem);
return this;
};
/**
* Sets the <code>selectedKey</code> property.
*
* Default value is an empty string <code>""</code> or <code>undefined</code>.
*
* @public
* @param {string} sKey New value for property <code>selectedKey</code>.
* If the provided <code>sKey</code> is an empty string <code>""</code> or <code>undefined</code>,
* the selection is cleared.
* If duplicate keys exist, the first item matching the key is selected.
* @returns {sap.m.Input} <code>this</code> to allow method chaining.
* @since 1.44
*/
Input.prototype.setSelectedKey = function(sKey) {
sKey = this.validateProperty("selectedKey", sKey);
this.setProperty("selectedKey", sKey, true);
if (this._hasTabularSuggestions()) {
return this;
}
if (!sKey) {
this.setSelectionItem();
return this;
}
var oItem = this.getSuggestionItemByKey(sKey);
this.setSelectionItem(oItem);
return this;
};
/**
* Gets the item with the given key from the aggregation <code>suggestionItems</code>.
* <b>Note:</b> If duplicate keys exist, the first item matching the key is returned.
*
* @public
* @param {string} sKey An item key that specifies the item to retrieve.
* @returns {sap.ui.core.Item} Suggestion item.
* @since 1.44
*/
Input.prototype.getSuggestionItemByKey = function(sKey) {
var aItems = this.getSuggestionItems() || [],
oItem,
i;
for (i = 0; i < aItems.length; i++) {
oItem = aItems[i];
if (oItem.getKey() === sKey) {
return oItem;
}
}
};
/**
* Gets <code>sap.m.FormattedText</code> aggregation based on its current parent.
* If the SuggestionPopover is open that is the <code>sap.m.ValueStateHeader</code>, otherwise is the Input itself.
*
* @private
* @returns {sap.m.FormattedText} Aggregation used for value state message that can contain links.
* @since 1.78
*/
Input.prototype._getFormattedValueStateText = function() {
var bSuggestionsPopoverIsOpen = this._isSuggestionsPopoverOpen(),
oValueStateHeaderFormattedText = bSuggestionsPopoverIsOpen ? this._oSuggPopover._getValueStateHeader().getFormattedText() : null;
if (bSuggestionsPopoverIsOpen && oValueStateHeaderFormattedText) {
return oValueStateHeaderFormattedText;
} else {
return InputBase.prototype.getFormattedValueStateText.call(this);
}
};
/**
* Updates and synchronizes the <code>selectedRow</code> association and <code>selectedKey</code> properties.
*
* @private
* @param {sap.m.ColumnListItem} oListItem Selected item.
* @param {boolean} bInteractionChange Specifies if the change is triggered by user interaction.
*/
Input.prototype.setSelectionRow = function (oListItem, bInteractionChange) {
if (!oListItem) {
this.setAssociation("selectedRow", null, true);
return;
}
this._oSuggPopover._iPopupListSelectedIndex = -1;
this._bSelectingItem = true;
var oItem,
fSuggestionRowValidator = this.getSuggestionRowValidator();
if (fSuggestionRowValidator) {
oItem = fSuggestionRowValidator(oListItem);
if (!(oItem instanceof Item)) {
oItem = null;
}
}
var iCount = this._iSetCount,
sKey = "",
sNewValue;
this.setAssociation("selectedRow", oListItem, true);
if (oItem) {
sKey = oItem.getKey();
}
this.setProperty("selectedKey", sKey, true);
// fire suggestion item select event
if (bInteractionChange) {
this.fireSuggestionItemSelected({
selectedRow: oListItem
});
}
// choose which field should be used for the value
if (iCount !== this._iSetCount) {
// if the event handler modified the input value we take this one as new value
sNewValue = this.getValue();
} else {
// for tabular suggestions we call a result filter function
if (oItem) {
sNewValue = this._getDisplayText(oItem);
} else {
sNewValue = this._fnRowResultFilter ? this._fnRowResultFilter(oListItem) : Input._DEFAULTRESULT_TABULAR(oListItem);
}
}
this._sSelectedValue = sNewValue;
this.updateInputField(sNewValue);