No announcement yet.

TUTORIAL (Part 2): Alternative to the SC provided file uploader

  • Filter
  • Time
  • Show
Clear All
new posts

  • TUTORIAL (Part 2): Alternative to the SC provided file uploader

    Back to Part 1

    Step 4 - Modify an SC app to use the uploader

    So - with all the prep work done, you now need to update your SC app to use it all. plupload offers different versions of their "widget" - all are supplied / callable in the file you downloaded.

    "Core API" is the basic implementation (looks similar to the standard SC implementation, but is more flexible), "UI Widget" & "Queue Widget" - both are much nicer fuller upload interfaces. I use "UI Widget" in this tutorial. The plupload website shows live examples of the different types (and the source code to invoke) if you want to see or get more information.

    Application Background

    Before explaining how I use this, a very brief bit of background on the overall system it is used within.

    I have a timesheet management system which records, for a user, time they have spent working on projects per week. This is all entered in the SC PHP/database system as normal. However, for some users they need a paper copy of their timesheet signed by the client so they can get paid.

    The system allows them (optionally) to upload a scanned copy of that paper timesheet and add a link to their timesheet record pointing to that uploaded file. It is the uploading of this file that I use plupload for.

    The image below is a sample timesheet record. At the bottom you can see no uploaded timesheet file is there (and the button at the bottom says "upload timesheet").


    Clicking that "upload timesheet" button calls an SC control app (via sc_redir) that implements the plupload package - see image below.


    The control app comprises of the top rectangle (which is a plupload widget). The widget is "constructed" through code in the control form's OnLoad event - provided below. Aside from that code the form has a single manual field (not linked to anything) to hold some message text in the bottom rectangle. The button is a PHP button that closes the form and checks if anything was uploaded (by looking at the "upload_log.txt" file). It also updates the database with file information if there was anything uploaded. The 2 code elements follow. (NOTE: the global variable [from_app] is used to tell the calling form that it was called as a result of an upload attempt. This is so that calling app can do some specific tidying up it wouldn't do otherwise - plus reset [from_app] to "").

    The control also has a status message area (controlled by plupload) indicating it's readiness or any errors when uploading. It is an HTML element called "console".

    The "Upload Timesheet" button is a link calling the control form app. The form's onLoad event is the bit that uses the plupload plugin - the code is:

    {Hidden} = "Use this screen to upload a PDF or an image file of your timesheet (max. size 2MB). " .
    	"AFTER the upload has completed click 'Close Uploader' below.<br/>";
    [from_app] = "uploader";
    // Remove previous upload log file if present.
    $file = [jsp] . 'upload_log.txt';	
    if (file_exists($file)) {
    // To use the UI Widget - decomment next 3 lines
    echo '<link href="' . [jsp] . 'jquery.ui.plupload/css/jquery.ui.plupload.css" type="text/css" rel="stylesheet" meda="screen">';
    echo '<script src="' . [jsp] . 'plupload.full.min.js" type="text/javascript"></script>';
    echo '<script src="' . [jsp] . 'jquery.ui.plupload/jquery.ui.plupload.js" type="text/javascript"></script>';
    // To use the Queue Widget - decomment next 3 lines
    //echo '<link href="' . [jsp] . 'jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" rel="stylesheet" meda="screen">';
    //echo '<script src="' . [jsp] . 'plupload.full.min.js" type="text/javascript"></script>';
    //echo '<script src="' . [jsp] . 'jquery.plupload.queue/jquery.plupload.queue.js" type="text/javascript"></script>';
    $jsURL = [jsURL];
    $jsp = [jsp];
    $jspflash = [jspflash];
    $jspsilver = [jspsilver];
    echo <<<END
    <div id="uploader">
        <p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
    <pre id="console"><b><FONT COLOR="FFA500">Uploader is ready;</FONT></b></pre> 
    <script type="text/javascript">
    // Initialize the widget when the DOM is ready
    $(function() {
            // General settings
            runtimes : 'html5,flash,silverlight,html4',
            // Maximum file size
            max_file_size : '2mb',
            chunk_size: '1mb',
            // Specify what files to browse for
            filters : [
                {title : "Image files", extensions : "jpg,gif,png"},
                {title : "PDF files", extensions : "pdf"}
    		// Rename files by clicking on their titles
            rename: false,
            sortable: false,
            // Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
            dragdrop: true,
    		multi_selection: false,
    		prevent_duplicates: true,
    		max_file_count: 1,
            // Views to activate
            views: {
                list: true,
                thumbs: true, 		// Show thumbs
                active: 'thumbs'
            // Flash settings
            flash_swf_url : '$jspflash',		
            // Silverlight settings
            silverlight_xap_url : '$jspsilver',	
    		init : {
                PostInit: function() {
                    // Called after initialization is finished and internal event handlers bound
                    document.getElementById('uploadfiles').onclick = function() {
                        return false;
                FileUploaded: function(up, file, response) {
                    // Called when all files are either uploaded or failed
    				var response = jQuery.parseJSON( response.response );
    				if ((response.error) && (response.error.code > 500)) {
    					document.getElementById('console').innerHTML = 
    						'<b><FONT COLOR="FFA500">Error: ' + response.error.message + '</FONT></b>';
    				} else {
    					document.getElementById('console').innerHTML = 
    						'<b><FONT COLOR="FFA500">File uploaded successfully!</FONT></b>';
    I use the following local and global variable to control the paths for where plupload and other bits of its suite are. I do it this way because the paths differ between my dev and prod environments and this way I only change it in one place - in my case they're defined in my menu app.

    $jsURL = [jsURL];
    $jsp = [jsp];
    $jspflash = [jspflash];
    $jspsilver = [jspsilver];
    Here is a screen after a successful upload.


    After clicking on "Close Uploader" you are returned to the calling app. The code behind it is:

    // Check if log file exists first - if not then nothing was uploaded, so quit.
    $line = "";
    $file = [jsp] . 'upload_log.txt'; 
    if ( file_exists($file) ) {
    	// Check if an "ERROR:" in the log file - if not then it's the filename of uploaded file
    	// so update DB with that info.
    	$line = file_get_contents($file);
    	if (substr($line,0,6) != "ERROR:") {
    		$insert_sql = "UPDATE tbltimesheets SET SignedTimesheet = '" . $line . "' WHERE TimesheetID = '" .
    			[Record_TSID] . "'";	
    	} else {
    		$line = "";
    sc_redir(form_tbltimesheets,signedTS = $line,"_parent");
    You will see that the file uploaded is now a link, and the "upload" button has changed to a "delete" button.


    Clicking that "delete" button deletes the file from the server and updates the database accordingly. It is a PHP button with this code (also uses a confirmation message in the button's settings):

    if (trim([signedTS]) != "") {			// if there is an uploaded timesheet associated with this record...
    	if (!unlink([fp] . [signedTS])) {	// ... then try and delete it
    		// if fails may be a perimissions issue on folder
    		echo "<script type='text/javascript'>alert('File delete failed: " . [fp] . [signedTS] . ". " .
    			"File delete cancelled.');</script>";	
    $insert_sql = "UPDATE tbltimesheets SET SignedTimesheet = '' WHERE TimesheetID = '" . {TimesheetID} . "'";
    NOTE: [signedTS] is a global variable that holds the name of the uploaded file if a timesheet record has one - and [fp] is a global variable holding the filepath to where I store the uploaded files.

    That's pretty much the essentials - feel free to ask for clarifications if I've been a bit vague or unclear.


    Back to Part 1
    Last edited by adz1111; 03-16-2015, 09:00 PM.

  • #2
    Interesting. I also started playing with the standard jquery file uploader but then the blueimp version. DIdnt have the time to finish it tho..
    Thanks for sharing this.


    • #3
      Good, Thanks for sharing.


      • #4
        well done man! saved on bookmarks for future reference.


        • #5
          Fantastic !
          Hope scriptcase people read this tutorial


          • #6
            Originally posted by kakibox View Post
            Fantastic !
            Hope scriptcase people read this tutorial
            It could happen.

            Dave Prue
            Code Whisperer
            Lahar International Corp


            • #7
              very nice adz, very nice dude

              thanks a lot