@openui5/sap.ui.commons 1.143.0 → 1.144.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRDPARTY.txt +1 -1
- package/package.json +4 -4
- package/src/sap/ui/commons/.library +2 -2
- package/src/sap/ui/commons/Accordion.js +2 -2
- package/src/sap/ui/commons/AccordionRenderer.js +1 -1
- package/src/sap/ui/commons/AccordionSection.js +2 -2
- package/src/sap/ui/commons/ApplicationHeader.js +2 -2
- package/src/sap/ui/commons/ApplicationHeaderRenderer.js +1 -1
- package/src/sap/ui/commons/Area.js +2 -2
- package/src/sap/ui/commons/AutoComplete.js +2 -2
- package/src/sap/ui/commons/AutoCompleteRenderer.js +1 -1
- package/src/sap/ui/commons/Button.js +2 -2
- package/src/sap/ui/commons/ButtonRenderer.js +2 -2
- package/src/sap/ui/commons/Callout.js +2 -2
- package/src/sap/ui/commons/CalloutBase.js +2 -2
- package/src/sap/ui/commons/CalloutBaseRenderer.js +1 -1
- package/src/sap/ui/commons/CalloutRenderer.js +1 -1
- package/src/sap/ui/commons/Carousel.js +2 -2
- package/src/sap/ui/commons/CarouselRenderer.js +1 -1
- package/src/sap/ui/commons/CheckBox.js +2 -2
- package/src/sap/ui/commons/CheckBoxRenderer.js +1 -1
- package/src/sap/ui/commons/ColorPicker.js +2 -2
- package/src/sap/ui/commons/ComboBox.js +2 -2
- package/src/sap/ui/commons/ComboBoxRenderer.js +1 -1
- package/src/sap/ui/commons/DatePicker.js +2 -2
- package/src/sap/ui/commons/DatePickerRenderer.js +1 -1
- package/src/sap/ui/commons/Dialog.js +2 -2
- package/src/sap/ui/commons/DialogRenderer.js +1 -1
- package/src/sap/ui/commons/DropdownBox.js +2 -2
- package/src/sap/ui/commons/DropdownBoxRenderer.js +1 -1
- package/src/sap/ui/commons/FileUploader.js +2150 -22
- package/src/sap/ui/commons/FileUploaderHttpRequestMethod.js +41 -0
- package/src/sap/ui/commons/FileUploaderParameter.js +25 -15
- package/src/sap/ui/commons/FileUploaderRenderer.js +114 -5
- package/src/sap/ui/commons/FileUploaderXHRSettings.js +49 -0
- package/src/sap/ui/commons/FormattedTextView.js +2 -2
- package/src/sap/ui/commons/FormattedTextViewRenderer.js +1 -1
- package/src/sap/ui/commons/HorizontalDivider.js +2 -2
- package/src/sap/ui/commons/HorizontalDividerRenderer.js +1 -1
- package/src/sap/ui/commons/Image.js +2 -2
- package/src/sap/ui/commons/ImageMap.js +2 -2
- package/src/sap/ui/commons/ImageMapRenderer.js +1 -1
- package/src/sap/ui/commons/ImageRenderer.js +1 -1
- package/src/sap/ui/commons/InPlaceEdit.js +2 -2
- package/src/sap/ui/commons/InPlaceEditRenderer.js +1 -1
- package/src/sap/ui/commons/Label.js +2 -2
- package/src/sap/ui/commons/LabelRenderer.js +1 -1
- package/src/sap/ui/commons/Link.js +2 -2
- package/src/sap/ui/commons/LinkRenderer.js +1 -1
- package/src/sap/ui/commons/ListBox.js +2 -2
- package/src/sap/ui/commons/ListBoxRenderer.js +2 -2
- package/src/sap/ui/commons/Menu.js +2 -2
- package/src/sap/ui/commons/MenuBar.js +2 -2
- package/src/sap/ui/commons/MenuBarRenderer.js +1 -1
- package/src/sap/ui/commons/MenuButton.js +2 -2
- package/src/sap/ui/commons/MenuButtonRenderer.js +1 -1
- package/src/sap/ui/commons/MenuItem.js +2 -2
- package/src/sap/ui/commons/MenuItemBase.js +2 -2
- package/src/sap/ui/commons/MenuRenderer.js +1 -1
- package/src/sap/ui/commons/MenuTextFieldItem.js +2 -2
- package/src/sap/ui/commons/Message.js +2 -2
- package/src/sap/ui/commons/MessageBar.js +2 -2
- package/src/sap/ui/commons/MessageBarRenderer.js +1 -1
- package/src/sap/ui/commons/MessageBox.js +2 -2
- package/src/sap/ui/commons/MessageList.js +2 -2
- package/src/sap/ui/commons/MessageListRenderer.js +1 -1
- package/src/sap/ui/commons/MessageRenderer.js +1 -1
- package/src/sap/ui/commons/MessageToast.js +2 -2
- package/src/sap/ui/commons/MessageToastRenderer.js +1 -1
- package/src/sap/ui/commons/Paginator.js +2 -2
- package/src/sap/ui/commons/PaginatorRenderer.js +1 -1
- package/src/sap/ui/commons/Panel.js +2 -2
- package/src/sap/ui/commons/PanelRenderer.js +1 -1
- package/src/sap/ui/commons/PasswordField.js +2 -2
- package/src/sap/ui/commons/PasswordFieldRenderer.js +1 -1
- package/src/sap/ui/commons/ProgressIndicator.js +2 -2
- package/src/sap/ui/commons/ProgressIndicatorRenderer.js +1 -1
- package/src/sap/ui/commons/RadioButton.js +2 -2
- package/src/sap/ui/commons/RadioButtonGroup.js +2 -2
- package/src/sap/ui/commons/RadioButtonGroupRenderer.js +1 -1
- package/src/sap/ui/commons/RadioButtonRenderer.js +1 -1
- package/src/sap/ui/commons/RangeSlider.js +2 -2
- package/src/sap/ui/commons/RangeSliderRenderer.js +1 -1
- package/src/sap/ui/commons/RatingIndicator.js +2 -2
- package/src/sap/ui/commons/RatingIndicatorRenderer.js +1 -1
- package/src/sap/ui/commons/ResponsiveContainer.js +2 -2
- package/src/sap/ui/commons/ResponsiveContainerRange.js +2 -2
- package/src/sap/ui/commons/ResponsiveContainerRenderer.js +1 -1
- package/src/sap/ui/commons/RichTooltip.js +2 -2
- package/src/sap/ui/commons/RichTooltipRenderer.js +1 -1
- package/src/sap/ui/commons/RoadMap.js +2 -2
- package/src/sap/ui/commons/RoadMapRenderer.js +1 -1
- package/src/sap/ui/commons/RoadMapStep.js +2 -2
- package/src/sap/ui/commons/RowRepeater.js +2 -2
- package/src/sap/ui/commons/RowRepeaterFilter.js +2 -2
- package/src/sap/ui/commons/RowRepeaterRenderer.js +1 -1
- package/src/sap/ui/commons/RowRepeaterSorter.js +2 -2
- package/src/sap/ui/commons/SearchField.js +2 -2
- package/src/sap/ui/commons/SearchFieldRenderer.js +1 -1
- package/src/sap/ui/commons/SearchProvider.js +2 -2
- package/src/sap/ui/commons/SegmentedButton.js +2 -2
- package/src/sap/ui/commons/SegmentedButtonRenderer.js +1 -1
- package/src/sap/ui/commons/Slider.js +2 -2
- package/src/sap/ui/commons/SliderRenderer.js +1 -1
- package/src/sap/ui/commons/Splitter.js +2 -2
- package/src/sap/ui/commons/SplitterRenderer.js +1 -1
- package/src/sap/ui/commons/Tab.js +2 -2
- package/src/sap/ui/commons/TabStrip.js +2 -2
- package/src/sap/ui/commons/TabStripRenderer.js +1 -1
- package/src/sap/ui/commons/TextArea.js +2 -2
- package/src/sap/ui/commons/TextAreaRenderer.js +1 -1
- package/src/sap/ui/commons/TextField.js +2 -2
- package/src/sap/ui/commons/TextFieldRenderer.js +2 -2
- package/src/sap/ui/commons/TextView.js +2 -2
- package/src/sap/ui/commons/TextViewRenderer.js +1 -1
- package/src/sap/ui/commons/Title.js +2 -2
- package/src/sap/ui/commons/ToggleButton.js +2 -2
- package/src/sap/ui/commons/ToggleButtonRenderer.js +1 -1
- package/src/sap/ui/commons/Toolbar.js +2 -2
- package/src/sap/ui/commons/ToolbarRenderer.js +1 -1
- package/src/sap/ui/commons/ToolbarSeparator.js +2 -2
- package/src/sap/ui/commons/Tree.js +2 -2
- package/src/sap/ui/commons/TreeNode.js +2 -2
- package/src/sap/ui/commons/TreeRenderer.js +1 -1
- package/src/sap/ui/commons/TriStateCheckBox.js +2 -2
- package/src/sap/ui/commons/TriStateCheckBoxRenderer.js +1 -1
- package/src/sap/ui/commons/ValueHelpField.js +2 -2
- package/src/sap/ui/commons/ValueHelpFieldRenderer.js +1 -1
- package/src/sap/ui/commons/form/Form.js +2 -2
- package/src/sap/ui/commons/form/FormContainer.js +2 -2
- package/src/sap/ui/commons/form/FormElement.js +2 -2
- package/src/sap/ui/commons/form/FormLayout.js +2 -2
- package/src/sap/ui/commons/form/FormLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/form/FormRenderer.js +1 -1
- package/src/sap/ui/commons/form/GridContainerData.js +2 -2
- package/src/sap/ui/commons/form/GridElementData.js +2 -2
- package/src/sap/ui/commons/form/GridLayout.js +2 -2
- package/src/sap/ui/commons/form/GridLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/form/ResponsiveLayout.js +2 -2
- package/src/sap/ui/commons/form/ResponsiveLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/form/SimpleForm.js +2 -2
- package/src/sap/ui/commons/form/SimpleFormRenderer.js +1 -1
- package/src/sap/ui/commons/layout/AbsoluteLayout.js +2 -2
- package/src/sap/ui/commons/layout/AbsoluteLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/layout/BorderLayout.js +2 -2
- package/src/sap/ui/commons/layout/BorderLayoutArea.js +2 -2
- package/src/sap/ui/commons/layout/BorderLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/layout/HorizontalLayout.js +2 -2
- package/src/sap/ui/commons/layout/HorizontalLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/layout/MatrixLayout.js +2 -2
- package/src/sap/ui/commons/layout/MatrixLayoutCell.js +2 -2
- package/src/sap/ui/commons/layout/MatrixLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/layout/MatrixLayoutRow.js +2 -2
- package/src/sap/ui/commons/layout/PositionContainer.js +2 -2
- package/src/sap/ui/commons/layout/ResponsiveFlowLayout.js +2 -2
- package/src/sap/ui/commons/layout/ResponsiveFlowLayoutData.js +2 -2
- package/src/sap/ui/commons/layout/ResponsiveFlowLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/layout/VerticalLayout.js +2 -2
- package/src/sap/ui/commons/layout/VerticalLayoutRenderer.js +1 -1
- package/src/sap/ui/commons/library.js +41 -6
- package/src/sap/ui/commons/messagebundle.properties +12 -0
- package/src/sap/ui/commons/themes/base/AbsoluteLayout.less +2 -1
- package/src/sap/ui/commons/themes/base/Accordion.less +8 -7
- package/src/sap/ui/commons/themes/base/AccordionSection.less +17 -13
- package/src/sap/ui/commons/themes/base/Carousel.less +20 -19
- package/src/sap/ui/commons/themes/base/ControlsInUITable.less +12 -36
- package/src/sap/ui/commons/themes/base/FileUploader.less +104 -1
- package/src/sap/ui/commons/themes/base/FormattedTextView.less +11 -10
- package/src/sap/ui/commons/themes/base/library.source.less +1 -1
- package/src/sap/ui/commons/themes/sap_hcb/library.source.less +1 -1
|
@@ -1,19 +1,55 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* OpenUI5
|
|
3
|
-
* (c) Copyright
|
|
3
|
+
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// Provides control sap.ui.commons.FileUploader.
|
|
8
8
|
sap.ui.define([
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
'sap/ui/core/Control',
|
|
10
|
+
'./library',
|
|
11
|
+
"sap/ui/core/ControlBehavior",
|
|
12
|
+
"sap/ui/core/Element",
|
|
13
|
+
'sap/ui/core/LabelEnablement',
|
|
14
|
+
'sap/ui/core/InvisibleText',
|
|
15
|
+
"sap/ui/core/Lib",
|
|
16
|
+
'sap/ui/core/library',
|
|
17
|
+
'sap/ui/core/StaticArea',
|
|
18
|
+
'sap/ui/Device',
|
|
19
|
+
'./FileUploaderRenderer',
|
|
20
|
+
'sap/ui/dom/containsOrEquals',
|
|
21
|
+
'sap/ui/events/KeyCodes',
|
|
22
|
+
'sap/base/Log',
|
|
23
|
+
'sap/base/security/encodeXML',
|
|
24
|
+
"sap/ui/thirdparty/jquery",
|
|
25
|
+
"sap/ui/commons/Button",
|
|
26
|
+
"sap/ui/commons/TextField",
|
|
27
|
+
// jQuery Plugin "addAriaDescribedBy"
|
|
28
|
+
'sap/ui/dom/jquery/Aria'
|
|
29
|
+
], function(
|
|
30
|
+
Control,
|
|
31
|
+
library,
|
|
32
|
+
ControlBehavior,
|
|
33
|
+
Element,
|
|
34
|
+
LabelEnablement,
|
|
35
|
+
InvisibleText,
|
|
36
|
+
Library,
|
|
37
|
+
coreLibrary,
|
|
38
|
+
StaticArea,
|
|
39
|
+
Device,
|
|
40
|
+
FileUploaderRenderer,
|
|
41
|
+
containsOrEquals,
|
|
42
|
+
KeyCodes,
|
|
43
|
+
Log,
|
|
44
|
+
encodeXML,
|
|
45
|
+
jQuery,
|
|
46
|
+
Button,
|
|
47
|
+
TextField
|
|
48
|
+
) {
|
|
49
|
+
|
|
50
|
+
// shortcut for sap.ui.core.ValueState
|
|
51
|
+
var ValueState = coreLibrary.ValueState;
|
|
52
|
+
var HttpRequestMethod = library.FileUploaderHttpRequestMethod;
|
|
17
53
|
|
|
18
54
|
/**
|
|
19
55
|
* Constructor for a new FileUploader.
|
|
@@ -23,10 +59,9 @@ sap.ui.define([
|
|
|
23
59
|
*
|
|
24
60
|
* @class
|
|
25
61
|
* The framework generates an input field and a button with text "Browse ...". The API supports features such as on change uploads (the upload starts immediately after a file has been selected), file uploads with explicit calls, adjustable control sizes, text display after uploads, or tooltips containing complete file paths.
|
|
26
|
-
* @extends sap.ui.unified.FileUploader
|
|
27
62
|
*
|
|
28
63
|
* @author SAP SE
|
|
29
|
-
* @version 1.
|
|
64
|
+
* @version 1.144.0
|
|
30
65
|
*
|
|
31
66
|
* @constructor
|
|
32
67
|
* @public
|
|
@@ -34,18 +69,2111 @@ sap.ui.define([
|
|
|
34
69
|
* Please use the control sap.ui.unified.FileUploader of the library sap.ui.unified instead.
|
|
35
70
|
* @alias sap.ui.commons.FileUploader
|
|
36
71
|
*/
|
|
37
|
-
var FileUploader =
|
|
38
|
-
|
|
72
|
+
var FileUploader = Control.extend("sap.ui.commons.FileUploader", /** @lends sap.ui.commons.FileUploader.prototype */ { metadata : {
|
|
39
73
|
deprecated : true,
|
|
40
|
-
library : "sap.ui.commons"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
74
|
+
library : "sap.ui.commons",
|
|
75
|
+
interfaces : ["sap.ui.core.IFormContent", "sap.ui.commons.IProcessableBlobs"],
|
|
76
|
+
properties : {
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Value of the path for file upload.
|
|
80
|
+
*/
|
|
81
|
+
value : {type : "string", group : "Data", defaultValue : ''},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Disabled controls have different colors, depending on customer settings.
|
|
85
|
+
*/
|
|
86
|
+
enabled : {type : "boolean", group : "Behavior", defaultValue : true},
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Used when URL address is on a remote server.
|
|
90
|
+
*/
|
|
91
|
+
uploadUrl : {type : "sap.ui.core.URI", group : "Data", defaultValue : ''},
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Unique control name for identification on the server side after sending data to the server.
|
|
95
|
+
*/
|
|
96
|
+
name : {type : "string", group : "Data", defaultValue : null},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Specifies the displayed control width.
|
|
100
|
+
*/
|
|
101
|
+
width : {type : "sap.ui.core.CSSSize", group : "Misc", defaultValue : ''},
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* If set to "true", the upload immediately starts after file selection.
|
|
105
|
+
* With the default setting, the upload needs to be explicitly triggered.
|
|
106
|
+
*/
|
|
107
|
+
uploadOnChange : {type : "boolean", group : "Behavior", defaultValue : false},
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Additional data that is sent to the back end service.
|
|
111
|
+
*
|
|
112
|
+
* Data will be transmitted as value of a hidden input where the name is derived from the
|
|
113
|
+
* <code>name</code> property with suffix "-data".
|
|
114
|
+
*/
|
|
115
|
+
additionalData : {type : "string", group : "Data", defaultValue : null},
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* If the FileUploader is configured to upload the file directly after the file is selected,
|
|
119
|
+
* it is not allowed to upload a file with the same name again. If a user should be allowed
|
|
120
|
+
* to upload a file with the same name again this parameter has to be "true".
|
|
121
|
+
*
|
|
122
|
+
* A typical use case would be if the files have different paths.
|
|
123
|
+
*/
|
|
124
|
+
sameFilenameAllowed : {type : "boolean", group : "Behavior", defaultValue : false},
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The button's text can be overwritten using this property.
|
|
128
|
+
*/
|
|
129
|
+
buttonText : {type : "string", group : "Misc", defaultValue : null},
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The chosen files will be checked against an array of file types.
|
|
133
|
+
*
|
|
134
|
+
* If at least one file does not fit the file type restriction, the upload is prevented.
|
|
135
|
+
* <b>Note:</b> This property is not supported by Microsoft Edge.
|
|
136
|
+
*
|
|
137
|
+
* Example: <code>["jpg", "png", "bmp"]</code>.
|
|
138
|
+
*/
|
|
139
|
+
fileType : {type : "string[]", group : "Data", defaultValue : null},
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Allows multiple files to be chosen and uploaded from the same folder.
|
|
143
|
+
*
|
|
144
|
+
* This property is not supported by Internet Explorer 9.
|
|
145
|
+
*
|
|
146
|
+
* <b>Note:</b> Keep in mind that the various operating systems for mobile devices
|
|
147
|
+
* can react differently to the property so that fewer upload functions may be
|
|
148
|
+
* available in some cases.
|
|
149
|
+
*/
|
|
150
|
+
multiple : {type : "boolean", group : "Behavior", defaultValue : false},
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A file size limit in megabytes which prevents the upload if at least one file exceeds it.
|
|
154
|
+
*
|
|
155
|
+
* This property is not supported by Internet Explorer 9.
|
|
156
|
+
*/
|
|
157
|
+
maximumFileSize : {type : "float", group : "Data", defaultValue : null},
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The chosen files will be checked against an array of MIME types defined in this property.
|
|
161
|
+
*
|
|
162
|
+
* If at least one file does not fit the MIME type restriction, the upload is prevented.
|
|
163
|
+
*
|
|
164
|
+
* <b>Note:</b> This property is not supported by Internet Explorer.
|
|
165
|
+
* It is only reliable for common file types like images, audio, video, plain text and HTML documents.
|
|
166
|
+
* File types that are not recognized by the browser result in <code>file.type</code> to be returned
|
|
167
|
+
* as an empty string. In this case the verification could not be performed.
|
|
168
|
+
* The file upload is not prevented and the validation based on file type is left to the receiving backend side.
|
|
169
|
+
*
|
|
170
|
+
*
|
|
171
|
+
* Example: <code>["image/png", "image/jpeg"]</code>.
|
|
172
|
+
*/
|
|
173
|
+
mimeType : {type : "string[]", group : "Data", defaultValue : null},
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* If set to "true", the request will be sent as XHR request instead of a form submit.
|
|
177
|
+
*
|
|
178
|
+
* This property is not supported by Internet Explorer 9.
|
|
179
|
+
*/
|
|
180
|
+
sendXHR : {type : "boolean", group : "Behavior", defaultValue : false},
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Chosen HTTP request method for file upload.
|
|
184
|
+
* @since 1.81.0
|
|
185
|
+
*
|
|
186
|
+
*/
|
|
187
|
+
httpRequestMethod : {type: "sap.ui.commons.FileUploaderHttpRequestMethod", group : "Behavior", defaultValue : HttpRequestMethod.Post},
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Placeholder for the text field.
|
|
191
|
+
*/
|
|
192
|
+
placeholder : {type : "string", group : "Appearance", defaultValue : null},
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Style of the button.
|
|
196
|
+
*
|
|
197
|
+
* Values "Transparent, "Accept", "Reject", or "Emphasized" are allowed.
|
|
198
|
+
*/
|
|
199
|
+
style : {type : "string", group : "Appearance", defaultValue : null},
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* If set to "true", the <code>FileUploader</code> will be rendered as Button only,
|
|
203
|
+
* without showing the input field.
|
|
204
|
+
*/
|
|
205
|
+
buttonOnly : {type : "boolean", group : "Appearance", defaultValue : false},
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* If set to "false", the request will be sent as file only request instead of a multipart/form-data request.
|
|
209
|
+
*
|
|
210
|
+
* Only one file could be uploaded using this type of request. Required for sending such a request is
|
|
211
|
+
* to set the property <code>sendXHR</code> to "true". This property is not supported by Internet Explorer 9.
|
|
212
|
+
*/
|
|
213
|
+
useMultipart : {type : "boolean", group : "Behavior", defaultValue : true},
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The maximum length of a filename which the <code>FileUploader</code> will accept.
|
|
217
|
+
*
|
|
218
|
+
* If the maximum filename length is exceeded, the corresponding event <code>filenameLengthExceed</code> is fired.
|
|
219
|
+
* @since 1.24.0
|
|
220
|
+
*/
|
|
221
|
+
maximumFilenameLength : {type : "int", group : "Data", defaultValue : null},
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Visualizes warnings or errors related to the text field.
|
|
225
|
+
*
|
|
226
|
+
* Possible values: Warning, Error, Success, None.
|
|
227
|
+
* @since 1.24.0
|
|
228
|
+
*/
|
|
229
|
+
valueState : {type : "sap.ui.core.ValueState", group : "Data", defaultValue : ValueState.None},
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Custom text for the value state message pop-up.
|
|
233
|
+
*
|
|
234
|
+
* <b>Note:</b> If not specified, a default text, based on the value state type, will be used instead.
|
|
235
|
+
* @since 1.52
|
|
236
|
+
*/
|
|
237
|
+
valueStateText : {type : "string", group : "Misc", defaultValue : null},
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Icon to be displayed as graphical element within the button.
|
|
241
|
+
*
|
|
242
|
+
* This can be a URI to an image or an icon font URI.
|
|
243
|
+
* @since 1.26.0
|
|
244
|
+
*/
|
|
245
|
+
icon : {type : "sap.ui.core.URI", group : "Appearance", defaultValue : ''},
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Icon to be displayed as graphical element within the button when it is hovered (only if also a base icon was specified).
|
|
249
|
+
*
|
|
250
|
+
* If not specified, the base icon is used. If an icon font icon is used, this property is ignored.
|
|
251
|
+
* @since 1.26.0
|
|
252
|
+
*/
|
|
253
|
+
iconHovered : {type : "sap.ui.core.URI", group : "Appearance", defaultValue : ''},
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Icon to be displayed as graphical element within the button when it is selected (only if also a base icon was specified).
|
|
257
|
+
*
|
|
258
|
+
* If not specified, the base or hovered icon is used. If an icon font icon is used, this property is ignored.
|
|
259
|
+
* @since 1.26.0
|
|
260
|
+
*/
|
|
261
|
+
iconSelected : {type : "sap.ui.core.URI", group : "Appearance", defaultValue : ''},
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* If set to true (default), the display sequence is 1. icon 2. control text.
|
|
265
|
+
* @since 1.26.0
|
|
266
|
+
*/
|
|
267
|
+
iconFirst : {type : "boolean", group : "Appearance", defaultValue : true},
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* If set to true, the button is displayed without any text.
|
|
271
|
+
* @since 1.26.0
|
|
272
|
+
*/
|
|
273
|
+
iconOnly : {type : "boolean", group : "Appearance", defaultValue : false},
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Allows users to upload all files from a given directory and its corresponding subdirectories.
|
|
277
|
+
* @since 1.105.0
|
|
278
|
+
*
|
|
279
|
+
* <b>Note:</b> This feature is supported on all WebKit-based browsers as well as Microsoft Edge and Firefox after version 50.
|
|
280
|
+
* <b>Note:</b> Multiple directory selection is not supported.
|
|
281
|
+
*/
|
|
282
|
+
directory : {type : "boolean", group : "Behavior", defaultValue : false}
|
|
283
|
+
},
|
|
284
|
+
aggregations : {
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* The parameters for the <code>FileUploader</code> which are rendered as a hidden input field.
|
|
288
|
+
* @since 1.12.2
|
|
289
|
+
*/
|
|
290
|
+
parameters : {type : "sap.ui.commons.FileUploaderParameter", multiple : true, singularName : "parameter"},
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* The header parameters for the <code>FileUploader</code> which are only submitted with XHR requests.
|
|
294
|
+
* Header parameters are not supported by Internet Explorer 9.
|
|
295
|
+
*/
|
|
296
|
+
headerParameters : {type : "sap.ui.commons.FileUploaderParameter", multiple : true, singularName : "headerParameter"},
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Settings for the <code>XMLHttpRequest</code> object.
|
|
300
|
+
* <b>Note:</b> This aggregation is only used when the <code>sendXHR</code> property is set to <code>true</code>.
|
|
301
|
+
* @since 1.52
|
|
302
|
+
*/
|
|
303
|
+
xhrSettings : {type : "sap.ui.commons.FileUploaderXHRSettings", multiple : false}
|
|
304
|
+
},
|
|
305
|
+
associations : {
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Association to controls / IDs which describe this control (see WAI-ARIA attribute <code>aria-describedby</code>).
|
|
309
|
+
*/
|
|
310
|
+
ariaDescribedBy: {type: "sap.ui.core.Control", multiple: true, singularName: "ariaDescribedBy"},
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Association to controls / IDs which label this control (see WAI-ARIA attribute <code>aria-labelledby</code>).
|
|
314
|
+
*/
|
|
315
|
+
ariaLabelledBy: {type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy"}
|
|
316
|
+
},
|
|
317
|
+
events : {
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Event is fired when the value of the file path has been changed.
|
|
321
|
+
*
|
|
322
|
+
* <b>Note:</b> Keep in mind that because of the HTML input element of type file, the
|
|
323
|
+
* event is also fired in Chrome browser when the Cancel button of the
|
|
324
|
+
* uploads window is pressed.
|
|
325
|
+
*/
|
|
326
|
+
change : {
|
|
327
|
+
parameters : {
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* New file path value.
|
|
331
|
+
*/
|
|
332
|
+
newValue : {type : "string"},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Files.
|
|
336
|
+
*/
|
|
337
|
+
files : {type : "object[]"}
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Event is fired as soon as the upload request is completed (either successful or unsuccessful).
|
|
343
|
+
*
|
|
344
|
+
* To see if the upload request was successful, check the <code>status</code> parameter for a value 2xx.
|
|
345
|
+
* The actual progress of the upload can be monitored by listening to the <code>uploadProgress</code> event.
|
|
346
|
+
* However, this covers only the client side of the upload process and does not give any success status
|
|
347
|
+
* from the server.
|
|
348
|
+
*/
|
|
349
|
+
uploadComplete : {
|
|
350
|
+
parameters : {
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* The name of a file to be uploaded.
|
|
354
|
+
*/
|
|
355
|
+
fileName : {type : "string"},
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Response message which comes from the server.
|
|
359
|
+
*
|
|
360
|
+
* On the server side this response has to be put within the "body" tags of the response
|
|
361
|
+
* document of the iFrame. It can consist of a return code and an optional message. This does not
|
|
362
|
+
* work in cross-domain scenarios.
|
|
363
|
+
*/
|
|
364
|
+
response : {type : "string"},
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* ReadyState of the XHR request.
|
|
368
|
+
*
|
|
369
|
+
* Required for receiving a <code>readyStateXHR</code> is to set the property <code>sendXHR</code>
|
|
370
|
+
* to true. This property is not supported by Internet Explorer 9.
|
|
371
|
+
*/
|
|
372
|
+
readyStateXHR : {type : "string"},
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Status of the XHR request.
|
|
376
|
+
*
|
|
377
|
+
* Required for receiving a <code>status</code> is to set the property <code>sendXHR</code> to true.
|
|
378
|
+
* This property is not supported by Internet Explorer 9.
|
|
379
|
+
*/
|
|
380
|
+
status : {type : "int"},
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Http-Response which comes from the server.
|
|
384
|
+
*
|
|
385
|
+
* Required for receiving <code>responseRaw</code> is to set the property <code>sendXHR</code> to true.
|
|
386
|
+
*
|
|
387
|
+
* This property is not supported by Internet Explorer 9.
|
|
388
|
+
*/
|
|
389
|
+
responseRaw : {type : "string"},
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Http-Response-Headers which come from the server.
|
|
393
|
+
*
|
|
394
|
+
* Provided as a JSON-map, i.e. each header-field is reflected by a property in the <code>headers</code>
|
|
395
|
+
* object, with the property value reflecting the header-field's content.
|
|
396
|
+
*
|
|
397
|
+
* Required for receiving <code>headers</code> is to set the property <code>sendXHR</code> to true.
|
|
398
|
+
* This property is not supported by Internet Explorer 9.
|
|
399
|
+
*/
|
|
400
|
+
headers : {type : "object"},
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Http-Request-Headers.
|
|
404
|
+
*
|
|
405
|
+
* Required for receiving <code>requestHeaders</code> is to set the property <code>sendXHR</code> to true.
|
|
406
|
+
* This property is not supported by Internet Explorer 9.
|
|
407
|
+
*/
|
|
408
|
+
requestHeaders : {type : "object[]"}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Event is fired when the type of a file does not match the <code>mimeType</code> or <code>fileType</code> property.
|
|
414
|
+
*/
|
|
415
|
+
typeMissmatch : {
|
|
416
|
+
parameters : {
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* The name of a file to be uploaded.
|
|
420
|
+
*/
|
|
421
|
+
fileName : {type : "string"},
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* The file ending of a file to be uploaded.
|
|
425
|
+
*/
|
|
426
|
+
fileType : {type : "string"},
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* The MIME type of a file to be uploaded.
|
|
430
|
+
*/
|
|
431
|
+
mimeType : {type : "string"}
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Event is fired when the size of a file is above the <code>maximumFileSize</code> property.
|
|
437
|
+
* This event is not supported by Internet Explorer 9 (same restriction as for the property
|
|
438
|
+
* <code>maximumFileSize</code>).
|
|
439
|
+
*/
|
|
440
|
+
fileSizeExceed : {
|
|
441
|
+
parameters : {
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* The name of a file to be uploaded.
|
|
445
|
+
*/
|
|
446
|
+
fileName : {type : "string"},
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* The size in MB of a file to be uploaded.
|
|
450
|
+
*/
|
|
451
|
+
fileSize : {type : "string"}
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Event is fired when the size of the file is 0
|
|
457
|
+
*/
|
|
458
|
+
fileEmpty : {
|
|
459
|
+
parameters : {
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* The name of the file to be uploaded.
|
|
463
|
+
*/
|
|
464
|
+
fileName: {type : "string"}
|
|
465
|
+
}
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Event is fired when the file is allowed for upload on client side.
|
|
470
|
+
*/
|
|
471
|
+
fileAllowed : {},
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Event is fired after the upload has started and before the upload is completed.
|
|
475
|
+
*
|
|
476
|
+
* It contains progress information related to the running upload. Depending on file size, band width
|
|
477
|
+
* and used browser the event is fired once or multiple times.
|
|
478
|
+
*
|
|
479
|
+
* This event is only supported with property <code>sendXHR</code> set to true, i.e. the event is not
|
|
480
|
+
* supported in Internet Explorer 9.
|
|
481
|
+
*
|
|
482
|
+
* @since 1.24.0
|
|
483
|
+
*/
|
|
484
|
+
uploadProgress : {
|
|
485
|
+
parameters : {
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Indicates whether or not the relative upload progress can be calculated out of loaded and total.
|
|
489
|
+
*/
|
|
490
|
+
lengthComputable : {type : "boolean"},
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* The number of bytes of the file which have been uploaded by the time the event was fired.
|
|
494
|
+
*/
|
|
495
|
+
loaded : {type : "float"},
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* The total size of the file to be uploaded in bytes.
|
|
499
|
+
*/
|
|
500
|
+
total : {type : "float"},
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* The name of a file to be uploaded.
|
|
504
|
+
*/
|
|
505
|
+
fileName : {type : "string"},
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Http-Request-Headers.
|
|
509
|
+
*
|
|
510
|
+
* Required for receiving <code>requestHeaders</code> is to set the property <code>sendXHR</code> to true.
|
|
511
|
+
* This property is not supported by Internet Explorer 9.
|
|
512
|
+
*/
|
|
513
|
+
requestHeaders : {type : "object[]"}
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Event is fired after the current upload has been aborted.
|
|
519
|
+
*
|
|
520
|
+
* This event is only supported with property <code>sendXHR</code> set to true, i.e. the event is not supported
|
|
521
|
+
* in Internet Explorer 9.
|
|
522
|
+
* @since 1.24.0
|
|
523
|
+
*/
|
|
524
|
+
uploadAborted : {
|
|
525
|
+
parameters : {
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* The name of a file to be uploaded.
|
|
529
|
+
*/
|
|
530
|
+
fileName : {type : "string"},
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Http-Request-Headers.
|
|
534
|
+
*
|
|
535
|
+
* Required for receiving <code>requestHeader</code> is to set the property <code>sendXHR</code> to true.
|
|
536
|
+
* This property is not supported by Internet Explorer 9.
|
|
537
|
+
*/
|
|
538
|
+
requestHeaders : {type : "object[]"}
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Event is fired, if the filename of a chosen file is longer than the value specified with the
|
|
544
|
+
* <code>maximumFilenameLength</code> property.
|
|
545
|
+
* @since 1.24.0
|
|
546
|
+
*/
|
|
547
|
+
filenameLengthExceed : {
|
|
548
|
+
parameters : {
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* The filename, which is longer than specified by the value of the property <code>maximumFilenameLength</code>.
|
|
552
|
+
*/
|
|
553
|
+
fileName : {type : "string"}
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Event is fired before an upload is started.
|
|
559
|
+
* @since 1.30.0
|
|
560
|
+
*/
|
|
561
|
+
uploadStart : {
|
|
562
|
+
parameters : {
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* The name of a file to be uploaded.
|
|
566
|
+
*/
|
|
567
|
+
fileName : {type : "string"},
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Http-Request-Headers.
|
|
571
|
+
*
|
|
572
|
+
* Required for receiving <code>requestHeaders</code> is to set the property <code>sendXHR</code>
|
|
573
|
+
* to true. This property is not supported by Internet Explorer 9.
|
|
574
|
+
*/
|
|
575
|
+
requestHeaders : {type : "object[]"}
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
/**
|
|
579
|
+
* Fired before select file dialog opens.
|
|
580
|
+
* @since 1.102.0
|
|
581
|
+
*/
|
|
582
|
+
beforeDialogOpen : {},
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Fired after select file dialog closes.
|
|
586
|
+
* @since 1.102.0
|
|
587
|
+
*/
|
|
588
|
+
afterDialogClose : {}
|
|
589
|
+
}
|
|
590
|
+
}, renderer: FileUploaderRenderer});
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Initializes the control.
|
|
594
|
+
* It is called from the constructor.
|
|
595
|
+
* @private
|
|
596
|
+
*/
|
|
597
|
+
FileUploader.prototype.init = function(){
|
|
598
|
+
var that = this;
|
|
599
|
+
// load the respective UI-Elements from the FileUploaderHelper
|
|
600
|
+
this.oFilePath = this._createTextField(this.getId() + "-fu_input").addEventDelegate({
|
|
601
|
+
onAfterRendering: function () {
|
|
602
|
+
if (that.getWidth()) {
|
|
603
|
+
that._resizeDomElements();
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
this.oBrowse = this._createButton(this.getId() + "-fu_button");
|
|
608
|
+
this.oFilePath.setParent(this);
|
|
609
|
+
this.oBrowse.setParent(this);
|
|
610
|
+
|
|
611
|
+
this.oFileUpload = null;
|
|
612
|
+
|
|
613
|
+
if (ControlBehavior.isAccessibilityEnabled()) {
|
|
614
|
+
if (!FileUploader.prototype._sAccText) {
|
|
615
|
+
var rb = Library.getResourceBundleFor("sap.ui.commons");
|
|
616
|
+
FileUploader.prototype._sAccText = rb.getText("FILEUPLOAD_ACC");
|
|
617
|
+
}
|
|
618
|
+
if (this.oBrowse.addAriaDescribedBy) {
|
|
619
|
+
this.oBrowse.addAriaDescribedBy(this.getId() + "-AccDescr");
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (this.oFilePath) {
|
|
623
|
+
this.oFilePath.addAriaLabelledBy(InvisibleText.getStaticId("sap.ui.commons", "FILEUPLOAD_FILENAME"));
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
this._submitAfterRendering = false;
|
|
627
|
+
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
FileUploader.prototype.setIcon = function(sIcon) {
|
|
631
|
+
this.oBrowse.setIcon(sIcon);
|
|
632
|
+
this.setProperty("icon", sIcon, false);
|
|
633
|
+
return this;
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
FileUploader.prototype.setIconHovered = function(sIconHovered) {
|
|
637
|
+
this.setProperty("iconHovered", sIconHovered, false);
|
|
638
|
+
if (this.oBrowse.setIconHovered) {
|
|
639
|
+
this.oBrowse.setIconHovered(sIconHovered);
|
|
640
|
+
}
|
|
641
|
+
return this;
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
FileUploader.prototype.setIconSelected = function(sIconSelected) {
|
|
645
|
+
this.setProperty("iconSelected", sIconSelected, false);
|
|
646
|
+
if (this.oBrowse.setIconSelected) {
|
|
647
|
+
this.oBrowse.setIconSelected(sIconSelected);
|
|
648
|
+
} else {
|
|
649
|
+
this.oBrowse.setActiveIcon(sIconSelected);
|
|
650
|
+
}
|
|
651
|
+
return this;
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
FileUploader.prototype.setIconFirst = function(bIconFirst) {
|
|
655
|
+
this.oBrowse.setIconFirst(bIconFirst);
|
|
656
|
+
this.setProperty("iconFirst", bIconFirst, false);
|
|
657
|
+
return this;
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Ensures that FileUploader's internal button will have a reference back to the labels, by which
|
|
662
|
+
* the FileUploader is labelled
|
|
663
|
+
*
|
|
664
|
+
* @returns {this} Reference to <code>this</code> for method chaining
|
|
665
|
+
* @private
|
|
666
|
+
*/
|
|
667
|
+
FileUploader.prototype._ensureBackwardsReference = function () {
|
|
668
|
+
var oInternalButton = this.oBrowse,
|
|
669
|
+
aInternalButtonAriaLabelledBy = oInternalButton.getAriaLabelledBy(),
|
|
670
|
+
aReferencingLabels = LabelEnablement.getReferencingLabels(this);
|
|
671
|
+
|
|
672
|
+
if (aInternalButtonAriaLabelledBy) {
|
|
673
|
+
aReferencingLabels.forEach(function (sLabelId) {
|
|
674
|
+
if (aInternalButtonAriaLabelledBy.indexOf(sLabelId) === -1) {
|
|
675
|
+
oInternalButton.addAriaLabelledBy(sLabelId);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
return this;
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
FileUploader.prototype.setName = function (sName) {
|
|
684
|
+
this.setProperty("name", sName, false);
|
|
685
|
+
this._rerenderInputField();
|
|
686
|
+
return this;
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
FileUploader.prototype.setFileType = function(vTypes) {
|
|
690
|
+
// Compatibility issue: converting the given types to an array in case it is a string
|
|
691
|
+
var aTypes = this._convertTypesToArray(vTypes);
|
|
692
|
+
this.setProperty("fileType", aTypes, false);
|
|
693
|
+
this._rerenderInputField();
|
|
694
|
+
return this;
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
FileUploader.prototype.setMimeType = function(vTypes) {
|
|
698
|
+
// Compatibility issue: converting the given types to an array in case it is a string
|
|
699
|
+
var aTypes = this._convertTypesToArray(vTypes);
|
|
700
|
+
this.setProperty("mimeType", aTypes, false);
|
|
701
|
+
this._rerenderInputField();
|
|
702
|
+
return this;
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
FileUploader.prototype.setMultiple = function(bMultiple) {
|
|
706
|
+
this.setProperty("multiple", bMultiple, false);
|
|
707
|
+
this._rerenderInputField();
|
|
708
|
+
return this;
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
FileUploader.prototype.setDirectory = function(bDirectory) {
|
|
712
|
+
this.setProperty("directory", bDirectory, false);
|
|
713
|
+
this._rerenderInputField();
|
|
714
|
+
return this;
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
FileUploader.prototype._rerenderInputField = function() {
|
|
718
|
+
if (this.oFileUpload) {
|
|
719
|
+
var aFiles = this.oFileUpload.files;
|
|
720
|
+
this._clearInputField();
|
|
721
|
+
this._prepareFileUpload();
|
|
722
|
+
|
|
723
|
+
// Register change event listener for the new input field
|
|
724
|
+
jQuery(this.oFileUpload).on("change", this.handlechange.bind(this));
|
|
725
|
+
// Reattach files to the input field if already selected
|
|
726
|
+
/*eslint strict: [2, "never"]*/
|
|
727
|
+
this.oFileUpload.files = aFiles;
|
|
728
|
+
this._cacheDOMEls();
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
FileUploader.prototype.setTooltip = function(oTooltip) {
|
|
733
|
+
var sTooltip;
|
|
734
|
+
|
|
735
|
+
Control.prototype.setTooltip.call(this, oTooltip);
|
|
736
|
+
|
|
737
|
+
if (this.oFileUpload) {
|
|
738
|
+
sTooltip = this.getTooltip_AsString();
|
|
739
|
+
|
|
740
|
+
if (sTooltip) {
|
|
741
|
+
this.oFileUpload.setAttribute("title", sTooltip);
|
|
742
|
+
} else {
|
|
743
|
+
this.oFileUpload.setAttribute("title", this.getValue() ? this.getValue() : this._getNoFileChosenText());
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
return this;
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
FileUploader.prototype.addAriaLabelledBy = function(sID) {
|
|
750
|
+
this.addAssociation("ariaLabelledBy", sID);
|
|
751
|
+
this.oBrowse.addAriaLabelledBy(sID);
|
|
752
|
+
|
|
753
|
+
return this;
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
FileUploader.prototype.removeAriaLabelledBy = function(sID) {
|
|
757
|
+
var sLabelId = this.removeAssociation("ariaLabelledBy", sID);
|
|
758
|
+
if (!sLabelId) {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
this.oBrowse.removeAriaLabelledBy(sLabelId);
|
|
763
|
+
|
|
764
|
+
return sLabelId;
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
FileUploader.prototype.removeAllAriaLabelledBy = function() {
|
|
768
|
+
var aLabelIds = this.removeAllAssociation("ariaLabelledBy"),
|
|
769
|
+
aButtonLabels = this.oBrowse.getAriaLabelledBy();
|
|
770
|
+
|
|
771
|
+
// We make sure to leave any sap.m.Label in the button's ariaLabelledBy
|
|
772
|
+
aLabelIds.forEach(function(sLabelId) {
|
|
773
|
+
if (aButtonLabels.indexOf(sLabelId) >= 0) {
|
|
774
|
+
this.oBrowse.removeAriaLabelledBy(sLabelId);
|
|
775
|
+
}
|
|
776
|
+
}.bind(this));
|
|
777
|
+
|
|
778
|
+
return aLabelIds;
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
FileUploader.prototype.addAriaDescribedBy = function(sID) {
|
|
782
|
+
this.addAssociation("ariaDescribedBy", sID);
|
|
783
|
+
this.oBrowse.addAriaDescribedBy(sID);
|
|
784
|
+
|
|
785
|
+
return this;
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
FileUploader.prototype.removeAriaDescribedBy = function(sID) {
|
|
789
|
+
var sDescriptionId = this.removeAssociation("ariaDescribedBy", sID);
|
|
790
|
+
if (!sDescriptionId) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
this.oBrowse.removeAriaDescribedBy(sDescriptionId);
|
|
795
|
+
|
|
796
|
+
return sDescriptionId;
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
FileUploader.prototype.removeAllAriaDescribedBy = function() {
|
|
800
|
+
var aDescriptionIds = this.removeAllAssociation("ariaDescribedBy"),
|
|
801
|
+
aButtonDescriptionIds = this.oBrowse.getAriaDescribedBy();
|
|
802
|
+
|
|
803
|
+
// Keep the default accessibility description in the -AccDescr element
|
|
804
|
+
aDescriptionIds.forEach(function(sLabelId) {
|
|
805
|
+
if (aButtonDescriptionIds.indexOf(sLabelId) >= 0) {
|
|
806
|
+
this.oBrowse.removeAriaDescribedBy(sLabelId);
|
|
807
|
+
}
|
|
808
|
+
}.bind(this));
|
|
809
|
+
|
|
810
|
+
return aDescriptionIds;
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
FileUploader.prototype._createTextField = function(sId) {
|
|
815
|
+
var oTextField = new TextField(sId);
|
|
816
|
+
return oTextField;
|
|
817
|
+
};
|
|
818
|
+
FileUploader.prototype._setTextFieldContent = function(oTextField, sWidth){
|
|
819
|
+
oTextField.setWidth(sWidth);
|
|
820
|
+
};
|
|
821
|
+
FileUploader.prototype._createButton = function(sId){
|
|
822
|
+
var oButton = new Button(sId);
|
|
823
|
+
return oButton;
|
|
824
|
+
};
|
|
825
|
+
FileUploader.prototype._addFormClass = function(){ return "sapUiCFUM"; };
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
/*
|
|
829
|
+
* Generates the text, which would be placed as an accessibility description,
|
|
830
|
+
* based on the current FileUploader's placeholder, value and tooltip.
|
|
831
|
+
*/
|
|
832
|
+
FileUploader.prototype._generateAccDescriptionText = function () {
|
|
833
|
+
var sTooltip = this.getTooltip_AsString(),
|
|
834
|
+
sPlaceholder = this.getPlaceholder(),
|
|
835
|
+
sValue = this.getValue(),
|
|
836
|
+
bIsRequired = LabelEnablement.isRequired(this),
|
|
837
|
+
sAccDescription = "";
|
|
838
|
+
|
|
839
|
+
if (bIsRequired) {
|
|
840
|
+
sAccDescription += Library.getResourceBundleFor("sap.ui.commons").getText("FILEUPLOAD_REQUIRED") + " ";
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
if (sTooltip) {
|
|
844
|
+
sAccDescription += sTooltip + " ";
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (sValue) {
|
|
848
|
+
sAccDescription += sValue + " ";
|
|
849
|
+
} else if (sPlaceholder) {
|
|
850
|
+
sAccDescription += sPlaceholder + " ";
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
sAccDescription += this._sAccText;
|
|
854
|
+
|
|
855
|
+
return sAccDescription;
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Helper to ensure, that the types (file or mime) are inside an array.
|
|
861
|
+
* The FUP also accepts comma-separated strings for its fileType and mimeType property.
|
|
862
|
+
* @private
|
|
863
|
+
*/
|
|
864
|
+
FileUploader.prototype._convertTypesToArray = function (vTypes) {
|
|
865
|
+
if (typeof vTypes === "string") {
|
|
866
|
+
if (vTypes === "") {
|
|
867
|
+
return [];
|
|
868
|
+
} else {
|
|
869
|
+
return vTypes.split(",").map(function (sType) {
|
|
870
|
+
return sType.trim();
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
return vTypes;
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Terminates the control when it has been destroyed.
|
|
879
|
+
* @private
|
|
880
|
+
*/
|
|
881
|
+
FileUploader.prototype.exit = function(){
|
|
882
|
+
|
|
883
|
+
// destroy the nested controls
|
|
884
|
+
this.oFilePath.destroy();
|
|
885
|
+
this.oBrowse.destroy();
|
|
886
|
+
|
|
887
|
+
// remove the IFRAME
|
|
888
|
+
if (this.oIFrameRef) {
|
|
889
|
+
jQuery(this.oIFrameRef).off();
|
|
890
|
+
StaticArea.getDomRef().removeChild(this.oIFrameRef);
|
|
891
|
+
this.oIFrameRef = null;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
if (this.oFileUpload) {
|
|
895
|
+
this._clearInputField();
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
if (this.FUEl) {
|
|
899
|
+
this.FUEl = null;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
if (this.FUDataEl) {
|
|
903
|
+
this.FUDataEl = null;
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
FileUploader.prototype._clearInputField = function() {
|
|
908
|
+
jQuery(this.oFileUpload).off();
|
|
909
|
+
this.oFileUpload.parentElement.removeChild(this.oFileUpload);
|
|
910
|
+
this.oFileUpload = null;
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Clean up event listeners before rendering
|
|
915
|
+
* @private
|
|
916
|
+
*/
|
|
917
|
+
FileUploader.prototype.onBeforeRendering = function() {
|
|
918
|
+
// store the file uploader outside in the static area
|
|
919
|
+
var oStaticArea = StaticArea.getDomRef();
|
|
920
|
+
jQuery(this.oFileUpload).appendTo(oStaticArea);
|
|
921
|
+
|
|
922
|
+
if (!this.getName()) {
|
|
923
|
+
Log.warning("Name property is not set. It would be used instead to identify the control on the server.", this);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// unbind the custom event handlers
|
|
927
|
+
jQuery(this.oFileUpload).off();
|
|
928
|
+
|
|
929
|
+
if (this.getIconOnly() && this.getButtonOnly()) {
|
|
930
|
+
this.oBrowse.setText("");
|
|
931
|
+
this.oBrowse.setTooltip(this.getTooltip_AsString() || this.getBrowseText());
|
|
932
|
+
} else if (this.getIconOnly()) {
|
|
933
|
+
this.oBrowse.setText("");
|
|
934
|
+
this.oBrowse.setTooltip(this.getBrowseText());
|
|
935
|
+
} else {
|
|
936
|
+
this.oBrowse.setText(this.getButtonText() || this.getBrowseText());
|
|
937
|
+
this.oBrowse.setTooltip("");
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
this.oFilePath.setPlaceholder(this.getPlaceholder());
|
|
941
|
+
};
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* Prepare the upload processing, establish the change handler for the
|
|
945
|
+
* pure html input object.
|
|
946
|
+
* @private
|
|
947
|
+
*/
|
|
948
|
+
FileUploader.prototype.onAfterRendering = function() {
|
|
949
|
+
|
|
950
|
+
// prepare the file upload control and the upload iframe
|
|
951
|
+
this.prepareFileUploadAndIFrame();
|
|
952
|
+
|
|
953
|
+
this._cacheDOMEls();
|
|
954
|
+
this._addLabelFeaturesToBrowse();
|
|
955
|
+
|
|
956
|
+
// event listener registration for change event
|
|
957
|
+
jQuery(this.oFileUpload).on("change", this.handlechange.bind(this));
|
|
958
|
+
|
|
959
|
+
this.oFilePath.$().attr("tabindex", "-1");
|
|
960
|
+
|
|
961
|
+
setTimeout(this._recalculateWidth.bind(this), 0);
|
|
962
|
+
|
|
963
|
+
this.oFilePath.$().find('input').removeAttr("role").attr("aria-live", "polite");
|
|
964
|
+
|
|
965
|
+
if (this._submitAfterRendering) {
|
|
966
|
+
this._submitAndResetValue();
|
|
967
|
+
this._submitAfterRendering = false;
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
FileUploader.prototype._cacheDOMEls = function() {
|
|
973
|
+
this.FUEl = this.getDomRef("fu");
|
|
974
|
+
this.FUDataEl = this.getDomRef("fu_data");
|
|
975
|
+
};
|
|
976
|
+
|
|
977
|
+
FileUploader.prototype.onfocusin = function(oEvent) {
|
|
978
|
+
|
|
979
|
+
if (!this.oFilePath.shouldValueStateMessageBeOpened || this.oFilePath.shouldValueStateMessageBeOpened()) {
|
|
980
|
+
this.openValueStateMessage();
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
FileUploader.prototype.onsapfocusleave = function(oEvent) {
|
|
986
|
+
|
|
987
|
+
if (!oEvent.relatedControlId || !containsOrEquals(this.getDomRef(), Element.getElementById(oEvent.relatedControlId).getFocusDomRef())) {
|
|
988
|
+
this.closeValueStateMessage();
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
FileUploader.prototype._recalculateWidth = function() {
|
|
994
|
+
// calculation of the width of the overlay for the original file upload
|
|
995
|
+
// !Device.browser.msie check: only for non IE browsers since there we need
|
|
996
|
+
// the button in front of the fileuploader
|
|
997
|
+
if (this.getWidth()) {
|
|
998
|
+
if (this.getButtonOnly() && this.oBrowse.getDomRef()) {
|
|
999
|
+
this.oBrowse.getDomRef().style.width = this.getWidth();
|
|
1000
|
+
}
|
|
1001
|
+
// Recalculate the textfield width...
|
|
1002
|
+
this._resizeDomElements();
|
|
1003
|
+
}
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Returns the DOM element that should be focused, when the focus is set onto the control.
|
|
1008
|
+
* @returns {Element} The DOM element that should be focused
|
|
1009
|
+
*/
|
|
1010
|
+
FileUploader.prototype.getFocusDomRef = function() {
|
|
1011
|
+
return this.oBrowse.getDomRef();
|
|
1012
|
+
};
|
|
1013
|
+
|
|
1014
|
+
FileUploader.prototype._resizeDomElements = function() {
|
|
1015
|
+
var sId = this.getId();
|
|
1016
|
+
this._oBrowseDomRef = this.oBrowse.getDomRef();
|
|
1017
|
+
var $b = jQuery(this._oBrowseDomRef);
|
|
1018
|
+
var _buttonWidth = $b.parent().outerWidth(true);
|
|
1019
|
+
this._oFilePathDomRef = this.oFilePath.getDomRef();
|
|
1020
|
+
var oDomRef = this._oFilePathDomRef;
|
|
1021
|
+
var sWidth = this.getWidth();
|
|
1022
|
+
|
|
1023
|
+
if (sWidth.substr( -1) == "%" && oDomRef) {
|
|
1024
|
+
// Special case - if the width is not in px, we only change the top element
|
|
1025
|
+
|
|
1026
|
+
// Resize all elements from the input field up to the control element itself.
|
|
1027
|
+
while (oDomRef.id != sId) {
|
|
1028
|
+
oDomRef.style.width = "100%";
|
|
1029
|
+
oDomRef = oDomRef.parentNode;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
oDomRef.style.width = sWidth;
|
|
1033
|
+
} else if (oDomRef){
|
|
1034
|
+
oDomRef.style.width = sWidth;
|
|
1035
|
+
|
|
1036
|
+
// Now make sure the field including the button has the correct size
|
|
1037
|
+
var $fp = jQuery(this._oFilePathDomRef);
|
|
1038
|
+
var _newWidth = $fp.outerWidth() - _buttonWidth;
|
|
1039
|
+
if (_newWidth < 0) {
|
|
1040
|
+
this.oFilePath.getDomRef().style.width = "0px";
|
|
1041
|
+
if (this.oFileUpload) {
|
|
1042
|
+
this.oFileUpload.style.width = $b.outerWidth(true);
|
|
1043
|
+
}
|
|
1044
|
+
} else {
|
|
1045
|
+
this.oFilePath.getDomRef().style.width = _newWidth + "px";
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
FileUploader.prototype.onresize = function() {
|
|
1051
|
+
this._recalculateWidth();
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
FileUploader.prototype.onThemeChanged = function() {
|
|
1055
|
+
this._recalculateWidth();
|
|
1056
|
+
};
|
|
1057
|
+
|
|
1058
|
+
FileUploader.prototype.setEnabled = function(bEnabled){
|
|
1059
|
+
var $oFileUpload = jQuery(this.oFileUpload);
|
|
1060
|
+
|
|
1061
|
+
this.setProperty("enabled", bEnabled, false);
|
|
1062
|
+
this.oFilePath.setEnabled(bEnabled);
|
|
1063
|
+
this.oBrowse.setEnabled(bEnabled);
|
|
1064
|
+
|
|
1065
|
+
if (this.getEnabled()) {
|
|
1066
|
+
$oFileUpload.removeAttr('disabled');
|
|
1067
|
+
} else {
|
|
1068
|
+
$oFileUpload.attr('disabled', 'disabled');
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
return this;
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
FileUploader.prototype.setValueState = function(sValueState) {
|
|
1075
|
+
|
|
1076
|
+
this.setProperty("valueState", sValueState, false);
|
|
1077
|
+
//as of 1.23.1 oFilePath can be an sap.ui.commons.TextField or an sap.m.Input, which both have a valueState
|
|
1078
|
+
if (this.oFilePath.setValueState) {
|
|
1079
|
+
this.oFilePath.setValueState(sValueState);
|
|
1080
|
+
} else {
|
|
1081
|
+
Log.warning("Setting the valueState property with the combination of libraries used is not supported.", this);
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
var bControlFocused = containsOrEquals(this.getDomRef(), document.activeElement);
|
|
1085
|
+
|
|
1086
|
+
switch (sValueState) {
|
|
1087
|
+
case ValueState.Error:
|
|
1088
|
+
case ValueState.Warning:
|
|
1089
|
+
case ValueState.Success:
|
|
1090
|
+
this.oBrowse.addAssociation("ariaDescribedBy", this.oFilePath.getId() + "-message-sr");
|
|
1091
|
+
if (bControlFocused) {
|
|
1092
|
+
this.openValueStateMessage();
|
|
1093
|
+
}
|
|
1094
|
+
break;
|
|
1095
|
+
default:
|
|
1096
|
+
this.oBrowse.removeAssociation("ariaDescribedBy", this.oFilePath.getId() + "-message-sr");
|
|
1097
|
+
if (bControlFocused) {
|
|
1098
|
+
this.closeValueStateMessage();
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
return this;
|
|
1103
|
+
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
FileUploader.prototype.setValueStateText = function(sValueStateText) {
|
|
1107
|
+
if (this.oFilePath.setValueStateText) {
|
|
1108
|
+
this.oFilePath.setValueStateText(sValueStateText);
|
|
1109
|
+
} else {
|
|
1110
|
+
Log.warning("Setting the valueStateText property with the combination of libraries used is not supported.", this);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
return this.setProperty("valueStateText", sValueStateText, false);
|
|
1114
|
+
};
|
|
1115
|
+
|
|
1116
|
+
FileUploader.prototype.setStyle = function(sStyle) {
|
|
1117
|
+
this.setProperty("style", sStyle, true);
|
|
1118
|
+
if (sStyle) {
|
|
1119
|
+
if (sStyle == "Transparent") {
|
|
1120
|
+
if (this.oBrowse.setLite) {
|
|
1121
|
+
this.oBrowse.setLite(true);
|
|
1122
|
+
} else {
|
|
1123
|
+
this.oBrowse.setType("Transparent");
|
|
1124
|
+
}
|
|
1125
|
+
} else if (this.oBrowse.setType) {
|
|
1126
|
+
this.oBrowse.setType(sStyle);
|
|
1127
|
+
} else {
|
|
1128
|
+
if (sStyle == "Emphasized") {
|
|
1129
|
+
sStyle = "Emph";
|
|
1130
|
+
}
|
|
1131
|
+
this.oBrowse.setStyle(sStyle);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return this;
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
FileUploader.prototype.setValue = function(sValue, bFireEvent, bSupressFocus) {
|
|
1138
|
+
var oldValue = this.getValue();
|
|
1139
|
+
var oFiles;
|
|
1140
|
+
if ((oldValue != sValue) || this.getSameFilenameAllowed()) {
|
|
1141
|
+
// only upload when a valid value is set
|
|
1142
|
+
var bUpload = this.getUploadOnChange() && sValue;
|
|
1143
|
+
// when we do not upload we re-render (cause some browsers don't like
|
|
1144
|
+
// to change the value of file uploader INPUT elements)
|
|
1145
|
+
this.setProperty("value", sValue, bUpload);
|
|
1146
|
+
if (this.oFileUpload && !this.getTooltip_AsString()) {
|
|
1147
|
+
this.oFileUpload.setAttribute("title", sValue ? sValue : this._getNoFileChosenText());
|
|
1148
|
+
}
|
|
1149
|
+
if (this.oFilePath) {
|
|
1150
|
+
this.oFilePath.setValue(sValue);
|
|
1151
|
+
//refocus the Button, except bSupressFocus is set
|
|
1152
|
+
if (this.oBrowse.getDomRef() && !bSupressFocus && containsOrEquals(this.getDomRef(), document.activeElement)) {
|
|
1153
|
+
this.oBrowse.focus();
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
var oForm = this.getDomRef("fu_form"),
|
|
1157
|
+
sapMInnerInput = this.getDomRef("fu_input-inner");
|
|
1158
|
+
//reseting the input fields if setValue("") is called, also for undefined and null
|
|
1159
|
+
if (this.oFileUpload && /* is visible: */ oForm && !sValue) {
|
|
1160
|
+
// some browsers do not allow to clear the value of the fileuploader control
|
|
1161
|
+
// therefore we utilize the form and reset the values inside this form and
|
|
1162
|
+
// apply the additionalData again afterwards
|
|
1163
|
+
oForm.reset();
|
|
1164
|
+
this.getDomRef("fu_input").value = "";
|
|
1165
|
+
//if the sap.m library is used, we also need to clear the inner input-field of sap.m.Input
|
|
1166
|
+
if (sapMInnerInput) {
|
|
1167
|
+
sapMInnerInput.value = "";
|
|
1168
|
+
}
|
|
1169
|
+
//keep the additional data on the form
|
|
1170
|
+
jQuery(this.FUDataEl).val(this.getAdditionalData());
|
|
1171
|
+
}
|
|
1172
|
+
// only fire event when triggered by user interaction
|
|
1173
|
+
if (bFireEvent) {
|
|
1174
|
+
if (window.File) {
|
|
1175
|
+
oFiles = this.FUEl.files;
|
|
1176
|
+
}
|
|
1177
|
+
if (!this.getSameFilenameAllowed() || (sValue && oldValue != sValue)) {
|
|
1178
|
+
this.fireChange({id:this.getId(), newValue:sValue, files:oFiles});
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
if (bUpload) {
|
|
1182
|
+
this.upload();
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return this;
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
* Clears the content of the <code>FileUploader</code>.
|
|
1191
|
+
*
|
|
1192
|
+
* <b>Note:</b> The attached additional data however is retained.
|
|
1193
|
+
*
|
|
1194
|
+
* @public
|
|
1195
|
+
* @since 1.25.0
|
|
1196
|
+
* @returns {this} Reference to <code>this</code> for method chaining
|
|
1197
|
+
*/
|
|
1198
|
+
FileUploader.prototype.clear = function () {
|
|
1199
|
+
var uploadForm = this.getDomRef("fu_form");
|
|
1200
|
+
if (uploadForm) {
|
|
1201
|
+
uploadForm.reset();
|
|
1202
|
+
} else if (this.oFileUpload) {
|
|
1203
|
+
this.oFileUpload.files = new DataTransfer().files;
|
|
1204
|
+
}
|
|
1205
|
+
//clear the value, don't fire change event, and suppress the refocusing of the file input field
|
|
1206
|
+
return this.setValue("", false, true);
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Programmatically opens the file picker dialog.
|
|
1211
|
+
*
|
|
1212
|
+
* @since 1.112
|
|
1213
|
+
* @returns {this} Reference to <code>this</code> for method chaining
|
|
1214
|
+
* @private
|
|
1215
|
+
* @ui5-restricted sap.suite.ui.commons.CloudFilePicker
|
|
1216
|
+
*/
|
|
1217
|
+
FileUploader.prototype.openFilePicker = function () {
|
|
1218
|
+
if (this.oFileUpload) {
|
|
1219
|
+
this.oFileUpload.click();
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
return this;
|
|
1223
|
+
};
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Provides a reference to the type "file" input field of the control.
|
|
1227
|
+
*
|
|
1228
|
+
* @since 1.112
|
|
1229
|
+
* @returns {HTMLElement|null} The input type "file" DOM representation.
|
|
1230
|
+
* @private
|
|
1231
|
+
* @ui5-restricted sap.suite.ui.commons.CloudFilePicker
|
|
1232
|
+
*/
|
|
1233
|
+
FileUploader.prototype.getInputReference = function () {
|
|
1234
|
+
return this.oFileUpload;
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
FileUploader.prototype.onmousedown = function(oEvent) {
|
|
1238
|
+
this.oBrowse.onmousedown(oEvent);
|
|
1239
|
+
};
|
|
1240
|
+
|
|
1241
|
+
FileUploader.prototype.onmouseup = function(oEvent) {
|
|
1242
|
+
this.oBrowse.onmouseup(oEvent);
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
FileUploader.prototype.onmouseover = function (oEvent) {
|
|
1246
|
+
jQuery(this.oBrowse.getDomRef()).addClass('sapUiBtnStdHover');
|
|
1247
|
+
this.oBrowse.onmouseover(oEvent);
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1250
|
+
FileUploader.prototype.onmouseout = function (oEvent) {
|
|
1251
|
+
jQuery(this.oBrowse.getDomRef()).removeClass('sapUiBtnStdHover');
|
|
1252
|
+
this.oBrowse.onmouseout(oEvent);
|
|
1253
|
+
};
|
|
1254
|
+
|
|
1255
|
+
FileUploader.prototype.setAdditionalData = function(sAdditionalData) {
|
|
1256
|
+
// set the additional data in the hidden input
|
|
1257
|
+
this.setProperty("additionalData", sAdditionalData, true);
|
|
1258
|
+
var oAdditionalData = this.FUDataEl;
|
|
1259
|
+
if (oAdditionalData) {
|
|
1260
|
+
sAdditionalData = this.getAdditionalData() || "";
|
|
1261
|
+
oAdditionalData.value = sAdditionalData;
|
|
1262
|
+
}
|
|
1263
|
+
return this;
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
FileUploader.prototype.sendFiles = function(aXhr, iIndex) {
|
|
1267
|
+
var that = this;
|
|
1268
|
+
var bAllPosted = true;
|
|
1269
|
+
|
|
1270
|
+
for (var i = 0; i < aXhr.length; i++) {
|
|
1271
|
+
if (!aXhr[i].bPosted) {
|
|
1272
|
+
bAllPosted = false;
|
|
1273
|
+
break;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
if (bAllPosted) {
|
|
1278
|
+
if (this.getSameFilenameAllowed() && this.getUploadOnChange()) {
|
|
1279
|
+
that.setValue("", true);
|
|
1280
|
+
}
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
var oXhr = aXhr[iIndex];
|
|
1285
|
+
var sFilename = oXhr.file.name ? oXhr.file.name : "MultipartFile";
|
|
1286
|
+
var oRequestHeaders = oXhr.requestHeaders;
|
|
1287
|
+
|
|
1288
|
+
var fnProgressListener = function(oProgressEvent) {
|
|
1289
|
+
var oProgressData = {
|
|
1290
|
+
lengthComputable: !!oProgressEvent.lengthComputable,
|
|
1291
|
+
loaded: oProgressEvent.loaded,
|
|
1292
|
+
total: oProgressEvent.total
|
|
1293
|
+
};
|
|
1294
|
+
that.fireUploadProgress({
|
|
1295
|
+
"lengthComputable": oProgressData.lengthComputable,
|
|
1296
|
+
"loaded": oProgressData.loaded,
|
|
1297
|
+
"total": oProgressData.total,
|
|
1298
|
+
"fileName": sFilename,
|
|
1299
|
+
"requestHeaders": oRequestHeaders
|
|
1300
|
+
});
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
oXhr.xhr.upload.addEventListener("progress", fnProgressListener);
|
|
1304
|
+
|
|
1305
|
+
oXhr.xhr.onreadystatechange = function() {
|
|
1306
|
+
|
|
1307
|
+
var sResponse;
|
|
1308
|
+
var sResponseRaw;
|
|
1309
|
+
var mHeaders = {};
|
|
1310
|
+
var sPlainHeader;
|
|
1311
|
+
var aHeaderLines;
|
|
1312
|
+
var iHeaderIdx;
|
|
1313
|
+
var sReadyState;
|
|
1314
|
+
sReadyState = oXhr.xhr.readyState;
|
|
1315
|
+
var iStatus = oXhr.xhr.status;
|
|
1316
|
+
|
|
1317
|
+
if (oXhr.xhr.readyState == 4) {
|
|
1318
|
+
//this check is needed, because (according to the xhr spec) the readyState is set to OPEN (4)
|
|
1319
|
+
//as soon as the xhr is aborted. Only after the progress events are fired, the state is set to UNSENT (0)
|
|
1320
|
+
if (oXhr.xhr.responseXML) {
|
|
1321
|
+
sResponse = oXhr.xhr.responseXML.documentElement.textContent;
|
|
1322
|
+
}
|
|
1323
|
+
sResponseRaw = oXhr.xhr.response;
|
|
1324
|
+
|
|
1325
|
+
//Parse the http-header into a map
|
|
1326
|
+
sPlainHeader = oXhr.xhr.getAllResponseHeaders();
|
|
1327
|
+
if (sPlainHeader) {
|
|
1328
|
+
aHeaderLines = sPlainHeader.split("\u000d\u000a");
|
|
1329
|
+
for (var i = 0; i < aHeaderLines.length; i++) {
|
|
1330
|
+
if (aHeaderLines[i]) {
|
|
1331
|
+
iHeaderIdx = aHeaderLines[i].indexOf("\u003a\u0020");
|
|
1332
|
+
mHeaders[aHeaderLines[i].substring(0, iHeaderIdx)] = aHeaderLines[i].substring(iHeaderIdx + 2);
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
that.fireUploadComplete({
|
|
1337
|
+
"fileName": sFilename,
|
|
1338
|
+
"headers": mHeaders,
|
|
1339
|
+
"response": sResponse,
|
|
1340
|
+
"responseRaw": sResponseRaw,
|
|
1341
|
+
"readyStateXHR": sReadyState,
|
|
1342
|
+
"status": iStatus,
|
|
1343
|
+
"requestHeaders": oRequestHeaders
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
that._bUploading = false;
|
|
1347
|
+
};
|
|
1348
|
+
if (oXhr.xhr.readyState === 0 || oXhr.bPosted) {
|
|
1349
|
+
iIndex++;
|
|
1350
|
+
that.sendFiles(aXhr, iIndex);
|
|
1351
|
+
} else {
|
|
1352
|
+
oXhr.xhr.send(oXhr.file);
|
|
1353
|
+
oXhr.bPosted = true;
|
|
1354
|
+
iIndex++;
|
|
1355
|
+
that.sendFiles(aXhr, iIndex);
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Starts the upload (as defined by uploadUrl).
|
|
1362
|
+
*
|
|
1363
|
+
* @param {boolean} [bPreProcessFiles] Set to <code>true</code> to allow pre-processing of the files before sending the request.
|
|
1364
|
+
* As a result, the <code>upload</code> method becomes asynchronous. See {@link sap.ui.commons.IProcessableBlobs} for more information.
|
|
1365
|
+
* <b>Note:</b> This parameter is only taken into account when <code>sendXHR</code> is set to <code>true</code>.
|
|
1366
|
+
*
|
|
1367
|
+
* @type void
|
|
1368
|
+
* @public
|
|
1369
|
+
*/
|
|
1370
|
+
FileUploader.prototype.upload = function(bPreProcessFiles) {
|
|
1371
|
+
var uploadForm,
|
|
1372
|
+
sActionAttr;
|
|
1373
|
+
|
|
1374
|
+
//supress Upload if the FileUploader is not enabled
|
|
1375
|
+
if (!this.getEnabled()) {
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
uploadForm = this.getDomRef("fu_form");
|
|
1380
|
+
|
|
1381
|
+
try {
|
|
1382
|
+
this._bUploading = true;
|
|
1383
|
+
if (this.getSendXHR() && window.File) {
|
|
1384
|
+
var aFiles = this.FUEl.files;
|
|
1385
|
+
if (bPreProcessFiles) {
|
|
1386
|
+
this._sendProcessedFilesWithXHR(aFiles);
|
|
1387
|
+
} else {
|
|
1388
|
+
this._sendFilesWithXHR(aFiles);
|
|
1389
|
+
}
|
|
1390
|
+
} else if (uploadForm) {
|
|
1391
|
+
// In order to do the submit, the action DOM attribute of the inner form should be accurate.
|
|
1392
|
+
// If there is a change in the passed to the uploadUrl property string, we must ensure that it is
|
|
1393
|
+
// applied in the DOM and the submit is performed after there is new rendering.
|
|
1394
|
+
sActionAttr = uploadForm.getAttribute("action");
|
|
1395
|
+
if (sActionAttr !== this.getUploadUrl()) {
|
|
1396
|
+
this._submitAfterRendering = true;
|
|
1397
|
+
} else {
|
|
1398
|
+
this._submitAndResetValue();
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
} catch (oException) {
|
|
1402
|
+
Log.error("File upload failed:\n" + oException.message);
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
FileUploader.prototype._submitAndResetValue = function() {
|
|
1407
|
+
var uploadForm = this.getDomRef("fu_form");
|
|
1408
|
+
|
|
1409
|
+
uploadForm.submit();
|
|
1410
|
+
this.fireUploadStart();
|
|
1411
|
+
this._resetValueAfterUploadStart();
|
|
1412
|
+
};
|
|
1413
|
+
|
|
1414
|
+
/**
|
|
1415
|
+
* Aborts the currently running upload.
|
|
1416
|
+
*
|
|
1417
|
+
* @param {string} sHeaderParameterName
|
|
1418
|
+
* The name of the parameter within the <code>headerParameters</code> aggregation to be checked.
|
|
1419
|
+
*
|
|
1420
|
+
* <b>Note:</b> aborts the request, sent with a header parameter with the provided name.
|
|
1421
|
+
* The parameter is taken into account if the sHeaderParameterValue parameter is provided too.
|
|
1422
|
+
*
|
|
1423
|
+
* @param {string} sHeaderParameterValue
|
|
1424
|
+
* The value of the parameter within the <code>headerParameters</code> aggregation to be checked.
|
|
1425
|
+
*
|
|
1426
|
+
* <b>Note:</b> aborts the request, sent with a header parameter with the provided value.
|
|
1427
|
+
* The parameter is taken into account if the sHeaderParameterName parameter is provided too.
|
|
1428
|
+
* @public
|
|
1429
|
+
* @since 1.24.0
|
|
1430
|
+
*/
|
|
1431
|
+
FileUploader.prototype.abort = function(sHeaderParameterName, sHeaderParameterValue) {
|
|
1432
|
+
if (!this.getUseMultipart()) {
|
|
1433
|
+
var iStart = this._aXhr.length - 1;
|
|
1434
|
+
for (var i = iStart; i > -1; i--) {
|
|
1435
|
+
if (sHeaderParameterName && sHeaderParameterValue) {
|
|
1436
|
+
for (var j = 0; j < this._aXhr[i].requestHeaders.length; j++) {
|
|
1437
|
+
var sHeader = this._aXhr[i].requestHeaders[j].name;
|
|
1438
|
+
var sValue = this._aXhr[i].requestHeaders[j].value;
|
|
1439
|
+
if (sHeader == sHeaderParameterName && sValue == sHeaderParameterValue) {
|
|
1440
|
+
this._aXhr[i].xhr.abort();
|
|
1441
|
+
this.fireUploadAborted({
|
|
1442
|
+
"fileName": this._aXhr[i].fileName,
|
|
1443
|
+
"requestHeaders": this._aXhr[i].requestHeaders
|
|
1444
|
+
});
|
|
1445
|
+
// Remove aborted entry from internal array.
|
|
1446
|
+
this._aXhr.splice(i, 1);
|
|
1447
|
+
Log.info("File upload aborted.");
|
|
1448
|
+
break;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
} else {
|
|
1452
|
+
this._aXhr[i].xhr.abort();
|
|
1453
|
+
this.fireUploadAborted({
|
|
1454
|
+
"fileName": this._aXhr[i].fileName,
|
|
1455
|
+
"requestHeaders": this._aXhr[i].requestHeaders
|
|
1456
|
+
});
|
|
1457
|
+
// Remove aborted entry from internal array.
|
|
1458
|
+
this._aXhr.splice(i, 1);
|
|
1459
|
+
Log.info("File upload aborted.");
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
} else if (this._uploadXHR && this._uploadXHR.abort) {
|
|
1463
|
+
// fires a progress event 'abort' on the _uploadXHR
|
|
1464
|
+
this._uploadXHR.abort();
|
|
1465
|
+
this.fireUploadAborted({
|
|
1466
|
+
"fileName": null,
|
|
1467
|
+
"requestHeaders": null
|
|
1468
|
+
});
|
|
1469
|
+
Log.info("File upload aborted.");
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
FileUploader.prototype.onclick = function(oEvent) {
|
|
1474
|
+
var bFileInput = oEvent.target.getAttribute("type") === "file";
|
|
1475
|
+
if (bFileInput && this.getSameFilenameAllowed() && this.getEnabled()) {
|
|
1476
|
+
this.setValue("", true);
|
|
1477
|
+
}
|
|
1478
|
+
//refocus the Button, except bSupressFocus is set
|
|
1479
|
+
if (this.oBrowse.getDomRef() && (Device.browser.safari || containsOrEquals(this.getDomRef(), document.activeElement))) {
|
|
1480
|
+
this.oBrowse.focus();
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
if (oEvent.target.getAttribute("type") === "file") {
|
|
1484
|
+
this.fireBeforeDialogOpen();
|
|
1485
|
+
|
|
1486
|
+
document.body.onfocus = function () {
|
|
1487
|
+
this.fireAfterDialogClose();
|
|
1488
|
+
document.body.onfocus = null;
|
|
1489
|
+
}.bind(this);
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
|
|
1493
|
+
//
|
|
1494
|
+
//Event Handling
|
|
1495
|
+
//
|
|
1496
|
+
FileUploader.prototype.onkeydown = function(oEvent) {
|
|
1497
|
+
if (!this.getEnabled()) {
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
if (this.getSameFilenameAllowed() && this.getUploadOnChange()) {
|
|
1501
|
+
this.setValue("", true);
|
|
1502
|
+
}
|
|
1503
|
+
var iKeyCode = oEvent.keyCode;
|
|
1504
|
+
if (iKeyCode === KeyCodes.ENTER) {
|
|
1505
|
+
// consider to always put the focus on the hidden file uploader
|
|
1506
|
+
// and let the fileuploader manage the keyboard interaction
|
|
1507
|
+
if (this.oFileUpload) {
|
|
1508
|
+
this.oFileUpload.click();
|
|
1509
|
+
oEvent.preventDefault();
|
|
1510
|
+
oEvent.stopPropagation();
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
this.oBrowse._bPressedSpace = false;
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1517
|
+
FileUploader.prototype.onkeyup = function(oEvent) {
|
|
1518
|
+
if (!this.getEnabled()) {
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
if (this.getSameFilenameAllowed() && this.getUploadOnChange()) {
|
|
1522
|
+
this.setValue("", true);
|
|
1523
|
+
}
|
|
1524
|
+
var iKeyCode = oEvent.keyCode,
|
|
1525
|
+
eKC = KeyCodes;
|
|
1526
|
+
if (iKeyCode === eKC.DELETE || iKeyCode === eKC.BACKSPACE) {
|
|
1527
|
+
if (this.oFileUpload) {
|
|
1528
|
+
this.setValue("", true);
|
|
1529
|
+
}
|
|
1530
|
+
} else if (iKeyCode === eKC.SPACE) {
|
|
1531
|
+
this.oFileUpload.click();
|
|
1532
|
+
oEvent.preventDefault();
|
|
1533
|
+
oEvent.stopPropagation();
|
|
1534
|
+
} else if (iKeyCode !== eKC.TAB &&
|
|
1535
|
+
iKeyCode !== eKC.SHIFT &&
|
|
1536
|
+
iKeyCode !== eKC.F6 &&
|
|
1537
|
+
iKeyCode !== eKC.PAGE_UP &&
|
|
1538
|
+
iKeyCode !== eKC.PAGE_DOWN &&
|
|
1539
|
+
iKeyCode !== eKC.ESCAPE &&
|
|
1540
|
+
iKeyCode !== eKC.END &&
|
|
1541
|
+
iKeyCode !== eKC.HOME &&
|
|
1542
|
+
iKeyCode !== eKC.ARROW_LEFT &&
|
|
1543
|
+
iKeyCode !== eKC.ARROW_UP &&
|
|
1544
|
+
iKeyCode !== eKC.ARROW_RIGHT &&
|
|
1545
|
+
iKeyCode !== eKC.ARROW_DOWN) {
|
|
1546
|
+
oEvent.preventDefault();
|
|
1547
|
+
oEvent.stopPropagation();
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
this.oBrowse._bPressedSpace = false;
|
|
1551
|
+
};
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Helper function to check if the given filename is longer than the specified 'maximumFilenameLength'.
|
|
1555
|
+
* @param {string} [sFilename] the filename which should be tested
|
|
1556
|
+
* @param {boolean} [bFireEvent] if necessary, this flag triggers that a filenameLengthExceed event is fired
|
|
1557
|
+
* @returns {boolean} whether the filename is too long or not
|
|
1558
|
+
* @private
|
|
1559
|
+
*/
|
|
1560
|
+
FileUploader.prototype._isFilenameTooLong = function (sFilename) {
|
|
1561
|
+
var iMaxFilenameLength = this.getMaximumFilenameLength();
|
|
1562
|
+
if (iMaxFilenameLength !== 0 && sFilename.length > iMaxFilenameLength) {
|
|
1563
|
+
Log.info("The filename of " + sFilename + " (" + sFilename.length + " characters) is longer than the maximum of " + iMaxFilenameLength + " characters.");
|
|
1564
|
+
return true;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
return false;
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
FileUploader.prototype.handlechange = function(oEvent) {
|
|
1571
|
+
if (this.oFileUpload && this.getEnabled()) {
|
|
1572
|
+
var aFileTypes = this.getFileType();
|
|
1573
|
+
|
|
1574
|
+
var sFileString = '';
|
|
1575
|
+
var bWrongType, sName, iIdx, sFileEnding;
|
|
1576
|
+
var uploadForm = this.getDomRef("fu_form");
|
|
1577
|
+
|
|
1578
|
+
if (window.File) {
|
|
1579
|
+
var aFiles = oEvent.target.files;
|
|
1580
|
+
|
|
1581
|
+
if (this._areFilesAllowed(aFiles)) {
|
|
1582
|
+
this.fireFileAllowed();
|
|
1583
|
+
sFileString = this._generateInputValue(aFiles);
|
|
1584
|
+
} else {
|
|
1585
|
+
uploadForm.reset();
|
|
1586
|
+
this.setValue("", true, true);
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
} else if (aFileTypes && aFileTypes.length > 0) {
|
|
1590
|
+
// This else case is executed if the File-API is not supported by the browser (especially IE9).
|
|
1591
|
+
// Check if allowed file types match the chosen file from the oFileUpload IFrame Workaround.
|
|
1592
|
+
bWrongType = true;
|
|
1593
|
+
sName = this.oFileUpload.value || "";
|
|
1594
|
+
iIdx = sName.lastIndexOf(".");
|
|
1595
|
+
sFileEnding = (iIdx === -1) ? "" : sName.substring(iIdx + 1);
|
|
1596
|
+
for (var l = 0; l < aFileTypes.length; l++) {
|
|
1597
|
+
if (sFileEnding == aFileTypes[l]) {
|
|
1598
|
+
bWrongType = false;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
if (bWrongType) {
|
|
1602
|
+
Log.info("File: " + sName + " is of type " + sFileEnding + ". Allowed types are: " + aFileTypes + ".");
|
|
1603
|
+
this.fireTypeMissmatch({
|
|
1604
|
+
fileName:sName,
|
|
1605
|
+
fileType:sFileEnding
|
|
1606
|
+
});
|
|
1607
|
+
uploadForm.reset();
|
|
1608
|
+
this.setValue("", true, true);
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
//check if the filename is too long and fire the corresponding event if necessary
|
|
1612
|
+
if (this._isFilenameTooLong(sName)) {
|
|
1613
|
+
this.fireFilenameLengthExceed({
|
|
1614
|
+
fileName: sName
|
|
1615
|
+
});
|
|
1616
|
+
uploadForm.reset();
|
|
1617
|
+
this.setValue("", true, true);
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
if (sName) {
|
|
1621
|
+
this.fireFileAllowed();
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
// due to new security mechanism modern browsers simply
|
|
1626
|
+
// append a fakepath in front of the filename instead of
|
|
1627
|
+
// returning the filename only - we strip this path now
|
|
1628
|
+
var sValue = this.oFileUpload.value || "";
|
|
1629
|
+
var iIndex = sValue.lastIndexOf("\\");
|
|
1630
|
+
|
|
1631
|
+
if (iIndex >= 0) {
|
|
1632
|
+
sValue = sValue.substring(iIndex + 1);
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
if (this.getMultiple() || this.getDirectory()) {
|
|
1636
|
+
sValue = sFileString;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
//sValue has to be filled to avoid clearing the FilePath by pressing cancel
|
|
1640
|
+
if (sValue || Device.browser.chrome) { // in Chrome the file path has to be cleared as the upload will be avoided
|
|
1641
|
+
this.setValue(sValue, true);
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
|
|
1646
|
+
//
|
|
1647
|
+
// Private
|
|
1648
|
+
//
|
|
1649
|
+
|
|
1650
|
+
/*
|
|
1651
|
+
* Send passed files as argument trough XHR request.
|
|
1652
|
+
* @param {array} [aFiles] list of files from type window.File, this array is returned from input type="file" or from Drag and Drop
|
|
1653
|
+
* @returns this
|
|
1654
|
+
* @private
|
|
1655
|
+
*/
|
|
1656
|
+
FileUploader.prototype._sendFilesWithXHR = function (aFiles) {
|
|
1657
|
+
var iFiles,
|
|
1658
|
+
sHeader,
|
|
1659
|
+
sValue,
|
|
1660
|
+
oXhrEntry,
|
|
1661
|
+
oXHRSettings = this.getXhrSettings();
|
|
1662
|
+
|
|
1663
|
+
if (aFiles.length > 0) {
|
|
1664
|
+
if (this.getUseMultipart()) {
|
|
1665
|
+
//one xhr request for all files
|
|
1666
|
+
iFiles = 1;
|
|
1667
|
+
} else {
|
|
1668
|
+
//several xhr requests for every file
|
|
1669
|
+
iFiles = aFiles.length;
|
|
1670
|
+
}
|
|
1671
|
+
// Save references to already uploading files if a new upload comes between upload and complete or abort
|
|
1672
|
+
this._aXhr = this._aXhr || [];
|
|
1673
|
+
for (var j = 0; j < iFiles; j++) {
|
|
1674
|
+
//keep a reference on the current upload xhr
|
|
1675
|
+
this._uploadXHR = new window.XMLHttpRequest();
|
|
1676
|
+
|
|
1677
|
+
oXhrEntry = {
|
|
1678
|
+
xhr: this._uploadXHR,
|
|
1679
|
+
requestHeaders: []
|
|
1680
|
+
};
|
|
1681
|
+
this._aXhr.push(oXhrEntry);
|
|
1682
|
+
oXhrEntry.xhr.open(this.getHttpRequestMethod(), this.getUploadUrl(), true);
|
|
1683
|
+
if (oXHRSettings) {
|
|
1684
|
+
oXhrEntry.xhr.withCredentials = oXHRSettings.getWithCredentials();
|
|
1685
|
+
}
|
|
1686
|
+
if (this.getHeaderParameters()) {
|
|
1687
|
+
var aHeaderParams = this.getHeaderParameters();
|
|
1688
|
+
for (var i = 0; i < aHeaderParams.length; i++) {
|
|
1689
|
+
sHeader = aHeaderParams[i].getName();
|
|
1690
|
+
sValue = aHeaderParams[i].getValue();
|
|
1691
|
+
oXhrEntry.requestHeaders.push({
|
|
1692
|
+
name: sHeader,
|
|
1693
|
+
value: sValue
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
var sFilename = aFiles[j].name;
|
|
1698
|
+
var aRequestHeaders = oXhrEntry.requestHeaders;
|
|
1699
|
+
oXhrEntry.fileName = sFilename;
|
|
1700
|
+
oXhrEntry.file = aFiles[j];
|
|
1701
|
+
this.fireUploadStart({
|
|
1702
|
+
"fileName": sFilename,
|
|
1703
|
+
"requestHeaders": aRequestHeaders
|
|
1704
|
+
});
|
|
1705
|
+
for (var k = 0; k < aRequestHeaders.length; k++) {
|
|
1706
|
+
// Check if request is still open in case abort() was called.
|
|
1707
|
+
if (oXhrEntry.xhr.readyState === 0) {
|
|
1708
|
+
break;
|
|
1709
|
+
}
|
|
1710
|
+
sHeader = aRequestHeaders[k].name;
|
|
1711
|
+
sValue = aRequestHeaders[k].value;
|
|
1712
|
+
oXhrEntry.xhr.setRequestHeader(sHeader, sValue);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
if (this.getUseMultipart()) {
|
|
1716
|
+
var formData = new window.FormData();
|
|
1717
|
+
var name = this.FUEl.name;
|
|
1718
|
+
for (var l = 0; l < aFiles.length; l++) {
|
|
1719
|
+
this._appendFileToFormData(formData, name, aFiles[l]);
|
|
1720
|
+
}
|
|
1721
|
+
formData.append("_charset_", "UTF-8");
|
|
1722
|
+
var data = this.FUDataEl.name;
|
|
1723
|
+
if (this.getAdditionalData()) {
|
|
1724
|
+
var sData = this.getAdditionalData();
|
|
1725
|
+
formData.append(data, sData);
|
|
1726
|
+
} else {
|
|
1727
|
+
formData.append(data, "");
|
|
1728
|
+
}
|
|
1729
|
+
if (this.getParameters()) {
|
|
1730
|
+
var oParams = this.getParameters();
|
|
1731
|
+
for (var m = 0; m < oParams.length; m++) {
|
|
1732
|
+
var sName = oParams[m].getName();
|
|
1733
|
+
sValue = oParams[m].getValue();
|
|
1734
|
+
formData.append(sName, sValue);
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
oXhrEntry.file = formData;
|
|
1738
|
+
this.sendFiles(this._aXhr, 0);
|
|
1739
|
+
} else {
|
|
1740
|
+
this.sendFiles(this._aXhr, 0);
|
|
1741
|
+
}
|
|
1742
|
+
this._bUploading = false;
|
|
1743
|
+
this._resetValueAfterUploadStart();
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
return this;
|
|
1747
|
+
};
|
|
1748
|
+
|
|
1749
|
+
/**
|
|
1750
|
+
* Append a file to passed FormData object handling special case where there is a Blob or window.File with a name
|
|
1751
|
+
* parameter passed.
|
|
1752
|
+
* @param {object} oFormData receiving FormData object
|
|
1753
|
+
* @param {string} sFieldName name of the form field
|
|
1754
|
+
* @param {object} oFile object to be appended
|
|
1755
|
+
* @private
|
|
1756
|
+
*/
|
|
1757
|
+
FileUploader.prototype._appendFileToFormData = function (oFormData, sFieldName, oFile) {
|
|
1758
|
+
// BCP: 1770523801 We pass third parameter 'name' only for instance of 'Blob' that has a 'name'
|
|
1759
|
+
// parameter to prevent the append method failing on Safari browser.
|
|
1760
|
+
if (oFile instanceof window.Blob && oFile.name) {
|
|
1761
|
+
oFormData.append(sFieldName, oFile, oFile.name);
|
|
1762
|
+
} else {
|
|
1763
|
+
oFormData.append(sFieldName, oFile);
|
|
1764
|
+
}
|
|
1765
|
+
};
|
|
1766
|
+
|
|
1767
|
+
/**
|
|
1768
|
+
* Processes the passed files and sends them afterwards via XHR request.
|
|
1769
|
+
* @param {window.File[]} [aFiles] list of files from type window.File
|
|
1770
|
+
* @returns {this} Reference to <code>this</code> for method chaining
|
|
1771
|
+
* @private
|
|
1772
|
+
*/
|
|
1773
|
+
FileUploader.prototype._sendProcessedFilesWithXHR = function (aFiles) {
|
|
1774
|
+
this.getProcessedBlobsFromArray(aFiles).then(function(aBlobs){
|
|
1775
|
+
this._sendFilesWithXHR(aBlobs);
|
|
1776
|
+
}.bind(this)).catch(function(oResult){
|
|
1777
|
+
Log.error("File upload failed: " + oResult && oResult.message ? oResult.message : "no details available");
|
|
1778
|
+
});
|
|
1779
|
+
return this;
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1782
|
+
/*
|
|
1783
|
+
* Check if passed files complies with the provided file restrictions.
|
|
1784
|
+
* These restrictions are the values of properties like "fileType", "maximumFileSize", "mimeType", "maximumFilenameLength"
|
|
1785
|
+
* @param {array} [aFiles] list of files from type window.File, this array is returned from input type="file" or from Drag and Drop
|
|
1786
|
+
* @returns {boolean}
|
|
1787
|
+
* @private
|
|
1788
|
+
*/
|
|
1789
|
+
FileUploader.prototype._areFilesAllowed = function (aFiles) {
|
|
1790
|
+
var sName, bWrongType, iIdx, sFileEnding, sType,
|
|
1791
|
+
fMaxSize = this.getMaximumFileSize(),
|
|
1792
|
+
aMimeTypes = this.getMimeType(),
|
|
1793
|
+
aFileTypes = this.getFileType();
|
|
1794
|
+
|
|
1795
|
+
for (var i = 0; i < aFiles.length; i++) {
|
|
1796
|
+
sName = aFiles[i].name;
|
|
1797
|
+
sType = aFiles[i].type || "unknown";
|
|
1798
|
+
|
|
1799
|
+
var fSize = ((aFiles[i].size / 1024) / 1024);
|
|
1800
|
+
if (fMaxSize && (fSize > fMaxSize)) {
|
|
1801
|
+
Log.info("File: " + sName + " is of size " + fSize + " MB which exceeds the file size limit of " + fMaxSize + " MB.");
|
|
1802
|
+
this.fireFileSizeExceed({
|
|
1803
|
+
fileName: sName,
|
|
1804
|
+
fileSize: fSize
|
|
1805
|
+
});
|
|
1806
|
+
|
|
1807
|
+
return false;
|
|
1808
|
+
}
|
|
1809
|
+
if (fSize === 0){
|
|
1810
|
+
Log.info("File: " + sName + " is empty!");
|
|
1811
|
+
this.fireFileEmpty({
|
|
1812
|
+
fileName: sName
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
//check if the filename is too long and fire the corresponding event if necessary
|
|
1816
|
+
if (this._isFilenameTooLong(sName)) {
|
|
1817
|
+
this.fireFilenameLengthExceed({
|
|
1818
|
+
fileName: sName
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
return false;
|
|
1822
|
+
}
|
|
1823
|
+
//check allowed mime-types for potential mismatches
|
|
1824
|
+
if (aMimeTypes && aMimeTypes.length > 0) {
|
|
1825
|
+
var bWrongMime = true;
|
|
1826
|
+
for (var j = 0; j < aMimeTypes.length; j++) {
|
|
1827
|
+
if (sType == aMimeTypes[j] || aMimeTypes[j] == "*/*" || sType.match(aMimeTypes[j])) {
|
|
1828
|
+
bWrongMime = false;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
if (bWrongMime && sType !== "unknown") {
|
|
1832
|
+
Log.info("File: " + sName + " is of type " + sType + ". Allowed types are: " + aMimeTypes + ".");
|
|
1833
|
+
this.fireTypeMissmatch({
|
|
1834
|
+
fileName: sName,
|
|
1835
|
+
mimeType: sType
|
|
1836
|
+
});
|
|
1837
|
+
|
|
1838
|
+
return false;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
//check allowed file-types for potential mismatches
|
|
1842
|
+
if (aFileTypes && aFileTypes.length > 0) {
|
|
1843
|
+
bWrongType = true;
|
|
1844
|
+
iIdx = sName.lastIndexOf(".");
|
|
1845
|
+
sFileEnding = (iIdx === -1) ? "" : sName.substring(iIdx + 1);
|
|
1846
|
+
for (var k = 0; k < aFileTypes.length; k++) {
|
|
1847
|
+
if (sFileEnding.toLowerCase() == aFileTypes[k].toLowerCase()) {
|
|
1848
|
+
bWrongType = false;
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
if (bWrongType) {
|
|
1852
|
+
Log.info("File: " + sName + " is of type " + sFileEnding + ". Allowed types are: " + aFileTypes + ".");
|
|
1853
|
+
this.fireTypeMissmatch({
|
|
1854
|
+
fileName:sName,
|
|
1855
|
+
fileType:sFileEnding
|
|
1856
|
+
});
|
|
1857
|
+
|
|
1858
|
+
return false;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
return true;
|
|
1864
|
+
};
|
|
1865
|
+
|
|
1866
|
+
/**
|
|
1867
|
+
* Validate provided files from drag and drop event and send them trough XHR
|
|
1868
|
+
* Be aware that this method is private and is created only for drag and drop enablement inside sap.m.UploadCollection
|
|
1869
|
+
* @param {window.File[]} [aFiles] list of files from type window.File, this array is returned from input type="file" or from Drag and Drop
|
|
1870
|
+
* @returns {this} Reference to <code>this</code> for method chaining
|
|
1871
|
+
* @private
|
|
1872
|
+
*/
|
|
1873
|
+
FileUploader.prototype._sendFilesFromDragAndDrop = function (aFiles) {
|
|
1874
|
+
if (this._areFilesAllowed(aFiles)) {
|
|
1875
|
+
this._sendFilesWithXHR(aFiles);
|
|
1876
|
+
}
|
|
1877
|
+
return this;
|
|
1878
|
+
};
|
|
1879
|
+
|
|
1880
|
+
/**
|
|
1881
|
+
* The value in the FileUplader input is generated from this method.
|
|
1882
|
+
* It contains the names of the files in quotes divided by space.
|
|
1883
|
+
* @param {window.File[]} [aFiles] list with files from type window.File, this array is returned from input type="file" or from Drag and Drop
|
|
1884
|
+
* @returns {string} The value of the input
|
|
1885
|
+
*/
|
|
1886
|
+
FileUploader.prototype._generateInputValue = function (aFiles) {
|
|
1887
|
+
var sFileString = "";
|
|
1888
|
+
|
|
1889
|
+
for (var i = 0; i < aFiles.length; i++) {
|
|
1890
|
+
sFileString = sFileString + '"' + aFiles[i].name + '" ';
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
return sFileString;
|
|
1894
|
+
};
|
|
1895
|
+
|
|
1896
|
+
/**
|
|
1897
|
+
* Helper to retrieve the I18N texts for a button
|
|
1898
|
+
* @private
|
|
1899
|
+
*/
|
|
1900
|
+
FileUploader.prototype.getBrowseText = function() {
|
|
1901
|
+
|
|
1902
|
+
// as the text is the same for all FileUploaders, get it only once
|
|
1903
|
+
if (!FileUploader.prototype._sBrowseText) {
|
|
1904
|
+
var rb = Library.getResourceBundleFor("sap.ui.commons");
|
|
1905
|
+
FileUploader.prototype._sBrowseText = rb.getText("FILEUPLOAD_BROWSE");
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
return FileUploader.prototype._sBrowseText ? FileUploader.prototype._sBrowseText : "Browse...";
|
|
1909
|
+
|
|
1910
|
+
};
|
|
1911
|
+
|
|
1912
|
+
/**
|
|
1913
|
+
* Helper to retrieve the I18N text for the tooltip when there is no file chosen
|
|
1914
|
+
* @private
|
|
1915
|
+
*/
|
|
1916
|
+
FileUploader.prototype._getNoFileChosenText = function() {
|
|
1917
|
+
|
|
1918
|
+
// as the text is the same for all FileUploaders, get it only once
|
|
1919
|
+
if (!FileUploader.prototype._sNoFileChosenText) {
|
|
1920
|
+
var rb = Library.getResourceBundleFor("sap.ui.commons");
|
|
1921
|
+
FileUploader.prototype._sNoFileChosenText = rb.getText("FILEUPLOAD_NO_FILE_CHOSEN");
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
return FileUploader.prototype._sNoFileChosenText ? FileUploader.prototype._sNoFileChosenText : "No file chosen";
|
|
1925
|
+
|
|
1926
|
+
};
|
|
1927
|
+
|
|
1928
|
+
/**
|
|
1929
|
+
* Getter for shortened value.
|
|
1930
|
+
* @private
|
|
1931
|
+
* @deprecated the value now is the short value (filename only)!
|
|
1932
|
+
*/
|
|
1933
|
+
FileUploader.prototype.getShortenValue = function() {
|
|
1934
|
+
return this.getValue();
|
|
1935
|
+
};
|
|
1936
|
+
|
|
1937
|
+
/**
|
|
1938
|
+
* Prepares the hidden IFrame for uploading the file (in static area).
|
|
1939
|
+
* @private
|
|
1940
|
+
*/
|
|
1941
|
+
FileUploader.prototype.prepareFileUploadAndIFrame = function() {
|
|
1942
|
+
this._prepareFileUpload();
|
|
1943
|
+
|
|
1944
|
+
if (!this.oIFrameRef) {
|
|
1945
|
+
// create the upload iframe
|
|
1946
|
+
var oIFrameRef = document.createElement("iframe");
|
|
1947
|
+
oIFrameRef.style.display = "none";
|
|
1948
|
+
/*eslint-enable no-script-url */
|
|
1949
|
+
oIFrameRef.id = this.getId() + "-frame";
|
|
1950
|
+
StaticArea.getDomRef().appendChild(oIFrameRef);
|
|
1951
|
+
oIFrameRef.contentWindow.name = this.getId() + "-frame";
|
|
1952
|
+
|
|
1953
|
+
// sink the load event of the upload iframe
|
|
1954
|
+
this._bUploading = false; // flag for uploading
|
|
1955
|
+
jQuery(oIFrameRef).on("load", function(oEvent) {
|
|
1956
|
+
if (this._bUploading) {
|
|
1957
|
+
Log.info("File uploaded to " + this.getUploadUrl());
|
|
1958
|
+
var sResponse;
|
|
1959
|
+
try {
|
|
1960
|
+
sResponse = this.oIFrameRef.contentWindow.document.body.innerHTML;
|
|
1961
|
+
} catch (ex) {
|
|
1962
|
+
// in case of cross-domain submit we get a permission denied exception
|
|
1963
|
+
// when we try to access the body of the IFrame document
|
|
1964
|
+
}
|
|
1965
|
+
this.fireUploadComplete({"response": sResponse});
|
|
1966
|
+
this._bUploading = false;
|
|
1967
|
+
}
|
|
1968
|
+
}.bind(this));
|
|
1969
|
+
|
|
1970
|
+
// keep the reference
|
|
1971
|
+
this.oIFrameRef = oIFrameRef;
|
|
1972
|
+
|
|
1973
|
+
}
|
|
1974
|
+
};
|
|
1975
|
+
|
|
1976
|
+
FileUploader.prototype._prepareFileUpload = function() {
|
|
1977
|
+
if (!this.oFileUpload) {
|
|
1978
|
+
// create the file uploader markup
|
|
1979
|
+
var aFileUpload = [];
|
|
1980
|
+
aFileUpload.push('<input ');
|
|
1981
|
+
aFileUpload.push('type="file" ');
|
|
1982
|
+
aFileUpload.push('aria-hidden="true" ');
|
|
1983
|
+
if (this.getName()) {
|
|
1984
|
+
if (this.getMultiple() || this.getDirectory()) {
|
|
1985
|
+
aFileUpload.push('name="' + encodeXML(this.getName()) + '[]" ');
|
|
1986
|
+
} else {
|
|
1987
|
+
aFileUpload.push('name="' + encodeXML(this.getName()) + '" ');
|
|
1988
|
+
}
|
|
1989
|
+
} else if (this.getMultiple() || this.getDirectory()) {
|
|
1990
|
+
aFileUpload.push('name="' + this.getId() + '[]" ');
|
|
1991
|
+
} else {
|
|
1992
|
+
aFileUpload.push('name="' + this.getId() + '" ');
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
aFileUpload.push('id="' + this.getId() + '-fu" ');
|
|
1996
|
+
// for IE9 the file uploader itself gets the focus to make sure that the
|
|
1997
|
+
// keyboard interaction works and there is no security issue - unfortunately
|
|
1998
|
+
// this has the negative side effect that 2 tabs are required.
|
|
1999
|
+
aFileUpload.push('tabindex="-1" ');
|
|
2000
|
+
aFileUpload.push('size="1" ');
|
|
2001
|
+
|
|
2002
|
+
if (this.getTooltip_AsString() ) {
|
|
2003
|
+
aFileUpload.push('title="' + encodeXML(this.getTooltip_AsString()) + '" ');
|
|
2004
|
+
//} else if (this.getTooltip() ) {
|
|
2005
|
+
// object tooltip, do nothing - tooltip will be displayed
|
|
2006
|
+
} else {
|
|
2007
|
+
// only if there is no tooltip, then set value or default tooltip as fallback
|
|
2008
|
+
aFileUpload.push('title="' + encodeXML(this.getValue() ? this.getValue() : this._getNoFileChosenText()) + '" ');
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
if (!this.getEnabled()) {
|
|
2012
|
+
aFileUpload.push('disabled="disabled" ');
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
if (this.getDirectory()) {
|
|
2016
|
+
aFileUpload.push('webkitdirectory ');
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
if (this.getMultiple()) {
|
|
2020
|
+
aFileUpload.push('multiple ');
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
if ((this.getMimeType() || this.getFileType()) && window.File) {
|
|
2024
|
+
var sAcceptedTypes = this._getAcceptedTypes();
|
|
2025
|
+
aFileUpload.push('accept="' + encodeXML(sAcceptedTypes) + '" ');
|
|
2026
|
+
}
|
|
2027
|
+
aFileUpload.push('>');
|
|
2028
|
+
|
|
2029
|
+
// add it into the control markup
|
|
2030
|
+
this.oFileUpload = jQuery(aFileUpload.join("")).prependTo(this.$().find(".sapUiFupInputMask")).get(0);
|
|
2031
|
+
} else {
|
|
2032
|
+
|
|
2033
|
+
// move the file uploader from the static area to the control markup
|
|
2034
|
+
jQuery(this.oFileUpload).prependTo(this.$().find(".sapUiFupInputMask"));
|
|
2035
|
+
|
|
2036
|
+
}
|
|
2037
|
+
};
|
|
2038
|
+
|
|
2039
|
+
FileUploader.prototype.openValueStateMessage = function() {
|
|
2040
|
+
|
|
2041
|
+
if (this.oFilePath.openValueStateMessage) {
|
|
2042
|
+
this.oFilePath.openValueStateMessage();
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
};
|
|
2046
|
+
|
|
2047
|
+
FileUploader.prototype.closeValueStateMessage = function() {
|
|
2048
|
+
|
|
2049
|
+
if (this.oFilePath.closeValueStateMessage) {
|
|
2050
|
+
this.oFilePath.closeValueStateMessage();
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
};
|
|
2054
|
+
|
|
2055
|
+
FileUploader.prototype._getAcceptedTypes = function() {
|
|
2056
|
+
var aMimeTypes = this.getMimeType() || [],
|
|
2057
|
+
aFileTypes = this.getFileType() || [];
|
|
2058
|
+
aFileTypes = aFileTypes.map(function(item) {
|
|
2059
|
+
return item.indexOf(".") === 0 ? item : "." + item;
|
|
2060
|
+
});
|
|
2061
|
+
return aFileTypes.concat(aMimeTypes).join(",");
|
|
2062
|
+
};
|
|
2063
|
+
|
|
2064
|
+
FileUploader.prototype._resetValueAfterUploadStart = function () {
|
|
2065
|
+
Log.info("File uploading to " + this.getUploadUrl());
|
|
2066
|
+
if (this.getSameFilenameAllowed() && this.getUploadOnChange() && this.getUseMultipart()) {
|
|
2067
|
+
this.setValue("", true);
|
|
2068
|
+
}
|
|
2069
|
+
};
|
|
2070
|
+
/*
|
|
2071
|
+
* Add default input type=file and label behaviour to file uploader.
|
|
2072
|
+
*/
|
|
2073
|
+
FileUploader.prototype._addLabelFeaturesToBrowse = function () {
|
|
2074
|
+
let $browse;
|
|
2075
|
+
const fnBrowseClickHandler = (oEvent) => {
|
|
2076
|
+
oEvent.preventDefault();
|
|
2077
|
+
oEvent.stopPropagation();
|
|
2078
|
+
this.FUEl.click(); // The default behaviour on click on label is to open "open file" dialog. The only way to attach click event that is transferred from the label to the button is this way. AttachPress and attachTap don't work in this case.
|
|
2079
|
+
};
|
|
2080
|
+
|
|
2081
|
+
if (this.oBrowse && this.oBrowse.$().length) {
|
|
2082
|
+
$browse = this.oBrowse.$();
|
|
2083
|
+
|
|
2084
|
+
if (this.oBrowse.getAriaLabelledBy()) {
|
|
2085
|
+
LabelEnablement.getReferencingLabels(this).forEach(function (sLabelId) {
|
|
2086
|
+
const $externalLabel = Element.getElementById(sLabelId).$();
|
|
2087
|
+
$externalLabel.off("click").on("click", fnBrowseClickHandler);
|
|
2088
|
+
}, this);
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
$browse.off("click").on("click", fnBrowseClickHandler);
|
|
2092
|
+
|
|
2093
|
+
// The event propagation needs to be stopped so composing controls, which also react on
|
|
2094
|
+
// drag and drop events like the sap.m.UploadCollection or sap.m.upload.UploadSet aren't affected.
|
|
2095
|
+
$browse.off("dragover").on("dragover", (oEvent) => {
|
|
2096
|
+
oEvent.preventDefault();
|
|
2097
|
+
oEvent.stopPropagation();
|
|
2098
|
+
});
|
|
2099
|
+
$browse.off("dragenter").on("dragenter", (oEvent) => {
|
|
2100
|
+
oEvent.preventDefault();
|
|
2101
|
+
oEvent.stopPropagation();
|
|
2102
|
+
});
|
|
2103
|
+
$browse.off("drop").on("drop", (oEvent) => {
|
|
2104
|
+
oEvent.preventDefault();
|
|
2105
|
+
oEvent.stopPropagation();
|
|
2106
|
+
var aFileList = oEvent.originalEvent.dataTransfer.files;
|
|
2107
|
+
// TODO: enable directory drag and drop
|
|
2108
|
+
if ((!this.getMultiple() && aFileList.length > 1) || this.getDirectory()) {
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
this.oFileUpload.files = aFileList;
|
|
2113
|
+
var oChangeEvent = {
|
|
2114
|
+
target: {
|
|
2115
|
+
files: aFileList
|
|
2116
|
+
}
|
|
2117
|
+
};
|
|
2118
|
+
this.handlechange(oChangeEvent);
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
2121
|
+
};
|
|
2122
|
+
|
|
2123
|
+
/**
|
|
2124
|
+
* Allows to process Blobs before they get uploaded. This API can be used to create custom Blobs
|
|
2125
|
+
* and upload these custom Blobs instead of the received/initials Blobs in the parameter <code>aBlobs</code>.
|
|
2126
|
+
* One use case could be to create and upload zip archives based on the passed Blobs.
|
|
2127
|
+
* The default implementation of this API should simply resolve with the received Blobs (parameter <code>aBlobs</code>).
|
|
2128
|
+
*
|
|
2129
|
+
* This API is only supported in case <code>sendXHR</code> is <code>true</code>. This means only IE10+ is supported, while IE9 and below is not.
|
|
2130
|
+
*
|
|
2131
|
+
* This is a default implementation of the interface <code>sap.ui.commons.IProcessableBlobs</code>.
|
|
2132
|
+
*
|
|
2133
|
+
* @public
|
|
2134
|
+
* @since 1.52
|
|
2135
|
+
* @param {Blob[]} aBlobs The initial Blobs which can be used to determine/calculate a new array of Blobs for further processing.
|
|
2136
|
+
* @returns {Promise<Blob[]>} A Promise that resolves with an array of Blobs which is used for the final uploading.
|
|
2137
|
+
*/
|
|
2138
|
+
FileUploader.prototype.getProcessedBlobsFromArray = function (aBlobs){
|
|
2139
|
+
return new Promise(function(resolve){
|
|
2140
|
+
resolve(aBlobs);
|
|
2141
|
+
});
|
|
2142
|
+
};
|
|
2143
|
+
|
|
2144
|
+
// If the file has been edited after it has been chosen,
|
|
2145
|
+
// Chrome 85 fails silently on submit, so we could
|
|
2146
|
+
// check if it is readable first.
|
|
2147
|
+
// https://stackoverflow.com/questions/61916331
|
|
2148
|
+
// BCP: 2070313680
|
|
2149
|
+
|
|
2150
|
+
/**
|
|
2151
|
+
* Checks if the chosen file is readable.
|
|
2152
|
+
*
|
|
2153
|
+
* @returns {Promise} A promise that resolves successfully
|
|
2154
|
+
* if the chosen file can be read and fails with an error message if it cannot
|
|
2155
|
+
* @public
|
|
2156
|
+
*/
|
|
2157
|
+
FileUploader.prototype.checkFileReadable = function() {
|
|
2158
|
+
return new Promise(function(resolve, reject) {
|
|
2159
|
+
var oReader;
|
|
2160
|
+
|
|
2161
|
+
if (window.File && this.FUEl && this.FUEl.files.length) {
|
|
2162
|
+
oReader = new FileReader();
|
|
2163
|
+
oReader.readAsArrayBuffer(this.FUEl.files[0].slice(0, 1));
|
|
2164
|
+
|
|
2165
|
+
oReader.onload = function() {
|
|
2166
|
+
resolve();
|
|
2167
|
+
};
|
|
2168
|
+
|
|
2169
|
+
oReader.onerror = function() {
|
|
2170
|
+
reject(oReader.error);
|
|
2171
|
+
};
|
|
2172
|
+
} else {
|
|
2173
|
+
resolve();
|
|
2174
|
+
}
|
|
2175
|
+
}.bind(this));
|
|
2176
|
+
};
|
|
49
2177
|
|
|
50
2178
|
return FileUploader;
|
|
51
2179
|
|