Posted By

sinanazifi on 09/18/13


Tagged


Versions (?)

How to add a already loaded image into browser, into a form field of type 'file'.


 / Published in: HAML
 

This code can collect and Date and Description from user, then User can drag/drop an image in drop area to load it into browser OR if browser doesn't support drag/drop, then user can see a normal file input instead to browse and choose an image. after that user can determine a crop area for corresponding image. until here everything works charming. If I use a file input as a form field, after submit, in controller function ( by using WebImage static methods) I can get all images existing in request easily. Problem is when I use a drag/drop method to load a image in browser. then there is no File object in Request to could be retrieved in Controller using WebImage methods. How can I add this File object somehow to Request? I can't use Ajax because sometimes user needs to load image in browser and determine a Crop area for that.

  1. @model Progresspics_b14.Models.Level
  2.  
  3. @{
  4. ViewBag.Title = "Create";
  5. }
  6.  
  7. <script>
  8. function previewfile(file) {
  9. if (tests.filereader === true && acceptedTypes[file.type] === true) {
  10. var reader = new FileReader();
  11. reader.onload = function (event) {
  12. var image = new Image();
  13. image.id = "imgcrop";
  14. image.src = event.target.result;
  15.  
  16. // 'holder' always is holding only one image. If drag/drop multiple files, then only one last file will be holding there.
  17. // if there is already an image holded in 'holder', by drag/drop new image, old image will be replaced with new one.
  18. while (imageholder.childNodes.length > 0) {
  19. imageholder.removeChild(imageholder.lastChild);
  20. }
  21. imageholder.appendChild(image);
  22.  
  23. api = $.Jcrop('#imgcrop', { onSelect: storeCoords, aspectRatio: 1 / 2, boxWidth: document.getElementById('imageholder').clientWidth });
  24. };
  25.  
  26. reader.readAsDataURL(file);
  27. } else {
  28. holder.innerHTML += '<p>Uploaded ' + file.name + ' ' + (file.size ? (file.size / 1024 | 0) + 'K' : '');
  29. console.log(file);
  30. }
  31. }
  32.  
  33. function storeCoords(c) {
  34. jQuery('#X').val(c.x);
  35. jQuery('#Y').val(c.y);
  36. jQuery('#Z').val(c.w);
  37. jQuery('#A').val(c.h);
  38. }
  39.  
  40. function readfiles(files) {
  41.  
  42. var formData = tests.formdata ? new FormData() : null;
  43. for (var i = 0; i < files.length; i++) {
  44. if (tests.formdata) formData.append('file', files[i]);
  45. previewfile(files[i]);
  46. }
  47.  
  48. //// now post a new XHR request
  49. //if (tests.formdata) {
  50. // var xhr = new XMLHttpRequest();
  51. // xhr.open('POST', '/devnull.php');
  52. // xhr.onload = function() {
  53. // progress.value = progress.innerHTML = 100;
  54. // };
  55.  
  56. // if (tests.progress) {
  57. // xhr.upload.onprogress = function (event) {
  58. // if (event.lengthComputable) {
  59. // var complete = (event.loaded / event.total * 100 | 0);
  60. // progress.value = progress.innerHTML = complete;
  61. // }
  62. // }
  63. // }
  64. // xhr.send(formData);
  65. //}
  66. }
  67. </script>
  68. <style>
  69. #holder {
  70. border: 2px dashed #898989;
  71. min-height: 50px;
  72. text-align: center;
  73. }
  74.  
  75. #imageholder {
  76. border: 2px solid #ccc;
  77. clear: both; /*min-width: 50px;*/
  78. min-height: 50px; /* margin: 10px auto;*/
  79. }
  80.  
  81. #holder.hover {
  82. border: 5px dashed #0c0;
  83. }
  84.  
  85. #Text { /*width: 220px;*/
  86. margin: 10px auto 0 auto;
  87. position: relative;
  88. text-align: left;
  89. color: #bbb;
  90. font-size: 15px;
  91. }
  92.  
  93. #holder img {
  94. display: block;
  95. margin: 10px auto;
  96. }
  97.  
  98. #holder p {
  99. margin: 10px;
  100. font-size: 14px;
  101. }
  102.  
  103. progress {
  104. width: 100%;
  105. }
  106.  
  107. progress:after {
  108. content: '%';
  109. }
  110.  
  111. .fail {
  112. background: #c00;
  113. padding: 2px;
  114. color: #fff;
  115. }
  116.  
  117. .hidden {
  118. display: none !important;
  119. }
  120. </style>
  121.  
  122. <h2>Create</h2>
  123. <br />
  124. <div>
  125. @using (Html.BeginForm("create", "Level", FormMethod.Post, new { id = "upload_form", enctype = "multipart/form-data" }))
  126. {
  127.  
  128. @Html.AntiForgeryToken()
  129. @Html.ValidationSummary(true)
  130.  
  131. <fieldset>
  132. <legend>Level</legend>
  133. @Html.HiddenFor(model => model.PostId)
  134.  
  135. <div class="editor-label">
  136. @Html.LabelFor(model => model.LevelDate)
  137. </div>
  138. <div>
  139. <input type="date" id="LevelDate" name="LevelDate" title="Date" />
  140. @Html.ValidationMessageFor(model => model.LevelDate)
  141. </div>
  142.  
  143. <div class="editor-label">
  144. @Html.LabelFor(model => model.Description)
  145. </div>
  146. <div class="editor-field">
  147. @Html.EditorFor(model => model.Description)
  148. @Html.ValidationMessageFor(model => model.Description)
  149. </div>
  150.  
  151. <div id="holder">
  152. <div id="Text">DROP HERE ('jpeg', 'gif', 'png')</div>
  153. </div>
  154. <p id="alt_upload">
  155. <label>
  156. Drag & drop not supported, but you can still upload via this input field:<br>
  157. <input type="file" id="uplaod_filedialog">
  158. </label>
  159. </p>
  160. <p id="filereader">File API & FileReader API not supported</p>
  161. <p id="formdata">XHR2's FormData is not supported</p>
  162. <p id="progress">XHR2's upload progress isn't supported</p>
  163.  
  164. <div id="imageholder"></div>
  165.  
  166. <input type="hidden" id="X" />
  167. <input type="hidden" id="Y" />
  168. <input type="hidden" id="Z" />
  169. <input type="hidden" id="A" />
  170.  
  171. <script>
  172. var imageholder = document.getElementById('imageholder'),
  173. holder = document.getElementById('holder'),
  174. tests = {
  175. filereader: typeof FileReader != 'undefined',
  176. dnd: 'draggable' in document.createElement('span'),
  177. formdata: !!window.FormData,
  178. },
  179. support = {
  180. filereader: document.getElementById('filereader'),
  181. formdata: document.getElementById('formdata'),
  182. progress: document.getElementById('progress')
  183. },
  184. acceptedTypes = {
  185. 'image/png': true,
  186. 'image/jpeg': true,
  187. 'image/gif': true
  188. },
  189. fileupload = document.getElementById('alt_upload');
  190.  
  191. "filereader formdata progress".split(' ').forEach(function (api) {
  192. if (tests[api] === false) {
  193. support[api].className = 'fail';
  194. } else {
  195. // I could have done el.hidden = true, but IE doesn't support
  196. // hidden, so I tried to create a polyfill that would extend the
  197. // Element.prototype, but then IE10 doesn't even give me access
  198. // to the Element object. Brilliant.
  199. support[api].className = 'hidden';
  200. }
  201. });
  202.  
  203. if (tests.dnd) {
  204. fileupload.className = 'hidden';
  205. holder.className = '';
  206. holder.ondragover = function () { this.className = 'hover'; return false; };
  207. holder.ondragend = function () { this.className = ''; return false; };
  208. holder.ondrop = function (e) {
  209. this.className = '';
  210. e.preventDefault();
  211. readfiles(e.dataTransfer.files);
  212. $('#upload_form').in {
  213. formData: { example: 'test' }
  214.  
  215. });
  216. };
  217. } else {
  218. holder.className = 'hidden';
  219. fileupload.className = '';
  220. fileupload.querySelector('input').onchange = function () {
  221. readfiles(this.files);
  222. };
  223. }
  224. </script>
  225.  
  226. <p>
  227. <input type="submit" value="Save" />@Html.ActionLink("Back to List", "Index")
  228. </p>
  229.  
  230. </fieldset>
  231. }
  232. </div>
  233.  
  234.  
  235. @section Scripts {
  236. @Scripts.Render("~/bundles/jqueryval")
  237. }

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: pakbaz on September 19, 2013

if you don't want to use ajax that try create an input element (or use the same one you have for other browser) on the fly using javascript, then you can prevent default action and do the trick and add file to its value. but I still think ajax is better just because you do everything in backend, if you crop it you can then modify the image on server based on values you get after page submit. As for me I remember what I used after trying all those, I used telerik which is free for MVC ( I am not sure about license terms) anyway here is my code and in hidden field I catch the value after form submit.

function FileUploadSuccess(e) { if (e.operation == "upload") { $("#hiddenFileUpload").val(getFileInfo(e)); //alert('uploaded'); } else if (e.operation == "remove") { $("#hiddenFileUpload").val(""); //alert('deleted'); } } function getFileInfo(e) { return $.map(e.files, function (file) { var info = file.name;

            // File size is not available in all browsers
            //if (file.size > 0) {
            //    info += " (" + Math.ceil(file.size / 1024) + " KB)";
            //}
            return info;
        }).join(", ");
    }

                    @(Html.Telerik().Upload().Name("pictures").Multiple(false)
                            .Async(async => async.Save("Save", "Upload").Remove("Remove", "Upload").AutoUpload(true))
                            .ClientEvents(e => e.OnSuccess("FileUploadSuccess")))
                    @Html.Hidden("hiddenFileUpload")

You need to login to post a comment.