- 1. Summary
- 2. Step by Step Guide
- 2.1 Registering a new handler
- 2.2 Passing Parameters
- 2.3 Supported events
- 2.4 Additional parameters
- Sample web handler
- SwatInput Attributes for UPLOAD (Subtype)
- 3. Documentation
1. Summary
Support is needed for handling the upload of files and efficiently sending them to the back-end. This involves registering a new web-handler, passing necessary parameters, and managing various upload events and additional parameters to ensure smooth operation. The document also includes sample code for setting up the web-handler and provides alternatives for using the SwatUpload control.
2. Step by Step Guide
2.1 Registering a new handler
In SWAT, a new web-handler must be registered in openedge.properties, similar to AppDataWebHandler, under:
[app.ROOT.WEB]
[app.restbasic.WEB]
A new entry must be added:
handlerXX=path.to.class: /{URL}/{path-param-1}/{path-param-2}
2.2 Passing Parameters
//PATH PARAMS:
poRequest:GetPathParameter ("path-param-1":U)
//QUERY PARAMS:
DEFINE VARIABLE oQueryString AS CharacterDictionary NO-UNDO.
ListHelper:AlternatingListToDictionary(STRING(poRequest:GetContextValue("QUERY_STRING")), "&", "=").
WEB-CONTEXT:URL-DECODE(oQueryString:GetValue("Value")).
In the SwatInput or DynFillin, the upload URL must be specified:
- in the
uploadURL
attribute - by calling
.setURL()
on the upload control from theEventUploadFileAdd
function uploadURL
must include the /web prefix.
2.3 Supported events
Events | Description |
EventUploadComplete | Fires when all files from the list have been uploaded to the server |
EventUploadFileAdd | Fires when the user adds a file to the upload queue |
EventUploadBeforeFileAdd | Fires when the user adds a file to the upload queue |
EventUploadFail | Fires when the file upload has failed |
EventUploadBeforeClear | Fires before the clear event is triggered; can prevent clear event if the function returns the following: return { preventAction: true }; |
EventUploadClear | Fires on clear files; only if not prevented |
EventUploadBeforeFileRemove | Fires before a single file is removed from the list; can prevent remove event if the function returns the following: return { preventAction: true }; |
EventUploadFileRemove | Fires when a single file is removed from the list; only if remove is not prevented |
2.4 Additional parameters
Parameter | Description |
setAutoRemove | enables the mode in which files are immediately removed from the item after downloading has been completed |
setAutoStart | Enables the mode in which files are immediately loaded after selecting |
uploadTooltip | Attribute where you can specify the tooltip values for the different buttons;
Accepts a json string (default: {}), where you can sppecify the different tooltips: browse,upload, cancel, clear |
JSON example:
{"browse": "new label", "clean": "new clean label"}
Tooltip labels are also translatable in the common files. Place a custom translation under:
upload.tooltip.<name-of-key>
where name-of-key is one of the above 4.
"upload": {
"tooltip": {
"browse": "Search",
"clear": "Remove"
}
},
Sample web handler
USING Progress.Lang.*.
USING Progress.Json.ObjectModel.JsonObject FROM PROPATH.
USING OpenEdge.Web.WebResponse FROM PROPATH.
USING OpenEdge.Web.IWebRequest FROM PROPATH.
USING OpenEdge.Net.HTTP.IHttpResponse FROM PROPATH.
USING OpenEdge.Net.HTTP.StatusCodeEnum FROM PROPATH.
USING Consultingwerk.Framework.Collections.CharacterDictionary FROM PROPATH.
USING Consultingwerk.Util.ListHelper FROM PROPATH.
USING Consultingwerk.OERA.ServiceInterface FROM PROPATH.
USING Consultingwerk.Util.GarbageCollectorHelper FROM PROPATH.
USING Consultingwerk.Exceptions.Exception FROM PROPATH.
USING Akioma.Swat.Util.FileHelper FROM PROPATH.
CLASS Akioma.Swat.OERA.WebHandler.Test
INHERITS Consultingwerk.OERA.JsdoGenericService.WebHandler.SmartWebHandler:
METHOD OVERRIDE PROTECTED INTEGER HandlePost(poRequest AS IWebRequest):
DEFINE VARIABLE cFileName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cFullPath AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPathParam AS CHARACTER NO-UNDO.
DEFINE VARIABLE cValue AS CHARACTER NO-UNDO.
DEFINE VARIABLE pData AS MEMPTR NO-UNDO.
DEFINE VARIABLE oQueryString AS CharacterDictionary NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
ASSIGN
oResponse = NEW WebResponse()
oResponse:ContentType = "application/json"
cPathParam = poRequest:GetPathParameter ("Test":U).
oQueryString = ListHelper:AlternatingListToDictionary(STRING(poRequest:GetContextValue("QUERY_STRING")), "&", "=")
.
DO ON ERROR UNDO, THROW:
ServiceInterface:Activate().
ASSIGN
cValue = WEB-CONTEXT:URL-DECODE(oQueryString:GetValue("Value"))
WHEN oQueryString:ContainsKey("Value")
.
MESSAGE 'cPathParam is ' cPathParam.
MESSAGE 'cValue is ' cPathParam.
cFullPath = SESSION:TEMP-DIR + 'test.txt'.
pData = WEB-CONTEXT:GET-BINARY-DATA("file").
COPY-LOB FROM pData TO FILE FileHelper:GetFileSystemPath(cFullPath).
oResponse:StatusCode = INTEGER (StatusCodeEnum:OK).
THIS-OBJECT:WriteJsonResponse(oResponse, cFileName, TRUE, "").
RETURN 0.
END.
CATCH oError AS Progress.Lang.Error:
oResponse:StatusCode = INTEGER(StatusCodeEnum:BadRequest).
THIS-OBJECT:WriteJsonErrorResponse(oResponse, cFileName, oError).
RETURN 500.
END CATCH.
FINALLY:
SET-SIZE(pData) = 0.
ServiceInterface:Deactivate().
END FINALLY.
END METHOD.
METHOD PRIVATE VOID WriteJsonErrorResponse(
INPUT poResponse AS IHttpResponse,
INPUT pcFileName AS CHARACTER,
INPUT poError AS Progress.Lang.Error
):
DEFINE VARIABLE cMessage AS CHARACTER NO-UNDO.
DEFINE VARIABLE iIdx AS INTEGER NO-UNDO.
cMessage = "".
DO iIdx = 1 TO poError:NumMessages:
cMessage = cMessage
+ (IF cMessage <> "" THEN "~n" ELSE "")
+ poError:GetMessage(iIdx)
.
END.
IF TYPE-OF(poError, Progress.Lang.AppError) AND CAST(poError, Progress.Lang.AppError):ReturnValue > "" THEN
cMessage = cMessage
+ (IF cMessage <> "" THEN "~n" ELSE "")
+ CAST(poError, Progress.Lang.AppError):ReturnValue
.
THIS-OBJECT:WriteJsonResponse(poResponse, pcFileName, FALSE, cMessage).
END METHOD.
METHOD PRIVATE VOID WriteJsonResponse(
INPUT poResponse AS IHttpResponse,
INPUT pcFileName AS CHARACTER,
INPUT plSuccess AS LOGICAL,
INPUT pcMessage AS CHARACTER
):
DEFINE VARIABLE oResponseJson AS JsonObject NO-UNDO.
DEFINE VARIABLE oResponseExtraJson AS JsonObject NO-UNDO.
oResponseJson = NEW JsonObject().
oResponseJson:Add("filename", pcFileName).
oResponseJson:Add("state", TRUE).
oResponseExtraJson = NEW JsonObject().
oResponseExtraJson:Add("success", plSuccess).
oResponseExtraJson:Add("message", pcMessage).
oResponseJson:Add("extra", oResponseExtraJson).
poResponse:Entity = oResponseJson.
poResponse:ContentType = "application/json".
THIS-OBJECT:WriteResponse(poResponse).
FINALLY:
GarbageCollectorHelper:DeleteObject(oResponseExtraJson).
GarbageCollectorHelper:DeleteObject(oResponseJson).
END FINALLY.
END METHOD.
END CLASS.
FileUploadWebHandler.cls
is a working example in SWAT.
https://community.progress.com/s/article/How-to-load-a-binary-file-with-webhandlers
Alternatively, the SwatUpload control can be used, if the desired outcome is just uploading files to the backend and assigning the value in a form field.
For the form field, a swat input(left) or dynfillin(right) can be used. Either must be of subtype UPLOAD:
Limitations: events are bound on the form, for all children of type 'upload'; only one upload control should be used in a form.
SwatInput Attributes for UPLOAD (Subtype)
- multipleFileSelection (default:
true
) - This attribute defines whether the user can select a single file (false
) or multiple files (true
) for uploading.
3. Documentation
To find more information, you can check the following documentation.
Back to Use Cases
Back to Build.One Help-Center Home