{"id":1161,"date":"2014-03-04T09:00:31","date_gmt":"2014-03-04T03:30:31","guid":{"rendered":"http:\/\/ramkulkarni.com\/blog\/?p=1161"},"modified":"2014-03-04T09:00:31","modified_gmt":"2014-03-04T03:30:31","slug":"cfmobile-example-taking-picture-and-uploading-to-coldfusion-server","status":"publish","type":"post","link":"http:\/\/ramkulkarni.com\/blog\/cfmobile-example-taking-picture-and-uploading-to-coldfusion-server\/","title":{"rendered":"CFMobile Example &#8211; Taking picture and uploading to ColdFusion server"},"content":{"rendered":"<p>In this post I am going to show you how to create a mobile application using ColdFusion Splendor that can take a picture and upload the picture to CF server. This application uses Camera and File APIs.<\/p>\n<p>The application is very simple &#8211; it has two buttons, one to take picture and the other one to set URL where pictures are to be uploaded. You can set URL of the server before taking a picture or after, just before it is to be uploaded. Once the URL is set, it is stored in the localStorage and will be remembered. \u00a0There is a messages div where the\u00a0application\u00a0displays messages about different operations it is performing.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1163\" data-permalink=\"http:\/\/ramkulkarni.com\/blog\/cfmobile-example-taking-picture-and-uploading-to-coldfusion-server\/2014_03_04_image1\/\" data-orig-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1.png?fit=480%2C800\" data-orig-size=\"480,800\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"2014_03_04_image1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1.png?fit=180%2C300\" data-large-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1.png?fit=480%2C800\" class=\"alignnone size-medium wp-image-1163\" alt=\"2014_03_04_image1\" src=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1-180x300.png?resize=180%2C300\" width=\"180\" height=\"300\" srcset=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1.png?resize=180%2C300 180w, https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image1.png?w=480 480w\" sizes=\"(max-width: 180px) 100vw, 180px\" data-recalc-dims=\"1\" \/><\/a> <a href=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1164\" data-permalink=\"http:\/\/ramkulkarni.com\/blog\/cfmobile-example-taking-picture-and-uploading-to-coldfusion-server\/2014_03_04_image2\/\" data-orig-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2.png?fit=480%2C800\" data-orig-size=\"480,800\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"2014_03_04_image2\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2.png?fit=180%2C300\" data-large-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2.png?fit=480%2C800\" class=\"alignnone size-medium wp-image-1164\" alt=\"2014_03_04_image2\" src=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2-180x300.png?resize=180%2C300\" width=\"180\" height=\"300\" srcset=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2.png?resize=180%2C300 180w, https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image2.png?w=480 480w\" sizes=\"(max-width: 180px) 100vw, 180px\" data-recalc-dims=\"1\" \/><\/a> <a href=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3.png\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1165\" data-permalink=\"http:\/\/ramkulkarni.com\/blog\/cfmobile-example-taking-picture-and-uploading-to-coldfusion-server\/2014_03_04_image3\/\" data-orig-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3.png?fit=480%2C800\" data-orig-size=\"480,800\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"2014_03_04_image3\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3.png?fit=180%2C300\" data-large-file=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3.png?fit=480%2C800\" class=\"alignnone size-medium wp-image-1165\" alt=\"2014_03_04_image3\" src=\"https:\/\/i0.wp.com\/138.197.85.232\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3-180x300.png?resize=180%2C300\" width=\"180\" height=\"300\" srcset=\"https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3.png?resize=180%2C300 180w, https:\/\/i0.wp.com\/ramkulkarni.com\/blog\/wp-content\/uploads\/2014\/03\/2014_03_04_image3.png?w=480 480w\" sizes=\"(max-width: 180px) 100vw, 180px\" data-recalc-dims=\"1\" \/><\/a><\/p>\n<p><!--more-->Here is HTML UI code in the index.cfm &#8211;<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #bc7a00;\"><!--<span class=\"hiddenSpellError\" pre=\"\"-->DOCTYPE html&gt;<\/span>\n\n<span style=\"color: #008000; font-weight: bold;\">&lt;h1&gt;<\/span>CFMobile Photo Demo App <span style=\"color: #008000; font-weight: bold;\">&lt;\/h1&gt;<\/span>\nThis demo app shows how to take picture and upload to CF server using CFMobile features.<span style=\"color: #008000; font-weight: bold;\">&lt;br&gt;<\/span>\n\n<span style=\"color: #008000; font-weight: bold;\">&lt;button<\/span>  <span style=\"color: #7d9029;\">type=<\/span><span style=\"color: #ba2121;\">\"button\"<\/span> <span style=\"color: #7d9029;\">id=<\/span><span style=\"color: #ba2121;\">\"takePictBtn\"<\/span><span style=\"color: #008000; font-weight: bold;\">&gt;<\/span>Take Picture <span style=\"border: 1px solid #FF0000;\">&amp;<\/span> Upload<span style=\"color: #008000; font-weight: bold;\">&lt;\/button&gt;&lt;br&gt;<\/span>\n<span style=\"color: #008000; font-weight: bold;\">&lt;button<\/span> <span style=\"color: #7d9029;\">type=<\/span><span style=\"color: #ba2121;\">\"button\"<\/span> <span style=\"color: #7d9029;\">id=<\/span><span style=\"color: #ba2121;\">\"setServerURLBtn\"<\/span><span style=\"color: #008000; font-weight: bold;\">&gt;<\/span>Set Server URL<span style=\"color: #008000; font-weight: bold;\">&lt;\/button&gt;<\/span>\n<span style=\"color: #008000; font-weight: bold;\">&lt;h2&gt;<\/span>Messages<span style=\"color: #008000; font-weight: bold;\">&lt;\/h2&gt;<\/span>\n<span style=\"color: #008000; font-weight: bold;\">&lt;div<\/span> <span style=\"color: #7d9029;\">id=<\/span><span style=\"color: #ba2121;\">\"msgDiv\"<\/span><span style=\"color: #008000; font-weight: bold;\">&gt;&lt;\/div&gt;<\/span><\/pre>\n<\/div>\n<p>Then there is a JavaScript block where I register event handlers for buttons. I also have a utility function to display messages in \u00a0the msgDiv &#8211;<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000; font-weight: bold;\">&lt;script &gt;<\/span>\n\t<span style=\"color: #008000;\">document<\/span>.getElementById(<span style=\"color: #ba2121;\">\"setServerURLBtn\"<\/span>).onclick <span style=\"color: #666666;\">=<\/span> <span style=\"color: #008000; font-weight: bold;\">function<\/span>(){\n\t\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> serverUrl <span style=\"color: #666666;\">=<\/span> <span style=\"color: #ba2121;\">\"\"<\/span>;\n\t\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (<span style=\"color: #008000; font-weight: bold;\">typeof<\/span> localStorage.serverUrl <span style=\"color: #666666;\">!==<\/span> <span style=\"color: #ba2121;\">\"undefined\"<\/span>)\n\t\t\tserverUrl <span style=\"color: #666666;\">=<\/span> localStorage.serverUrl;\n\t\tserverUrl <span style=\"color: #666666;\">=<\/span> prompt(<span style=\"color: #ba2121;\">\"Enter Server URL\"<\/span>,serverUrl);\n\t\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (serverUrl <span style=\"color: #666666;\">!=<\/span> <span style=\"color: #008000; font-weight: bold;\">null<\/span>)\n\t\t\tlocalStorage.serverUrl <span style=\"color: #666666;\">=<\/span> serverUrl;\n\t};\n\n\t<span style=\"color: #008000;\">document<\/span>.getElementById(<span style=\"color: #ba2121;\">\"takePictBtn\"<\/span>).onclick <span style=\"color: #666666;\">=<\/span> <span style=\"color: #008000; font-weight: bold;\">function<\/span>(){\n\t\ttakePictureAndUpload();\n\t};\n\n\t<span style=\"color: #008000; font-weight: bold;\">function<\/span> displayMessage (msg, append)\n\t{\n\t\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> divElm <span style=\"color: #666666;\">=<\/span> <span style=\"color: #008000;\">document<\/span>.getElementById(<span style=\"color: #ba2121;\">\"msgDiv\"<\/span>);\n\t\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (append <span style=\"color: #666666;\">!=<\/span> <span style=\"color: #008000; font-weight: bold;\">undefined<\/span> <span style=\"color: #666666;\">&amp;&amp;<\/span> <span style=\"color: #666666;\">!<\/span>append)\n\t\t\tdivElm.innerHTML <span style=\"color: #666666;\">=<\/span> <span style=\"color: #ba2121;\">\"\"<\/span>;\n\t\tdivElm.innerHTML <span style=\"color: #666666;\">+=<\/span> msg;\n\t}\n<span style=\"color: #008000; font-weight: bold;\">&lt;\/script&gt;<\/span><\/pre>\n<\/div>\n<p>Event handler for the\u00a0setServerURLBtn first checks if server url is already stored in the localStorage. If yes, it\u00a0initializes input field with that url. After user enters the URL, this function sets it to localstorage.serverUrl variable.<\/p>\n<p>Event handler for\u00a0takePictBtn calls\u00a0takePictureAndUpload function which we will see in the cfclient block later. Note that I am not assigning\u00a0takePictureAndUpload directly to the event handler because when that code is executed by the browser, cfclient block is not initialized yet and so\u00a0takePictureAndUpload function would not be available.<\/p>\n<p>Remaining\u00a0code in this file is cfclient code. First we enable device APIs (required because we are going to use Camera APIs) in cfclientsettings tag. Then we start cfclient block.<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000; font-weight: bold;\">&lt;cfclientsettings<\/span> <span style=\"color: #7d9029;\">enabledeviceapi=<\/span><span style=\"color: #ba2121;\">\"true\"<\/span> <span style=\"color: #008000; font-weight: bold;\">&gt;<\/span>\n<span style=\"color: #008000; font-weight: bold;\">&lt;cfclient&gt;<\/span>\n\t<span style=\"color: #008000;\">&lt;cfscript&gt;<\/span>\n          <span style=\"color: #408080; font-style: italic;\">\/\/TODO: code to take picture and upload to server<\/span>\n         <span style=\"color: #008000;\">&lt;\/cfscript&gt;<\/span>\n<span style=\"color: #008000; font-weight: bold;\">&lt;\/cfclient&gt;<\/span><\/pre>\n<\/div>\n<p>We will now add functions in the cfscript block of cfclient. The first function is\u00a0takePictureAndUpload &#8211;<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #19177c;\">function<\/span> <span style=\"color: #0000ff;\">takePictureAndUpload<\/span>()\n{\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">imageUrl<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">cfclient.camera.getPicture<\/span>();\n\n\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (<span style=\"color: #666666;\">!<\/span><span style=\"color: #0000ff;\">isDefined<\/span>(<span style=\"color: #ba2121;\">\"imageUrl\"<\/span>) <span style=\"color: #666666;\">||<\/span> <span style=\"color: #19177c;\">imageUrl.length<\/span> <span style=\"color: #666666;\">==<\/span> <span style=\"color: #666666;\">0<\/span>)\n\t\t<span style=\"color: #19177c;\">return<\/span>;\n\n\t<span style=\"color: #0000ff;\">displayMessage<\/span>(<span style=\"color: #ba2121;\">\"Temporary image - \"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">imageUrl<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"&lt;br&gt;&lt;hr&gt;\"<\/span>, <span style=\"color: #19177c;\">false<\/span>);\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/This file is in a temporary file system. Move it to persistent file system<\/span>\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">newFilePath<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">copyFileFromTempToPersistentFileSystem<\/span>(<span style=\"color: #19177c;\">imageUrl<\/span>);\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/Now upload file to the server<\/span>\n\t<span style=\"color: #0000ff;\">uploadFileToServer<\/span>(<span style=\"color: #19177c;\">newFilePath<\/span>);\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/Delete temporary file<\/span>\n\t<span style=\"color: #0000ff;\">cfclient.file.remove<\/span>(<span style=\"color: #19177c;\">imageUrl<\/span>);\n\t<span style=\"color: #0000ff;\">displayMessage<\/span>(<span style=\"color: #ba2121;\">\"Deleted temporaty file \"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">imageUrl<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"&lt;br&gt;&lt;hr&gt;\"<\/span>);\n}<\/pre>\n<\/div>\n<p>cfclient.camera.getPicture() launches device&#8217;s camera application. Depending on options passed to this function, it either returns path of the saved picture or picture data in base64 format. In this application I am not passing any options and the API returns path of the picture file.<br \/>\nPhoneGap supports two kinds of file system types &#8211; persistent and temporary. Files generated by device APIs are generally stored in the temporary file system. As the name suggest, all files stored in this file system are temporary in nature and many not be available later. So I need to move the picture file from temporary file system to \u00a0persistent file system. I will do that in\u00a0copyFileFromTempToPersistentFileSystem that we will see shortly.<\/p>\n<p>Once I get path of the file (returned by\u00a0copyFileFromTempToPersistentFileSystem)\u00a0in persistent file system, I call another function, uploadFileToServer and then delete temporary file.<\/p>\n<p>Here is the code for \u00a0copyFileFromTempToPersistentFileSystem function &#8211;<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #19177c;\">function<\/span> <span style=\"color: #0000ff;\">copyFileFromTempToPersistentFileSystem<\/span> (<span style=\"color: #19177c;\">tempFilePath<\/span>)\n{\n\t<span style=\"color: #408080; font-style: italic;\">\/\/save existing file system<\/span>\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">oldFileSystem<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">cfclient.file.getFileSystem<\/span>();\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/Get file object from the path<\/span>\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">tmpFile<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">cfclient.file.get<\/span>(<span style=\"color: #19177c;\">tempFilePath<\/span>);\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/set persistent file system<\/span>\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">persistentfileSystem<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">cfclient.file.setFileSystem<\/span>(<span style=\"color: #ba2121;\">\"persistent\"<\/span>);\n\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">newFilePath<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #19177c;\">persistentfileSystem.root.fullPath<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"\/\"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">tmpFile.name<\/span>;\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/If file with the same name exists in the persistent file system, then try save<\/span>\n\t<span style=\"color: #408080; font-style: italic;\">\/\/it with different name<\/span>\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">count<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #666666;\">1<\/span>;\n\t<span style=\"color: #0000ff;\">while<\/span> (<span style=\"color: #19177c;\">count<\/span> <span style=\"color: #666666;\">&lt;<\/span> <span style=\"color: #666666;\">10<\/span>)\n\t{\n\t\t<span style=\"color: #19177c;\">try<\/span>\n\t\t{\n\t\t\t<span style=\"color: #0000ff;\">cfclient.file.get<\/span>(<span style=\"color: #19177c;\">newFilePath<\/span>);\n\n\t\t\t<span style=\"color: #408080; font-style: italic;\">\/\/file already exists. Try different file name<\/span>\n\t\t\t<span style=\"color: #19177c;\">count<\/span><span style=\"color: #666666;\">++<\/span>;\n\t\t\t<span style=\"color: #19177c;\">newFilePath<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #19177c;\">persistentfileSystem.root.fullPath<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"\/\"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #0000ff;\">replace<\/span>(<span style=\"color: #19177c;\">tmpFile.name<\/span>,<span style=\"color: #ba2121;\">\".\"<\/span>,<span style=\"color: #ba2121;\">\"_\"<\/span>) <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"_\"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">count<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\".jpg\"<\/span>;\n\t\t}\n\t\t<span style=\"color: #0000ff;\">catch<\/span> (<span style=\"color: #19177c;\">any<\/span> <span style=\"color: #19177c;\">e<\/span>) {\n\t\t\t<span style=\"color: #408080; font-style: italic;\">\/\/Assume file does not exists. Go ahead and copy from temp location to persistent location.\t<\/span>\n\t\t\t<span style=\"color: #0000ff;\">console.log<\/span>(<span style=\"color: #ba2121;\">\"Exception : \"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">e.message<\/span>);\n\t\t\t<span style=\"color: #008000; font-weight: bold;\">break<\/span>;\n\t\t}\n\t}\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/Copy file<\/span>\n\t<span style=\"color: #0000ff;\">cfclient.file.copy<\/span>(<span style=\"color: #19177c;\">tempFilePath<\/span>,<span style=\"color: #19177c;\">newFilePath<\/span>);\n\t<span style=\"color: #0000ff;\">displayMessage<\/span>(<span style=\"color: #ba2121;\">\"Image file copied to \"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">newFilePath<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"&lt;br&gt;&lt;hr&gt;\"<\/span>);\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/Restore old file system<\/span>\n\t<span style=\"color: #0000ff;\">cfclient.file.setFileSystem<\/span>(<span style=\"color: #19177c;\">oldFileSystem.name<\/span>);\n\n\t<span style=\"color: #408080; font-style: italic;\">\/\/return new file path<\/span>\n\t<span style=\"color: #19177c;\">return<\/span> <span style=\"color: #19177c;\">newFilePath<\/span>;\n}<\/pre>\n<\/div>\n<p>And\u00a0uploadFileToServer function &#8211;<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #19177c;\">function<\/span> <span style=\"color: #0000ff;\">uploadFileToServer<\/span>(<span style=\"color: #19177c;\">imageFilePath<\/span>)\n{\n\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (<span style=\"color: #666666;\">!<\/span><span style=\"color: #0000ff;\">structKeyExists<\/span>(<span style=\"color: #19177c;\">localStorage<\/span>,<span style=\"color: #ba2121;\">\"serverUrl\"<\/span>))\n\t{\n\t\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">serverUrl<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">prompt<\/span>(<span style=\"color: #ba2121;\">\"Enter Server URL\"<\/span>,<span style=\"color: #19177c;\">serverUrl<\/span>);\n\t\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (<span style=\"color: #19177c;\">serverUrl<\/span> <span style=\"color: #666666;\">!=<\/span> <span style=\"color: #19177c;\">null<\/span>)\n\t\t\t<span style=\"color: #19177c;\">localStorage.serverUrl<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #19177c;\">serverUrl<\/span>;\n\t\t<span style=\"color: #008000; font-weight: bold;\">else<\/span>\n\t\t{\n\t\t\t<span style=\"color: #0000ff;\">alert<\/span>(<span style=\"color: #ba2121;\">\"No file uploaded\"<\/span>);\n\t\t\t<span style=\"color: #19177c;\">return<\/span>;\n\t\t}\n\t}\n\n\t<span style=\"color: #0000ff;\">displayMessage<\/span>(<span style=\"color: #ba2121;\">\"uploading file to \"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">localStorage.serverUrl<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #ba2121;\">\"&lt;br&gt;&lt;hr&gt;\"<\/span>);\n\n\t<span style=\"color: #008000; font-weight: bold;\">var<\/span> <span style=\"color: #19177c;\">uploadOptions<\/span> <span style=\"color: #666666;\">=<\/span> {\n\t\t<span style=\"color: #19177c;\">fileKey<\/span>:<span style=\"color: #ba2121;\">\"uploadedPicture\"<\/span>,\n\t\t<span style=\"color: #19177c;\">fileName<\/span>:<span style=\"color: #ba2121;\">\"uploadedPictured.jpg\"<\/span>\n\t};\n\n\t<span style=\"color: #0000ff;\">cfclient.file.upload<\/span>(<span style=\"color: #19177c;\">imageFilePath<\/span>, <span style=\"color: #19177c;\">localStorage.serverUrl<\/span>,\n\t\t\t<span style=\"color: #19177c;\">onFileUploaded<\/span>, <span style=\"color: #19177c;\">uploadError<\/span>, <span style=\"color: #19177c;\">uploadOptions<\/span>\n\t);\n\n\t<span style=\"color: #19177c;\">function<\/span> <span style=\"color: #0000ff;\">onFileUploaded<\/span>()\n\t{\n\t\t<span style=\"color: #0000ff;\">displayMessage<\/span>(<span style=\"color: #ba2121;\">\"File uploaded successfully\"<\/span>);\n\t}\n\n\t<span style=\"color: #19177c;\">function<\/span> <span style=\"color: #0000ff;\">uploadError<\/span>(<span style=\"color: #19177c;\">err<\/span>)\n\t{\n\t\t<span style=\"color: #408080; font-style: italic;\">\/\/See error codes at http:\/\/docs.phonegap.com\/en\/3.3.0\/cordova_file_file.md.html#FileTransferError<\/span>\n\t\t<span style=\"color: #008000; font-weight: bold;\">if<\/span> (<span style=\"color: #19177c;\">err.code<\/span> <span style=\"color: #666666;\">==<\/span> <span style=\"color: #666666;\">3<\/span>)\n\t\t\t<span style=\"color: #0000ff;\">alert<\/span>(<span style=\"color: #ba2121;\">\"Error uploading file - Connection error\"<\/span>);\n\t\t<span style=\"color: #008000; font-weight: bold;\">else<\/span>\n\t\t\t<span style=\"color: #0000ff;\">alert<\/span>(<span style=\"color: #ba2121;\">\"Error uploading file. Code - \"<\/span> <span style=\"color: #666666;\">+<\/span> <span style=\"color: #19177c;\">err.code<\/span>);\n\t}\n\n}<\/pre>\n<\/div>\n<p>This function first checks if user has already entered URL where files is to be uploaded. If it is not set, then it prompts user to enter the URL. Then it sets form field options in\u00a0uploadOptions struct.<br \/>\nImage data would be sent in a form field assigned to\u00a0fileKey field. In this application it is &#8220;uploadedPicture&#8221;. As per <a href=\"http:\/\/docs.phonegap.com\/en\/3.3.0\/cordova_file_file.md.html#FileUploadOptions\" target=\"_blank\">PhoneGap docs<\/a>\u00a0fileName field tells \u00a0server the name to be used when saving the uploaded file. But I found that this field is not passed to the server, or server does not save file with the name assigned to this field. I have not investigated if the bug is in PhoneGap or cfclient implementation.<\/p>\n<p>cfclient.file.upload function actually sends file data to the server. Third and fourth argument to this function are success and error calbacks respectively. In this example those are\u00a0onFileUploaded \u00a0(success callback) and\u00a0uploadError (error callback) functions.<\/p>\n<p>That completes the client side code. Now let&#8217;s see how the server-side code (to receive uploaded file and save it on the server) could be written (it is in fileUploadHandler.cfm in server folder of this project) &#8211;<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #408080; font-style: italic;\">&lt;!--- Save uploaded file from a mobile application ---&gt;<\/span>\n<span style=\"color: #008000;\">&lt;cfif<\/span> <span style=\"color: #0000ff;\">structKeyExists<\/span>(<span style=\"color: #19177c;\">form<\/span>,<span style=\"color: #ba2121;\">\"uploadedPicture\"<\/span>)<span style=\"color: #008000;\">&gt;<\/span>\n\t<span style=\"color: #008000;\">&lt;cftry&gt;<\/span>\n\t\t<span style=\"color: #408080; font-style: italic;\">&lt;!--- save file in the current folder ---&gt;<\/span>\n\t\t<span style=\"color: #008000;\">&lt;cfset<\/span> <span style=\"color: #19177c;\">fileInfo<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">getFileInfo<\/span>(<span style=\"color: #19177c;\">form.uploadedPicture<\/span>)<span style=\"color: #008000;\">&gt;<\/span>\n\n\t\t<span style=\"color: #008000;\">&lt;cfset<\/span> <span style=\"color: #19177c;\">path<\/span> <span style=\"color: #666666;\">=<\/span> <span style=\"color: #0000ff;\">getDirectoryFromPath<\/span>(<span style=\"color: #0000ff;\">getTemplatePath<\/span>()) <span style=\"color: #666666;\">&amp;<\/span> <span style=\"color: #ba2121;\">\"\/\"<\/span> <span style=\"color: #666666;\">&amp;<\/span> <span style=\"color: #19177c;\">fileInfo.name<\/span> <span style=\"color: #666666;\">&amp;<\/span> <span style=\"color: #ba2121;\">\".jpg\"<\/span><span style=\"color: #008000;\">&gt;<\/span>\n\t\t<span style=\"color: #008000;\">&lt;cffile<\/span> <span style=\"color: #19177c;\">action<\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #ba2121;\">\"copy\"<\/span> <span style=\"color: #19177c;\">destination<\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #ba2121;\">\"#path#\"<\/span> <span style=\"color: #19177c;\">source<\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #ba2121;\">\"#form.uploadedPicture#\"<\/span> <span style=\"color: #008000;\">&gt;<\/span>\n\t<span style=\"color: #008000;\">&lt;cfcatch<\/span> <span style=\"color: #19177c;\">type<\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #ba2121;\">\"any\"<\/span> <span style=\"color: #19177c;\">name<\/span><span style=\"color: #666666;\">=<\/span><span style=\"color: #ba2121;\">\"e\"<\/span><span style=\"color: #008000;\">&gt;<\/span>\n\t\t<span style=\"color: #008000; font-weight: bold;\">&lt;cflog<\/span> <span style=\"color: #7d9029;\">text=<\/span><span style=\"color: #ba2121;\">\"#e.message#\"<\/span> <span style=\"color: #008000; font-weight: bold;\">&gt;<\/span>\n\t<span style=\"color: #008000;\">&lt;\/cfcatch&gt;<\/span>\n\t<span style=\"color: #008000;\">&lt;\/cftry&gt;<\/span>\n<span style=\"color: #008000;\">&lt;\/cfif&gt;<\/span><\/pre>\n<\/div>\n<p>Note that the uploaded file date is stored in the form field &#8220;uploadedPicture&#8221;, as specified in the client side code in uploadFileToServer function. The above code saves picture file in the same folder as the CFML file processing it.<\/p>\n<p>I have provided links to download Android application and Thunder project below. If you download the project, you will see that client side code is in the root folder of the project and server-side code is in a subfolder called &#8216;server&#8217;. There is Application.cfm in the root of the project and another one in the &#8216;server&#8217; folder. It is important that client and server CFML code have their own Application.cfm.<br \/>\nI have added Application.cfm in the project root so that I could run this application in the Shell app. But since server folder is a child of project folder, it would use Application.cfm in the project root, if it does not have its own Application.cfm. So I included an empty Application.cfm in the server folder too. It would be better to have client and server code in completely independent folders, but in this case I added server folder in the root of client folder to simplify packaging of the project.<\/p>\n<p>You will find all uploaded pictures from this application in CFMobilePhotoApp\/server folder on the server.<\/p>\n<p>When you package the application in Thunder, make sure you select only index.cfm in project properties-&gt;ColdFusion Mobile Project-&gt;Resource Selection tab.<\/p>\n<p><a href=\"http:\/\/ramkulkarni.com\/temp\/2014-03-04\/CFMobilePhotoApp.zip\" target=\"_blank\">Download project<\/a> and <a href=\"http:\/\/ramkulkarni.com\/temp\/2014-03-04\/CFMobilePhotoApp.apk\" target=\"_blank\">Android APK<\/a>\u00a0for this application.<\/p>\n<p>-Ram Kulkarni<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post I am going to show you how to create a mobile application using ColdFusion Splendor that can take a picture and upload the picture to CF server. This application uses Camera and File APIs. The application is very simple &#8211; it has two buttons, one to take picture and the other one &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/ramkulkarni.com\/blog\/cfmobile-example-taking-picture-and-uploading-to-coldfusion-server\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;CFMobile Example &#8211; Taking picture and uploading to ColdFusion server&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[32,23,78,17,1],"tags":[94,96,24,13,97],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2g9O8-iJ","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1161"}],"collection":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/comments?post=1161"}],"version-history":[{"count":0,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/posts\/1161\/revisions"}],"wp:attachment":[{"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/media?parent=1161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/categories?post=1161"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ramkulkarni.com\/blog\/wp-json\/wp\/v2\/tags?post=1161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}