Display image upload after page refresh - html

Hi i have a registration form with a avatar upload.
The form is working perfectly and i am happy with it, but i have 1 problem.
After i upload A avatar image and go onto the next page i can then go back to the registration page and the image remains in memory...
But i have no way of displaying it as i have no idea how to access the image as it is in memory somewhere.
But i can at this point complete my registration again without having to upload A image And the image is then displayed on the following page..
(the "required" is ignored in the form also as it has a file in memory)
Not sure if this explanation is doing me any favors but if any 1 can see from my code how i could again display the image if its in memory after a page refresh.
Thank you.
Simple Version.
"How Do I Access The Uploaded Image if Still in Memory And Display It Again On Page Refresh..."
<form id='login-form' name='formsub' class='form' action='../imageupload/formfillsignup.php' method='post' enctype='multipart/form-data'>
<label id='usernamelabel'>UserName</label>
<input id='em1' type='name' name='username' placeholder='3-15 Characters ' pattern='^[a-zA-Z][a-zA-Z0-9-_\. ]{3,15}$' autocomplete='new-password' required onChange='checkusername();' class='imp'/>
<label id='emaillabel'>Email</label>
<input id='em2' type='email' autocomplete='new-email' placeholder='Standard Email Format Required' name='email' pattern='[a-zA-Z0-9]+#[a-zA-Z0-9]+\.[a-zA-Z]{2,}'required onChange='alertemail();' class='imp' />
<label id='passwordlabel'>PassWord</label> <div class='reveal' id='revealPass' onclick='revealpasswords();' title='show/hide Passwords'></div>
<input id='p1' type='password' autocomplete='new-password' placeholder='1 UpperCase + 1 Number' name='password' pattern='(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' required onChange='alertpass();' class='imp' />
<label id='confirmpasswordlabel'>Confirm PassWord</label>
<input id='p2' type='password' autocomplete='new-password' placeholder='1 UpperCase + 1 Number ' name='confirmpassword' pattern='(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' required onChange='checkPasswordMatch();' class='imp'/>
<label class="custom-file-upload">
<input type="file" id="file1" name="avatar" accept="image/*" required />
<h7>Upload Avatar</h7>
</label>
<div class='image' id='imagediv'></div>
<button class='signupbutton' type='button' onclick='checkfile();'>Register</button>
</form>
<script>
$(function () {
$('input[type=file]').change(function () {
var val = $(this).val().toLowerCase(),
regex = new RegExp("(.*?)\.(jpg|jpeg|png|gif|bmp|JPG|JPEG|PNG|GIF|BMP)$");
if (!(regex.test(val))) {
$(this).val('');
$("#signintext").text("JPG JPEG PNG BMP GIF ONLY"), $("#signintext").css({"color":"#f40351"}), $( "#signintext" ).addClass( "errorglow" );
$('#imagediv').css('background-image', 'url("../images/mainpage/uploadimage.jpg")');
$('#imagediv').css('opacity','0.2');
}else
{
if (regex.test(val)) {
$("#signintext").text("Avatar Upload Completed"), $("#signintext").css({"color":"#03f4bc"}) , $( "#signintext" ).removeClass( "errorglow" );
var file = this.files[0];
var reader = new FileReader();
reader.onloadend = function () {
$('#imagediv').css('background-image', 'url("' + reader.result + '")');
$('#imagediv').css('opacity','1');
}
if (file) {
reader.readAsDataURL(file);
} else {
var file1=document.getElementById('file1');
file1.files.length == 0;
$(file1).val('');
return false;
}
}
}
});
</script>

When the page is refreshed the DOM is completely rebuilt. To retain the image across refreshes use localStorage. When the image is uploaded for the first time you would save it locally. When the page loads you would check localStorage for the existence of an image; if the image is present then you would load it into your image frame.
You need to save the image in base64 encoding. To do this listen for the file upload change event, and then use FileReader to encode as a data URL.
document.getElementById("file1").addEventListener('change', function() {
var file = this.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
localStorage.setItem("profileImageData", reader.result);
};
} );
When the page is loaded you need to check localStorage and add the encoded image. Loading an encoded image as a CSS background in JavaScript doesn't work so you'll have to insert it as an image.
window.onload = function() {
var profileImage = localStorage.getItem("profileImageData");
if (profileImage !== null) {
document.getElementyId("imagediv").innerHTML = "<img src='" + profileImage + "'>";
}
}

Related

What is the appropriate html5 input placeholder to paste a screenshot into?

I want to add an input box (a placeholder) where the user could paste a screenshot into. img is not going to do it as it requires the screenshot to be saved into an image file, then the scr be directed to it. Too cumbersome. I want a simple copy (or print screen) and paste to do it.
I modified the code from the following discussion:
HTML Paste Clipboard Image to File Input,
but it does not work.
<form id="new_document_attachment" method="post">
<div class="actions"><input type="submit" name="commit" value="Submit" /></div>
<img src="" alt="Screen Shot" id="image_attachment_doc">
</form>
<script>
const form = document.getElementById("new_document_attachment");
const imageInput = document.getElementById("image_attachment_doc");
imageInput.addEventListener('change', () => {
form.submit();
});
window.addEventListener('paste', e => {
imageInput.src = e.clipboardData.files;});
</script>
You need to convert the image data in the File object into a Data URL.
Thanks to Loading an image to a <img> from <input file>
Your example is also a bit limited in that although the image would show up, the page would reload almost immediately.
In the example below the form is not submitted.
const log = document.getElementById("log");
window.addEventListener('paste', e => {
var files = e.clipboardData.files;
//Put the file into an input so it will be included with the form submit
document.getElementById("files").files = files;
//This won't work because the src holds a string
//and the file object becomes serialized into "[object%20File]"
//This can be seen in the console
document.getElementById("img").src = files[0];
//Show image by loading it as an DataURL
var fr = new FileReader();
fr.onload = function() {
document.getElementById("img").src = fr.result;
}
fr.readAsDataURL(files[0]);
});
<form id="form" method="post">
<img id="img" alt="Screen Shot">
<input type="file" name="files" id="files" />
<input type="submit" />
</form>
<p>Press Ctrl+V to paste an image into this window</p>

show the list of files selected from different directories and ability to remove the files

I am trying to attach some files (zero/single/multiple) and send them as attachments to an email using ANGULARJS and spring.
One thing noticed is when selecting the files from multiple directories only the recently selected file is shown and previous selected file is not shown. How can I show all the files selected by the user from different directories too and give the ability to delete the file (all files or one file) before submitting the form.
Demo:http://plnkr.co/edit/M3f0TxHNozRxFEnrqyiF?p=preview
html:
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
TO: <input type="text" name="to" id="to" ng-model="to" required ></input><br>
Subject : <input type="text" name="subject" id="subject" ng-model="subject"></input>
<br>Attachment: <input type="file" ng-file-model="files" multiple /> <br>
<p ng-repeat="file in files">
{{file.name}}
</p>
<textarea rows="20" maxlength=35000 name="message" ng-model="message" ></textarea>
<button type="button" ng-click="upload()">Send</button>
</body>
js:
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.files = [];
$scope.upload=function(){
alert($scope.files.length+" files selected ... Write your Code to send the mail");
};
});
app.directive('ngFileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.ngFileModel);
var isMultiple = attrs.multiple;
var modelSetter = model.assign;
element.bind('change', function () {
var values = [];
angular.forEach(element[0].files, function (item) {
var value = {
// File Name
name: item.name,
//File Size
size: item.size,
//File URL to view
url: URL.createObjectURL(item),
// File Input Value
_file: item
};
values.push(value);
});
scope.$apply(function () {
if (isMultiple) {
modelSetter(scope, values);
} else {
modelSetter(scope, values[0]);
}
});
});
}
};
}]);
The default browser behavior is showing currently selected files, to cahnge that you've to customize that filed. And also, I saw your custom directive code, it doesn't allow to select multiple files from different directories.
So, what you can do is, create another scope variable & every time user selects file/files you push those files to this array. In this way you've have set of all selected files from same/different directories and then you can have delete functionality over each file which's ultimately going to be updated.
Updated html view part:
Attachment: <input type="file" ng-file-model="files" multiple /><br>
<p ng-repeat="file in filesToUpload track by $index">
{{file.name}} <span class="delete-file" ng-click="deleteFile($index)">X</span>
</p>
And for this new array update directive scope.$apply part as:
scope.$apply(function () {
if (isMultiple) {
modelSetter(scope, values);
} else {
modelSetter(scope, values[0]);
}
if(values){
scope.filesToUpload = scope.filesToUpload.concat(values);
}
});
In controller have deleteFile function as:
$scope.deleteFile = function(index){
$scope.filesToUpload.splice(index, 1);
};
Working Demo Example
Now user'll be able to delete files anytime. But the input field will still show the last selected file/files and after deleting particular file also it'll not change its status so for that you can just hide field by opacity: 0; css & then create customized Upload button & from that trigger click on actual hidden file input element.
Update: Check this update of same code with custom upload button:
Plunker Example

how to view image on mvc website instantly after uploading?

I have website with form I'am uploading image from using Html.BeginForm() through the controller. Uploaded image saves correctly (i see it in folder) but I can't see it on website. To do so I have to reload entire webbrowser.
How can I make image showing on my website after uploading? Website shows this image few times, on different views, always by <img scr="imagePatch"/>. New image just saves itself with the same name as previous one, replacing it.
there are many ways to do this
you can use html file api inside your form.
$(document).ready(function(){
// render the image in our view
function renderImage(input,file) {
// generate a new FileReader object
var reader = new FileReader();
// inject an image with the src url
reader.onload = function(event) {
the_url = event.target.result;
$('.img-preview__').remove();
$(input).after("<img class='img-preview__' src='" + the_url + "' />")
}
// when the file is read it triggers the onload event above.
reader.readAsDataURL(file);
}
// handle input changes ... you can change selector
$("#the-file-input").change(function(event) {
// grab the first image in the FileList object and pass it to the function
renderImage(event.target,this.files[0]);
});
});
this will work nice . either you can make your image preview look like better.
for image preview element use this css code
img.img-preview__ {
width: 120px;
border: 3px solid #ddd;
border-radius: 3px;
display: inline-block;
}
for example
<h2>Create</h2>
#using (Html.BeginForm("Create", "Image", null, FormMethod.Post,
new { enctype = "multipart/form-data" })) {
<fieldset>
<legend>Image</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ImagePath)
</div>
<div class="editor-field">
<input id="the-file-input" title="Upload a product image"
type="file" name="file" />
</div>
<p><input type="submit" value="Create" /></p>
</fieldset>
}
I hope this help

MVC 5 prevent page refresh on form submit

yBrowser: IE9
Technologies: MVC5
I am mainly using Angular for everything on my page. (Single Page App).
But because I am working with IE9, I can't use FileAPI.. So, I decided to go with MVC's Form Actions to get HttpPostedFileBase in my controller methods to handle fileupload.
Html Code: (Is present in a modal)
#using (Html.BeginForm("UploadTempFileToServer", "Attachment", FormMethod.Post, new { enctype = "multipart/form-data", id = "attachmentForm" }))
{
<div>
<span id="addFiles" class="btn btn-success fileinput-button" ng-class="{disabled: disabled}" onclick="$('#fileUpload').click();">
<span>Add files...</span>
</span>
<input id="fileUpload" type="file" name="files" class="fileInput" onchange="angular.element(this).scope().fileAdded(this)" />
</div>
<div>
<span class="control-label bold">{{currentFilePath}}</span>
<input name="fileUniqueName" value="{{fileUniqueName}}" />
<input id="attachmentSubmit" type="submit" value="Upload File" />
</div>
}
MVC Controller:
public void UploadTempFileToServer(IEnumerable<HttpPostedFileBase> files, string fileUniqueName)
{
var folderPath = fileStorageFolder;
foreach (var file in files)
{
if (file.ContentLength > 0)
{
file.SaveAs(folderPath + fileUniqueName);
}
}
}
Question #1: Does anyone know of a way to send the HttpPostedFileBase data to the controller, without using form's submit action?
I don't mind using Jquery if need be. I have tried hijacking the form's submit action and that didn't work.
I tried sending the file control's data using non submit button event, but no luck there either.
If not:
Question #2 How do I prevent the page from going to /Attachment/UploadTempFileToServer after the execution of submit is completed?
To answer #2 (and assuming you're using jQuery):
$(document).on('submit', '#attachmentForm', function(event){
event.preventDefault();
// everything else you want to do on submit
});
For #1, unfortunately, unless a browser supports XMLHttpRequest2 objects (which I don't believe IE9 does), you can't send file data via ajax. There are plugins that let you submit the form to a hidden iframe, though. I think Mike Alsup's Form plugin has that ability: http://malsup.com/jquery/form/#file-upload
So, after much research and attempts. This is my solution:
Using https://github.com/blueimp/jQuery-File-Upload/wiki
HTML:
Earlier I was using a hidden file upload control and triggering its click via a span. But because of security issues a file input which is opened by javascript can't be submitted by javascript too.
<div class="col-md-7">
<div class="fileupload-buttonbar">
<label class="upload-button">
<span class="btn btn-success btnHover">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
<input id="fileUpload" type="file" name="files"/>
</span>
</label>
</div>
</div>
Javascript:
$('#fileUpload').fileupload({
autoUpload: true,
url: '/Attachment/UploadTempFileToServer/',
dataType: 'json',
add: function (e, data) {
var fileName = data.files[0].name;
var ext = fileName.substr(fileName.lastIndexOf('.'), fileName.length);
var attachment = {
AttachmentName: fileName,
Extension: ext
}
var fileUniqueName = id + ext;
//Sending the custom attribute to C#
data.formData = {
fileUniqueName: fileUniqueName
}
data.submit().success(function (submitData, jqXhr) {
attachment.Path = submitData.path;
//Add the attachment to the list of attached files to show in the table.
$scope.attachmentControl.files.push(attachment);
//Since this is not a direct angular event.. Apply needs to be called for this to be bound to the view.
$scope.$apply();
}).error(function (errorData, textStatus, errorThrown) {
});
},
fail: function (data, textStatus, errorThrown) {
}
});
C#:
public virtual ActionResult UploadTempFileToServer(string fileUniqueName)
{
//Getting these values from the web.config.
var folderPath = fileStorageServer + fileStorageFolder + "\\" + tempFileFolder + "\\";
var httpPostedFileBase = this.Request.Files[0];
if (httpPostedFileBase != null)
{
httpPostedFileBase.SaveAs(folderPath + fileUniqueName);
}
return Json(new
{
path = folderPath + fileUniqueName
},
"text/html"
);
}

How to allow <input type="file"> to accept only image files?

I need to upload only image file through <input type="file"> tag.
Right now, it accepts all file types. But, I want to restrict it to only specific image file extensions which include .jpg, .gif etc.
How can I achieve this functionality?
Use the accept attribute of the input tag. To accept only PNG's, JPEG's and GIF's you can use the following code:
<label>Your Image File
<input type="file" name="myImage" accept="image/png, image/gif, image/jpeg" />
</label>
Or simply:
<label>Your Image File
<input type="file" name="myImage" accept="image/*" />
</label>
Note that this only provides a hint to the browser as to what file-types to display to the user, but this can be easily circumvented, so you should always validate the uploaded file on the server also.
It should work in IE 10+, Chrome, Firefox, Safari 6+, Opera 15+, but support is very sketchy on mobiles (as of 2015) and by some reports, this may actually prevent some mobile browsers from uploading anything at all, so be sure to test your target platforms well.
For detailed browser support, see http://caniuse.com/#feat=input-file-accept
Using this:
<input type="file" accept="image/*">
works in both FF and Chrome.
Use it like this
<input type="file" accept=".png, .jpg, .jpeg" />
It worked for me
https://jsfiddle.net/ermagrawal/5u4ftp3k/
Steps:
1. Add accept attribute to input tag
2. Validate with javascript
3. Add server side validation to verify if the content is really an expected file type
For HTML and javascript:
<html>
<body>
<input name="image" type="file" id="fileName" accept=".jpg,.jpeg,.png" onchange="validateFileType()"/>
<script type="text/javascript">
function validateFileType(){
var fileName = document.getElementById("fileName").value;
var idxDot = fileName.lastIndexOf(".") + 1;
var extFile = fileName.substr(idxDot, fileName.length).toLowerCase();
if (extFile=="jpg" || extFile=="jpeg" || extFile=="png"){
//TO DO
}else{
alert("Only jpg/jpeg and png files are allowed!");
}
}
</script>
</body>
</html>
Explanation:
The accept attribute filters the files that will be displayed in the
file chooser popup. However, it is not a validation. It is only a
hint to the browser. The user can still change the options in the
popup.
The javascript only validates for file extension, but cannot
really verify if the select file is an actual jpg or png.
So you have to write for file content validation on server side.
This can be achieved by
<input type="file" accept="image/*" />
But this is not a good way. you have to code on the server side to check the file an image or not.
Check if image file is an actual image or fake image
if(isset($_POST["submit"])) {
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if($check !== false) {
echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
}
else {
echo "File is not an image.";
$uploadOk = 0;
}
}
For more reference, see here
http://www.w3schools.com/tags/att_input_accept.asp
http://www.w3schools.com/php/php_file_upload.asp
Using type="file" and accept="image/*" (or the format you want), allow the user to chose a file with specific format. But you have to re check it again in client side, because the user can select other type of files.
This works for me.
<input #imageInput accept="image/*" (change)="processFile(imageInput)" name="upload-photo" type="file" id="upload-photo" />
And then, in your javascript script
processFile(imageInput) {
if (imageInput.files[0]) {
const file: File = imageInput.files[0];
var pattern = /image-*/;
if (!file.type.match(pattern)) {
alert('Invalid format');
return;
}
// here you can do whatever you want with your image. Now you are sure that it is an image
}
}
Just as an addition: if you want to include all modern image file types with the best cross-browser support it should be:
<input type="file" accept="image/apng, image/avif, image/gif, image/jpeg, image/png, image/svg+xml, image/webp">
This allows all image file types that can be displayed in most browsers while excluding less commons formats like TIFF or formats that are not suitable for the web like PSD.
you can use accept attribute for <input type="file"> read this docs http://www.w3schools.com/tags/att_input_accept.asp
You can add specific type of image or other file type and do validation in your code :
<input style="margin-left: 10px; margin-top: 5px;" type="file" accept="image/x-png,image/jpeg,application/pdf"
(change)="handleFileInput($event,'creditRatingFile')" name="creditRatingFile" id="creditRatingFile">
handleFileInput(event) {
console.log(event);
const file = event.target.files[0];
if (file.size > 2097152) {
throw err;
} else if (
file.type !== "application/pdf" &&
file.type !== "application/wps-office.pdf" &&
file.type !== 'application/pdf' && file.type !== 'image/jpg' && file.type !== 'image/jpeg' && file.type !== "image/png"
) {
throw err;
} else {
console.log('file valid')
}
}
In html;
<input type="file" accept="image/*">
This will accept all image formats but no other file like pdf or video.
But if you are using django, in django forms.py;
image_field = forms.ImageField(Here_are_the_parameters)
If you want to upload multiple images at once you can add multiple attribute to input.
upload multiple files: <input type="file" multiple accept='image/*'>
Simple and powerful way(dynamic accept)
place formats in array like "image/*"
var upload=document.getElementById("upload");
var array=["video/mp4","image/png"];
upload.accept=array;
upload.addEventListener("change",()=>{
console.log(upload.value)
})
<input type="file" id="upload" >
Other people's answers refactored for ReactJS (hooks)
import React from 'react';
const ImageUploader = () => {
const handleImageUpload = (e) => {
// If no file selected, return
if (e.target.files.length === 0) return false;
const file = e.target.files[0];
// If no image selected, return
if (!/^image\//.test(file.type)) {
alert(`File ${file.name} is not an image.`);
return false;
}
// ...
};
return (
<>
<input type='file' accept='image/*' onChange={(e) => handleImageUpload(e)} />
</>
);
};
export default ImageUploader;