Visual Builder

Get Involved. Join the Conversation.

Topic

    Himanshu Sethi
    How to give file upload functionality using oracle VBCS.
    Topic posted June 3, 2019 by Himanshu SethiRed Ribbon: 250+ Points, last edited June 3, 2019 
    196 Views, 17 Comments
    Title:
    How to give file upload functionality using oracle VBCS.
    Summary:
    How to give file upload functionality using oracle VBCS.
    Content:

    I have to use file upload functionality in my application where on click of choose file , a file from my local should be uploaded along with progress bar in which file size , upload speed , status and delete icon should be visible. On click of stop uploading , a file should stop to upload and status should come as failed with retry icon. On click of retry icon same file should start uploading with cancel icon at the end of it.

    PFA the screenshot with name 'a' and 'b' for what exactly I need and the screenshot with name 'c' for what I have achieved in which it is not working for multiple upload thing and I am also not sure whether I have followed correct approach or not.

    Please refer to 'https://service.mcafee.com/pop' in which at the bottom file upload functionality is given , same I have to achieve in my page as well.

    Please let me know if any other details are required.

    Thanks,

    Himanshu Sethi

    Image:
    Document:
    b.PNG (11KB)
    Document:
    c.PNG (7KB)

    Comment

     

    • Shay Shmeltzer

      The basics of getting a file upload functionality is explained here:

      Uploading and Reading a Text File in Visual Builder

      If you also need to add a progress bar, you can look at adding the oj-progress JET component to your page:

      https://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=progress&demo=default

       

       

      • Himanshu Sethi

        Hi Shmeltzer

        I have imported HTML and JS component for oj-file-picker from OJET cookbook.It's working fine. Now I also want to give progress bar , file size , file speed , status if file is uploading or file is failed ,  delete icon.

        I have also imported oj-progress-bar in my application by giving same HTML and JS code as given in OJET cookbook progress bar , also given CSS property visible then also I am not able to see progress bar in my applicaton.

        Please help me to understand the reason for the same and how I can get progress bar on click of upload button along with file size , file speed and delete and retry icon.

        Please refer to the upload functionality in  https://service.mcafee.com/pop at the bottom of the page , I want to make same functionality in my application.

        Please let me know if any other details are required.

        Thanks,

        Himanshu 

         

        • Shay Shmeltzer

          Can you share the code of the page that doesn't work?

          The following HTML code shows a progress bar for me just fine:

          <div class="oj-flex">
              <oj-progress id="oj-progress-734762401-1" class="oj-flex-item oj-sm-12 oj-md-4" value="30"></oj-progress>
          </div>

           

          Note that it will be up to you to manage the value in the progress bar and to advance it as the file loads.

           

          • Himanshu Sethi

            Hi Shmeltzer

            I have imported HTML and CSS component for oj-progress-bar from Oracle JET cookbook similar to oj-file-picker .

            -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

            (1) PFB the HTML code for mfe-progress-bar(custom component that I have created)

            Note:I have just copied this code from Oracle JET cookbook.

              <html lang="en-us" style="height:100%;" dir="ltr">
                <head>
                  <title>Progress - Basic</title>
                  <meta charset="UTF-8">
                  <meta http-equiv="x-ua-compatible" content="IE=edge">
                  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
                  <meta name="viewport" content="width=device-width, initial-scale=1.0">
                  <link rel="icon" type="image/x-icon" href="../css/images/favicon.ico">
                  <link rel="apple-touch-icon-precomposed" href="../css/images/touchicon.png">
                  <meta name="apple-mobile-web-app-title" content="Oracle JET">
                  <link rel="stylesheet" id="css" href="http://www.oracle.com/webfolder/technetwork/jet/css/libs/oj/v7.0.0/alta/oj-alta-min.css">
                  <link rel="stylesheet" href="../css/demo.css">
                  <script>
                    // The "oj_whenReady" global variable enables a strategy that the busy context whenReady,
                    // will implicitly add a busy state, until the application calls applicationBootstrapComplete
                    // on the busy state context.
                    window["oj_whenReady"] = true;
                  </script>
                  <script src="http://www.oracle.com/webfolder/technetwork/jet/js/libs/require/require.js"></script>
                  <!-- RequireJS bootstrap file -->
                  <script src="../js/main.js"></script>
                  <script src="../js/demo.js"></script>
                
              <script>!function(){function o(n,i){if(n&&i)for(var r in i)i.hasOwnProperty(r)&&(void 0===n[r]?n[r]=i[r]:n[r].constructor===Object&&i[r].constructor===Object?o(n[r],i[r]):n[r]=i[r])}try{var n=decodeURIComponent("");if(n.length>0&&window.JSON&&"function"==typeof window.JSON.parse){var i=JSON.parse(n);void 0!==window.BOOMR_config?o(window.BOOMR_config,i):window.BOOMR_config=i}}catch(r){window.console&&"function"==typeof window.console.error&&console.error("mPulse: Could not parse configuration",r)}}();</script>
              <script>!function(a){var e="https://s.go-mpulse.net/boomerang/",t="addEventListener";if("False"=="True")a.BOOMR_config=a.BOOMR_config||{},a.BOOMR_config.PageParams=a.BOOMR_config.PageParams||{},a.BOOMR_config.PageParams.pci=!0,e="https://s2.go-mpulse.net/boomerang/";if(function(){function n(e){a.BOOMR_onload=e&&e.timeStamp||(new Date).getTime()}if(!a.BOOMR||!a.BOOMR.version&&!a.BOOMR.snippetExecuted){a.BOOMR=a.BOOMR||{},a.BOOMR.snippetExecuted=!0;var i,o,r,O=document.createElement("iframe");if(a[t])a[t]("load",n,!1);else if(a.attachEvent)a.attachEvent("onload",n);O.src="javascript:void(0)",O.title="",O.role="presentation",(O.frameElement||O).style.cssText="width:0;height:0;border:0;display:none;",r=document.getElementsByTagName("script")[0],r.parentNode.insertBefore(O,r);try{o=O.contentWindow.document}catch(_){i=document.domain,O.src="javascript:var d=document.open();d.domain='"+i+"';void(0);",o=O.contentWindow.document}o.open()._l=function(){var a=this.createElement("script");if(i)this.domain=i;a.id="boomr-if-as",a.src=e+"DXNLE-YBWWY-AR74T-WMD99-77VRA",BOOMR_lstart=(new Date).getTime(),this.body.appendChild(a)},o.write("<bo"+'dy onload="document._l();">'),o.close()}}(),"".length>0)if(a&&"performance"in a&&a.performance&&"function"==typeof a.performance.setResourceTimingBufferSize)a.performance.setResourceTimingBufferSize();!function(){if(BOOMR=a.BOOMR||{},BOOMR.plugins=BOOMR.plugins||{},!BOOMR.plugins.AK){var e="false"=="true"?1:0,t="",n="xhouklvygjxlexhxnhaq-f-5f9336da0-clientnsv4-s.akamaihd.net",i={"ak.v":20,"ak.cp":"82485","ak.ai":parseInt("165266",10),"ak.ol":"0","ak.cr":4,"ak.ipv":4,"ak.proto":"h2","ak.rid":"1790a6ba","ak.r":26720,"ak.a2":e,"ak.m":"dscx","ak.n":"essl","ak.bpcip":"185.221.69.0","ak.cport":36455,"ak.gh":"23.194.187.205","ak.quicv":"","ak.tlsv":"tls1.2","ak.0rtt":"","ak.csrc":"-","ak.acc":"","ak.t":"1559718337"};if(""!==t)i["ak.ruds"]=t;var o={i:!1,av:function(e){var t="http.initiator";if(e&&(!e[t]||"spa_hard"===e[t]))i["ak.feo"]=void 0!==a.aFeoApplied?1:0,BOOMR.addVar(i)},rv:function(){var a=["ak.bpcip","ak.cport","ak.cr","ak.csrc","ak.gh","ak.ipv","ak.m","ak.n","ak.ol","ak.proto","ak.quicv","ak.tlsv","ak.0rtt","ak.r","ak.acc","ak.t"];BOOMR.removeVar(a)}};BOOMR.plugins.AK={akVars:i,akDNSPreFetchDomain:n,init:function(){if(!o.i){var a=BOOMR.subscribe;a("before_beacon",o.av,null,null),a("onbeacon",o.rv,null,null),o.i=!0}return this},is_complete:function(){return!0}}}}()}(window);</script>
                                  <script>var w=window;if(w.performance||w.mozPerformance||w.msPerformance||w.webkitPerformance){var d=document;AKSB=w.AKSB||{},AKSB.q=AKSB.q||[],AKSB.mark=AKSB.mark||function(e,_){AKSB.q.push(["mark",e,_||(new Date).getTime()])},AKSB.measure=AKSB.measure||function(e,_,t){AKSB.q.push(["measure",e,_,t||(new Date).getTime()])},AKSB.done=AKSB.done||function(e){AKSB.q.push(["done",e])},AKSB.mark("firstbyte",(new Date).getTime()),AKSB.prof={custid:"82485",ustr:"",originlat:"0",clientrtt:"4",ghostip:"23.194.187.205",ipv6:false,pct:"10",clientip:"185.221.69.46",requestid:"1790a6ba",region:"26720",protocol:"h2",blver:14,akM:"dscx",akN:"ae",akTT:"O",akTX:"1",akTI:"1790a6ba",ai:"165266",ra:"false",pmgn:"",pmgi:"",pmp:"",qc:""},function(e){var _=d.createElement("script");_.async="async",_.src=e;var t=d.getElementsByTagName("script"),t=t[t.length-1];t.parentNode.insertBefore(_,t)}(("https:"===d.location.protocol?"https:":"http:")+"//ds-aksb-a.akamaihd.net/aksb.min.js")}</script>
                                  </head>
                <body class="demo-disable-bg-image">
                  <div id="sampleDemo" style="" class="demo-padding demo-container">
                    <div id="componentDemoContent" style="width: 1px; min-width: 100%;">
                      
                      <div id="progressBarWrapper">
                        <oj-progress style="width:50%" value="{{progressValue}}"></oj-progress>
                        <br/>
                        <oj-progress id="progressCircle" type="circle" value="{{progressValue}}"></oj-progress>
                        <br/>
                        <oj-input-number id="spinner-input" step="10" value="{{progressValue}}" aria-label="Enter a value for the oj-progress"></oj-input-number>
                        <oj-button id="indeterminateButton" data-bind="click: indeterminate">Indeterminate Value</oj-button>
                       </div>
              
                      
                    </div>
                  </div>
                </body>
              </html>

             

            (2) PFB the JS code for mfe-progress-bar(custom component that I have created)

            Note:I have just copied this code from Oracle JET cookbook.

              require(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojknockout', 'ojs/ojbutton', 'ojs/ojprogress', 'ojs/ojinputnumber'],
                function(oj, ko, $)
                {
                function ViewModel()
                {
                var self = this;
                self.progressValue = ko.observable(20);
                self.indeterminate = function() {
                self.progressValue(-1);
                };
                }
                ko.applyBindings(new ViewModel(), document.getElementById('progressBarWrapper'));
                });
             
            (3) CSS code
             

            mfe-progress-bar:not(.oj-complete){
              visibility: visible;
            }

            mfe-progress-bar{

            }

            PFB the HTML code of my page where I have added mfe-file-picker and mfe-progress-bar.

             <mfe-file-picker id="mfe-file-picker--59034198-1"></mfe-file-picker> 
              <mfe-progress-bar id="mfe-progress-bar--59034198-1"></mfe-progress-bar> 

            ---------------------------------------------------------------------------------------------------------------

            I am not able to understand 1 more thing , how oj-progress-bar is working in my application when I am copying the same line of code in my application- <oj-progress id="oj-progress-734762401-1" class="oj-flex-item oj-sm-12" value="30"></oj-progress>

            PFA the screenshot with name 'A' when I am using mfe-file-picker and mfe-progress-bar.

            PFA the screenshot with name 'B' when I am using mfe-file-picker and oj-progress.

            Thanks,

            Himanshu

            A.PNG (5KB)
            • Shay Shmeltzer

              You don't need to copy all this JET code into your VB - and in fact copying it will probably won't work like this.

              Specifically - in VB you already have the component available in the component palette so just drag and drop it into your page from the component palette. 

              Also the right way to bind components in VB is to variables you define in a page, not using knockout binding like the JET cookbook.

              JS functions should be implemented as page module functions in your page's JS section - then you can refer to them from your pages.

               

              • Himanshu Sethi

                Hi Shay

                For now I have used File Picker for upload section.

                PFA the screenshot for the same for below 2 issues.

                I am facing below 2 issues:

                (1) I want each file in next line along with file name and file speed , but in my case all file details are coming in a single line since it is an array.

                (2)I do not want duplicate files again to be uploaded for that I try to run my code but it is showing name is not undefined.

                PFB the HTML and JS code for MFE-FILE-PICKER for my application.

                HTML

                 <div id="parentContainer" style="padding:10px">
                          <label for="selected">Selected files: </label>
                          <table>
                          <tr><span id="selected" data-bind="text: ko.toJSON(fileNames)"></span></tr>
                          </table>
                          <oj-file-picker on-oj-select='[[selectListener]]'>
                             <div tabindex='0' slot='trigger'
                                    class='oj-filepicker-dropzone'>
                                 <p class='oj-filepicker-text'>I'm a clickable dropzone</p>
                              </div>
                            </oj-file-picker>          
                            <p></p>
                            <p></p>
                            <oj-file-picker class='oj-filepicker-custom'
                                            select-on='click'
                                            on-oj-select='[[selectListener]]'>
                              <oj-button slot='trigger'>
                                 <span slot='startIcon' class='oj-fwk-icon oj-fwk-icon-arrowbox-n'></span>
                                 Upload
                              </oj-button>
                            </oj-file-picker>

                JS

                var self = this;
                        function basicModel() {
                          self.fileNames = ko.observableArray([]);
                          self.selectListener = function(event) {
                            var files = event.detail.files;
                            for (var i = 0; i < files.length; i++) {
                                for(var k=0;k<=self.fileNames.length;k++)
                              {
                                if(files[i].name!=self.fileNames[k][name])
                                {
                                  self.fileNames.push(files[i].name + files[i].size);
                                  console.log("Himanshu" + self.fileNames);
                                }
                                else
                                {
                                  console.log("Himanshu" + self.fileNames);
                                }
                              } 
                                          }
                          }
                        }

                Please let me know if any other details are required.

                Thanks,

                Himanshu

                • Shay Shmeltzer

                  You still are using a "JET" approach for doing things (with knockout) instead of using the VB approach.

                  I would suggest you start with this blog for the basics of how to work with the file picker -

                  https://blogs.oracle.com/groundside/uploading-and-reading-a-text-file-in-visual-builder

                  For showing the files selected, you can assign the return from the ojSelect event into an array variable in VB. Then attach that array to a collection component such as a list to show each row in a separate line.

                   

                   

                  • Himanshu Sethi

                    Hi Shay

                    I have followed all the steps mentioned in "https://blogs.oracle.com/groundside/uploading-and-reading-a-text-file-in-visual-builder".

                    But I am facing problem in Step 6 - File Parsing Function

                    Till step 5 , I have done same thing in my application as mentioned in the given blog and I am getting the given message in console attached in the screenshot with name ''Step 5"

                    But after doing changes mentioned in step 6 , I am getting an error in console "TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'."

                    PFA the screenshot for the same with name "Error".

                    I know it's been a very long discussion regarding this topic , but I am thankful to you for your valuable responses.

                    Thanks,

                    Himanshu

                    Step 5.PNG (104KB)
                    • Duncan Mills

                      The chances are that you have misconfigured something - check that you are indeed passing $chain.variables.detail.files to the parsing function. Debugging the JavaScript would help you as well as that will tell you what is being passed into the function.  Note that the code supplied in the blog only expects text files so if you pass in an image then it will fail.  You need to use other file reading functions from the HTML File API to deal with binaries

                      • Himanshu Sethi

                        Hi Duncan/Shay

                        Thanks for your valuable response.

                        Can you please tell regarding mfe-file-picker , I am not able to upload more than 1 file , it is showing error attached in the screenshot 'Error-1.png'

                        PFB the JS CODE

                            require(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojknockout',
                                'ojs/ojfilepicker', 'ojs/ojbutton'
                              ],
                              function(oj, ko, $) {
                                var self = this;
                                function basicModel() {
                                  //self.fileNames = ko.observableArray([]);
                                   //var viewModel = {fileNames : ko.observable()};
                                  self.fileNames = ko.observable();
                                  
                                  self.selectListener = function(event) {
                                    var files = event.detail.files;
                                    
                                    for (var i = 0; i < files.length; i++) {
                                      self.fileNames=self.fileNames + self.fileNames(files[i].name + "   "   + files[i].size) ;
                                      }
                                  }
                                }
                                
                                $(function() {
                                  ko.applyBindings(new basicModel(), document.getElementById(
                                    'parentContainer'));
                                });

                              });

                         

                        PFB the HTML code

                         <tr><span id="selected" data-bind="text: fileNames"></span></tr> 

                        Thanks in Advance

                        Himanshu

                        • Duncan Mills

                          You should not be trying to use knockout in page module code and certainly never be calling applyBindings.  The equivalent functions of observables are supplied by Visual Builder variables, so your function should return the values you want set into the variables and then you use an assign variables action in the chain to map the results of this module function to those variables.  Any parts of the UI bound to the variables will then be notified

                          • Himanshu Sethi

                            Hi Duncan

                            I am new to VBCS , can you tell the exact steps to be followed for achieving the multiple file upload thing.

                            I tried the given below hyperlink that you have given in previous post "https://blogs.oracle.com/groundside/uploading-and-reading-a-text-file-in-visual-builder".

                            By using this link I was able to read a file in console but it has file content. I want to achieve file size , file name , file speed etc. For that only I am trying to use Knockout.js but using this I am getting all the file properties in array format in a single line but I need 1 file properties in 1 line , then next file properties in next line and so on.

                            I hope that I have made my point clear. Also I understand the response posted by you but I am failing to implement the same in VBCS.

                            It would be better if you can provide me HTML and JS code for multiple file upload functionality where each file properties should be displayed in different lines.

                            Thanks a lot for your valuable response.

                            • Shay Shmeltzer

                              If you are using the approach from the blog and you set the file picker to allow selection of multiple files, then in the ojSelect event the action chain gets the list of all the files in the details parameter to the action.

                              (Check the browser console to see the details as shown in the image)

                              This include info on the file name, type and size.

                              You can access that data in your action chain for example using:

                              [[ $chain.variables.detail.files[0].name ]]

                              • Himanshu Sethi

                                Hi Shay

                                I am able to achieve multiple file upload functionality in different lines.

                                I want to know how we can print the same filelist in console. I am using below line

                                console.log("Hi " + self.fileNames);

                                where fileNames is an observable array. But it is showing entire observable array and not the filelist.

                                PFB the JS part for the same.

                                function(oj, ko, $) {
                                        var self = this;
                                       
                                        function basicModel() {
                                          self.fileNames = ko.observableArray([]);
                                        
                                          removeFile = function() {
                                            self.fileNames.remove(this);
                                          };

                                          self.selectListener = function(event) {
                                            var files = event.detail.files;
                                            for (var i = 0; i < files.length; i++) {
                                              self.fileNames.push(files[i]);
                                               console.log("Hello " + self.fileNames);
                                                  }
                                          }

                                        }

                                Please let me know what command I should give to print all the file properties.

                                Thanks in Advance.

                                • Shay Shmeltzer

                                  You should be using a PageModule function into which you can pass the array of selected records and then you can use the console.log in a loop to print the info.

                                  An example of using a PageModule function is in this VB crash course video around min 21:

                                  https://youtu.be/tHDA-BJ53tM?t=1266

                                  More info on that - http://andrejusb.blogspot.com/2018/06/custom-javascript-client-code-in-oracle.html

                                  • Himanshu Sethi

                                    Hi Shay

                                    Actually I have created custom file picker component and there is no option of design in custom component. So I will not be able to design the component with any page module function in 'mfe-file-picker' custom component.

                                    I only want that no duplicate files should be uploaded and it should throw error once user is trying to upload it again.

                                    Hence I want to compare what is being uploaded and what already is there in self.filenames array.

                                    Please let me know if you need more details for the same.

                                    Thanks,

                                    Himanshu

                                    • Duncan Mills

                                      If you have created a custom component then just pass the existing file list variable into that component and then in the component code you can do what you want