I am new to Web Dynpro and I am wondering if anyone can help me with an application that I am currently developing. I have a particular requirement to store images in a database table (not MIME repository) and then display them in a WD table element. An image can be of JPEG, PNG or TIFF format and is associated with an employee record.
I want to create a view in my application that displays multiple images in a table, one image per row. I want to do this using Web Dynpro for ABAP, not Java. I have looked into pretty much all examples available for Web Dynpro and came to the conclusion that Components such as WDR_TEST_EVENTS and WDR_TEST_UI_ELEMENTS do not have any examples of images being stored in a database table and viewed in/from a Web Dynpro table element. Programs such as RSDEMO_PICTURE_CONTROL, DEMO_PICTURE_CONTROL and SAP_PICTURE_DEMO do not show this either.
The images to be displayed in the Dynpro table are to come from a z-type table, stored in a column of data type XSTRING (RAW STRING). So I would also like to know how to upload these images into this z-type table using ABAP code (not Java).
Your help would be greatly appreciated.
You should use fileUpload and filedownload uielement.
Firstly file upload
1. Create a node FILEUPLOAD with 2 attributes filename type string and filecontent type XSTRING
2. Place a fileupload uielement ib your view.
3. Bind the Data property with filecontent attribute and filename property with filename attribute
4. Create a button next to the fileupload uielement. Create OnAction method for this button.
In this method place, read the content of the uploaded file and save it in your custom database table, use the following code,
Data: l_node type ref to if_wd_context_node. l_node = wd_Context->get_child_node( 'FILEDOWNLOAD' ). " your node name l_node->get_static_attributes( importig static_attributes = ls_stru ). " ls_stru-filecontent will have your image in XSTRING Format. Just save this in your custom table usig INSERT/MODFIY statements
Now FileDownload Part,
1. Under your node that is bound to the table, create an attribute CONTENT type XSTRING and NAME type STRING.
2. Create a column in the table with cell editor as FILEDOWNLOAD.
3. Bind the data property with the attribute CONTENT and text property with the attribute NAME.
4. On in your Action method for Attach, fetch data from your custom table and pass it to the node using bind_table.
Hope this helps!
My apologies for "hijacking" this thread but I have the same problem as Ken. I have used your suggestions in this and previous posts and I can upload an image into my db table and then show it using the link in the filedownload component. However, my requirement is the same as Ken's I believe - I need to be able to show that image in the wd table w/o having the user to click on the link and showing that image in a separate page or section.
Essentially, I want an image to be just another column in the wd table or alv and is visible immediately after image data (rawstring or xstring in context) is retrieved from the database table and bound to wd table in my application.
Is this possible and if it is then how it's achieved?
I did this here:
The process of creating the image in the table isn't anything special. The trick is creating the URLs for the images.
One approach is to place each image into the ICM cache and generate a temporary URL for it. This has been discussed (with source code) several times on this forum. If you can't find that solution, let me know and I can post it again.
However for this project, I didn't take that approach. I create a custom HTTP handler. It reads the image name from the URL and looks up the content from the database and returns it in the HTTP response. It is like the MIME Repository handler except written specifically for the Z-Table that is storing my product images. You can download the source code for this handler class from last year's TechEd Mentors' Hands-On Workshop:
I have created a custom ICM handler class to serve the images via their own handler URL - exactly as you prescribed in one of your earlier posts. I followed your steps and even reused some of your code from the link that you have provided.
Now I am trying to execute a simple test where I have the Images table which has following fields:
Filename - the actual image file name (i.e. desktop.gif) - string
Content - the actual binary image content - RAWSTRING
Image_GUID - the unique identifier of this image (ties really to another table that keeps employee data) - GUID_16
In my WD application I just have one context called IMAGE_INFO which has filename, image_url and image_ID plus the actual IMAGE column that maps to image_url (i have both there for debugging purpose).
The intention here is to read the image data from the database table and display it in the ALV or table grid in WD application and for that purpose I have a table control in the view that is bound to IMAGE_INFO context.
My problem is that the image URL is displaying as zmho/images/desktop.gif as oppose to http://..../sap/....desktop.gif as it should. It almost seems that ICM handler and/or node is not implemented correctly.
What am I doing wrong? I copied your code exactly and followed your instructions to the letter. Does it matter where I place my ICM Node? Currently, my application is running under following path: "http://SERVERNAME:PORT#/sap/bc/webdynpro/sap/appname" - of course, this is a DEV environment. Does the node have to be under this path and does need to have a distinct name or the same name as my application or wd component?
My apologies for not being able to grasp this, I am very new to Web Dynpro and ABAP.
Please help. In the meantime though, I will try using your other suggestion about utilizing temporary cache entry and see where that puts me.
Edited by: Dino B. on Jul 30, 2009 7:17 PM
Edited by: Dino B. on Jul 30, 2009 8:12 PM
>Does the node have to be under this path and does need to have a distinct name or the same name as my application or wd component?
The node can be anywhere in the hierarchy, but where you place it will create the URL for accessing the image. My images are served out from http://<host>:<port>/zmho/images/desktop.gif because that is where I place my handler in the ICF hierarchy. See the screen shot here:
Unfortunately, I have tried everything and it didn't seem to work. I am now thinking that I should try with MIME but I am reluctant since at some point I would have to store approx. 18K of images.
I have also looked at your other demos (Flash Islands) and tried to the code and approach from there with no luck. I am not getting the "path" correct, it seems like the server path is not coming through and is not being concatenated by default.
Thanks for your help and patience Thomas, I really appreciate it but I think that I will need a step by step information on how to do this and I'm afraid that you simply do not have time for that.
Hi Dino, I have placed the following code in the OnAction method of my upload button and it works fine for me. I have 2 nodes; 1) CN_FILE - 1:1 cardinality; 2 attributes CONTENT type XSTRING and NAME type STRING ; these attributes are bound to the data and fileName property. 2) CN_IMAGES - 0:n cardinality; Only 1 attribute IMAGE type STRING; bound to cell editor of the table column Now in the OnAction method of the Button i have placed the below code. So whenever you upload an image it is added in the table. Try it out! Regards, Radhika.
METHOD onactionupload . " get the content of the uploaded file DATA lo_nd_cn_file TYPE REF TO if_wd_context_node. DATA lo_el_cn_file TYPE REF TO if_wd_context_element. DATA ls_cn_file TYPE wd_this->element_cn_file. * navigate from <CONTEXT> to <CN_FILE> via lead selection lo_nd_cn_file = wd_context->get_child_node( name = wd_this->wdctx_cn_file ). * get element via lead selection lo_el_cn_file = lo_nd_cn_file->get_element( ). * get all declared attributes lo_el_cn_file->get_static_attributes( IMPORTING static_attributes = ls_cn_file ). * display upload image below in image uielement. DATA:gx_mimetype TYPE string VALUE 'JPG'. ****Create the cached response object that we will insert our content into DATA: cached_response TYPE REF TO if_http_response. CREATE OBJECT cached_response TYPE cl_http_response EXPORTING add_c_msg = 1. TRY. " ignore, if compression can not be switched on CALL METHOD cached_response->set_compression EXPORTING OPTIONS = cached_response->co_compress_based_on_mime_type EXCEPTIONS OTHERS = 1. CATCH cx_root. ENDTRY. ****set the data and the headers DATA: l_app_type TYPE string. DATA: l_xstring TYPE xstring, i_cache_timeout TYPE i VALUE '300'. cached_response->set_data( ls_cn_file-content ). l_app_type = gx_mimetype. cached_response->set_header_field( name = if_http_header_fields=>content_type value = l_app_type ). ****Set the Response Status cached_response->set_status( code = 200 reason = 'OK' ). ****Set the Cache Timeout - 60 seconds - we only need this in the cache ****long enough to build the page and allow the Image on the Client to request it. cached_response->server_cache_expire_rel( expires_rel = i_cache_timeout ). DATA: r_url TYPE string. DATA: i_path TYPE string VALUE '/sap/public', i_format TYPE string VALUE 'JPG'. ****Create a unique URL for the object DATA: guid TYPE guid_32. CALL FUNCTION 'GUID_CREATE' IMPORTING ev_guid_32 = guid. CONCATENATE i_path '/' guid '.' i_format INTO r_url. ****Cache the URL cl_http_server=>server_cache_upload( url = r_url response = cached_response ). " append the url to table DATA lo_nd_cn_images TYPE REF TO if_wd_context_node. DATA lt_images TYPE wd_this->elements_cn_images. DATA ls_images TYPE wd_this->element_cn_images. * navigate from <CONTEXT> to <CN_IMAGES> via lead selection lo_nd_cn_images = wd_context->get_child_node( name = wd_this->wdctx_cn_images ). lo_nd_cn_images->get_static_attributes_table( IMPORTING table = lt_images ). ls_images-image = r_url. APPEND ls_images TO lt_images. "bind tehtable lo_nd_cn_images->bind_table( lt_images ). ENDMETHOD.
THANK YOU BOTH Thomas and Radhika! It works now using the temporary cache approach with the code that Radhika suplied. I can now see images in the table. Now that I have that figured out I think it will be simple enough to load images from the z-table using this same code. Once I have more time (if ever!) I will devote it to building a service using Thomas' approach so it is accessible to everyone. I have no doubt that others in my company will want to use the same general idea.
Once again thank you gentlemen, you have been quite helpful. I will ask Ken as the originator of this request (we work in the same company) to award due points to both of you fine gents.
Edited by: Dino B. on Aug 3, 2009 7:29 PM
I have the similar requirement to upload and download the images .Can you please tell me how did you work out and can you tell how you done this with step by step procedure with Nodes/Attributes and if possible please send me the code too..
Thanks in advance....
You setup the service node in SICF, right? Just right mouse click on the Service Node in SICF and choose Test Service from the context menu. You will probably get an exception message from you image handler because no image ID was specified, the URL in the browser will be exactly what you need to build in your application to referece these images.
In my case I put my new service nodes right off the default_host in SICF:
Therefore the URL that gets generated when I test is:
In my code when I build this URL, I just concatenate /zmho/images/ together with the filename. The path isn't relative to the WD applciation since it refers back to the root node of the SICF hierarchy - not does it need to contain the hostname/domain/port:
loop at i_img assigning <wa_img>. append initial line to lt_product_info assigning <wa_info>. <wa_info>-product_guid = <wa_img>-product_guid. <wa_info>-filename = <wa_img>-filename. concatenate `/zmho/images/` <wa_info>-filename into <wa_info>-image_url.